同 Pod 内的容器使用共享卷通信

本文旨在说明如何让一个 Pod 内的两个容器使用一个卷(Volume)进行通信。 参阅如何让两个进程跨容器通过 共享进程名字空间

Before you begin

你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 建议在至少有两个节点的集群上运行本教程,且这些节点不作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:

To check the version, enter kubectl version.

创建一个包含两个容器的 Pod

在这个练习中,你会创建一个包含两个容器的 Pod。两个容器共享一个卷用于他们之间的通信。 Pod 的配置文件如下:

pods/two-container-pod.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: two-containers
  5. spec:
  6. restartPolicy: Never
  7. volumes:
  8. - name: shared-data
  9. emptyDir: {}
  10. containers:
  11. - name: nginx-container
  12. image: nginx
  13. volumeMounts:
  14. - name: shared-data
  15. mountPath: /usr/share/nginx/html
  16. - name: debian-container
  17. image: debian
  18. volumeMounts:
  19. - name: shared-data
  20. mountPath: /pod-data
  21. command: ["/bin/sh"]
  22. args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]

在配置文件中,你可以看到 Pod 有一个共享卷,名为 shared-data

配置文件中的第一个容器运行了一个 nginx 服务器。共享卷的挂载路径是 /usr/share/nginx/html。 第二个容器是基于 debian 镜像的,有一个 /pod-data 的挂载路径。第二个容器运行了下面的命令然后终止。

  1. echo Hello from the debian container > /pod-data/index.html

注意,第二个容器在 nginx 服务器的根目录下写了 index.html 文件。

创建一个包含两个容器的 Pod:

  1. kubectl apply -f https://k8s.io/examples/pods/two-container-pod.yaml

查看 Pod 和容器的信息:

  1. kubectl get pod two-containers --output=yaml

这是输出的一部分:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. ...
  5. name: two-containers
  6. namespace: default
  7. ...
  8. spec:
  9. ...
  10. containerStatuses:
  11. - containerID: docker://c1d8abd1 ...
  12. image: debian
  13. ...
  14. lastState:
  15. terminated:
  16. ...
  17. name: debian-container
  18. ...
  19. - containerID: docker://96c1ff2c5bb ...
  20. image: nginx
  21. ...
  22. name: nginx-container
  23. ...
  24. state:
  25. running:
  26. ...

你可以看到 debian 容器已经被终止了,而 nginx 服务器依然在运行。

进入 nginx 容器的 shell:

  1. kubectl exec -it two-containers -c nginx-container -- /bin/bash

在 shell 中,确认 nginx 还在运行。

  1. root@two-containers:/# ps aux

输出类似于这样:

  1. USER PID ... STAT START TIME COMMAND
  2. root 1 ... Ss 21:12 0:00 nginx: master process nginx -g daemon off;

回忆一下,debian 容器在 nginx 的根目录下创建了 index.html 文件。 使用 curl 向 nginx 服务器发送一个 GET 请求:

  1. root@two-containers:/# curl localhost

输出表示 nginx 提供了 debian 容器写的页面:

  1. Hello from the debian container

讨论

Pod 能有多个容器的主要原因是为了支持辅助应用(helper applications),以协助主应用(primary application)。 辅助应用的典型例子是数据抽取,数据推送和代理。辅助应用和主应用经常需要相互通信。 就如这个练习所示,通信通常是通过共享文件系统完成的,或者,也通过回环网络接口 localhost 完成。 举个网络接口的例子,web 服务器带有一个协助程序用于拉取 Git 仓库的更新。

在本练习中的卷为 Pod 生命周期中的容器相互通信提供了一种方法。如果 Pod 被删除或者重建了, 任何共享卷中的数据都会丢失。

What’s next

最后修改 December 15, 2020 at 3:12 PM PST: Update communicate-containers-same-pod-shared-volume.md (68e1ee3be)