1. 程式人生 > >ASP.NET Core on K8S深入學習(3)Deployment

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
View Code

  更多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

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。