本文將展示如何使用共享卷(Volume)來實現相同Pod中的兩個容器間通信。
注意:本文針對K8S的版本號為v1.9,其他版本可能會有少許不同。
0x00 准備工作
需要有一個K8S集群,並且配置好了kubectl
命令行工具來與集群通信。如果未准備好集群,那么你可以使用Minikube創建一個K8S集群,或者你也可以使用下面K8S環境二者之一:
如果需要查看K8S版本信息,可以輸入指令kubectl version
。
0x01 創建一個運行兩個容器的Pod
在本節中,我們會創建一個運行了兩個容器的Pod。這兩個容器共享了一個可以用於二者間通信的卷。下面是該Pod的配置文件:
apiVersion: v1
kind: Pod
metadata:
name: two-containers
spec:
restartPolicy: Never
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: debian-container
image: debian
volumeMounts:
- name: shared-data
mountPath: /pod-data
command: ["/bin/sh"]
args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]
在該配置文件中,可以看到該Pod擁有一個名為shared-data
的卷。
在該配置文件中,第一個容器運行了一個nginx服務器,共享卷在該容器中的掛載路徑為/usr/share/nginx/html
。第二個容器基於debian鏡像,共享卷在該容器中的掛載路徑為/pod-data
。此外,第二個人容器運行了以下命令,然后終止。
echo Hello from the debian container > /pod-data/index.html
注意,第二個容器在nginx服務器根目錄下創建了index.html
文件。
創建Pod和兩個容器:
kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/two-container-pod.yaml
查看關於該Pod和容器的信息:
kubectl get pod two-containers --output=yaml
下面是部分輸出結果:
apiVersion: v1
kind: Pod
metadata:
...
name: two-containers
namespace: default
...
spec:
...
containerStatuses:
- containerID: docker://c1d8abd1 ...
image: debian
...
lastState:
terminated:
...
name: debian-container
...
- containerID: docker://96c1ff2c5bb ...
image: nginx
...
name: nginx-container
...
state:
running:
...
可以看到,debian容器已經終止了,而nginx容器則仍在運行。
獲取一個nginx容器的shell:
kubectl exec -it two-containers -c nginx-container -- /bin/bash
在該shell中,我們驗證了nginx仍在運行:
root@two-containers:/# apt-get update
root@two-containers:/# apt-get install curl procps
root@two-containers:/# ps aux
輸出結果類似如下:
USER PID ... STAT START TIME COMMAND
root 1 ... Ss 21:12 0:00 nginx: master process nginx -g daemon off;
前面debian容器在nginx的根目錄下創建了index.html
文件,下面指令使用curl
向nginx服務器發送一個GET請求:
root@two-containers:/# curl localhost
輸出結果顯示,nginx服務器返回了debian容器創建的那個web頁面:
Hello from the debian container
0x02 總結
Pod中之所以能夠包含多個容器,其主要原因是為了支持輔助主程序的輔助程序。輔助程序的經典例子是數據拉取器、數據推送器和代理。輔助程序與主程序間經常需要通信,通常情況下是通過一個共享文件系統來實現的,正如本文中展示的那樣;或者,通過環回網絡接口localhost。這種方式的一個例子是Web服務器,以及與之配套的拉取Git倉庫更新的輔助程序。
本文中的共享卷提供了一種在Pod生命周期內實現容器間通信的方式。如果該Pod被刪除並重建,那么共享卷中的任何數據都將會丟失。