1. 程式人生 > 其它 >02-k8s各應用管理器與pod介紹

02-k8s各應用管理器與pod介紹

Deployment StatefulSet DaemonSet

前言:Deployment的發展

雖然ReplicaSet可以確保在任何給定時間執行的Pod副本達到指定的數量,但是Deployment(部署)是一個更高階的概念,它管理ReplicaSet併為Pod和ReplicaSet提供宣告性更新以及許多其他有用的功能,所以建議在實際使用中,採用Deployment代替ReplicaSet。

如果在Deployment物件中描述了所需的狀態,Deployment控制器就會以可控制的速率將實際狀態更改為期望狀態。也可以在Deployment中建立新的ReplicaSet,或者刪除現有的Deployment並使用新的Deployment部署所用的資源。


一、無狀態應用管理器Deployment

deployment用於部署無狀態的服務,是k8s中最常用的控制器。管理物件為pod。

一般用於管理維護企業內部無狀態的微服務,比如configserver、zuul、springboot。

deployment可以管理多個副本的Pod實現無縫遷移、自動擴容縮容、自動災難恢復、一鍵回滾等功能。

Deployment管理器基礎操作

建立Deployment

方式1:手動建立

kubectl create deployment {deployment-name} --image=nginx

方式2:以yaml格式或json格式建立Deployment

kubectl create -f test-nginx.yaml

查詢deployment狀態

檢視指定deployment的詳細資訊

kubectl describe deployment {deployment-name} -n {namespace-name}

kubectl get deployments -o wide

解析:-o wide 檢視全部詳情

匯出deployment配置

匯出已建立的deployment配置檔案至指定路徑:

kubectl get deployments test-nginx -o yaml >/data1/k8s-app/deploy/test-nginx.yaml

檢視指定某一pod下的日誌

kubectl logs {pod-name} -n {namespace-name}

修改deployment配置

修改某個指定deployment配置

kubectl edit deployment {deployment-name} -n {namespace-name}

kubectl apply -f xxx.yaml -n {namespace-name}

kubectl replace -f xxx.yaml -n {namespace-name}


版本升級操作:

手動改映象並記錄:

kubectl set image deploy {deployment-name} -n {namespace-name} XXX=xx(版本資訊) --record

解析:
--record 表示記錄本次修改

檢視部署歷史:

kubectl rollout history deploy {deployment-name} -n {namespace-name}

更新多次,需要檢視某次更新的詳細資訊:

kubectl rollout history deploy {deployment-name} -n {namespace-name} --revision=3

解析:
--revision 指定版本號

回滾到上一個版本:

kubectl rollout undo deploy {deployment-name} -n {namespace-name}

回滾到指定版本:

kubectl rollout undo deploy {deployment-name} -n {namespace-name} --to-revision=2

解析:
--to-revision=2 表示回滾到更新的第2個版本


擴容與縮容

動態調整Pod的副本數:

kubectl scale deploy {deployment-name} -n {namespace-name} --replicas=5

解析:
--replicas=5 將原有副本數修改為5,若原有為2個,將擴容3個副本;若原有為10個,將縮容

注意:這裡的擴容縮容,不會修改原有rs

Deployment更新的暫停與恢復(用set 修改多處更新)

暫停Deployment更新

kubectl rollout pause deploy {deployment-name} -n {namespace-name}

set修改deployment資源

kubectl set image ......

kubectl set resources deploy {deployment-name} -c {container-name}(指定容器) --limits=cpu=200m,memory=128Mi --requests=cpu=10m,memory=16Mi

恢復Deployment更新:

kubectl rollout resume {deployment-name} -n {namespace-name}

注意:恢復更新的Deployment建立了一個新的RS(複製集)

注意事項:
可修改yaml格式來更新Deployment,其中在spec下的幾個引數配置解析為:

  • replicas: 4 表示副本數,4為4個副本
  • revisionHistoryLimit:設定保留RS舊的revision的個數,設定為0的話,不保留歷史資料;
  • minReadySeconds:可選引數,指定新建立的Pod在沒有任何容器崩潰的情況下視為Ready最小的秒數,預設為0,即一旦被建立就視為可用。
關於滾動更新的策略引數解析:

strategy.type:更新deployment的方式,預設是RollingUpdate;

  • RollingUpdate表示滾動更新,可以指定maxSurge和maxUnavailable
  • maxUnavailable:指定在回滾或更新時最大不可用的Pod的數量,可選欄位,預設25%,可以設定成數字或百分比,如果該值為0,那麼maxSurge就不能0
  • maxSurge:可以超過期望值的最大Pod數,可選欄位,預設為25%,可以設定成數字或百分比,如果該值為0,那麼maxUnavailable不能為0
  • Recreate:重建,先刪除舊的Pod,在建立新的Pod

示例:

# kubectl get deploy nginx -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "12"
    kubernetes.io/change-cause: kubectl set image deploy nginx nginx=nginx:1.15.3
      --record=true
  creationTimestamp: "2020-09-19T02:41:11Z"
  generation: 19
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.15.3
        imagePullPolicy: IfNotPresent
        name: nginx
        resources:
          limits:
            cpu: 200m
            memory: 128Mi
          requests:
            cpu: 10m
            memory: 16Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

二、有狀態應用管理StatefulSet

StatefulSet(有狀態集,縮寫為sts)主要用於管理有狀態應用程式的工作負載API物件。常用於部署有狀態的且需要有序啟動的應用程式。

和Deployment類似,一個StatefulSet也同樣管理著基於相同容器規範的Pod。不同的是,StatefulSet為每個Pod維護了一個粘性標識。這些Pod是根據相同的規範建立的,但是不可互換,每個Pod都有一個持久的識別符號,在重新排程時也會保留,一般格式為StatefulSetName-Number。比如定義一個名字是Redis-Sentinel的StatefulSet,指定建立三個Pod,那麼創建出來的Pod名字就為Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2。

StatefulSet建立的Pod一般使用Headless Service(無頭服務)負責Pod的網路身份和通訊,需要提前建立此服務。和普通的Service的區別在於Headless Service沒有ClusterIP,它使用的是Endpoint進行互相通訊。在刪除一個StatefulSet時,不保證對Pod的終止,要在StatefulSet中實現Pod的有序和正常終止,可以在刪除之前將StatefulSet的副本縮減為0。

Headless一般格式為:
statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local

解析:

  • statefulSetName 為StatefulSet的名字;
  • 0..N-1 為Pod所在的序號,從0開始到N-1;
  • serviceName 為Headless Service的名字,建立StatefulSet時,必須指定Headless Service名稱;
  • namespace 為服務所在的名稱空間;
  • .cluster.local 為Cluster Domain(叢集域)。
StatefulSet注意事項:

一般StatefulSet用於有以下一個或者多個需求的應用程式:

  • 需要穩定的獨一無二的網路識別符號。
  • 需要持久化資料。
  • 需要有序的、優雅的部署和擴充套件。
  • 需要有序的自動滾動更新。
  • 如果應用程式不需要任何穩定的識別符號或者有序的部署、刪除或者擴充套件,應該使用無狀態的控制器部署應用程式,比如Deployment或者ReplicaSet。

StatefulSet是Kubernetes 1.9版本之前的beta資源,在1.5版本之前的任何Kubernetes版本都沒有。
Pod所用的儲存必須由PersistentVolume Provisioner(持久化卷配置器)根據請求配置StorageClass,或者由管理員預先配置,當然也可以不配置儲存。
為了確保資料安全,刪除和縮放StatefulSet不會刪除與StatefulSet關聯的卷,可以手動選擇性地刪除PVC和PV(參考PV和PVC節)。

Deployment管理器基礎操作

定義一個StatefulSet資源yaml檔案

定義一個簡單的StatefulSet的示例如下:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web

注意:
此示例沒有新增儲存配置

其中:

  • kind: Service 定義了一個名字為Nginx的Headless Service,建立的Service格式為nginx-0.nginx.default.svc.cluster.local,其他的類似,因為沒有指定Namespace(名稱空間),所以預設部署在default。
  • kind: StatefulSet 定義了一個名字為web的StatefulSet,replicas表示部署Pod的副本數。
  • 在StatefulSet中必須設定Pod選擇器(.spec.selector)用來匹配其標籤(.spec.template.metadata.labels)。在1.8版本之前,如果未配置該欄位(.spec.selector),將被設定為預設值,在1.8版本之後,如果未指定匹配Pod Selector,則會導致StatefulSet建立錯誤。
  • 當StatefulSet控制器建立Pod時,它會新增一個標籤statefulset.kubernetes.io/pod-name,該標籤的值為Pod的名稱,用於匹配Service。
檢視更新過程

kubuctl rollout status sts {statefulset-name} -n {namespace-name}

過濾檢視pod配置中某一資訊

kubectl get pod {pod-name} -n {namespace-name} -oyaml | grep image

kubectl get po -l app=nginx -w
-w 引數表示動態檢視pod的更新過程

在pod的配置中,updateStrategy 表示更新策略,其中若type: RollingUpdate 表示滾動更新,修改pod配置後會根據建立順序更新,配置為:

updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate

解析:
	partition: 0 表示分段更新,0表示小於0的pod不更新(即更新所有pod);其中數字表示更新的分段(pod)數;舉例:若StatefulSet的pod數有5個,現在partition: 2;那麼pod2前面的pod不會更新(pod0、pod1),更新的pod為pod2、pod3、pod4。多用於灰度釋出(先讓指定pod更新,在更新其它pod)

若type: OnDelete 表示只有刪除pod時,才會更新修改的配置,且配置應為:

updateStrategy:
    type: RollingUpdate
StatefulSet的刪除

一般情況,刪除sts時,pod會被重建

涉及概念:級聯刪除與非級聯刪除

  • 級聯刪除:刪除StatefulSet時同時刪除pod,若不指定,預設為級聯刪除
  • 非級聯刪除:刪除StatefulSet時不刪除pod,但刪除sts後,pod變成“孤兒”,此時刪除pod不會被重建

設定級聯刪除或非級聯刪除
非級聯刪除:

kubectl delete sts {statefulset-name} -n {namespace-name} --cascade=false


三、守護程序服務DaemonSet

DaemonSet 是守護程序集,縮寫為ds,在所有節點或者是匹配條件的節點(通過打標籤形式)上都部署一個Pod。

使用DaemonSet的場景
  • 執行叢集儲存的daemon,比如ceph或者glusterd
  • 節點的CNI網路外掛,calico
  • 節點日誌的收集:fluentd或者是filebeat
  • 節點的監控:node exporter
  • 服務暴露:部署一個ingress-nginx
建立DaemonSet

kubectl create -f nginx-ds.yaml

示例:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate	  
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.15.2
        imagePullPolicy: IfNotPresent
        name: nginx
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
設定匹配條件的node部署pod

方法1命令部署:

kubectl label nodeXX(節點名稱) nodeXX(節點名稱-多個節點) ... ds=true

檢視標籤

kubectl get node --show-labels

方法2修改yaml檔案:(注意,若replace YAML檔案,會更新配置)

在spec下,新增

......
	  nodeSelector: 
	    ds: "ture"
......

另外,若需要新增或刪除ds節點,需進行label新增或刪除即可

DaemonSet更新配置
......
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1    ###最大不可用範圍,建議設為1
......

注意:在DaemonSet的生產環境中,建議更新策略採用OnDelete,避免影響所有節點上的pod,可用幾個不重要的pod做測試用

......
  updateStrategy:
    type: RollingUpdate	
......

四、Label與Selector

Label:對k8s中各種資源進行分類、分組,新增一個具有特別屬性的一個標籤。

Selector:通過一個過濾的語法進行查詢到對應標籤的資源

刪除label

kubectl label node {node-name} app- -n {namespace-name}

修改label

kubectl label pod {pod-name} app=xx(新名稱) -n {namespace-name} --overwrite

檢視所有ns下符合條件的標籤

kubectl get svc -A --show-labels

kubectl get pod -A --show-labels

kubectl get node -A --show-labels

根據需求檢視匹配條件的多種標籤表達示例:

所有ns下,標籤包含metrics-server和kubernetes-dashboad的pod

kubectl get po -A -l 'k8s-app in (metrics-server, kubernetes-dashboad)'

標籤為nginx,但不包含v1版本的pod

kubectl get po -l version!=v1,app=nginx

所有ns下,標籤為nginx,但不包含v1版本的pod

kubectl get po -A -l version!=v1,'app02 in (nginx,busybox)'

未完待續。。。。