Kubernetes addons 之 coredns部署
DNS 是 Kubernetes 的核心功能之一,通过 kube-dns 或 CoreDNS 作为集群的必备扩展来提供命名服务。
Kubernetes基于DNS的服务发现
在Kubernetes集群推荐使用Service Name作为服务的访问地址,因此需要一个Kubernetes集群范围的DNS服务实现从Service Name到Cluster Ip的解析,这就是Kubernetes基于DNS的服务发现功能。
Kubernetes DNS服务发展史
从Kubernetes 1.11开始,可使用CoreDNS作为Kubernetes的DNS插件进入GA状态,Kubernetes推荐使用CoreDNS作为集群内的DNS服务。 CoreDNS从2017年初就成为了CNCF的的孵化项目,CoreDNS的特点就是十分灵活和可扩展的插件机制,各种插件实现不同的功能,如重定向、定制DNS记录、记录日志等等。下图描述了CoreDNS的整体架构:
DNS 格式
Service
A records
- 普通(不是headless)service被分配了一个名为my-svc.my-namespace.svc.cluster.local形式的DNS A记录。 这解析为服务的群集IP。
- Headless(without a cluster IP) Service 也为DNS A records绑定了一个my-svc.my-namespace.svc.cluster.local形式记录。 与普通service不同,这将解析为服务选择的pod的IP集合。 当客户端访问时,会轮询访问该IP集合
SRV records
SRV 记录的创建是根据普通(或 Headless Service )ports 名称创建的,对于每个端口的命名,SRV记录的格式为_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local.
.对于普通的service,my-svc.my-namespace.svc.cluster.local
将解析为端口号和域名,对于
headless service,将解析成多条记录,对于service引用的每一个pod,auto-generated-name.my-svc.my-namespace.svc.cluster.local
将解析成包含端口号和域名的记录
更多内容请参考 kubernetes dns 规范
)
CoreDNS ConfigMap选项
在Kubernetes中,我们安装的CoreDNS使用了以下默认的Corefile配置。
apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system labels: addonmanager.kubernetes.io/mode: EnsureExists data: Corefile: | .:53 { errors health kubernetes cluster.local. in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } prometheus :9153 proxy . /etc/resolv.conf cache 30 loop reload loadbalance }
Upstream
用于解析指向外部主机的服务(外部服务)。
- prometheus:CoreDNS的度量标准可以在http//localhost:9153/Prometheus格式的指标中找到。
- proxy:任何不在Kubernetes集群域内的查询都将转发到预定义的解析器(/etc/resolv.conf)。
- cache:这将启用前端缓存。
- loop:检测简单的转发循环,如果找到循环则停止CoreDNS进程。
- reload:允许自动重新加载已更改的Corefile。编辑ConfigMap配置后,请等待两分钟以使更改生效。
- loadbalance:这是一个循环DNS负载均衡器,可以在答案中随机化A,AAAA和MX记录的顺序。
Kubernetes配置使用CoreDNS
- 进入源码包,我们在部署Dashboard的时候已经解压缩了kubernetes-src.tar.gz,进入 kubernetes/cluster/addons/dns/coredns目录
[root@k8s coredns]# ls coredns.yaml.base coredns.yaml.in coredns.yaml.sed Makefile transforms2salt.sed transforms2sed.sed #查看transforms2sed.sed的内容: [root@k8s coredns]# cat transforms2sed.sed s/__PILLAR__DNS__SERVER__/$DNS_SERVER_IP/g s/__PILLAR__DNS__DOMAIN__/$DNS_DOMAIN/g s/__PILLAR__CLUSTER_CIDR__/$SERVICE_CLUSTER_IP_RANGE/g s/__MACHINE_GENERATED_WARNING__/Warning: This is a file generated from the base underscore template file: __SOURCE_FILENAME__/g
- 将
$DNS_SERVER_IP
和$DNS_DOMAIN
替换成kubelet配置的内容。
[root@k8s cfg]# cat kubelet.config kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 10.0.52.14 port: 10250 readOnlyPort: 10255 cgroupDriver: cgroupfs clusterDNS: - "10.0.0.2" clusterDomain: cluster.local. failSwapOn: false authentication: anonymous: enabled: true
这里将$DNS_SERVER_IP
替换成10.0.0.2
,将$DNS_DOMAIN
替换成cluster.local.
- 执行下面的命令,生成部署coreDNS所需的coredns.yaml文件:
sed -f transforms2sed.sed coredns.yaml.base > coredns.yaml
- 替换镜像,将
k8s.gcr.io/coredns:1.2.6
替换成coredns/coredns:1.2.6
- 部署dns
kubectl apply -f coredns.yaml #查看coredns的Pod,确认所有Pod都处于Running状态: [root@k8s coredns]# kubectl get pods -n kube-system -l k8s-app=kube-dns NAME READY STATUS RESTARTS AGE coredns-dc8bbbcf9-k28h8 1/1 Running 0 18s
- 测试DNS
6.1 部署nginx,部署文件如下:
[root@k8s ~]# cat nginx.yaml apiVersion: apps/v1beta2 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.10 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: labels: run: nginx name: nginx namespace: default spec: type: NodePort ports: - port: 80 targetPort: 80 selector: app: nginx [root@k8s ~]# kubectl create -f nginx.yaml deployment.apps/nginx-deployment created service/nginx created [root@k8s ~]# kubectl get pod,svc NAME READY STATUS RESTARTS AGE pod/nginx-deployment-7544fc9954-d274k 1/1 Running 0 18s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 3d2h service/nginx NodePort 10.0.0.86 <none> 80:45498/TCP 18s
6.2 部署busybox,测试DNS功能
[root@k8s ~]# kubectl run -it --image=busybox:1.28.4 --rm --restart=Never sh If you don't see a command prompt, try pressing enter. / # nslookup kubernetes Server: 10.0.0.2 Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local Name: kubernetes Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local / # nslookup nginx Server: 10.0.0.2 Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local Name: nginx Address 1: 10.0.0.86 nginx.default.svc.cluster.local / # nslookup nginx.default.svc.cluster.local Server: 10.0.0.2 Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local Name: nginx.default.svc.cluster.local Address 1: 10.0.0.86 nginx.default.svc.cluster.local / # cat /etc/resolv.conf nameserver 10.0.0.2 search default.svc.cluster.local. svc.cluster.local. cluster.local. options ndots:5
DNS服务是Kubernetes赖以实现服务发现的核心组件之一,默认情况下只会创建一个DNS Pod,在生产环境中我们需要对coredns进行扩容。 有两种方式:
- 手动扩容 kubectl scale deploy/coredns --replicas=<num_you_want> -n kube-system
[root@k8s ~]# kubectl scale deploy/coredns --replicas=2 -n kube-system deployment.extensions/coredns scaled [root@k8s ~]# kubectl get deploy -n kube-system NAME READY UP-TO-DATE AVAILABLE AGE coredns 2/2 2 2 13m [root@k8s ~]#
- 查看dns规则
如图所示,nginx service的cluster IP:port为10.0.0.86:80,对应的pod的ip为:172.12.9.4,172.12.95.3,172.12.9.5
通过ipvsadm 命令查看,显示各个ip和端口的转发规则,如果所示10.0.0.86:80是通过rr(Round-Robin)默认调度算法来实现到172.12.9.4:80,172.12.95.3:80,172.12.9.5:80的pod中的转发和负载。