K8S之yaml 文件詳解pod、deployment、service(轉)

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

作者:

來源: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的端口

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章