带 Pod-to-Pod 通信的作业
在此示例中,你将运行一个索引式完成模式的 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
。
注意
如果你使用 minikube 或类似工具,你可能需要采取额外步骤来确保你有 DNS。启动具有 Pod-to-Pod 通信的 Job
要在 Job 中启用使用 Pod 主机名的 Pod-to-Pod 通信,你必须执行以下操作:
设置一个无头服务,并为 Job 创建的 Pod 配置有效的标签选择器。无头服务必须与 Job 在同一命名空间中。一种简单的方法是使用
job-name: <your-job-name>
选择器,因为job-name
标签将由 Kubernetes 自动添加。此配置将触发 DNS 系统为运行 Job 的 Pod 主机名创建记录。通过在 Job 模板规范中包含以下值,将无头服务配置为 Job Pod 的子域服务:
subdomain: <headless-svc-name>
示例
以下是一个通过 Pod 主机名启用 Pod-to-Pod 通信的 Job 的工作示例。该 Job 仅在所有 Pod 都成功地使用主机名相互 ping 通后才会完成。
注意
在以下示例中,每个 Pod 上执行的 Bash 脚本中,如果 Pod 需要从命名空间外部访问,Pod 主机名也可以加上命名空间前缀。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-hostname>.<headless-service-name>
在网络上相互访问。你应该会看到类似以下的输出:
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
注意
请注意,本例中使用的<pod-hostname>.<headless-service-name>
名称格式在 DNS 策略设置为 None
或 Default
时将不起作用。请参阅Pod 的 DNS 策略。