【问题小解决】如何解决多容器下修改hosts失效


问题现象

业务容器启动的逻辑中,修改了/etc/hosts文件,当 Pod 只存在这一个业务容器时,文件可以修改成功, 但存在多个时 (比如注入了 istio 的 sidecar),修改可能会失效。

分析

  1. 容器中的/etc/hosts是由 kubelet 生成并挂载到 Pod 中所有容器, 如果 Pod 有多个容器,它们挂载的/etc/hosts文件都对应宿主机上同一个文件, 路径通常为/var/lib/kubelet/pods/<pod-uid>/etc-hosts

如果是 docker 运行时,可以通过docker inspect <container-id> -f {{.HostsPath}}查看。

  1. kubelet 在启动容器时,都会走如下的调用链(makeMounts->makeHostsMount->ensureHostsFile)来给容器挂载 /etc/hosts, 而在 ensureHostsFile 函数中都会重新创建一个新的 etc-hosts 文件,导致在其他容器中对 /etc/hosts 文件做的任何修改都被还原了。

所以,当 Pod 中存在多个容器时,容器内修改 /etc/hosts 的操作可能会被覆盖回去。

解决方案

使用 HostAliases

如果只是某一个 workload 需要 hosts,可以用 HostAliases:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: apps/v1
kind: Deployment
metadata:
   name: host
spec:
   replicas: 1
   selector:
      matchLabels:
         app: host
   template:
      metadata:
         labels:
            app: host
      spec:
         hostAliases: # 这下面定义 hosts
         - ip: "10.10.10.10"
           hostnames:
           - "mysql.example.com"
         containers:
         - name: nginx
           image: nginx:latest

CoreDNS hosts

如果是多个 workload 都需要共同的 hosts,可以修改集群 CoreDNS 配置,在集群级别增加 hosts:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        hosts {
          1.1.1.1 huangzehong.me
          fallthrough
        }
        prometheus :9153
        ## 这里的文件就是宿主机的文件,个别系统该文件受systemd-resolved管理,无法直接改动
        ## 可以通过coredns_forward_request_total{k8s_app="kube-dns"}这个指标看到多少请求被转发至上游
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }    
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
  resourceVersion: "281"
  uid: bf0f0e56-fb2c-4392-9d42-1a55a127ecf2