ASP.NET Core on K8S深入學習(3)Deployment
上一篇《部署過程解析與安裝Dashboard》中我們瞭解K8S的部署過程,這一篇我們來了解一下K8S為我們提供的幾種應用執行方式:Deployment、DaemonSet與Job,它們是Kubernetes最重要的核心功能提供者。考慮到篇幅和更新速度,我將其分為兩篇文章,本篇會主要介紹Deployment,主要參考自CloudMan《每天5分鐘玩轉Kubernetes》,也推薦大家購買閱讀。
一、建立資源的兩種方式
K8S支援兩種建立資源的方式,分別是 使用kubectl命令直接建立 與 通過配置檔案+kubectl apply建立,下面以上一篇中的ASP.NET Core示例來分別介紹下這兩種方式。
1.1 Kubectl命令直接建立
第一種是通過kubectl命令直接建立:
kubectl run k8s-demo-deployment --image=edisonsaonian/k8s-demo:latest --replicas=2 --namespace=aspnetcore
這樣我們就部署了一個具有2個副本的k8s-demo(一個ASP.NET Core API示例)。
1.2 YAML配置檔案建立
第二種是通過配置檔案+kubectl apply(kubectl create也可以)建立:
apiVersion: apps/v1 kind: Deployment metadata: name: k8s-demo-deployment namespace: aspnetcore spec: replicas: 2 template: spec: containers: - name: k8s-demo image: edisonsaonian/k8s-demo ports: - containerPort: 80
不過,上面的配置檔案可能並不能直接執行,因為預設情況下K8S還有一些必填項的驗證,完整你可以參考下面這段配置:
apiVersion: apps/v1 kind: Deployment metadata: name: k8s-demo-deployment namespace: aspnetcore spec: replicas: 2 selector: matchLabels: app: aspnetcore_webapi template: metadata: labels: app: aspnetcore_webapi spec: containers: - name: k8s-demo image: edisonsaonian/k8s-demo ports: - containerPort: 80
更多yaml檔案的語法基礎,可以參考這一篇文章:https://www.kubernetes.org.cn/1414.html
如上所示,我們將資源的屬性都寫在了一個yaml格式的配置檔案中,有了這個配置檔案,我們只需要執行一句:
kubectl apply -f k8s-demo-deployment.yaml
1.3 相關補充
如果要刪除deployment,也只需要執行一句:
kubectl delete deployment k8s-demo-deployment
或者是下面這一句:
kubectl delete -f k8s-demo-deployment.yaml
執行之後,K8S會自動幫我們刪除相關Deployment、ReplicaSet(副本集)以及Pod。
可以看出,直接通過kubectl建立會比較省力和快捷,但是它無法做到很好的管理,不適合正式的、規模化的部署,因此我們一般會更加傾向於採用配置檔案的方式,但是使用配置檔案要求我們熟悉yaml的語法,如果存在類似製表符之類的特殊字元都是無法成功執行的。
二、Deployment必知必會
2.1 Deployment型別應用執行
這裡我們仍以上面提到的k8s-demo示例專案為例,通過下面這個配置檔案來建立資源:
apiVersion: apps/v1 kind: Deployment metadata: name: k8s-demo-deployment namespace: aspnetcore spec: replicas: 2 selector: matchLabels: app: aspnetcore_webapi template: metadata: labels: app: aspnetcore_webapi spec: containers: - name: k8s-demo image: edisonsaonian/k8s-demo ports: - containerPort: 80
通過下面的命令建立資源:
kubectl apply -f k8s-demo-deployment.yaml
下面我們來看看K8S到底為我們做了些什麼工作:
(1)檢視k8s-demo-deployment狀態
kubectl get deployment k8s-demo-deployment -n aspnetcore
可以看到,對於我們的這個deployment,生成了2個副本且正常執行。
如果想要獲得更加相信的資訊,可以使用下面這句:
kubectl describe deployment k8s-demo-deployment -n aspnetcore
從deployment的日誌中,可以看到如下圖所示的資訊:
可以看到,K8S的Deployment-Controller為k8s-demo建立了一個ReplicaSet名叫k8s-demo-deployment-54d5c97fb7,後面的Pod就是由這個ReplicaSet來管理的。
(2)檢視ReplicaSet的狀態
kubectl describe replicaset -n aspnetcore
會得到以下兩個圖所示的資訊:
從上圖可以看出,這個ReplicaSet是由Deployment k8s-demo-deployment 建立的。
從上圖中的日誌(Events代表日誌)可以看出,兩個副本Pod是由ReplicaSet-Controller建立的,且建立成功。
(3)檢視Pod的狀態
kubectl describe pod -n aspnetcore
同樣,也會得到如下圖所示的兩個資訊:
可以看出,此Pod是由ReplicaSet k8s-demo-deployment-54d5c97fb7建立的。下圖的日誌記錄了Pod的啟動過程:
從日誌中可以看到Pod的啟動過程,如果啟動過程中發生了異常(比如拉取映象失敗),都可以通過輸出的錯誤資訊檢視原因。
下圖是整個Deployment的部署過程,即kubectl→Deployment→ReplicaSet→Pod,也可以看出物件的命名方式的規則:
2.2 伸縮Scale
所謂伸縮,是指線上實時增加或減少Pod的副本數量。在剛剛的部署中,我們在配置檔案中定義的是2個副本,如下圖所示:
可以看到,兩個副本分別位於k8s-node1 和 k8s-node2上面。一般預設情況下,K8S不會將Pod排程到Master節點上,雖然Master節點也是可以作為Node節點晒用的。
這時,如果我們想要擴充套件副本數量從2到3,只需要修改配置檔案:
apiVersion: apps/v1 kind: Deployment metadata: name: k8s-demo-deployment namespace: aspnetcore spec: replicas: 3
......
然後再次apply:
kubectl apply -f k8s-demo-deployment.yaml
最終結果如下圖所示:
同理,如果想縮小副本數量,也是如上所述的步驟,不再贅述。
2.3 故障轉移FailOver
所謂K8S中的故障轉移(FailOver),就是當某個Node節點失效或宕機時,會將該Node上所執行的所有Pod轉移到其他健康的Node節點上繼續執行。
這裡繼續上例,我們有兩個Pod都執行在k8s-node2上,那麼我們這裡模擬k8s-node2故障,強制關閉該節點:
halt -h
等待一段時間後(放心,不會很快),當K8S檢測到k8s-node2不可用,會將k8s-node2上的Pod最終標記為Terminating狀態,並在k8s-node1上新建兩個Pod,維持副本總數量為3。
當然,也可以從Dashboard中直觀的看到:
當k8s-node2恢復後,Terminating的Pod會自動被刪除,不過已經執行在k8s-node1的Pod是不會重新排程回k8s-node2的。
2.4 善用label控制Pod位置
預設情況下,K8S的Scheduler會均衡排程Pod到所有可用的Node節點,但是有些時候希望將指定的Pod部署到指定的Node節點。例如,一個I/O密集型的Pod可以儘量部署在配置了SSD的Node節點,又或者一個需要GPU的Pod可以儘量部署在配置了GPU的Node節點上。
不用擔心,K8S為我們提供了label來實現這個功能,label是一個key/value對,可以靈活設定各種自定義的屬性。比如,我們這裡假設我們的k8s-demo示例專案是一個I/O密集型的API,還假設k8s-node1是一個配置了SSD的Node節點:
kubectl label node k8s-node1 disktype=ssd
kubectl get node --show-labels
顯示結果如下:可以看到,現在k8s-node多了一個label => disktype=ssd
接下來,我們就可以在配置檔案中為要部署的應用指定label了:
apiVersion: apps/v1 kind: Deployment metadata: name: k8s-demo-deployment namespace: aspnetcore spec: replicas: 3 selector: matchLabels: app: aspnetcore_webapi template: metadata: labels: app: aspnetcore_webapi spec: containers: - name: k8s-demo image: edisonsaonian/k8s-demo ports: - containerPort: 80 nodeSelector: disktype: ssd
然後,再次apply建立資源:
kubectl apply -f k8s-demo-deployment.yaml
驗證一下,所有的k8s-demo的Pod全都排程到了k8s-node1上面,符合預期:
如果k8s-node1不再是配置SSD了,那麼我們就可以為其刪掉這個label了:
kubectl label node k8s-node1 disktype-
注意,這裡的 - 就代表刪除,而且此時Pod不會重新部署,除非你刪除配置檔案中的配置然後再次apply。
三、小結
本文介紹了K8S中建立資源的兩種方式及對比,然後重點介紹了一下Deployment這個Controller,把玩了Deployment型別的應用執行、伸縮、故障轉移以及使用label來控制Pod的位置。執行應用是K8S最核心的功能,下一篇會繼續研究DaemonSet和Job這兩個Controller的應用方式和場景。當然,筆者也還是初學,有很多不足之處,也請多包涵。對於催更的童鞋,請耐心等待。
參考資料
(1)CloudMan,《每天5分鐘玩轉Kubernetes》
(2)李振良,《一天入門Kubernets教程》
(3)馬哥(馬永亮),《Kubernetes快速入門》
作者:周旭龍
出處:https://edisonchou.cnblogs.com
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。