Kubernetes DNS服务配置

Posted LightingLYG

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes DNS服务配置相关的知识,希望对你有一定的参考价值。

Kubernetes DNS服务配置
Kubernetes提供的DNS由以下三个组件组成:
1. etcd:DNS存储
2. kube2sky:将kubernetes master中的service(服务)注册到etcd
3. skyDNS:提供DNS域名解析服务 这三个组件以pod的方式启动和运行

skydns配置文件
首先创建DNS服务的ReplicationController配置文件skydns-rc.yaml:

apiVersion: v1
kind: ReplicationController
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    version: v8
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 1
  selector:
    k8s-app: kube-dns
    version: v8
  template:
    metadata:
      labels:
        k8s-app: kube-dns
        version: v8
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
      - name: etcd
        image: gcr.io/google_containers/etcd:2.0.9
        resources:
          limits:
            cpu: 100m
            memory: 50Mi
        command:
        - /usr/local/bin/etcd
        - -data-dir
        - /var/etcd/data
        - --listen-client-urls
        - http://127.0.0.1:2379,http://127.0.0.1:4001
        - --advertise-client-urls
        - http://127.0.0.1:2379,http://127.0.0.1:4001
        - --initial-cluster-token
        - skydns-etcd
        volumeMounts:
        - name: etcd-storage
          mountPath: /var/etcd/data
      - name: kube2sky
        image: gcr.io/google_containers/kube2sky:1.11
        resources:
          limits:
            cpu: 100m
            memory: 50Mi
        args:
       # command:
       # - /kube2sky
        - --kube_master_url=http://172.16.36.50:8080
        - -domain=cluster.local
      - name: skydns
        image: gcr.io/google_containers/skydns:2015-10-13-8c72f8c
        resources:
          limits:
            cpu: 100m
            memory: 50Mi
        args:
        #command:
        #- /skydns
        - -machines=http://127.0.0.1:4001
        - -addr=0.0.0.0:53
        - -domain=cluster.local
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
      volumes:
        - name: etcd-storage
          emptyDir: 
      dnsPolicy: Default

需要修改的几个配置参数如下:

  1. kube2sky容器需要访问kubernetes master,需要配置master所在物理主机的ip地址和端口号
  2. kube2sky容器和skydns容器的启动参数-domain,设置kubernetes集群中service所属的域名,本例中为cluster.local。启动后,kube2sky会监听kubernetes,当有新的service创建时,就会生成相应的记录并保存到etcd中。Kube2sky为每个service生成两条记录:
    <service_name>.<namespace_name>.<domain> <service_name>.<namespace_name>.svc.<domain>
  3. skydns的启动参数-addr=0.0.0.0:53表示使用本机TCP和UDP的53端口提供服务

创建DNS服务的service配置文件,skydns-svc.yaml:

apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "KubeDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 10.254.10.20
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP

注意:skydns服务使用的clusterIP需要我们指定一个固定的IP地址,每个node的kubelet进程都将使用这个ip地址,不能通过kubernetes自动分配,另外,这个ip地址需要在kube-apiserver启动参数--service-cluster-ip-range指定的ip地址范围内

修改每个node上的/etc/kubernetes/kubelet启动参数
--cluster_dns=10.254.10.20,为dns服务的clusterIP
--cluster_domain=cluster.local,为dns服务中设置的域名
重启kubelet服务

systemctl daemon-reload  
systemctl restart kubelet

创建kube-system namespace 创建kube-system.yaml,内容如下

apiVersion: v1
kind: Namespace
metadata:
  name: kube-system

创建namespace:

kubectl create -f kube-system.yaml
# 查看namespace:
kubectl get namespace

创建skydns pod服务

kubectl create -f skydns-rc.yaml
kubectl create -f skydns-svc.yaml
创建完成后,查看是否创建成功

[root@cti-m dns]# kubectl get rc --namespace=kube-system
NAME                   DESIRED   CURRENT   AGE
kube-dns               1         1         11h

[root@cti-m dns]# kubectl get pod --namespace=kube-system
NAME                         READY     STATUS    RESTARTS   AGE
kube-dns-gvvcj               3/3       Running   0          11h

然后,我们创建一个普通的service,以redis-master服务为例:

apiVersion: v1
kind: Service
metadata:
  name: redis-master
  labels:
    name: redis-master
spec:
  ports:
    - port: 6379
  selector:
    name: redis-master

查看创建出来的service:

[root@cti-m dns]# kubectl get services
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.254.0.1      <none>        443/TCP    1d
redis-master   10.254.47.239   <none>        6379/TCP   9s

通过DNS查找service
使用一个带有nslookup工具的pod来验证DNS服务是否能够正常工作,以busybox.yaml为例

[root@cti-m dns]# cat busybox.yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
    - image: gcr.io/google_containers/busybox
      command:
        - sleep
        - "3600"
      imagePullPolicy: IfNotPresent
      name: busybox
  restartPolicy: Always

运行kubectl create -f busybox.yaml完成创建
在该容器启动完成后,通过kubectl exec <container_id> -- nslookup进行测试

[root@cti-m dns]# kubectl exec busybox -- nslookup redis-master
Server:    10.254.10.20
Address 1: 10.254.10.20

Name:      redis-master
Address 1: 10.254.47.239
[root@cti-m dns]#

如果某个service属于自定义的命名空间,那么在进行service查找时,需要带上namespace的名字

[root@cti-m dns]# kubectl exec busybox -- nslookup kube-dns.kube-system
Server:    10.254.10.20
Address 1: 10.254.10.20

Name:      kube-dns.kube-system
Address 1: 10.254.10.20
[root@cti-m dns]#

DNS服务的工作原理解析

  1. kube2sky容器应用通过调用kubernetes master的API获得集群中所有service的信息,并持续监控新service的生成,然后写入etcd中
    查看etcd中存储的service信息:
[root@cti-m dns]# kubectl exec kube-dns-gvvcj -c etcd --namespace=kube-system etcdctl ls /skydns/local/cluster
/skydns/local/cluster/default
/skydns/local/cluster/svc
/skydns/local/cluster/kube-system

可以看到在skydns键下面,根据我们配置的域名(cluster.local)生成了local/cluster子键,接下来是namespace(default和kube-system)和svc(下面也按namespace生成子键)。

[root@cti-m dns]# kubectl exec kube-dns-gvvcj -c etcd --namespace=kube-system etcdctl get /skydns/local/cluster/default/redis-master
"host":"10.254.47.239","priority":10,"weight":10,"ttl":30,"targetstrip":0
[root@cti-m dns]#

可以看到,redis-master服务对应的完整域名为redis-master.default.cluster.local,并且其ip地址为:10.254.47.239

  1. 根据kubelet启动参数的设置(--cluster_dns),kubelet会在每个新创建的pod中设置DNS域名解析配置文件/etc/resolv.conf文件,在其中增加了一条nameserver配置和一条search配置:
# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.254.10.20
nameserver 114.114.114.114
options ndots:5

通过名字服务器10.254.10.20访问的实际上就是skydns在53端口上提供的DNS解析服务

以上是关于Kubernetes DNS服务配置的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes DNS 记录

基于kubernetes实现coredns的及验证

k8s 如何使用kube-dns实现服务发现

实践:Kubernetes 集群中 DNS 故障的可观测性与根因诊断

Kubernetes 部署集群内部DNS服务

k8s中的dns应用