使用hostPath作为共享卷的Pod Sidecar容器无法正常工作求助
我有一个包含1个主节点和1个工作节点的K8s集群。
场景1:使用EmptyDir共享卷的Sidecar正常运行
在同一Pod内部署简单的Sidecar容器,使用EmptyDir作为共享卷,运行正常。清单文件如下:
apiVersion: apps/v1 kind: Deployment metadata: name: pod-with-sidecar namespace: test spec: replicas: 1 selector: matchLabels: app: debian-nginx template: metadata: labels: app: debian-nginx spec: containers: - name: main-debian image: debian command: ["/bin/sh"] args: ["-c", "while true; do date >> /var/log/index.html; sleep 2;done"] volumeMounts: - mountPath: /var/log name: shared-log - name: sidecar-nginx image: nginx volumeMounts: - mountPath: /usr/share/nginx/html/index.html name: shared-log volumes: - name: shared-log emptyDir: {}
此场景下,主容器生成的/var/log/index.html有内容,Sidecar容器的/usr/share/nginx/html/index.html也能获取到对应内容。
场景2:使用hostPath共享卷的Sidecar无法正常工作
同样在同一Pod内部署Sidecar容器,但使用hostPath作为共享卷时无法正常工作。清单文件如下:
apiVersion: apps/v1 kind: Deployment metadata: name: pod-with-sidecar namespace: test spec: replicas: 1 selector: matchLabels: app: debian app: nginx template: metadata: labels: app: debian app: nginx spec: containers: # Main application container - name: main-debian image: debian command: ["/bin/sh", "-c"] args: ["while true; do data >> /var/log/index.html; sleep 2;done"] volumeMounts: - mountPath: /var/log name: shared-vol # Sidecar container - name: sidecar-nginx image: nginx:1.7.9 ports: - containerPort: 80 volumeMounts: - mountPath: /usr/share/nginx/html # nginx-specific mount path name: shared-vol volumes: - name: shared-vol hostPath: path: /mydata type: DirectoryOrCreate
注:该清单中主容器的args存在笔误,将
date误写为data。
此场景下,主容器创建了/var/log/index.html但文件为空,Sidecar容器的/usr/share/nginx/html/index.html同样无内容。执行kubectl exec验证结果如下:
testuser@kmasterl:~$ kubectl exec -it pod-with-sidecar-85f88c9d5d-xjcgh -c main-debian -n test -- /bin/bash root@pod-with-sidecar-85f88c9d5d-xjcgh:/# ls -lrt var/log total 0 -rw-r--r-- 1 root root 0 Dec 14 21:28 index.html root@pod-with-sidecar-85f88c9d5d-xjcgh:/# cat /var/log/index.html root@pod-with-sidecar-85f88c9d5d-xjcgh:/#
testuser@kmasterl:~$ kubectl exec -it pod-with-sidecar-85f88c9d5d-xjcgh -c sidecar-nginx -n test -- /bin/bash root@pod-with-sidecar-85f88c9d5d-xjcgh:/# ls -lrt /usr/share/nginx/html total 0 -rw-r--r-- 1 root root 0 Dec 14 21:28 index.html root@pod-with-sidecar-85f88c9d5d-xjcgh:/# cat usr/share/nginx/html/index.html root@pod-with-sidecar-85f88c9d5d-xjcgh:/#
核心疑问
为何使用hostPath作为共享卷时无法正常工作?
这个问题的核心原因有两个,按优先级排序:
1. 主容器命令的低级笔误(直接导致空文件)
主容器的启动参数里把date写成了data——Linux系统里根本没有data这个命令,每次循环执行都会报错,但因为错误输出没被重定向到文件,所以只会创建一个空的index.html,完全不会写入任何内容。
不管用EmptyDir还是hostPath,只要把data改回date,主容器就能正常把时间戳写入共享卷,Sidecar的nginx自然能读到内容。
2. 挂载方式的差异(次要注意点)
对比场景1和场景2的挂载配置:
- 场景1里,Sidecar是把EmptyDir卷直接挂载为单个文件(
/usr/share/nginx/html/index.html); - 场景2里,是把hostPath卷挂载为整个目录(
/usr/share/nginx/html)。
这种差异本身不会导致无内容,但要确保主容器写入的文件路径和Sidecar读取的路径完全对应——不过在当前案例里,这个不是问题的根源,核心还是命令写错了。
另外补充:hostPath卷是绑定到集群节点的本地目录,Pod调度到哪个节点就用哪个节点的/mydata,如果Pod后续被调度到其他节点,之前的数据会丢失,这是hostPath和EmptyDir的本质区别,但和这次的故障无关。
内容的提问来源于stack exchange,提问作者Kubespecial

