使用共享卷在同一 Pod 中的容器之间通信

本页面展示了如何使用卷 (Volume) 在同一 Pod 中运行的两个容器之间进行通信。另请参阅如何通过共享进程命名空间来允许容器之间进行通信。

准备工作

你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与你的集群通信。建议在至少有两个不充当控制平面主机的节点的集群上运行本教程。如果你还没有集群,你可以通过使用minikube来创建一个,或者你可以使用这些 Kubernetes 操场中的一个。

要检查版本,请输入 kubectl version

创建运行两个容器的 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

请注意,第二个容器将 index.html 文件写入 nginx 服务器的根目录。

创建 Pod 和两个容器

kubectl apply -f https://k8s.io/examples/pods/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 容器编写的网页

Hello from the debian container

讨论

Pod 可以有多个容器的主要原因是支持辅助应用程序来协助主应用程序。辅助应用程序的典型示例是数据拉取器、数据推送器和代理。辅助应用程序和主应用程序通常需要相互通信。通常,这通过共享文件系统(如本练习所示)或通过环回网络接口(localhost)完成。此模式的一个示例是 Web 服务器以及一个轮询 Git 存储库以获取新更新的辅助程序。

本练习中的卷提供了一种在 Pod 生命周期内容器之间通信的方式。如果 Pod 被删除并重新创建,共享卷中存储的任何数据都将丢失。

下一步

最后修改于 2023 年 8 月 24 日下午 6:38 PST:使用 code_sample 简码代替 code 简码 (e8b136c3b3)