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实现服务发现的整体架构:

k8s-kube-dns.png

2.3 Kubernetes 1.11版本开始 - CoreDNS进入GA

从Kubernetes 1.11开始,可使用CoreDNS作为Kubernetes的DNS插件进入GA状态,Kubernetes推荐使用CoreDNS作为集群内的DNS服务。 CoreDNS从2017年初就成为了CNCF的的孵化项目,CoreDNS的特点就是十分灵活和可扩展的插件机制,各种插件实现不同的功能,如重定向、定制DNS记录、记录日志等等。下图描述了CoreDNS的整体架构:

coredns-architecture.png

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_IPDNS_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

参考