K8S之yaml 檔案詳解pod、deployment、service(轉)

奋斗终生發表於2024-05-15

原文:https://blog.csdn.net/footless_bird/article/details/125946101

作者:墨鴉_Cormorant

來源:CSDN

K8S中的 yaml 檔案

yaml語法學習

Kubernetes 支援 YAML 和 JSON格式 管理資源物件

JSON 格式:主要用於 api 介面之間訊息的傳遞

YAML 格式:用於配置和管理,YAML是一種簡潔的非標記性語言,內容格式人性化,較易讀。


YAML語法格式:

大小寫敏感;

使用縮排表示層級關係;不支援Tab鍵製表符縮排,只使用空格縮排;

縮排的空格數目不重要,只要相同層級的元素左側對齊即可,通常開頭縮排兩個空格;

字元後縮排一個空格,如冒號,逗號,短橫杆(-) 等

"---" 表示YAML格式,一個檔案的開始,用於分隔檔案; 可以將建立多個資源寫在同一個 yaml 檔案中,用 --- 隔開,就不用寫多個 yaml 檔案了。

"#” 表示註釋;


yaml 檔案的學習方法:

多看別人(官方)寫的,能讀懂
能照著現場的檔案改著用
遇到不懂的,善用 kubectl explain ...命令查.

deployment資源

簡述

Deployment 為 Pod 和 ReplicaSet 提供了一個宣告式定義 (declarative) 方法,用來替代以前的 ReplicationController 更方便的管理應用。

作為最常用的 Kubernetes 物件,Deployment 經常會用來建立 ReplicaSet 和 Pod,我們往往不會直接在叢集中使用 ReplicaSet 部署一個新的微服務,一方面是因為 ReplicaSet 的功能其實不夠強大,一些常見的更新、擴容和縮容運維操作都不支援,Deployment 的引入就是為了支援這些複雜的操作。


典型用例如下:

使用 Deployment 來建立 ReplicaSet。ReplicaSet 在後臺建立 pod。檢查啟動狀態,看它是成功還是失敗。
然後,透過更新 Deployment 的 PodTemplateSpec 欄位來宣告 Pod 的新狀態。這會建立一個新的 ReplicaSet,Deployment 會按照控制的速率將 pod 從舊的 ReplicaSet 移動到新的 ReplicaSet 中。
如果當前狀態不穩定,回滾到之前的 Deployment revision。每次回滾都會更新 Deployment 的 revision。
擴容 Deployment 以滿足更高的負載。
暫停 Deployment 來應用 PodTemplateSpec 的多個修復,然後恢復上線。
根據 Deployment 的狀態判斷上線是否 hang 住了。
清除舊的不必要的 ReplicaSet。

deployment 原理

控制器模型
在Kubernetes架構中,有一個叫做kube-controller-manager的元件。這個元件,是一系列控制器的集合。其中每一個控制器,都以獨有的方式負責某種編排功能。而Deployment正是這些控制器中的一種。它們都遵循Kubernetes中一個通用的編排模式,即:控制迴圈

用一段go語言虛擬碼,描述這個控制迴圈

for {
    實際狀態 := 獲取叢集中物件X的實際狀態
    期望狀態 := 獲取叢集中物件X的期望狀態
    if 實際狀態 == 期望狀態 {
        什麼都不做
    }else{
        執行編排動作,將實際狀態調整為期望狀態
    }
}

在具體實現中,實際狀態往往來自於Kubernetes叢集本身。比如Kubelet透過心跳彙報的容器狀態和節點狀態,或者監控系統中儲存的應用監控資料,或者控制器主動收集的它感興趣的資訊,這些都是常見的實際狀態的來源;期望狀態一般來自使用者提交的YAML檔案,這些資訊都儲存在Etcd中

對於Deployment,它的控制器簡單實現如下:

Deployment Controller從Etcd中獲取到所有攜帶 “app:nginx”標籤的Pod,然後統計它們的數量,這就是實際狀態

Deployment物件的replicas的值就是期望狀態

Deployment Controller將兩個狀態做比較,然後根據比較結果,確定是建立Pod,還是刪除已有Pod

滾動更新
Deployment滾動更新的實現,依賴的是Kubernetes中的ReplicaSet

Deployment控制器實際操縱的,就是Replicas物件,而不是Pod物件。對於Deployment、ReplicaSet、Pod它們的關係如下圖:

ReplicaSet負責透過“控制器模式”,保證系統中Pod的個數永遠等於指定的個數。這也正是Deployment只允許容器的restartPolicy=Always的主要原因:只有容器能保證自己始終是running狀態的前提下,ReplicaSet調整Pod的個數才有意義。

Deployment同樣透過控制器模式,操作ReplicaSet的個數和屬性,進而實現“水平擴充套件/收縮”和“滾動更新”兩個編排動作對於“水平擴充套件/收縮”的實現,Deployment Controller只需要修改replicas的值即可。使用者執行這個操作的指令如下:

kubectl scale deployment nginx-deployment --replicas=4

Deployment.yaml 檔案解析

Deployment yaml檔案包含四個部分:

apiVersion: 表示版本。版本檢視命令:kubectl api-versions
kind: 表示資源
metadata: 表示元資訊
spec: 資源規範欄位
Deployment yaml 詳解:

apiVersion: apps/v1		# 指定api版本,此值必須在kubectl api-versions中。業務場景一般首選”apps/v1“
kind: Deployment		# 指定建立資源的角色/型別   
metadata:  		# 資源的後設資料/屬性 
  name: demo  	# 資源的名字,在同一個namespace中必須唯一
  namespace: default 	# 部署在哪個namespace中。不指定時預設為default名稱空間
  labels:  		# 自定義資源的標籤
    app: demo
    version: stable
  annotations:  # 自定義註釋列表
    name: string
spec: 	# 資源規範欄位,定義deployment資源需要的引數屬性,諸如是否在容器失敗時重新啟動容器的屬性
  replicas: 1 	# 宣告副本數目
  revisionHistoryLimit: 3 	# 保留歷史版本
  selector: 	# 標籤選擇器
    matchLabels: 	# 匹配標籤,需與上面的標籤定義的app保持一致
      app: demo
      version: stable
  strategy: 	# 策略
    type: RollingUpdate 	# 滾動更新策略
    rollingUpdate: 			# 滾動更新
      maxSurge: 1 			# 滾動升級時最大額外可以存在的副本數,可以為百分比,也可以為整數
      maxUnavailable: 0 	# 在更新過程中進入不可用狀態的 Pod 的最大值,可以為百分比,也可以為整數
  template: 	# 定義業務模板,如果有多個副本,所有副本的屬性會按照模板的相關配置進行匹配
    metadata: 	# 資源的後設資料/屬性 
      annotations: 		# 自定義註解列表
        sidecar.istio.io/inject: "false" 	# 自定義註解名字
      labels: 	# 自定義資源的標籤
        app: demo	# 模板名稱必填
        version: stable
    spec: 	# 資源規範欄位
      restartPolicy: Always		# Pod的重啟策略。[Always | OnFailure | Nerver]
      							# Always :在任何情況下,只要容器不在執行狀態,就自動重啟容器。預設
      							# OnFailure :只在容器異常時才自動容器容器。
      							  # 對於包含多個容器的pod,只有它裡面所有的容器都進入異常狀態後,pod才會進入Failed狀態
      							# Nerver :從來不重啟容器
      nodeSelector:   	# 設定NodeSelector表示將該Pod排程到包含這個label的node上,以key:value的格式指定
        caas_cluster: work-node
      containers:		# Pod中容器列表
      - name: demo 		# 容器的名字   
        image: demo:v1 		# 容器使用的映象地址   
        imagePullPolicy: IfNotPresent 	# 每次Pod啟動拉取映象策略
                                      	  # IfNotPresent :如果本地有就不檢查,如果沒有就拉取。預設 
                                      	  # Always : 每次都檢查
                                      	  # Never : 每次都不檢查(不管本地是否有)
        command: [string] 	# 容器的啟動命令列表,如不指定,使用打包時使用的啟動命令
        args: [string]     	# 容器的啟動命令引數列表
            # 如果command和args均沒有寫,那麼用Docker預設的配置
            # 如果command寫了,但args沒有寫,那麼Docker預設的配置會被忽略而且僅僅執行.yaml檔案的command(不帶任何引數的)
            # 如果command沒寫,但args寫了,那麼Docker預設配置的ENTRYPOINT的命令列會被執行,但是呼叫的引數是.yaml中的args
            # 如果如果command和args都寫了,那麼Docker預設的配置被忽略,使用.yaml的配置
        workingDir: string  	# 容器的工作目錄
        volumeMounts:    	# 掛載到容器內部的儲存卷配置
        - name: string     	# 引用pod定義的共享儲存卷的名稱,需用volumes[]部分定義的的卷名
          mountPath: string    	# 儲存卷在容器內mount的絕對路徑,應少於512字元
          readOnly: boolean    	# 是否為只讀模式
        - name: string
          configMap: 		# 型別為configMap的儲存卷,掛載預定義的configMap物件到容器內部
            name: string
            items:
            - key: string
              path: string
        ports:	# 需要暴露的埠庫號列表
          - name: http 	# 埠號名稱
            containerPort: 8080 	# 容器開放對外的埠 
          # hostPort: 8080	# 容器所在主機需要監聽的埠號,預設與Container相同
            protocol: TCP 	# 埠協議,支援TCP和UDP,預設TCP
        env:    # 容器執行前需設定的環境變數列表
        - name: string     # 環境變數名稱
          value: string    # 環境變數的值
        resources: 	# 資源管理。資源限制和請求的設定
          limits: 	# 資源限制的設定,最大使用
            cpu: "1" 		# CPU,"1"(1核心) = 1000m。將用於docker run --cpu-shares引數
            memory: 500Mi 	# 記憶體,1G = 1024Mi。將用於docker run --memory引數
          requests:  # 資源請求的設定。容器執行時,最低資源需求,也就是說最少需要多少資源容器才能正常執行
            cpu: 100m
            memory: 100Mi
        livenessProbe: 	# pod內部的容器的健康檢查的設定。當探測無響應幾次後將自動重啟該容器
        				  # 檢查方法有exec、httpGet和tcpSocket,對一個容器只需設定其中一種方法即可
          httpGet: # 透過httpget檢查健康,返回200-399之間,則認為容器正常
            path: /healthCheck 	# URI地址。如果沒有心跳檢測介面就為/
            port: 8089 		# 埠
            scheme: HTTP 	# 協議
            # host: 127.0.0.1 	# 主機地址
        # 也可以用這兩種方法進行pod內容器的健康檢查
        # exec: 		# 在容器內執行任意命令,並檢查命令退出狀態碼,如果狀態碼為0,則探測成功,否則探測失敗容器重啟
        #   command:   
        #     - cat   
        #     - /tmp/health   
        # 也可以用這種方法   
        # tcpSocket: # 對Pod內容器健康檢查方式設定為tcpSocket方式
        #   port: number 
          initialDelaySeconds: 30 	# 容器啟動完成後首次探測的時間,單位為秒
          timeoutSeconds: 5 	# 對容器健康檢查等待響應的超時時間,單位秒,預設1秒
          periodSeconds: 30 	# 對容器監控檢查的定期探測間隔時間設定,單位秒,預設10秒一次
          successThreshold: 1 	# 成功門檻
          failureThreshold: 5 	# 失敗門檻,連線失敗5次,pod殺掉,重啟一個新的pod
        readinessProbe: 		# Pod準備服務健康檢查設定
          httpGet:
            path: /healthCheck	# 如果沒有心跳檢測介面就為/
            port: 8089
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 5
        lifecycle:		# 生命週期管理  
          postStart:	# 容器執行之前執行的任務  
            exec:  
              command:  
                - 'sh'  
                - 'yum upgrade -y'  
          preStop:		# 容器關閉之前執行的任務  
            exec:  
              command: ['service httpd stop']
      initContainers:		# 初始化容器
      - command:
        - sh
        - -c
        - sleep 10; mkdir /wls/logs/nacos-0
        env:
        image: {{ .Values.busyboxImage }}
        imagePullPolicy: IfNotPresent
        name: init
        volumeMounts:
        - mountPath: /wls/logs/
          name: logs
      volumes:
      - name: logs
        hostPath:
          path: {{ .Values.nfsPath }}/logs
      volumes: 	# 在該pod上定義共享儲存卷列表
      - name: string     	# 共享儲存卷名稱 (volumes型別有很多種)
        emptyDir: {}     	# 型別為emtyDir的儲存卷,與Pod同生命週期的一個臨時目錄。為空值
      - name: string
        hostPath:      	# 型別為hostPath的儲存卷,表示掛載Pod所在宿主機的目錄
          path: string    # Pod所在宿主機的目錄,將被用於同期中mount的目錄
      - name: string
        secret: 			# 型別為secret的儲存卷,掛載叢集與定義的secre物件到容器內部
          scretname: string  
          items:     
          - key: string
            path: string
      imagePullSecrets: 	# 映象倉庫拉取映象時使用的金鑰,以key:secretkey格式指定
      - name: harbor-certification
      hostNetwork: false    # 是否使用主機網路模式,預設為false,如果設定為true,表示使用宿主機網路
      terminationGracePeriodSeconds: 30 	# 優雅關閉時間,這個時間內優雅關閉未結束,k8s 強制 kill
      dnsPolicy: ClusterFirst	# 設定Pod的DNS的策略。預設ClusterFirst
      		# 支援的策略:[Default | ClusterFirst | ClusterFirstWithHostNet | None]
      		# Default : Pod繼承所在宿主機的設定,也就是直接將宿主機的/etc/resolv.conf內容掛載到容器中
      		# ClusterFirst : 預設的配置,所有請求會優先在叢集所在域查詢,如果沒有才會轉發到上游DNS
      		# ClusterFirstWithHostNet : 和ClusterFirst一樣,不過是Pod執行在hostNetwork:true的情況下強制指定的
      		# None : 1.9版本引入的一個新值,這個配置忽略所有配置,以Pod的dnsConfig欄位為準
      affinity:  # 親和性除錯
        nodeAffinity: 	# 節點親和力
          requiredDuringSchedulingIgnoredDuringExecution: 	# pod 必須部署到滿足條件的節點上
            nodeSelectorTerms:	 	# 節點滿足任何一個條件就可以
            - matchExpressions: 	# 有多個選項時,則只有同時滿足這些邏輯選項的節點才能執行 pod
              - key: beta.kubernetes.io/arch
                operator: In
                values:
                - amd64
      tolerations:		# 汙點容忍度
      - operator: "Equal"		# 匹配型別。支援[Exists | Equal(預設值)]。Exists為容忍所有汙點
        key: "key1"
        value: "value1"
        effect: "NoSchedule"		# 汙點型別:[NoSchedule | PreferNoSchedule | NoExecute]
        								# NoSchedule :不會被排程 
										# PreferNoSchedule:儘量不排程
										# NoExecute:驅逐節點

Deployment.yaml 配置項說明

**livenessProbe:**存活指標
用於判斷 Pod(中的應用容器)是否健康,可以理解為健康檢查。使用 livenessProbe 來定期的去探測,如果探測成功,則 Pod 狀態可以判定為 Running;如果探測失敗,可kubectl會根據Pod的重啟策略來重啟容器。

如果未給Pod設定 livenessProbe,則預設探針永遠返回 Success。

執行 kubectl get pods 命令,輸出資訊中 STATUS 一列可以看到Pod是否處於Running狀態。

livenessProbe使用場景:有些後端應用在出現某些異常的時候會有假死的情況,這種情況容器依然是running狀態,但是應用是無法訪問的,所以需要加入存活探測livenessProbe來避免這種情況的發生。

參考:https://blog.csdn.net/qq_41980563/article/details/122139923

**readinessProbe:**就緒指標
就緒的意思是已經準備好了,Pod 的就緒可以理解為這個 Pod 可以接受請求和訪問。使用 readinessProbe 來定期的去探測,如果探測成功,則 Pod 的 Ready 狀態判定為 True;如果探測失敗,Pod 的 Ready 狀態判定為 False。

與 livenessProbe 不同的是,kubelet 不會對 readinessProbe 的探測情況有重啟操作。

當執行 kubectl get pods 命令,輸出資訊中 READY 一列可以看到 Pod 的 READY 狀態是否為 True。

readinessProbe 使用場景:k8s 應用更新雖然是滾動升級方式,但是很多後端程式啟動都比較久,容器起來了,但是服務未起來,而 k8s 只要容器起來了就會移除掉舊的容器,這種情況就會導致在更新發版的時候應用訪問失敗。這時候就需要配置 readinessProbe 就緒檢測,保證新的 pod 已經能正常使用了才會移除掉舊的 pod。

**initContainers:**初始化容器
用於主容器啟動時先啟動可一個或多個初始化容器,如果有多個,那麼這幾個 Init Container 按照定義的順序依次執行,只有所有的 Init Container 執行完後,主容器才會啟動。由於一個 Pod 裡的儲存卷是共享的,所以 Init Container 裡產生的資料可以被主容器使用到。

Init Container 可以在多種K8S資源裡被使用到,如 Deployment、Daemon Set、Pet Set、Job 等,但歸根結底都是在 Pod 啟動時,在主容器啟動前執行,做初始化工作。

**tolerations:**汙點容忍度
節點汙點:類似節點上的標籤或註解資訊,用來描述對應節點的後設資料資訊;汙點定義的格式和標籤、註解的定義方式很類似,都是用一個 key-value 資料來表示,不同於節點標籤,汙點的鍵值資料中包含對應汙點的 effect,汙點的 effect 是用於描述對應節點上的汙點有什麼作用;在 k8s 上汙點有三種 effect(效用)策略,第一種策略是 NoSchedule,表示拒絕 pod 排程到對應節點上執行;第二種策略是 PreferSchedule,表示儘量不把 pod 排程到此節點上執行;第三種策略是 NoExecute,表示拒絕將 pod 排程到此節點上執行;該效用相比 NoSchedule 要嚴苛一點;從上面的描述來看,對應汙點就是來描述拒絕pod執行在對應節點的節點屬性。

pod 對節點汙點的容忍度:pod 要想執行在對應有汙點的節點上,對應 pod 就要容忍對應節點上的汙點;pod 對節點汙點的容忍度就是在對應 pod 中定義怎麼去匹配節點汙點;通常匹配節點汙點的方式有兩種,一種是等值(Equal)匹配,一種是存在性(Exists)匹配;等值匹配表示對應pod的汙點容忍度,必須和節點上的汙點屬性相等,所謂汙點屬性是指汙點的 key、value 以及 effect;即容忍度必須滿足和對應汙點的key、value 和 effect 相同,這樣表示等值匹配關係,其運算子為 Equal;存在性匹配是指對應容忍度只需要匹配汙點的 key 和 effect 即可,value 不納入匹配標準,即容忍度只要滿足和對應汙點的 key 和 effect 相同就表示對應容忍度和節點汙點是存在性匹配,其運算子為 Exists;

service資源

簡述

Service是Kubernetes的核心概念,透過建立Service,可以為一組具有相同功能的容器應用提供一個統一的入口地址,並將請求負載分發到後端各個容器應用上。

Service.yaml 檔案解析

apiVersion: v1 	# 指定api版本,此值必須在kubectl api-versions中 
kind: Service 	# 指定建立資源的角色/型別 
metadata: 	# 資源的後設資料/屬性
  name: demo 	# 資源的名字,在同一個namespace中必須唯一
  namespace: default 	# 部署在哪個namespace中。不指定時預設為default名稱空間
  labels: 		# 設定資源的標籤
  - app: demo
  annotations:  # 自定義註解屬性列表
  - name: string
spec: 	# 資源規範欄位
  type: ClusterIP 	# service的型別,指定service的訪問方式,預設ClusterIP。
      # ClusterIP型別:虛擬的服務ip地址,用於k8s叢集內部的pod訪問,在Node上kube-porxy透過設定的iptables規則進行轉發
      # NodePort型別:使用宿主機埠,能夠訪問各個Node的外部客戶端透過Node的IP和埠就能訪問伺服器
      # LoadBalancer型別:使用外部負載均衡器完成到伺服器的負載分發,需要在spec.status.loadBalancer欄位指定外部負載均衡伺服器的IP,並同時定義nodePort和clusterIP用於公有云環境。
  clusterIP: string		#虛擬服務IP地址,當type=ClusterIP時,如不指定,則系統會自動進行分配,也可以手動指定。當type=loadBalancer,需要指定
  sessionAffinity: string	#是否支援session,可選值為ClietIP,預設值為空。ClientIP表示將同一個客戶端(根據客戶端IP地址決定)的訪問請求都轉發到同一個後端Pod
  ports:
    - port: 8080 	# 服務監聽的埠號
      targetPort: 8080 	# 容器暴露的埠
      nodePort: int		# 當type=NodePort時,指定對映到物理機的埠號
      protocol: TCP 	# 埠協議,支援TCP或UDP,預設TCP
      name: http 	# 埠名稱
  selector: 	# 選擇器。選擇具有指定label標籤的pod作為管理範圍
    app: demo
status:	# 當type=LoadBalancer時,設定外部負載均衡的地址,用於公有云環境    
  loadBalancer:	# 外部負載均衡器    
    ingress:
      ip: string	# 外部負載均衡器的IP地址
      hostname: string	# 外部負載均衡器的主機名

注:

port和nodePort都是service的埠,前者暴露給k8s叢集內部服務訪問,後者暴露給k8s叢集外部流量訪問。從上兩個埠過來的資料都需要經過反向代理kube-proxy,流入後端pod的targetPort上,最後到達pod內的容器。NodePort型別的service可供外部叢集訪問是因為service監聽了宿主機上的埠,即監聽了(所有節點)nodePort,該埠的請求會傳送給service,service再經由負載均衡轉發給Endpoints的節點。

ingress.yaml 檔案詳解

apiVersion: extensions/v1beta1 		# 建立該物件所使用的 Kubernetes API 的版本     
kind: Ingress 		# 想要建立的物件的類別,這裡為Ingress
metadata:
  name: showdoc		# 資源名字,同一個namespace中必須唯一
  namespace: op 	# 定義資源所在名稱空間
  annotations: 		# 自定義註解
    kubernetes.io/ingress.class: nginx    	# 宣告使用的ingress控制器
spec:
  rules:
  - host: showdoc.example.cn     # 服務的域名
    http:
      paths:
      - path: /      # 路由路徑
        backend:     # 後端Service
          serviceName: showdoc		# 對應Service的名字
          servicePort: 80           # 對應Service的埠

相關文章