使用 HostAliases 将条目添加到 Pod 的 /etc/hosts 文件

通过在 Pod 的 /etc/hosts 文件中添加条目,可以在 DNS 和其他选项不适用时提供 Pod 级别的主机名解析覆盖。你可以使用 PodSpec 中的 HostAliases 字段来添加这些自定义条目。

Kubernetes 项目建议使用 hostAliases 字段(Pod 的 .spec 的一部分)修改 DNS 配置,而不是使用 init 容器或其他方式直接编辑 /etc/hosts。通过其他方式进行的更改可能会在 Pod 创建或重启期间被 kubelet 覆盖。

默认 hosts 文件内容

启动一个分配了 Pod IP 的 Nginx Pod

kubectl run nginx --image nginx
pod/nginx created

检查 Pod IP

kubectl get pods --output=wide
NAME     READY     STATUS    RESTARTS   AGE    IP           NODE
nginx    1/1       Running   0          13s    10.200.0.4   worker0

hosts 文件内容看起来像这样

kubectl exec nginx -- cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
fe00::0	ip6-mcastprefix
fe00::1	ip6-allnodes
fe00::2	ip6-allrouters
10.200.0.4	nginx

默认情况下,hosts 文件仅包含 IPv4 和 IPv6 的样板条目,例如 localhost 和它自己的主机名。

使用 hostAliases 添加额外的条目

除了默认的样板条目外,你还可以向 hosts 文件添加额外的条目。例如:要将 foo.localbar.local 解析到 127.0.0.1,并将 foo.remotebar.remote 解析到 10.1.2.3,你可以在 Pod 的 .spec.hostAliases 下配置 HostAliases

apiVersion: v1
kind: Pod
metadata:
  name: hostaliases-pod
spec:
  restartPolicy: Never
  hostAliases:
  - ip: "127.0.0.1"
    hostnames:
    - "foo.local"
    - "bar.local"
  - ip: "10.1.2.3"
    hostnames:
    - "foo.remote"
    - "bar.remote"
  containers:
  - name: cat-hosts
    image: busybox:1.28
    command:
    - cat
    args:
    - "/etc/hosts"

你可以通过运行以下命令启动使用该配置的 Pod

kubectl apply -f https://k8s.io/examples/service/networking/hostaliases-pod.yaml
pod/hostaliases-pod created

检查 Pod 的详细信息以查看其 IPv4 地址和状态

kubectl get pod --output=wide
NAME                           READY     STATUS      RESTARTS   AGE       IP              NODE
hostaliases-pod                0/1       Completed   0          6s        10.200.0.5      worker0

hosts 文件内容看起来像这样

kubectl logs hostaliases-pod
# Kubernetes-managed hosts file.
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
fe00::0	ip6-mcastprefix
fe00::1	ip6-allnodes
fe00::2	ip6-allrouters
10.200.0.5	hostaliases-pod

# Entries added by HostAliases.
127.0.0.1	foo.local	bar.local
10.1.2.3	foo.remote	bar.remote

底部是指定的附加条目。

为什么 kubelet 管理 hosts 文件?

kubelet 为 Pod 的每个容器管理 hosts 文件,以防止容器运行时在容器启动后修改文件。从历史上看,Kubernetes 总是使用 Docker Engine 作为其容器运行时,而 Docker Engine 会在每个容器启动后修改 /etc/hosts 文件。

当前的 Kubernetes 可以使用各种容器运行时;即便如此,kubelet 仍然管理每个容器内的 hosts 文件,这样无论你使用哪种容器运行时,结果都会如预期一致。

最后修改于 2024 年 10 月 03 日 太平洋标准时间下午 4:50:移除重复信息 (05c1f011d4)