|
| 1 | +--- |
| 2 | +title: 带 Pod 间通信的 Job |
| 3 | +content_type: task |
| 4 | +min-kubernetes-server-version: v1.21 |
| 5 | +weight: 30 |
| 6 | +--- |
| 7 | +<!-- |
| 8 | +title: Job with Pod-to-Pod Communication |
| 9 | +content_type: task |
| 10 | +min-kubernetes-server-version: v1.21 |
| 11 | +weight: 30 |
| 12 | +--> |
| 13 | + |
| 14 | +<!-- overview --> |
| 15 | + |
| 16 | +<!-- |
| 17 | +In this example, you will run a Job in [Indexed completion mode](/blog/2021/04/19/introducing-indexed-jobs/) configured such that |
| 18 | +the pods created by the Job can communicate with each other using pod hostnames rather than pod IP addresses. |
| 19 | +
|
| 20 | +Pods within a Job might need to communicate among themselves. The user workload running in each pod could query the Kubernetes API server |
| 21 | +to learn the IPs of the other Pods, but it's much simpler to rely on Kubernetes' built-in DNS resolution. |
| 22 | +--> |
| 23 | +在此例中,你将以[索引完成模式](/blog/2021/04/19/introducing-indexed-jobs/)运行一个 Job, |
| 24 | +并通过配置使得该 Job 所创建的各 Pod 之间可以使用 Pod 主机名而不是 Pod IP 地址进行通信。 |
| 25 | + |
| 26 | +某 Job 内的 Pod 之间可能需要通信。每个 Pod 中运行的用户工作负载可以查询 Kubernetes API |
| 27 | +服务器以获知其他 Pod 的 IP,但使用 Kubernetes 内置的 DNS 解析会更加简单。 |
| 28 | + |
| 29 | +<!-- |
| 30 | +Jobs in Indexed completion mode automatically set the pods' hostname to be in the format of |
| 31 | +`${jobName}-${completionIndex}`. You can use this format to deterministically build |
| 32 | +pod hostnames and enable pod communication *without* needing to create a client connection to |
| 33 | +the Kubernetes control plane to obtain pod hostnames/IPs via API requests. |
| 34 | +
|
| 35 | +This configuration is useful |
| 36 | +for use cases where pod networking is required but you don't want to depend on a network |
| 37 | +connection with the Kubernetes API server. |
| 38 | +--> |
| 39 | +索引完成模式下的 Job 自动将 Pod 的主机名设置为 `${jobName}-${completionIndex}` 的格式。 |
| 40 | +你可以使用此格式确定性地构建 Pod 主机名并启用 Pod 通信,无需创建到 Kubernetes |
| 41 | +控制平面的客户端连接来通过 API 请求获取 Pod 主机名/IP。 |
| 42 | + |
| 43 | +此配置可用于需要 Pod 联网但不想依赖 Kubernetes API 服务器网络连接的使用场景。 |
| 44 | + |
| 45 | +## {{% heading "prerequisites" %}} |
| 46 | + |
| 47 | +<!-- |
| 48 | +You should already be familiar with the basic use of [Job](/docs/concepts/workloads/controllers/job/). |
| 49 | +--> |
| 50 | +你应该已熟悉了 [Job](/zh-cn/docs/concepts/workloads/controllers/job/) 的基本用法。 |
| 51 | + |
| 52 | +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} |
| 53 | + |
| 54 | +{{<note>}} |
| 55 | +<!-- |
| 56 | +If you are using MiniKube or a similar tool, you may need to take |
| 57 | +[extra steps](https://minikube.sigs.k8s.io/docs/handbook/addons/ingress-dns/) |
| 58 | +to ensure you have DNS. |
| 59 | +--> |
| 60 | +如果你正在使用 MiniKube 或类似的工具, |
| 61 | +你可能需要采取[额外的步骤](https://minikube.sigs.k8s.io/docs/handbook/addons/ingress-dns/)来确保你拥有 DNS。 |
| 62 | +{{</note>}} |
| 63 | + |
| 64 | +<!-- steps --> |
| 65 | + |
| 66 | +<!-- |
| 67 | +## Starting a Job with Pod-to-Pod Communication |
| 68 | +
|
| 69 | +To enable pod-to-pod communication using pod hostnames in a Job, you must do the following: |
| 70 | +--> |
| 71 | +## 启动带 Pod 间通信的 Job {#starting-a-job-with-pod-to-pod-communication} |
| 72 | + |
| 73 | +要在某 Job 中启用使用 Pod 主机名的 Pod 间通信,你必须执行以下操作: |
| 74 | + |
| 75 | +<!-- |
| 76 | +1. Set up a [headless service](/docs/concepts/services-networking/service/#headless-services) |
| 77 | +with a valid label selector for the pods created by your Job. The headless service must be in the same namespace as |
| 78 | +the Job. One easy way to do this is to use the `job-name: <your-job-name>` selector, since the `job-name` label will be automatically added by Kubernetes. This configuration will trigger the DNS system to create records of the hostnames of |
| 79 | +the pods running your Job. |
| 80 | +
|
| 81 | +2. Configure the headless service as subdomain service for the Job pods by including the following value in your Job template spec: |
| 82 | +--> |
| 83 | +1. 对于 Job 所创建的那些 Pod, |
| 84 | + 使用一个有效的标签选择算符创建[无头服务](/zh-cn/docs/concepts/services-networking/service/#headless-services)。 |
| 85 | + 该无头服务必须位于与该 Job 相同的名字空间内。 |
| 86 | + 实现这一目的的一种简单的方式是使用 `job-name: <任务名称>` 作为选择算符, |
| 87 | + 因为 `job-name` 标签将由 Kubernetes 自动添加。 |
| 88 | + 此配置将触发 DNS 系统为运行 Job 的 Pod 创建其主机名的记录。 |
| 89 | + |
| 90 | +2. 通过将以下值包括到你的 Job 模板规约中,针对该 Job 的 Pod,将无头服务配置为其子域服务: |
| 91 | + |
| 92 | + ```yaml |
| 93 | + subdomain: <无头服务的名称> |
| 94 | + ``` |
| 95 | +
|
| 96 | +<!-- |
| 97 | +### Example |
| 98 | +Below is a working example of a Job with pod-to-pod communication via pod hostnames enabled. |
| 99 | +The Job is completed only after all pods successfully ping each other using hostnames. |
| 100 | +--> |
| 101 | +### 示例 {#example} |
| 102 | +
|
| 103 | +以下是启用通过 Pod 主机名来完成 Pod 间通信的 Job 示例。 |
| 104 | +只有在使用主机名成功 ping 通所有 Pod 之后,此 Job 才会结束。 |
| 105 | +
|
| 106 | +{{<note>}} |
| 107 | +<!-- |
| 108 | +In the Bash script executed on each pod in the example below, the pod hostnames can be prefixed |
| 109 | +by the namespace as well if the pod needs to be reached from outside the namespace. |
| 110 | +--> |
| 111 | +在以下示例中的每个 Pod 中执行的 Bash 脚本中,如果需要从名字空间外到达 Pod, |
| 112 | +Pod 主机名也可以带有该名字空间作为前缀。 |
| 113 | +{{</note>}} |
| 114 | +
|
| 115 | +```yaml |
| 116 | +apiVersion: v1 |
| 117 | +kind: Service |
| 118 | +metadata: |
| 119 | + name: headless-svc |
| 120 | +spec: |
| 121 | + clusterIP: None # clusterIP 必须为 None 以创建无头服务 |
| 122 | + selector: |
| 123 | + job-name: example-job # 必须与 Job 名称匹配 |
| 124 | +--- |
| 125 | +apiVersion: batch/v1 |
| 126 | +kind: Job |
| 127 | +metadata: |
| 128 | + name: example-job |
| 129 | +spec: |
| 130 | + completions: 3 |
| 131 | + parallelism: 3 |
| 132 | + completionMode: Indexed |
| 133 | + template: |
| 134 | + spec: |
| 135 | + subdomain: headless-svc # 必须与 Service 名称匹配 |
| 136 | + restartPolicy: Never |
| 137 | + containers: |
| 138 | + - name: example-workload |
| 139 | + image: bash:latest |
| 140 | + command: |
| 141 | + - bash |
| 142 | + - -c |
| 143 | + - | |
| 144 | + for i in 0 1 2 |
| 145 | + do |
| 146 | + gotStatus="-1" |
| 147 | + wantStatus="0" |
| 148 | + while [ $gotStatus -ne $wantStatus ] |
| 149 | + do |
| 150 | + ping -c 1 example-job-${i}.headless-svc > /dev/null 2>&1 |
| 151 | + gotStatus=$? |
| 152 | + if [ $gotStatus -ne $wantStatus ]; then |
| 153 | + echo "Failed to ping pod example-job-${i}.headless-svc, retrying in 1 second..." |
| 154 | + sleep 1 |
| 155 | + fi |
| 156 | + done |
| 157 | + echo "Successfully pinged pod: example-job-${i}.headless-svc" |
| 158 | + done |
| 159 | +``` |
| 160 | +
|
| 161 | +<!-- |
| 162 | +After applying the example above, reach each other over the network |
| 163 | +using: `<pod-hostname>.<headless-service-name>`. You should see output similar to the following: |
| 164 | +--> |
| 165 | +应用上述示例之后,使用 `<Pod 主机名>.<无头服务名>` 通过网络到达彼此。 |
| 166 | +你应看到类似以下的输出: |
| 167 | + |
| 168 | +```shell |
| 169 | +kubectl logs example-job-0-qws42 |
| 170 | +``` |
| 171 | + |
| 172 | +``` |
| 173 | +Failed to ping pod example-job-0.headless-svc, retrying in 1 second... |
| 174 | +Successfully pinged pod: example-job-0.headless-svc |
| 175 | +Successfully pinged pod: example-job-1.headless-svc |
| 176 | +Successfully pinged pod: example-job-2.headless-svc |
| 177 | +``` |
| 178 | +
|
| 179 | +{{<note>}} |
| 180 | +<!-- |
| 181 | +Keep in mind that the `<pod-hostname>.<headless-service-name>` name format used |
| 182 | +in this example would not work with DNS policy set to `None` or `Default`. |
| 183 | +You can learn more about pod DNS policies [here](/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy). |
| 184 | +--> |
| 185 | +谨记此例中使用的 `<Pod 主机名>.<无头服务名称>` 名称格式不适用于设置为 `None` 或 `Default` 的 DNS 策略。 |
| 186 | +你可以在[此处](/zh-cn/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy)了解有关 |
| 187 | +Pod DNS 策略的更多信息。 |
| 188 | +{{</note>}} |
0 commit comments