image.png

相信大家在做容器化改造的时候都有遇到在k8s集群中运行的pod需要通过主机名连接k8s集群之外的数据库或者中间件之类的场景。k8s集群在部署了CoreDNS后,CoreDNS就会在集群内部添加svc的解析记录,svc再通过标签(label)与endpoint进行关联,当pod访问svc时,会自动将请求转发到与之绑定的pod上。但是,如果要从集群内部通过主机名访问集群外部的主机呢?该如何实现?

使用 HostAliases 向 Pod 的 /etc/hosts 文件中添加解析

Pod 中 /etc/hosts 文件默认配置
[root@jumpserver-app-1 ~]# kubectl exec -it 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.244.36.68	nginx

默认情况下,hosts只包含IPV4和IPV6的内容以及pod自身的解析

[root@jumpserver-app-1 ~]# kubectl get pod nginx -owide
NAME    READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          66d   10.244.36.68   k8s-node1   <none>           <none>
1、通过 HostAliases 增加外部解析

除了默认内容外,我们可以通过 .spec.hostAliases 为 Pod 配置 hostAliases,会自动将配置的解析记录写入 Pod 的 /etc/hosts 文件中

[root@jumpserver-app-1 manifests]# cat nginx.yml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx
  name: nginx
  namespace: default
spec:
  hostAliases:
  - ip: "172.17.251.3"
    hostname:
    - "test-mysql.local"
    - "test-zk.local"
  - ip: "172.17.251.4"
    hostname:
    - "abc.example.com"
    - "test.example.com"
  containers:
  - image: nginx
    name: nginx
  nodeName: k8s-node1
  nodeSelector:
    type: sss

hostAliases 用法可以通过命令 kubectl explain pod.spec.hostAliases 查看使用说明。

[root@jumpserver-app-1 manifests]# kubectl apply -f nginx.yml 
pod/nginx created
[root@jumpserver-app-1 mnt]# kubectl exec -it 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.244.36.93	nginx

# Entries added by HostAliases.
172.17.251.3	test-mysql.local	test-zk.local
172.17.251.4	abc.example.com	test.example.com

可以看到在 pod 的 /etc/hosts 文件的最下面已经通过 HostAliases 字段自动添加了自定义的解析记录

2、通过修改CoreDNS组件的ConfigMap添加自定义解析记录

正常情况下只需要在 CoreDNS 的 ConfigMap 中添加 hosts 字段,添加相应的解析记录即可。,重建CoreDNS组件,让其重新加载配置。

hosts {
            10.2.80.89 liheng-test.k8s.abc
        }

使用busybox启动一个容器进行测试

[root@jumpserver-app-1 test]# kubectl exec -it busybox -- nslookup liheng-test.k8s.abc
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      liheng-test.k8s.abc
Address 1: 10.2.80.89 liheng-test.k8s.abc
[root@jumpserver-app-1 test]# kubectl exec -it busybox -- ping liheng-test.k8s.abc
PING liheng-test.k8s.abc (10.2.80.89): 56 data bytes
64 bytes from 10.2.80.89: seq=0 ttl=54 time=1.400 ms
64 bytes from 10.2.80.89: seq=1 ttl=54 time=1.148 ms
64 bytes from 10.2.80.89: seq=2 ttl=54 time=0.634 ms
64 bytes from 10.2.80.89: seq=3 ttl=54 time=0.782 ms

通过测试结果,可以很明显的看出已经达到我们预期的效果。

如果文章对您有帮助,还想了解更过关于k8s相关的实战经验,请微信扫描下方二维码关注“IT运维图谱”公众号或着通过微信搜一搜关注公众号。 image.png