具有 Pod 到 Pod 通信的 Job

在本示例中,你将在索引完成模式下运行一个 Job,配置为 Job 创建的 Pod 可以使用 Pod 主机名而不是 Pod IP 地址进行相互通信。

Job 中的 Pod 可能需要在它们之间进行通信。在每个 Pod 中运行的用户工作负载可以查询 Kubernetes API 服务器来了解其他 Pod 的 IP,但是依靠 Kubernetes 的内置 DNS 解析要简单得多。

索引完成模式下的 Job 会自动将 Pod 的主机名设置为 ${jobName}-${completionIndex} 的格式。你可以使用此格式确定性地构建 Pod 主机名,并实现 Pod 通信,而无需创建与 Kubernetes 控制平面的客户端连接,以通过 API 请求获取 Pod 主机名/IP。

此配置适用于需要 Pod 网络,但又不想依赖与 Kubernetes API 服务器的网络连接的用例。

开始之前

你应该已经熟悉 Job 的基本用法。

你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具才能与你的集群通信。建议在至少有两个节点(不是控制平面主机)的集群上运行本教程。 如果你还没有集群,可以使用 minikube 创建一个,或者你可以使用以下 Kubernetes 游乐场之一

你的 Kubernetes 服务器必须是 v1.21 或更高版本。要检查版本,请输入 kubectl version

启动具有 Pod 到 Pod 通信的 Job

要在 Job 中使用 Pod 主机名启用 Pod 到 Pod 通信,你必须执行以下操作

  1. 为你的 Job 创建的 Pod 设置具有有效标签选择器的无头服务。无头服务必须与 Job 位于同一命名空间中。一种简单的方法是使用 job-name: <你的-job-名称> 选择器,因为 job-name 标签将由 Kubernetes 自动添加。此配置将触发 DNS 系统创建运行你的 Job 的 Pod 主机名的记录。

  2. 通过在你的 Job 模板规范中包含以下值,将无头服务配置为 Job Pod 的子域服务

    subdomain: <headless-svc-name>
    

示例

下面是一个通过启用 Pod 主机名实现 Pod 到 Pod 通信的 Job 工作示例。仅当所有 Pod 使用主机名成功互相 ping 通后,该 Job 才会完成。


apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None # clusterIP must be None to create a headless service
  selector:
    job-name: example-job # must match Job name
---
apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  completions: 3
  parallelism: 3
  completionMode: Indexed
  template:
    spec:
      subdomain: headless-svc # has to match Service name
      restartPolicy: Never
      containers:
      - name: example-workload
        image: bash:latest
        command:
        - bash
        - -c
        - |
          for i in 0 1 2
          do
            gotStatus="-1"
            wantStatus="0"             
            while [ $gotStatus -ne $wantStatus ]
            do                                       
              ping -c 1 example-job-${i}.headless-svc > /dev/null 2>&1
              gotStatus=$?                
              if [ $gotStatus -ne $wantStatus ]; then
                echo "Failed to ping pod example-job-${i}.headless-svc, retrying in 1 second..."
                sleep 1
              fi
            done                                                         
            echo "Successfully pinged pod: example-job-${i}.headless-svc"
          done          

应用以上示例后,使用以下命令通过网络互相访问:<pod-主机名>.<无头服务名称>。你应该看到类似于以下内容的输出

kubectl logs example-job-0-qws42
Failed to ping pod example-job-0.headless-svc, retrying in 1 second...
Successfully pinged pod: example-job-0.headless-svc
Successfully pinged pod: example-job-1.headless-svc
Successfully pinged pod: example-job-2.headless-svc
上次修改时间:太平洋标准时间 2023 年 8 月 23 日下午 2:05:更新 Job 以适合科学计算 (f3dfd99576)