一、PodInitializing
PodInitializing作為Kubernetes中的一個生命周期鉤子,用來對Pod做初始化操作。PodInitializing允許其他容器在容器生命周期鉤子(Pod lifecycle hook)被調用之前運行自己的指定初始化容器。這個容器可以執行任意用戶指定的操作,並且只在pod創建的時候運行一次。
這時候就要用到podinit了。PodInit是一種簡單的解決方案,在Kubernetes pod對象的生命周期管理中,我們向容器中添加了一個額外的容器。這個容器僅僅在Pod第一次啟動時運行一次,然後退出。它完成一些特定的初始化任務,並且這些任務旨在在其他容器之前運行。
同時,如果主容器(即正常應用運行的容器)從故障中恢復,則沒有必要再次運行初始化容器。因此,PodInit使用一個注釋來跟蹤每個容器的狀態。當容器成功地寫出到本地文件系統時,PodInit在啟動時通過查詢注釋來檢查容器是否運行過。
二、查看podinit日誌
1、查看podinit日誌文件路徑
cat /var/log/pods/${pod_namespace}_${pod_name}_${container_name}/init.log2、監聽podinit日誌
kubectl logs -n $pod_namespace $pod_name $container_name -c $container_name --follow | grep PODINIT-TRACE-LOG
3、查看podinit容器日誌
kubectl logs -n $pod_namespace $pod_name $container_name -c podinit
三、podinit實現原理
PodInit使用一個init container來完成特定的初始化任務。Pod的其餘部分被保留,僅在Init容器完成後才運行。使用kubelet中的PodAdmitHandler(以及PodAdmitFunc)來修改PodSpec以包含一個額外的初始化容器。
實現podinit需要以下步驟:
1、構建一個健壯的鏡像,該鏡像應該包含podinit可執行文件。
# Dockerfile FROM alpine:3.7 RUN apk add --no-cache tini ADD pod init ENTRYPOINT ["/sbin/tini", "-g", "--", "/pod"]
2、創建init容器
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
initContainers:
- image: busybox
name: install
command:
- cp
- -a
- /mnt/data/. /usr/share/nginx/html
volumeMounts:
- name: shared-data
mountPath: /mnt/data
volumes:
- name: shared-data
emptyDir: {}
3、podinit代碼示例:
#!/bin/sh -eu
export PODINIT_LOG_LOCATION=${PODINIT_LOG_LOCATION:-'/var/log/pod-init.log'}
echo "PODINIT-TRACE-LOG: pod namespace: $POD_NAMESPACE" >> $PODINIT_LOG_LOCATION
echo "PODINIT-TRACE-LOG: pod name: $POD_NAME" >> $PODINIT_LOG_LOCATION
echo "PODINIT-TRACE-LOG: container name: $CONTAINER_NAME" >> $PODINIT_LOG_LOCATION
# We are using this file to store the pod name and container name which are
# initialized by this init container so that if this init container crashes
# or fails, we don't re-run the init container.
INIT_FILE=/mnt/pod-init.data
INIT_MARKER="pod-init"
if [ ! -f ${INIT_FILE} ]; then
echo "PODINIT-TRACE-LOG: Creating init file ${INIT_FILE} in container ${CONTAINER_NAME}" >> $PODINIT_LOG_LOCATION
echo "${INIT_MARKER}" > ${INIT_FILE}
else
echo "PODINIT-TRACE-LOG: Initialization already executed in container ${CONTAINER_NAME}" >> $PODINIT_LOG_LOCATION
fi
四、podinit使用例子
1、podinit示例:
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
initContainers:
- name: init-myservice
image: busybox
command: ['sh','-c', 'echo Initializing... && sleep 3600']
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
containers:
- name: myapp
image: busybox
command: ['sh','-c', 'echo Sleeping... && sleep 3600']
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
2、podinit搭配kubernetes-csi使用:
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
initContainers:
- name: init-myservice
image: my-image
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
command: ['sh','-c','/bin/podinit $MY_PARAM && $MY_VOLUME_SCRIPT']
volumeMounts:
- name: my-volume
mountPath: /mnt/data
containers:
- name: myapp
image: busybox
command: ['sh','-c', 'echo Sleeping... && sleep 3600']
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: my-volume
mountPath: /mnt/data
volumes:
- name: my-volume
emptyDir: {}
以上兩個例子展示了podinit的使用場景,一個是與busybox一起使用,一個是與kubernetes-csi一起使用。這也充分說明了podinit的靈活性,開發人員可以自由發揮他的想象力。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/188645.html
微信掃一掃
支付寶掃一掃