使用CoreDNS实现Kubernetes基于DNS的服务发现
2018-10-12
1.Kubernetes基于DNS的服务发现 #
在Kubernetes集群推荐使用Service Name作为服务的访问地址,因此需要一个Kubernetes集群范围的DNS服务实现从Service Name到Cluster Ip的解析,这就是Kubernetes基于DNS的服务发现功能。
在从Kubernetes 1.10开始Dynamic Kubelet Configuration特性进入beta阶段,kubelet的大多数命令行参数都改为推荐在--config
指定位置的配置文件中进行配置,包括---cluster-dns
和--cluster-domain
两个参数,在kubelet的配置文件中配置如下:
1apiVersion: kubelet.config.k8s.io/v1beta1
2kind: KubeletConfiguration
3......
4clusterDNS:
5- 10.96.0.10
6clusterDomain: cluster.local
7......
其中clusterDNS指定了集群中所有容器将使用的DNS Server,即kubelet会在每个Pod内部设置DNS服务的地址为clusterDNS配置的地址。前面的配置中设置了Kubernetes集群访问内DNS服务器的地址是10.96.0.10,将由起完成Service Name到Cluster Ip的解析。有了这个配置,我们还需要在集群内部署DNS服务,DNS服务一般都是作为addon组件部署在Kubernetes集群内的。
2.Kubernetes DNS服务发展史 #
从Kubernetes 1.11开始,可使用CoreDNS作为Kubernetes的DNS插件进入GA状态,Kubernetes推荐使用CoreDNS作为集群内的DNS服务。 我们先看一下Kubernetes DNS服务的发展历程。
2.1 Kubernetes 1.3之前的版本 - skyDNS #
Kubernetes 1.3之前的版本使用skyDNS作为DNS服务,这个有点久远了。Kubernetes的DNS服务由kube2sky、skyDNS、etcd组成。 kube2sky通过kube-apiserver监听集群中Service的变化,将生成的DNS记录信息更新到etcd中,而skyDNS将从etcd中获取数据对外提供DNS的查询服务。
2.2 Kubernetes 1.3版本开始 - kubeDNS #
Kubernetes 1.3开始使用kubeDNS和dnsmasq替换了原来的kube2sky和skyDNS,不再使用etcd,而是将DNS记录直接存放在内存中,通过dnsmasq的缓存功能提高DNS的查询效率。下图是描述了Kubernetes使用kubeDNS实现服务发现的整体架构:
2.3 Kubernetes 1.11版本开始 - CoreDNS进入GA #
从Kubernetes 1.11开始,可使用CoreDNS作为Kubernetes的DNS插件进入GA状态,Kubernetes推荐使用CoreDNS作为集群内的DNS服务。 CoreDNS从2017年初就成为了CNCF的的孵化项目,CoreDNS的特点就是十分灵活和可扩展的插件机制,各种插件实现不同的功能,如重定向、定制DNS记录、记录日志等等。下图描述了CoreDNS的整体架构:
3.Kubernetes配置使用CoreDNS #
在Kubernetes中部署CoreDNS作为集群内的DNS服务有很多种方式,例如可以使用官方Helm Chart库中的helm chart部署,具体可查看CoreDNS Helm Chart。这里继承我们之前部署kubeDNS的传统,使用Kubernetes中addon库中的yaml文件部署,地址在这里coredns addon。
查看transforms2sed.sed的内容:
1s/__PILLAR__DNS__SERVER__/$DNS_SERVER_IP/g
2s/__PILLAR__DNS__DOMAIN__/$DNS_DOMAIN/g
3s/__PILLAR__CLUSTER_CIDR__/$SERVICE_CLUSTER_IP_RANGE/g
4s/__MACHINE_GENERATED_WARNING__/Warning: This is a file generated from the base underscore template file: __SOURCE_FILENAME__/g
将$DNS_SERVER_IP
和DNS_DOMAIN
替换成kubelet配置的内容。这里将$DNS_SERVER_IP
替换成10.96.0.10
,将DNS_DOMAIN
替换成cluster.local
。
执行下面的命令,生成部署coreDNS所需的coredns.yaml文件:
1sed -f transforms2sed.sed coredns.yaml.base > coredns.yaml
对coredns.yaml做微调,如修改镜像地址为私有镜像仓库,调整副本数量等等。
1kubectl delete -f kube-dns.yaml #删除原来的kubeDNS部署
2kubectl apply -f coredns.yaml
查看coredns的Pod,确认所有Pod都处于Running状态:
1kubectl get pods -n kube-system -l k8s-app=kube-dns
2NAME READY STATUS RESTARTS AGE
3coredns-699477c54d-9fsl2 1/1 Running 0 5m
4coredns-699477c54d-d6tb2 1/1 Running 0 5m
5coredns-699477c54d-qh54v 1/1 Running 0 5m
6coredns-699477c54d-vvqj9 1/1 Running 0 5m
7coredns-699477c54d-xcv8h 1/1 Running 0 6m
测试一下DNS功能是否好用:
1kubectl run curl --image=radial/busyboxplus:curl -i --tty
2
3nslookup kubernetes.default
4Server: 10.96.0.10
5Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
6
7Name: kubernetes
8Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
DNS服务是Kubernetes赖以实现服务发现的核心组件之一,默认情况下只会创建一个DNS Pod,在生产环境中我们需要对coredns进行扩容。 有两种方式:
- 手动扩容 kubectl –namespace=kube-system scale deployment coredns –replicas=<NUM_YOU_WANT>
- 使用DNS Horizontal Autoscaler