Pod 狀態管理
Downward API有提供了兩種方式來實現從容器內部獲取POD信息的方法:
- 環境變量的方式
- Downward API 卷文件掛載
通過這兩種方式,可以將pod的標簽信息,資源信息,狀態信息傳遞到Pod內部。
環境變量方式-將Pod信息註入為環境變量
參考鏈接
1、使用pod參數方式
使用如下文件:
apiVersion: v1 kind: Pod metadata: name: envars-pod spec: containers: - name: test-container image: busybox command: [ "sh", "-c"] args: - while true; do echo -en ‘\n‘; printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE; printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT; sleep 10; done; env: - name: MY_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: MY_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: MY_POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: MY_POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: MY_POD_SERVICE_ACCOUNT valueFrom: fieldRef: fieldPath: spec.serviceAccountName restartPolicy: Never
創建pod之後,通過logs查看:
# kubectl logs envars-pod
10.0.0.3
envars-pod
default
10.2.6.23
default
登錄pod,可以直接查看,發現環境變量中已經加載了這些參數:
kubectl exec -it envars-pod -- sh / # env MY_POD_SERVICE_ACCOUNT=default KUBERNETES_SERVICE_PORT=443 KUBERNETES_PORT=tcp://10.1.0.1:443 HOSTNAME=envars-pod SHLVL=1 HOME=/root MY_POD_NAMESPACE=default TERM=xterm MY_POD_IP=10.2.6.23 KUBERNETES_PORT_443_TCP_ADDR=10.1.0.1 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_PROTO=tcp MY_NODE_NAME=10.0.0.3 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT_443_TCP=tcp://10.1.0.1:443 KUBERNETES_SERVICE_HOST=10.1.0.1 PWD=/ MY_POD_NAME=envars-pod
通過yaml文件中指定的valueFrom這種方式的Downward語法獲取相關Pod信息。
2、 使用容器參數方式
如下文件:
apiVersion: v1 kind: Pod metadata: name: envars-con spec: containers: - name: test-container image: busybox:1.24 command: [ "sh", "-c"] args: - while true; do echo -en ‘\n‘; printenv MY_CPU_REQUEST MY_CPU_LIMIT; printenv MY_MEM_REQUEST MY_MEM_LIMIT; sleep 10; done; resources: requests: memory: "32Mi" cpu: "125m" limits: memory: "64Mi" cpu: "250m" env: - name: MY_CPU_REQUEST valueFrom: resourceFieldRef: containerName: test-container resource: requests.cpu - name: MY_CPU_LIMIT valueFrom: resourceFieldRef: containerName: test-container resource: limits.cpu - name: MY_MEM_REQUEST valueFrom: resourceFieldRef: containerName: test-container resource: requests.memory - name: MY_MEM_LIMIT valueFrom: resourceFieldRef: containerName: test-container resource: limits.memory restartPolicy: Never
運行此pod,查看日誌:
1
1
33554432
67108864
使用volume方式
參考鏈接
1、使用Pod 參數
創建如下文件:
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en ‘\n\n‘; cat /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en ‘\n\n‘; cat /etc/podinfo/annotations; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
通過downward API的volume方式,將pod的labels中的所有參數和annotations中的所有參數傳遞給了pod內。
在對應的路徑下,有一個隱藏的文件目錄,存放了這兩個文件。
2、通容器參數傳遞資源配額
如下Pod文件:
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: k8s.gcr.io/busybox:1.24
command: ["sh", "-c"]
args:
- while true; do
echo -en ‘\n‘;
if [[ -e /etc/podinfo/cpu_limit ]]; then
echo -en ‘\n‘; cat /etc/podinfo/cpu_limit; fi;
if [[ -e /etc/podinfo/cpu_request ]]; then
echo -en ‘\n‘; cat /etc/podinfo/cpu_request; fi;
if [[ -e /etc/podinfo/mem_limit ]]; then
echo -en ‘\n‘; cat /etc/podinfo/mem_limit; fi;
if [[ -e /etc/podinfo/mem_request ]]; then
echo -en ‘\n‘; cat /etc/podinfo/mem_request; fi;
sleep 5;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
- path: "cpu_request"
resourceFieldRef:
containerName: client-container
resource: requests.cpu
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
- path: "mem_request"
resourceFieldRef:
containerName: client-container
resource: requests.memory
通過如下方式,查看pod中傳遞的參數:
kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
/# cat /etc/podinfo/cpu_limit
Downward API的應用主要是在某些場景中,集群中的每個節點將需要將自身的標識(ID)及進程綁定IP地址等信息事先寫入配置文件中,進程啟動時讀取這些信息發布到服務的註冊中心,實現集群節點的自動發現功能。
Pod生命周期和重啟策略
Pod的常見狀態
當我們執行kubectl describe pod <pod-name>
時,會發現Pod都會有一個狀態值,下面列舉了Pod的5中狀態:
- Pending: API server 已經創建該Pod,但是Pod內還有一個或多個容器鏡像沒有創建,一般是在下載鏡像。
- Running: Pod內的所有容器均已經創建,且至少有一個容器處於運行狀態、正在啟動或重啟狀態。
- Succeeded: Pod內所有容器均已經成功執行退出,且不再重啟
- Failed: Pod內所有容器均已退出,但至少有一個容器退出為失敗狀態。
- Unknown: 由於某種原因無法獲取Pod狀態,可能由於網絡通信不暢導致。
Pod重啟策略(RestartPolicy)
Pod的重啟策略應用於Pod中的所有容器,並且僅在Pod所處的Node上由Kubelet進行判斷和重啟操作。
RestartPolicy包含三個設定:
- Always: 當容器失效時,由kubelet自動重啟該容器。
- OnFailure: 當容器終止運行且退出碼不為0時,由Kubelet自動重啟該容器。
- Never: 不論容器的運行狀態如何,Kubelet都不會重啟該容器。
當管理Pod的控制包括ReplicationController、Job、DaemonSet以及直接通過Kubelet管理(靜態Pod),對應的控制器對Pod的重啟策略要求如下: - RC和DaemonSet,ReplicaSet,Deployment: 必須設置為Always,需要保證容器的持續運行
- Job: OnFailure 或Never,確保容器不再執行
- kubelet: 在Pod失效時自動重啟它,不論將RestartPolicy設置為什麽值,也不會對Pod進行健康檢查。
Pod健康檢查
對Pod的健康狀態檢查可以通過兩類探針來檢查:LivenessProbe和ReadinessProbe。
- livenessProbe: 判斷容器是否存活(running),如果檢測到容器不健康,則kubelet將殺掉該容器,並根據容器的重啟策略做相應的處理。如果容器不包含LivenessProbe探針,則返回永遠是Success。
- readinessProbe: 用於判斷容器是否啟動完成(ready),可以接受請求。如果ReadinessProbe探針檢測到失敗,則Pod的狀態將被修改。Endpoint Controller將從Service的EndPoint中刪除包含該容器所在的Pod的EndPoint。
容器的探針對容器有3中實現方式:
- ExecAction: 在容器內執行一條命令,如果命令的返回碼為0,則表示容器健康。
- TCPSocketAction: 通過容器的端口號和IP地址執行TCP檢測,如果能夠建立TCP連接表示容器健康。
- HTTPGetAction: 通過容器的IP地址、端口號及路徑調用HTTP Get方法,如果相應的狀態碼大於等於200且小於400,則認為容器狀態健康。
下面是對應的三個示例,闡述了這3中實現方式:
1、使用ExecAction方式:
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5 # 從容器啟動時,到第一次執行健康探測的時間間隔
periodSeconds: 5 # 每隔5s 檢查一次
timeoutSeconds: 1 # 健康檢查發送請求後的等待響應時間,默認為1S,超時無響應,則會認為無法提供服務,kubelet會重啟該容器。
通過如下命令,可以查看到pod的健康狀態和重啟次數:
kubectl get pod -o wide
kubectl describe pod liveness-exec
2、使用TCPSockAction
如下文件示例:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 15
periodSeconds: 20
3、使用HTTPGetAction
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: mirrorgooglecontainers/liveness
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe 和livenessProbe 用法十分相似,只需要把 readinessProbe替換為livenessProbe即可。它們可以同時使用在同一個容器上,來確保流量不會流入未準備好的容器,並且讓容器在失敗的時候重新啟動。
Pod 狀態管理