Giới thiệu
Link bài viết gốc trên blog của mình: https://ductn.info/controller-kubernetes-with-golang-2/
Nối tiếp phần 1
mình thực hiện tiếp 1 tool
cho cụm kubernetes sử dụng thư viện client-go.
Ở phần trước, mình đã demo in ra list tên của các pods
trong cụm kubernetes
,
trong phần này mình sẽ làm 1 tool giúp chúng có thể update phiên bản image
đang được sử dụng trong deployment
và deploy lại container theo image mới.
Trông ứng dụng sẽ như thế này :3
Link source code đây nha: https://github.com/ductnn/kugo
Start
Vẫn giống như phần trước,
để bắt đầu anh em cài đặt golang và set up cụm kubernetes, sau đó anh em có
thể xem lại bước 1-2
ở phần 1 để khởi tạo tool nhé :3.
package main import ( "context" "flag" "fmt" "os" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/homedir"
) // Kube config path
func GetKubeConfigPath() string { var kubeConfigPath string homeDir := homedir.HomeDir() if _, err := os.Stat(homeDir + "/.kube/config"); err == nil { kubeConfigPath = homeDir + "/.kube/config" } else { fmt.Println("Enter kubernetes config directory: ") fmt.Scanf("%s", kubeConfigPath) } return kubeConfigPath
} func main() { // Set Kube config kubeConfigPath := GetKubeConfigPath() fmt.Println(kubeConfigPath) // Build configuration from config file config, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath) if err != nil { panic(err) } // Create clientser clientset, err := kubernetes.NewForConfig(config) if err != nil { panic(err) }
}
Mình sử dụng flag là package nổi tiếng của golang
hỗ trợ chúng ta truyền vào các flags
ở command
. Ví dụ như demo ở bên trên
mình truyền vào 3 flags
sau khi build file main.go.
-deployment test-app
-app test-app
-image ductn4/green-rain:v2
Chúng ta sẽ dùng flag
để tạo những commad flags như ví dụ trên. Chúng ta có
thể sử dụng os.Args[]
từ os package
. Đối với cli tool
nhỏ thì dùng os.Args[]
xong check. Còn không dùng flag
sẽ tiện hơn. Ngoài ra, flag
hỗ trợ luôn -h
cho chúng ta để show ra ý nghĩa của flag trong command:
➜ kugo git:(master) ✗ ./main -h
/Users/ductn/.kube/config
Usage of ./main: -app string application name (default "app") -deployment string deployment name -image string new image name
OK!!! Bắt đầu tạo ra các flags
:
deploymentName := flag.String("deployment", "", "deployment name")
imageName := flag.String("image", "", "new image name")
appName := flag.String("app", "app", "application name") flag.Parse() if *deploymentName == "" { fmt.Println("The deployment name must be specify.") os.Exit(0)
}
if *imageName == "" { fmt.Println("The new image name must be specify.") os.Exit(0)
}
-deployment name:<string>
: Tên của deployment
đang chạy.
-app name:<string>
: Tên của ứng dụng đang chạy.
-image name:<string>
: Tên image mới cần deploy.
Sau khi tạo xong flag
, chúng ta khởi tạo deployment
, phần này giống như
khởi tạo pods
trong phần trước:
// Create Deployment
deployment, err := clientset.AppsV1().Deployments("default").Get(context.TODO(), *deploymentName, metav1.GetOptions{})
if err != nil { panic(err)
}
Tiếp theo, chúng ta thực hiện check để kiểm tra trạng thái của deployment
xem có bị lỗi hoặc chưa deploy:
if errors.IsNotFound(err) { fmt.Printf("Deployment not found\n")
} else if statusError, isStatus := err.(*errors.StatusError); isStatus { fmt.Printf("Error getting deployment%v\n", statusError.ErrStatus.Message)
} else if err != nil { panic(err)
} else { // Next step ...
}
Kiểm tra xong, chúng ta sẽ thực hiện thay thế image
cũ thành image
mới:
containers := &deployment.Spec.Template.Spec.Containers
found := false for i := range *containers { c := *containers if c[i].Name == *appName { fmt.Println("Old Version Image: ", c[i].Image) fmt.Println("New Version Image: ", *imageName) c[i].Image = *imageName found = true }
}
Cuối cùng, chúng ta sẽ update
lại deployment
theo phiên bản mới của image
_, err := clientset.AppsV1().Deployments("default").Update(context.TODO(), deployment, metav1.UpdateOptions{})
if err != nil { panic(err)
}
Demo
Bước 1: Mình sẽ deploy 1 deployment
cùng với service: NodePort
, mình
có tạo sẵn 1 file deployment
ở đây
anh em có thể dùng luôn:
➜ test git:(master) ✗ kubectl apply -f deployment.yml
service/app-service created
deployment.apps/test-app created
➜ test git:(master) ✗ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/test-app-64d48d75c7-ctztl 1/1 Running 0 51s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/app-service NodePort 10.99.148.96 <none> 3000:32691/TCP 51s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3m31s NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/test-app 1/1 1 1 51s NAME DESIRED CURRENT READY AGE
replicaset.apps/test-app-64d48d75c7 1 1 1 51s
Mình sử dụng image: ductn4/green-rain:v1.0.1
để build 1 hiệu ứng nhỏ, anh em
bật vô xem đẹp lắm :3
Bước 2: Build đống code vừa viết nào :3, sau khi build xong sẽ sinh ra 1
file main
➜ kugo git:(master) ✗ go build main.go
➜ kugo git:(master) ✗ ls
README.md go.mod go.sum main main.go test
Bước 3: Thực thi file main
vừa tạo ra:
➜ kugo git:(master) ✗ ./main -deployment test-app -app test-app -image ductn4/green-rain:v2
/Users/ductn/.kube/config
Found deployment
Name deployment: test-app
Old Version Image: ductn4/green-rain:v1.0.1
New Version Image: ductn4/green-rain:v2
Anh em thấy đã có thông báo thay đổi version của image
, Check tý coi :3
➜ kugo git:(master) ✗ kubectl describe pods test-app-67c5b469d7-9k6lb
Name: test-app-67c5b469d7-9k6lb
Namespace: default
Priority: 0
Node: minikube/192.168.49.2
Start Time: Mon, 16 Aug 2021 23:58:39 +0700
Labels: app=test-app pod-template-hash=67c5b469d7
Annotations: <none>
Status: Running
IP: 172.17.0.4
IPs: IP: 172.17.0.4
Controlled By: ReplicaSet/test-app-67c5b469d7
Containers: test-app: Container ID: docker://bd06a004dee744207fd955191ed1df2e204254b1a44a2e1f0cc8e7c9bef20a4d Image: ductn4/green-rain:v2 Image ID: docker-pullable://ductn4/_@.com:31ec7424010c546d7cc028bf0355ec9dd58e4818e8cc3e266ff44a9ff7a3c109 Port: 3000/TCP Host Port: 0/TCP State: Running Started: Mon, 16 Aug 2021 23:58:48 +0700 Ready: True ...
Vậy là image
đã được update và deploy thành công, anh em vô xem lại hiệu ứng
nha, ver 2 nhìn xịn hơn ver 1 ở trên :3.
Mình đã làm xong tiếp 1 cái tool nhỏ nữa, anh em nào còn có ý tưởng gì hay hay chia sẻ để có thể cùng làm nha :3
Cảm ơn anh em đã đọc ???.