k8s之深入解剖Pod(二)
目錄:
Pod配置管理:ConfigMap
容器內獲取Pod資訊:Downward API
Pod生命週期和重啟策略
Pod健康檢查
一、ConfigMap
將應用所需的配置資訊與程式進行分離,可以使應用程式更好的被複用,通過不同的配置實現更靈活的功能。如果將應用打包成映象,再用環境變數或者外掛檔案的方式掛載配置,在大型容器叢集中會變得異常繁瑣,所以出現了統一的配置管理:ConfigMap
(1)ConfigMap:容器應用的配置管理
典型用法如下:
1、生成為容器內的環境變數
2、設定容器啟動命令的啟動引數(需設定為環境變數)
3、以Volume的形式掛載為容器內部的檔案或目錄
ConfigMap以一個或多個key:value的形式儲存在k8s系統中供應用使用,既可以用於表示一個變數的值,也可以表示一個完整配置檔案的內容。
(2)建立方式
1、通過yaml檔案進行建立
apiVersion: v1 kind: ConfigMap metadata: name: cm-1 data: home_path: /usr/soft
需要將配置定義在data下面,上述yaml檔案中在data中定義了一個key是home_path,value是/usr/soft的配置。
使用如下命令建立:
kubectl create -f cm_1.yaml
檢視建立的ConfigMap:
kubectl get cm 或 kubectl get configmap
檢視ConfigMap的詳細內容:
kubectl describe cm/cm-1
2、通過kubectl命令列建立
直接通過kubectl create configmap,可使用引數--from-file或--from-literal指定內容,並且可以在一行命令中指定多個引數。
(1)通過--from-file引數從檔案中進行建立,可以指定key的名稱,也可以在一個命令列中建立包含多個key的ConfigMap
例如:在當前目錄下建立一個檔名為config_1.conf,檔案內容就是“value1”
使用如下命令建立configmap,名為config-1
kubectl create configmap config-1 --from-file=config_1.conf
檢視:其會以檔名為key,檔案內容為value建立一條資料
(2)通過--from-file引數從目錄中進行建立,該目錄下的每個配置檔名都被設定為key,檔案的內容被設定為value
例如:在configmap目錄下由三個檔案
使用如下命令建立:
kubectl create configmap cm-name --from-file=file-dir
檢視詳細資料:其會以檔名作為key,檔案內容作為value
(3)--from-literal從文字中進行建立,直接將指定的key=value建立為configmap的內容
例如:建立一個key為name,value為Liusy的configmap資料
kubectl create configmap cm-3 --from-literal=name=liusy
(3)ConfigMap使用
以上述常見的cm-1為例
apiVersion: v1 kind: ConfigMap metadata: name: cm-1 data: home_path: /usr/soft
1、環境變數方式
本文建立一個Pod執行著nginx例項,在環境變數中使用cm-1的配置
apiVersion: v1 kind: Pod metadata: name: cm-nginx spec: containers: - name: cm-nginx image: nginx imagePullPolicy: IfNotPresent env: - name: home valueFrom: configMapKeyRef: name: cm-1 key: home_path
建立好Pod後進入容器:
檢視環境變數:
可以看到,home環境變數的值正是cm-1中配置的路徑
2、volumeMount模式
比如定義一個Pod,其中定義一個volume,volume中引用名為cm-1的configmap,將key為home_path的value值寫入homtpath.txt檔案中,在容器中的configfiles目錄上掛載這個volume
apiVersion: v1 kind: Pod metadata: name: mount-pod spec: volumes: - name: cm-volume configMap: name: cm-1 items: - key: home_path path: homepath.txt containers: - name: mount-pod image: nginx imagePullPolicy: IfNotPresent volumeMounts: - name: cm-volume mountPath: /configfiles
建立Pod後進入容器:
可以看到,configfiles目錄下確實生成了一個homepath.txt檔案,來檢視以下檔案的內容:
(4)ConfigMap使用限制
- ConfigMap必須在Pod之前建立
- ConfigMap有Namespace限制,只有在同一Namespace下才可使用
- 靜態Pod無法使用ConfigMap
二、容器內獲取Pod資訊:Downward API
在Pod建立之後,會被分配唯一的名字、IP地址,並處於某個Namespace中,那麼這些資訊在Pod中應該怎麼獲取呢,就是利用Downward API。
Downward API可以通過以下兩種方式將Pod資訊注入容器內部。
1、環境變數
用於單個變數(也就是在Pod定義中是單值的,非陣列),可以將Pod資訊和Container資訊注 入容器內部。
比如下例中將Pod的name、namespace、ip注入為環境變數
apiVersion: v1 kind: Pod metadata: name: pod-name namespace: kube-system spec: containers: - name: pod-name image: nginx imagePullPolicy: IfNotPresent env: - name: name valueFrom: fieldRef: fieldPath: metadata.name - name: ns valueFrom: fieldRef: fieldPath: metadata.namespace - name: ip valueFrom: fieldRef: fieldPath: status.podIP
建立Pod之後進入容器檢視相應的環境變數:
又比如下例中將resource注入為環境變數
apiVersion: v1 kind: Pod metadata: name: pod-name1 spec: containers: - name: c1 image: nginx imagePullPolicy: IfNotPresent resources: requests: cpu: "125m" memory: "32Mi" limits: cpu: "250m" memory: "64Mi" env: - name: req_cpu valueFrom: resourceFieldRef: containerName: c1 resource: requests.cpu - name: lim_cpu valueFrom: resourceFieldRef: containerName: c1 resource: limits.cpu - name: lim_me valueFrom: resourceFieldRef: containerName: c1 resource: limits.memory
建立Pod後進入容器檢視:
2、volume掛載
將陣列類資訊生成為檔案並掛載到容器內部。例如labels、annotations等
例如下例中將label資訊通過volume掛載到容器的label目錄
apiVersion: v1 kind: Pod metadata: name: pod-volume labels: name: pod-volume age: zero spec: containers: - name: c1 image: nginx imagePullPolicy: IfNotPresent volumeMounts: - name: v-l mountPath: /labels readOnly: false volumes: - name: v-l downwardAPI: items: - path: "labels" fieldRef: fieldPath: metadata.labels
上述yaml中建立了一個volume,通過items設定,會生成path值的檔案,檔案的內容就是相應的資訊,在容器中將volume掛載到/labels目錄下:
建立之後進入容器檢視檔案:
三、Pod生命週期和重啟策略
Pod的狀態包括以下幾種:
Pod的重啟策略應用於Pod內的所有容器,並且僅在Pod所處的Node上有kubelet進行判斷和重啟操作,當某個容器異常退出或者健康檢查失敗時,kubelet將根據RestartPolicy設定進行相應的操作。在spec.restartPolicy中配置相應的重啟策略
重啟策略有如下三個:
spec: restartPolicy: [Always|Never|OnFailure]
- Always:Pod一旦終止執行,kubelet都會進行重啟,這也是預設值
- Never:不會進行重啟
- OnFailure:容器非正常退出(即是退出碼不為0),kubelet會重啟容器,反之不會重啟。
kubelet重啟失效容器的時間間隔以sync-frequency乘以2n來計算,例如1,2,4,8等,最長延時5分鐘,且在重啟10分鐘之後重置該時間。
Pod的重啟策略與控制方式息息相關,當前可用於管理Pod的控制器包括RC,Job,DaemonSet及直接通過kubelet管理的靜態Pod,每種控制器對Pod的重啟策略如下:
- RC、DaemonSet:必須設定為Always,保證容器持續執行
- Job:OnFailure或Never,執行完就退出
- kubelet:在Pod失效時自動重啟它,不論RestartPolicy是什麼值,並且也不會進行健康檢查。
四、Pod健康檢查
k8s提供了Pod健康檢查機制,對於檢測到故障服務會被及時自動下線,以及通過重啟服務的方式使服務自動恢復。可通過兩類探針來檢查:LivenessProbe和ReadinessProbe
1、LivenessProbe
用於判斷容器是否存活(running狀態),如果探測到容器不健康,則kubelet殺掉此容器,並根據重啟策略做相應的處理。
kubelet定期執行LivenessProbe來判斷容器的健康狀態,有三種實現方式:
(1)ExecAction
在容器內部執行一個命令,如果返回0,則表明容器健康。
apiVersion: v1 kind: Pod metadata: name: live-exec spec: containers: - name: live-exec image: nginx args: - /bin/sh - -c - echo ok > /tmp/health;sleep 10;rm -rf /tmp/health;sleep 1000 livenessProbe: exec: command: - cat - /tmp/health initialDelaySeconds: 5 timeoutSeconds: 1
上述yaml是在容器啟動時將ok輸出到/tem/health檔案中,10s過後刪除此檔案。看效果:
kubectl describe pods/live-exec
當檔案被刪除之後,探針探測到容器不健康,所以會進行重啟
(2)TCPSocketAction
通過容器的IP地址和埠號進行TCP檢查,如果能建立TCP連線,則說明容器健康
apiVersion: v1 kind: Pod metadata: name: live-tcp spec: containers: - name: live-tcp image: nginx imagePullPolicy: IfNotPresent livenessProbe: tcpSocket: port: 80 initialDelaySeconds: 15 timeoutSeconds: 1
(3)HttpGetAction
通過容器的IP、埠及路徑呼叫HTTP Get方法,響應碼大於200,小於400,容器健康
apiVersion: v1 kind: Pod metadata: name: live-httpget spec: containers: - name: live-httpget image: nginx imagePullPolicy: IfNotPresent livenessProbe: httpGet: path: /_status/healthz port: 80 host: host scheme: HTTP httpHeaders: - name: string value: string initialDelaySeconds: 15 timeoutSeconds: 1
2、ReadinessProbe
用於判斷容器是否啟動完成(ready狀態),可接受請求。如果檢測到失敗,則Pod的狀態將被修改。Endpoint Controller將從service的Endpoint中刪除包含該容器所在Pod的Endpoint,此Pod不再接收請求。
此探針使用方式和上述livenessProbe相同。
例如:ExecAction方式
apiVersion: v1 kind: Pod metadata: name: read-exec spec: containers: - name: read-exec image: nginx command: ["/bin/bash","-c","mkdir /health;sleep 10;rm -rf /health;sleep 10;mkdir /health;sleep 600"] readinessProbe: exec: command: ["ls","/health"] initialDelaySeconds: 5 timeoutSeconds: 1
上述yaml在容器啟動建立一個目錄,10s後刪除,再10s後建立此目錄,看容器健康檢測情況
其在檢測出容器啟動失敗後會定時去檢測,不會重啟容器,直至檢測到容器健康。
對於每種探測方式,都需要配置以下兩個引數:
- initialDelaySeconds:啟動後多久進行健康檢查,單位是秒
- timeoutSeconds:健康檢查傳送請求後的等待響應的超時時間,單位是s,超時未響應,則會重啟該pod
===============================
我是Liusy,一個喜歡健身的程式設計師。
歡迎關注微信公眾號【Liusy01】,一起交流Java技術及健身,獲取更多幹貨,領取Java進階乾貨,領取最新大廠面試資料,一起成為Java大神。
來都來了,關注一波再溜