kubernetes:kubeDNS部署

一,理解Kubedns原理

        通俗理解,首先明白k8s dns是为服务的发现而生,即service的发现,为了能够让其它服务能够直接通过service 名字找到它们,于是就需要dns将service名转换为它的VIP, 那么service的变化如何知道? 如何知道目前有哪些service 及知道他们的vip呢,service的增加减少又如何知道了,  

         所以要有一个组件(1.3中是Kube2sky,1.3后是kubedns)来时刻监控它的变化,监控到了什么就把它记录下来,记录的是service和ip之间的映射关系,称为DNS解析记录,但是记录在某个位置呢,监控的组件不同,记录的位置也不同, Kube2sky是记录到etcd中,kubedns是记录到哪了呢, 记录在内存当中,使用树形结构在内存中保存监控到的记录。

         由于一切对集群的操作都是通过其API来的,所以它监控service资源变化也是借助于k8s API

      这个组件仅仅是记录下来以后,并不提供查询。所以查询就是另外一个组件的作用了,1.3之前是由Skydns来查询的, 所有服务(pod)都找skydns查询,1.3以后都是由dnsmasq查询的,它们从前面记录的地方查询相关service的解析记录,之所以用dnsmasq来查询,因为它提供DNS查询缓存,在内存中完成查询,查询速度非常快!

两个组件一个负责监控并记录,另外一个负责帮其它服务做查询,  两个组件必须要同时运行,如果其中一个出问题了,那么dns系统将无法解析,于是需要有另一个组件专门来监控它们的健康状态,这个组件就是exechealthz,Exechealthz是两个版本中唯一保留的容器,依然提供健康检查。

         在K8s中,这三个组件都是用容器运行的,而且是在同一个pod中,

       官方理解,上图:

   image.png

   

     ● dnsmasq简介

           Dnsmasq是一款小巧的DNS配置工具

           在kube-dns插件中的作用:

            ●   通过kubedns容器获取DNS规则,在集群中提供DNS查询服务,相当于dns的server端。

            

            ●   提供DNS缓存,提高查询性能

            

            ●   降低kubedns容器的压力、提高稳定性

            

            ●    Dockerfile在GitHub上Kubernetes组织的contrib仓库中,位于dnsmasq目录下

             

      ●  exechealthz简介

            

            ●    在kube-dns插件中提供健康检查功能

            

            ●    源码同样在contrib仓库中,位于exec-healthz目录下。

            

            ●    新版中会对两个容器都进行健康检查,更加完善。


       ●  总结

          kube-dns插件的三个容器的功能如下:

           

                ●    kubedns容器

                

                ●   监视k8s Service资源并更新DNS记录

                

                ●   替换etcd,使用TreeCache数据结构保存DNS记录并实现SkyDNS的Backend接口

                

                ●   接入SkyDNS,对dnsmasq提供DNS查询服务

                

                ●    dnsmasq容器

                

                ●   对集群提供DNS查询服务

                

                ●   设置kubedns为upstream

                

                ●   提供DNS缓存,降低kubedns负载,提高性能

                

                ●    exechealthz容器

                

                ●   定期检查kubedns和dnsmasq的健康状态

                

                ●   为k8s活性检测提供HTTP API

    


 二、部署kubedns         

    1,上官方网址下载需要的yaml部署文件:https://github.com/kubernetes/kubernetes/tree/release-1.8/cluster/addons/dns

1
2
   ls *.yaml *.base
      kubedns-cm.yaml  kubedns-sa.yaml  kubedns-controller.yaml.base  kubedns-svc.yaml.base

    2,主要是修改这四个部署文件

1
2
3
4
5
6
7
8
    cat kubedns-cm.yaml        #此文件不需修改
   apiVersion: v1
   kind: ConfigMap
   metadata:
     name: kube-dns
     namespace: kube-system
     labels:
       addonmanager.kubernetes.io/mode: EnsureExists
1
2
3
4
5
6
7
8
9
  # cat kubedns-sa.yaml       #此文件不需修改   
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: kube-dns
        namespace: kube-system
        labels:
        kubernetes.io/cluster-service"true"
        addonmanager.kubernetes.io/mode: Reconcile

  

    接下来主要修改的是 kubedns-controller.yaml 和 kubedns-svc.yaml

      主要diff来比较下原文件与修改过的文件区别:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
diff kubedns-controller.yaml.base /root/kubernetes/k8s-deploy/mainifest/dns/kubedns-controller.yaml 
 
58c58
<         image: gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.5
---
>         image: gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.4
 
88c88
<         - --domain=$DNS_DOMAIN.
---
>         - --domain=cluster.local.
 
109c109
<         image: gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5
---
>         image: gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.4
 
128c128
<         - --server=/$DNS_DOMAIN/127.0.0.1#10053
---
>         - --server=/cluster.local/127.0.0.1#10053
 
147c147
<         image: gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.5
---
>         image: gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.4
 
160,161c160,161
<         - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.$DNS_DOMAIN,5,A
<         - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.$DNS_DOMAIN,5,A
---
>         - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,A
>         - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,A 
 
无非就是将有 k8s-dns-sidecar-amd64:1.14.5 的改为 k8s-dns-sidecar-amd64:1.14.4,将变量集群域名的环境变量 $DNS_DOMAIN 替换我们之前设置好的域名,如cluster.local

   修改过后的完整文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# cat kubedns-controller.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  # replicas: not specified here:
  # 1. In order to make Addon Manager do not reconcile this replicas parameter.
  # 2. Default is 1.
  # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
  strategy:
    rollingUpdate:
      maxSurge: 10%
      maxUnavailable: 0
  selector:
    matchLabels:
      k8s-app: kube-dns
  template:
    metadata:
      labels:
        k8s-app: kube-dns
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
    spec:
      #tolerations:
      #- key: "CriticalAddonsOnly"
      # operator: "Exists"
      #volumes:
      #- name: kube-dns-config
      #  configMap:
      #    name: kube-dns
      #    optional: true
      containers:
      - name: kubedns
        image: hub.c.163.com/k8s163/k8s-dns-kube-dns-amd64:1.14.1
        resources:
          # TODO: Set memory limits when we've profiled the container for large
          # clusters, then set request = limit to keep this container in
          # guaranteed class. Currently, this container falls into the
          # "burstable" category so the kubelet doesn't backoff from restarting it.
          limits:
            memory: 170Mi
          requests:
            cpu: 100m
            memory: 70Mi
        livenessProbe:
          httpGet:
            path: /healthcheck/kubedns
            port: 10054
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        readinessProbe:
          httpGet:
            path: /readiness
            port: 8081
            scheme: HTTP
          # we poll on pod startup for the Kubernetes master service and
          # only setup the /readiness HTTP server once that's available.
          initialDelaySeconds: 3
          timeoutSeconds: 5
        args:
        - --domain=cluster.local.
        - --dns-port=10053
        #- --config-dir=/kube-dns-config
        - --v=2
        env:
        - name: PROMETHEUS_PORT
          value: "10055"
        ports:
        - containerPort: 10053
          name: dns-local
          protocol: UDP
        - containerPort: 10053
          name: dns-tcp-local
          protocol: TCP
        - containerPort: 10055
          name: metrics
          protocol: TCP
       # volumeMounts:
       # - name: kube-dns-config
       #   mountPath: /kube-dns-config
      - name: dnsmasq
        image: hub.c.163.com/k8s163/k8s-dns-dnsmasq-nanny-amd64:1.14.1
        livenessProbe:
          httpGet:
            path: /healthcheck/dnsmasq
            port: 10054
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        args:
        - -v=2
        - -logtostderr
        - -configDir=/etc/k8s/dns/dnsmasq-nanny
        - -restartDnsmasq=true
        - --
        - -k
        - --cache-size=1000
        - --log-facility=-
        - --server=/cluster.local/127.0.0.1#10053
        - --server=/in-addr.arpa/127.0.0.1#10053
        - --server=/ip6.arpa/127.0.0.1#10053
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        # see: https://github.com/kubernetes/kubernetes/issues/29055 for details
        resources:
          requests:
            cpu: 150m
            memory: 20Mi
        #volumeMounts:
        #- name: kube-dns-config
        #  mountPath: /etc/k8s/dns/dnsmasq-nanny
      - name: sidecar
        image: hub.c.163.com/k8s163/k8s-dns-sidecar-amd64:1.14.1
        livenessProbe:
          httpGet:
            path: /metrics
            port: 10054
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        args:
        - --v=2
        - --logtostderr
        - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,A
        - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,A
        ports:
        - containerPort: 10054
          name: metrics
          protocol: TCP
        resources:
          requests:
            memory: 20Mi
            cpu: 10m
      dnsPolicy: Default  # Don't use cluster DNS.
      serviceAccountName: kube-dns

    kubedns-controller 运行了 三个容器:kubedns dnsmasq sidecar,sidecar 是一个监控健康模块,同时向外暴露metrics 记录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 cat kubedns-svc.yaml
 
# Copyright 2016 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
 
# __MACHINE_GENERATED_WARNING__
 
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service"true"
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/name"KubeDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 10.254.0.2     #修改为我们设定的cluster的IP,其它默认。
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP

 

  部署文件设置好后,一起来创建:

1
# kubectl create -f kubedns-cm.yaml -f kubedns-sa.yaml -f kubedns-controller.yaml -f kubedns-svc.yaml

 查看创建后的pod,svc:

1
2
3
4
5
6
# kubectl get pod,svc -n kube-system
NAME                           READY     STATUS    RESTARTS   AGE
po/kube-dns-7797cb8758-dlhqs   3/3       Running   0          3h
 
NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
svc/kube-dns   ClusterIP   10.254.0.2   <none>        53/UDP,53/TCP   3h


 三,验证kubedns功能

    如果我们此前已经有了部署了许多pod和服务,并且在Kubelet 启动配置文件加入了 --cluster-dns=10.254.0.2 --cluster-domain=cluster.local  参数,则可以进入某个pod中的容器内查看其/etc/resolv.conf 文件

1
2
3
4
5
6
7
8
9
   root@jekins:~# cat /etc/resolv.conf 
   nameserver 10.254.0.2
   search default.svc.cluster.local svc.cluster.local cluster.local
   options ndots:5
 如上所示,根据kubelet的启动参数,kubelet会在每个pod中设置DNS域名解析文件/etc/resolv.conf,加入了nameser和search搜索域。最后应用程序就能够像访问网站一样,仅仅通过服务的名字就能访问到服务了。
  
  root@jek:~# ping jenkinsservice
  PING jenkinsservice.default.svc.cluster.local (10.254.145.97) 56(84) bytes of data.
  可以看到已经解析出来了

   通常可以启动一个带有nslookup工具的pod,比如busybox,镜像从gcr.io/google_containers/busybox下载,来验证DNS服务是否能够正常工作。

 

四,kubedns自动水平扩展

     在上面部署的Kubedns,它只有一个pod,如果这个pod没有了 又或一个pod因为解析量大无法撑起解析时,会导致dns无法工作,所以官方给了一个自动水平伸缩的方案,根据当前pod的负载来决定是否增加或减少pod数量,

称为,dns-horizontal-autoscaler ,部署文件位于kubernetes/cluster/addons/dns-horizontal-autoscale,下载下来可直接部署。

1
2
    /data/k8sdns# ls dns-horizontal-autoscaler*
    dns-horizontal-autoscaler-rbac.yaml  dns-horizontal-autoscaler.yaml

   

    dns-horizontal-autoscaler-rbac.yaml文件解析:

      实际它就创建了三个资源:ServiceAccount、ClusterRole、ClusterRoleBinding  ,创建帐户,创建角色,赋予权限,将帐户绑定到角色上面。

            image.png

             image.png


 而dns-horizontal-autoscaler.yaml 文件它就创建一个Deployment资源,里面跑了一个autoscaler的容器,直接部署即可。

 现在来部署: 先部署RBAC文件,再部署服务文件:

1
2
3
4
5
6
7
  # kubectl create -f dns-horizontal-autoscaler-rbac.yaml 
  serviceaccount "kube-dns-autoscaler" created
  clusterrole "system:kube-dns-autoscaler" created
  clusterrolebinding "system:kube-dns-autoscaler" created
 
  # kubectl create -f dns-horizontal-autoscaler.yaml 
  deployment "kube-dns-autoscaler" created

查看创建状态 ,并且可以看到在创建之前dns只有一个pod:

1
2
3
4
#  kubectl get pod -n kube-system
NAME                                   READY     STATUS              RESTARTS   AGE
kube-dns-7797cb8758-dlhqs              3/3       Running             3          19h
kube-dns-autoscaler-7db47cb9b7-gq5wk   0/1       ContainerCreating   0          21s

 过几分钟后查看,就会自动创建出来一个dns pod:

1
2
3
4
5
# kubectl get pod -n kube-system
NAME                                   READY     STATUS              RESTARTS   AGE
kube-dns-7797cb8758-dlhqs              3/3       Running             3          19h
kube-dns-7797cb8758-kwmqr              0/3       ContainerCreating   0          48s
kube-dns-autoscaler-7db47cb9b7-gq5wk   1/1       Running             0          1m

  至此,一个完整的kubedns部署完成了。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页