具有 Pod 到 Pod 通信的 Job
在本例中,您将在 索引完成模式 中运行一个作业,该模式配置为使作业创建的 Pod 可以使用 Pod 主机名而不是 Pod IP 地址相互通信。
作业中的 Pod 可能需要相互通信。运行在每个 Pod 中的用户工作负载可以查询 Kubernetes API 服务器以了解其他 Pod 的 IP,但依靠 Kubernetes 的内置 DNS 解析更简单。
索引完成模式下的作业会自动将 Pod 的主机名设置为 ${jobName}-${completionIndex}
格式。您可以使用此格式来确定性地构建 Pod 主机名并启用 Pod 通信,无需 创建与 Kubernetes 控制平面的客户端连接以通过 API 请求获取 Pod 主机名/IP。
此配置适用于需要 Pod 网络但又不想依赖与 Kubernetes API 服务器的网络连接的用例。
在您开始之前
您应该已经熟悉 作业 的基本用法。
您需要一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。建议您在至少有两个节点(不是作为控制平面主机)的集群上运行本教程。如果您还没有集群,可以使用 minikube 创建一个,或者您可以使用以下 Kubernetes Playground 之一
您的 Kubernetes 服务器必须是 v1.21 或更高版本。要检查版本,请输入kubectl version
。注意
如果您使用的是 MiniKube 或类似的工具,您可能需要采取 额外步骤 来确保您拥有 DNS。启动具有 Pod 到 Pod 通信的作业
要在作业中使用 Pod 主机名启用 Pod 到 Pod 通信,您必须执行以下操作
设置一个带有有效标签选择器的 无头服务,用于作业创建的 Pod。无头服务必须与作业位于同一个命名空间。一种简单的方法是使用
job-name: <your-job-name>
选择器,因为job-name
标签会由 Kubernetes 自动添加。此配置将触发 DNS 系统创建运行作业的 Pod 主机名的记录。通过在作业模板规范中包含以下值,将无头服务配置为作业 Pod 的子域服务
subdomain: <headless-svc-name>
示例
下面是具有 Pod 到 Pod 通信(通过 Pod 主机名启用)的工作示例。作业仅在所有 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 策略的更多信息 这里。