2020-08-31|閱讀時間 ‧ 約 10 分鐘

使用K8S Deployment來部屬App

總結一下,前幾篇介紹了:
1. 使用Minikube安裝Kubernetes 2. 將Docker image部屬到Minikube 3. 透過K8S Ingress 和 NodePort service直接連線Pod中的App 簡單的說,我們開發完成後,會將app build成一個docker image,透過指令指定image建立k8s pod,將我們開發好的app部屬在k8s pod中。
有發現不方便的地方了嗎? 也就是每次我只要有change,我必須從頭開始,把最新的code build成image,將舊的pod刪掉,然後再透過指令建立最新的pod,將最新的app部屬到k8s pod中。
因此,這邊可以使用K8S 的一個resource,叫做Deployment
一般來說,實務上我們不會直接把app部屬到pod,而是會使用Deployment,使用它有很多好處呢!
例如:
1. code進版後,我們可以直接把pod刪除,讓Deployment直接幫我們根據最新的image長出新的pod。 = 也就是說Deployment會幫忙redeploy pod,一旦有pod死掉或刪除,會自動重新長出來,可以指定要多少pod。
2. 指定image tag來取代目前的pod。
如果是照著前幾篇過來的,先把前面建立的pod, service, ingress都刪除:
$ kubectl delete pods hello-world
$ kubectl delete svc hello-world
$ kubectl delete ingress vic-example
-------------------------------------------------------------------------------------
以下內容, 會一步一步教學如何使用K8S Deployment來部屬App,即使沒看過前面幾篇也沒關係,因為在大部分情況下,都會直接用Deployment。 在開始之前,先啟動minikube:
$ minikube start --driver=docker
$ eval $(minikube docker-env)
=> 這個指令一定要做,才能使用local image
建立docker image: 按照之前的教學,建立image vic/hello_world,這邊不再贅述。
建立Deployment: 使用本機image 「vic/hello_world」 建立 「hello-world」 deployment:
$ kubectl create deployment hello-world --image=vic/hello_world
kubectl create deployment這個語法,加上之前提到的--image-pull-policy=Never來使用本機image,會發現根本沒有這個語法,因此先建立好deployment後再來修改,取得dashboard url:
$ minikube dashboard --url
瀏覽器打開dashboard,找到剛建立的Deployment來編輯:
原本imagePullPolicy是Always改為Never!
查詢剛剛建立的deployment:
$ kubectl get deployment hello-world
可以看到pod也被建立上去了:
$ kubectl get pods
建立Service:
使用 kubectl expose指令公開 Deployment,創建「hello-world」 Service:
$ kubectl expose deployment hello-world --port=6000 --target-port=5000
可以看到service已經建立上去了:
注意: 這邊跟上篇提到的node port是不一樣的,這邊是ClusterIP。
建立ingress:
接著照著上篇的教學,啟用ingress(如果已經有做過上篇,應該已經enable過了):
$ minikube addons enable ingress
Ingress需要撰寫yaml檔來做設定,以 minikube 內建的 Nginx Ingress 為例,建立一個hello-world-ingress.yaml:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
 name: vic-example
 annotations:
   nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
 rules:
 - host: hello.world.minikube
   http:
     paths:
     - path: /(.*|$)
       backend:
         serviceName: hello-world
         servicePort: 6000
其中host是對外的domain name,有點類似在設定apache的server name,設定好申請的domain即可從外部直接連線過來。 serviceName跟servicePort則填寫上面建立好的Service。
建立一個名為vic-example的Ingress:
$ kubectl apply -f hello-world-ingress.yaml


查看Ingress:
$ kubectl get ingress


由於這只是範例,並不是真的有hello.world.minikube這個domain name,因此為了模擬測試,可以在/etc/hosts中加入host ip mapping:
$ sudo nano /etc/hosts
打開瀏覽器測試APP:
了解Deployment的好處:
1. 試著把pod刪除看看:
可以發現,才剛刪除沒多久,就自動長出pod了。
2. 讓 Deployment 用指定 tag 的 image 取代原本的 Pod:
首先,假如我們有新版本的code開發完了:
build一個 v2.0 tag 的 image:
$ docker build -t vic/hello_world:v3.0 .
查看docker images:
$ docker images
接著讓 Deployment 用指定 tag 的 image 取代原本的 Pod:
$ kubectl set image deployment/hello-world hello-world-rf7wm=vic/hello_world:v2.0 --record
#kubectl set image deployment-name container-name=image-name
其中hello-world-rf7wm=container name,要從dashboard那邊查,找到Deployment後,按下編輯的圖示,如下圖紅框:
在 Pod 重新建立後,可以驗證一下 image 是不是更新了:
$ kubectl get pods -l app=hello-world -o jsonpath='{.items[0].spec.containers[0].image}'
檢查 Deployment 的歷史紀錄,確認是否有更新:
$ kubectl rollout history deployment hello-world
由於service跟ingress前面都建立過了是一樣的,所以直接用瀏覽器打開app看有無更新:
#Note:
刪除Deployment:
$ kubectl delete deployment xxx


刪除 Service:
$ kubectl delete svc xxx


刪除 Ingress:
$ kubectl delete ingress xxx


分享至
成為作者繼續創作的動力吧!
小弟是一位軟體工程師,樂於幫助他人,撰寫技術文章除了幫助自己複習以外,也希望可以幫助到他人,若文章內容有誤,還請大大不吝給予指教!
© 2024 vocus All rights reserved.