修改 Kubernetes 集群中容器的 hosts

最近工作中遇到一个问题,就是某个系统需要访问一个第三发系统,在没有私有DNS的情况下,只能通过修改hosts文件解析域名。

假设需要添加的解析为 1.2.3.4 thirdparty.com

而我们知道Docker的hosts文件是容器启动后动态加载的,所以无法在Dockerfile中设置。

而如果是使用docker run命令启动容器,可以使用`–add-host thirdparty.com:1.2.3.4`参数修改hosts;

如果是docker compose,则可以使用extra_hosts: "thirdparty.com:1.2.3.4"

但Kubernetes却没有提供类似的方法修改hosts…

刚开始尝试使用 Services,并手动创建EndPoints指向外部服务的地址。但这种方式实际提供的是一种服务,对于只是域名解析来说不合适。

还有一种最脏的办法是每次容器创建成功后通过脚本之行kubectl exec添加hosts,太脏了…

最后一种办法是我发现的最适合也相对干净的一种办法了,需要用到Kubernetes ConfigMap

创建一个ConfigMap

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: ConfigMap
metadata:
name: thirdparty-hosts
data:
hosts: |
thirdparty.com 1.2.3.4
baidu.com 2.3.4.5
google.com 3.4.5.6

集成start.sh脚本到镜像里

1
2
3
4
5
#!/bin/sh
cat /mnt/hosts.append/hosts >> /etc/hosts
exec your-app args

将ConfigMap以Volume的方式挂载并执行启动脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: extensions/v1beta1
kind: Deployment
spec:
template:
spec:
volumes:
- name: hosts-volume
configMap:
name: thirdparty-hosts
containers:
command:
- ./start.sh
volumeMounts:
- name: hosts-volume
mountPath: /mnt/hosts.append

这种方式虽然看起来也有点麻烦,但通过维护一个ConfigMap集中管理所有hosts还不错。

另外据说 V1.4 版本中添加了一个新特性能更好的解决这个问题,"external name" (CNAME) services,还没升级暂时不评价。