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