本篇已加入《.NET Core on K8S學習實踐系列文章索引》,能夠點擊查看更多容器化技術相關係列文章。html
上一篇《部署過程解析與安裝Dashboard》中咱們瞭解K8S的部署過程,這一篇咱們來了解一下K8S爲咱們提供的幾種應用運行方式:Deployment、DaemonSet與Job,它們是Kubernetes最重要的核心功能提供者。考慮到篇幅和更新速度,我將其分爲兩篇文章,本篇會主要介紹Deployment,主要參考自CloudMan《天天5分鐘玩轉Kubernetes》,也推薦你們購買閱讀。node
K8S支持兩種建立資源的方式,分別是 使用kubectl命令直接建立 與 經過配置文件+kubectl apply建立,下面以上一篇中的ASP.NET Core示例來分別介紹下這兩種方式。web
第一種是經過kubectl命令直接建立:api
kubectl run k8s-demo-deployment --image=edisonsaonian/k8s-demo:latest --replicas=2 --namespace=aspnetcore
這樣咱們就部署了一個具備2個副本的k8s-demo(一個ASP.NET Core API示例)。app
第二種是經過配置文件+kubectl apply(kubectl create也能夠)建立:ide
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.htmlspa
如上所示,咱們將資源的屬性都寫在了一個yaml格式的配置文件中,有了這個配置文件,咱們只須要執行一句:3d
kubectl apply -f k8s-demo-deployment.yaml
若是要刪除deployment,也只須要執行一句:日誌
kubectl delete deployment k8s-demo-deployment
或者是下面這一句:
kubectl delete -f k8s-demo-deployment.yaml
執行以後,K8S會自動幫咱們刪除相關Deployment、ReplicaSet(副本集)以及Pod。
能夠看出,直接經過kubectl建立會比較省力和快捷,可是它沒法作到很好的管理,不適合正式的、規模化的部署,所以咱們通常會更加傾向於採用配置文件的方式,可是使用配置文件要求咱們熟悉yaml的語法,若是存在相似製表符之類的特殊字符都是沒法成功執行的。
這裏咱們仍以上面提到的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,也能夠看出對象的命名方式的規則:
所謂伸縮,是指在線實時增長或減小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
最終結果以下圖所示:
同理,若是想縮小副本數量,也是如上所述的步驟,再也不贅述。
所謂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的。
默認狀況下,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快速入門》