原文: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的埠