欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

附011.Kubernetes-DNS及搭建

程序员文章站 2022-07-04 22:32:02
一 Kubernetes DNS介绍1.1 Kubernetes DNS发展作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,因此需要一个集群范围内的DNS服务来完成从服务名到ClusterIP的解析。DNS服务在Kubernetes的发展过程中经历了3个阶段,SkyDNS --... ......

一 kubernetes dns介绍

1.1 kubernetes dns发展

作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,因此需要一个集群范围内的dns服务来完成从服务名到clusterip的解析。
dns服务在kubernetes的发展过程中经历了3个阶段,skydns ----> kubedns ----> coredns。

1.2 skydns

在kubernetes 1.2版本时,dns服务是由skydns提供的,它由4个容器组成:kube2sky、skydns、etcd和healthz。
kube2sky容器监控kubernetes中service资源的变化,根据service的名称和ip地址信息生dns记录,并将其保存到etcd中。
skydns容器从etcd中读取dns记录,并为客户端容器应用提供dns查询服务。
healthz容器提供对skydns服务的健康检查功能。
skydns的总体架构如下:
附011.Kubernetes-DNS及搭建

1.3 kubedns

从kubernetes 1.4版本开始,skydns组件便被kubedns替换,主要考虑是skydns组件之间通信较多,整体性能不高。
kubedns由3个容器组成:kubedns、dnsmasq和sidecar,去掉了skydns中的etcd存储,将dns记录直接保存在内存中,以提高查询性能。
kubedns容器监控kubernetes中service资源的变化,根据service的名称和ip地址生成dns记录,并将dns记录保存在内存中。
dnsmasq容器从kubedns中获取dns记录,提供dns缓存,为客户端容器应用提供dns查询服务。
sidecar提供对kubedns和dnsmasq服务的健康检查功能。
kubedns的总体架构如下:
附011.Kubernetes-DNS及搭建

1.4 coredns

从kubernetes 1.11版本开始,kubernetes集群的dns服务由coredns提供。coredns是cncf基金会的一个项目,是用go语言实现的高性能、插件式、易扩展的dns服务端。
coredns解决了kubedns的一些问题,例如dnsmasq的安全漏洞、externalname不能使用stubdomains设置,等等。
coredns支持自定义dns记录及配置upstream dns server,可以统一管理kubernetes基于服务的内部dns和数据中心的物理dns。
coredns没有使用多个容器的架构,只用一个容器便实现了kubedns内3个容器的全部功能。
coredns的总体架构如下:
附011.Kubernetes-DNS及搭建

二 coredns部署

2.1 修改kubelet启动参数

部署之前需要修改每个node上kubelet的启动参数,加上以下两个参数:
  • --cluster-dns=169.169.0.100:为dns服务的clusterip地址。
  • --cluster-domain=cluster.local:为在dns服务中设置的域名。
然后重启kubelet服务。
提示:也可通过如下方式引入yaml配置文件实现:
  1 # vi /etc/systemd/system/kubelet.service
  2 ……
  3 --config=/etc/kubernetes/kubelet-config.yaml \
  4 ……
  5 # vi /etc/kubernetes/kubelet-config.yaml
  6 ……
  7 clusterdomain: "cluster.local"
  8 clusterdns:
  9   - "10.254.0.2"
 10 ……

2.2 创建授权

在启用了rbac的集群中, 还可以设置serviceaccount、 clusterrole、 clusterrolebinding对coredns容器进行权限设置。serviceaccount、 clusterrole、 clusterrolebinding相关yaml如下:
  1 [root@k8smaster01 ~]# vi corednsaccout.yaml
  2 # __machine_generated_warning__
  3 
  4 apiversion: v1
  5 kind: serviceaccount
  6 metadata:
  7   name: coredns
  8   namespace: kube-system
  9   labels:
 10       kubernetes.io/cluster-service: "true"
 11       addonmanager.kubernetes.io/mode: reconcile
 12 ---
 13 apiversion: rbac.authorization.k8s.io/v1
 14 kind: clusterrole
 15 metadata:
 16   labels:
 17     kubernetes.io/bootstrapping: rbac-defaults
 18     addonmanager.kubernetes.io/mode: reconcile
 19   name: system:coredns
 20 rules:
 21 - apigroups:
 22   - ""
 23   resources:
 24   - endpoints
 25   - services
 26   - pods
 27   - namespaces
 28   verbs:
 29   - list
 30   - watch
 31 - apigroups:
 32   - ""
 33   resources:
 34   - nodes
 35   verbs:
 36   - get
 37 ---
 38 apiversion: rbac.authorization.k8s.io/v1
 39 kind: clusterrolebinding
 40 metadata:
 41   annotations:
 42     rbac.authorization.kubernetes.io/autoupdate: "true"
 43   labels:
 44     kubernetes.io/bootstrapping: rbac-defaults
 45     addonmanager.kubernetes.io/mode: ensureexists
 46   name: system:coredns
 47 roleref:
 48   apigroup: rbac.authorization.k8s.io
 49   kind: clusterrole
 50   name: system:coredns
 51 subjects:
 52 - kind: serviceaccount
 53   name: coredns
 54   namespace: kube-system
 55 
 56 [root@k8smaster01 ~]# kubectl create -f corednsaccout.yaml

2.3 创建configmap

  1 [root@k8smaster01 ~]# vi corednsconfigmap.yaml
  2 apiversion: v1
  3 kind: configmap
  4 metadata:
  5   name: coredns
  6   namespace: kube-system
  7   labels:
  8       addonmanager.kubernetes.io/mode: ensureexists
  9 data:
 10   corefile: |
 11     .:53 {
 12         errors
 13         health
 14         kubernetes cluster.local in-addr.arpa ip6.arpa {
 15             pods insecure
 16             upstream
 17             fallthrough in-addr.arpa ip6.arpa
 18         }
 19         prometheus :9153
 20         forward . /etc/resolv.conf
 21         cache 30
 22         loop
 23         reload
 24         loadbalance
 25     }
 26 
 27 [root@k8smaster01 ~]# kubectl create -f corednsconfigmap.yaml

2.4 创建deployment

  1 [root@k8smaster01 ~]# vi corednsdeploy.yaml
  2 apiversion: apps/v1
  3 kind: deployment
  4 metadata:
  5   name: coredns
  6   namespace: kube-system
  7   labels:
  8     k8s-app: kube-dns
  9     kubernetes.io/cluster-service: "true"
 10     addonmanager.kubernetes.io/mode: reconcile
 11     kubernetes.io/name: "coredns"
 12 spec:
 13   # replicas: not specified here:
 14   # 1. in order to make addon manager do not reconcile this replicas parameter.
 15   # 2. default is 1.
 16   # 3. will be tuned in real time if dns horizontal auto-scaling is turned on.
 17   strategy:
 18     type: rollingupdate
 19     rollingupdate:
 20       maxunavailable: 1
 21   selector:
 22     matchlabels:
 23       k8s-app: kube-dns
 24   template:
 25     metadata:
 26       labels:
 27         k8s-app: kube-dns
 28       annotations:
 29         seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
 30     spec:
 31       priorityclassname: system-cluster-critical
 32       serviceaccountname: coredns
 33       tolerations:
 34         - key: "criticaladdonsonly"
 35           operator: "exists"
 36       nodeselector:
 37         beta.kubernetes.io/os: linux
 38       containers:
 39       - name: coredns
 40         image: registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.3.1
 41         imagepullpolicy: ifnotpresent
 42         resources:
 43           limits:
 44             memory: 170mi
 45           requests:
 46             cpu: 100m
 47             memory: 70mi
 48         args: [ "-conf", "/etc/coredns/corefile" ]
 49         volumemounts:
 50         - name: config-volume
 51           mountpath: /etc/coredns
 52           readonly: true
 53         ports:
 54         - containerport: 53
 55           name: dns
 56           protocol: udp
 57         - containerport: 53
 58           name: dns-tcp
 59           protocol: tcp
 60         - containerport: 9153
 61           name: metrics
 62           protocol: tcp
 63         livenessprobe:
 64           httpget:
 65             path: /health
 66             port: 8080
 67             scheme: http
 68           initialdelayseconds: 60
 69           timeoutseconds: 5
 70           successthreshold: 1
 71           failurethreshold: 5
 72         readinessprobe:
 73           httpget:
 74             path: /health
 75             port: 8080
 76             scheme: http
 77         securitycontext:
 78           allowprivilegeescalation: false
 79           capabilities:
 80             add:
 81             - net_bind_service
 82             drop:
 83             - all
 84           readonlyrootfilesystem: true
 85       dnspolicy: default
 86       volumes:
 87         - name: config-volume
 88           configmap:
 89             name: coredns
 90             items:
 91             - key: corefile
 92               path: corefile
 93 
 94 [root@k8smaster01 ~]# kubectl create -f corednsdeploy.yaml
提示:replicas副本的数量通常应该根据集群的规模和服务数量确定,如果单个coredns进程不足以支撑整个集群的dns查询,则可以通过水平扩展提高查询能力。由于dns服务是kubernetes集群的关键核心服务,所以建议为其deployment设置自动扩缩容控制器,自动管理其副本数量。
同时,对资源限制部分(cpu限制和内存限制) 的设置也应根据实际环境进行调整。

2.5 创建service

  1 [root@k8smaster01 ~]# vi corednssvc.yaml
  2 apiversion: v1
  3 kind: service
  4 metadata:
  5   name: kube-dns
  6   namespace: kube-system
  7   annotations:
  8     prometheus.io/port: "9153"
  9     prometheus.io/scrape: "true"
 10   labels:
 11     k8s-app: kube-dns
 12     kubernetes.io/cluster-service: "true"
 13     addonmanager.kubernetes.io/mode: reconcile
 14     kubernetes.io/name: "coredns"
 15 spec:
 16   selector:
 17     k8s-app: kube-dns
 18   clusterip: 10.254.0.2
 19   ports:
 20   - name: dns
 21     port: 53
 22     protocol: udp
 23   - name: dns-tcp
 24     port: 53
 25     protocol: tcp
 26   - name: metrics
 27     port: 9153
 28     protocol: tcp
 29 
 30 [root@k8smaster01 ~]# kubectl create -f corednssvc.yaml

2.6 确认验证

  1 [root@k8smaster01 ~]# kubectl get deployments --namespace=kube-system
  2 name                   ready   up-to-date   available   age
  3 coredns                1/1     1            1           14s
  4 [root@k8smaster01 ~]# kubectl get pod --namespace=kube-system
  5 name                                    ready   status    restarts   age
  6 coredns-5b46b98d57-cknrr                1/1     running   0          34s
  7 [root@k8smaster01 ~]# kubectl get svc --namespace=kube-system
  8 name                   type        cluster-ip     external-ip   port(s)                  age
  9 kube-dns               clusterip   10.254.0.2     <none>        53/udp,53/tcp,9153/tcp   47s

三 服务名dns解析

3.1 创建测试pod

  1 [root@k8smaster01 ~]# vi busybox.yaml
  2 apiversion: v1
  3 kind: pod
  4 metadata:
  5   name: busybox
  6   namespace: default
  7 spec:
  8   containers:
  9   - name: busybox
 10     image: gcr.azk8s.cn/google_containers/busybox
 11     command:
 12       - sleep
 13       - "3600"
 14 
 15 [root@k8smaster01 ~]# kubectl exec -ti busybox -- nslookup webapp		#测试解析
 16 server:    10.254.0.2
 17 address 1: 10.254.0.2 kube-dns.kube-system.svc.cluster.local
 18 
 19 name:      webapp
 20 address 1: 10.254.156.234 webapp.default.svc.cluster.local
提示:如果某个service属于不同的命名空间,那么在进行service查找时,需要补充namespace的名称,组合成完整的域名。
  1 [root@k8smaster01 ~]# kubectl exec -ti busybox -- nslookup kube-dns.kube-system	#补充kube-system的namespace
  2 server:    10.254.0.2
  3 address 1: 10.254.0.2 kube-dns.kube-system.svc.cluster.local
  4 
  5 name:      kube-dns.kube-system
  6 address 1: 10.254.0.2 kube-dns.kube-system.svc.cluster.local

四 coredns配置说明

4.1 常见插件

coredns的主要功能是通过插件系统实现的。coredns实现了一种链式插件结构,将dns的逻辑抽象成了一个个插件,能够灵活组合使用。
常用的插件如下:
  • loadbalance:提供基于dns的负载均衡功能。
  • loop:检测在dns解析过程中出现的简单循环问题。
  • cache:提供前端缓存功能。
  • health:对endpoint进行健康检查。
  • kubernetes:从kubernetes中读取zone数据。
  • etcd:从etcd读取zone数据,可以用于自定义域名记录。
  • file:从rfc1035格式文件中读取zone数据。
  • hosts:使用/etc/hosts文件或者其他文件读取zone数据,可以用于自定义域名记录。
  • auto:从磁盘中自动加载区域文件。
  • reload:定时自动重新加载corefile配置文件的内容。
  • forward:转发域名查询到上游dns服务器。
  • proxy:转发特定的域名查询到多个其他dns服务器,同时提供到多个dns服务器的负载均衡功能。
  • prometheus:为prometheus系统提供采集性能指标数据的url。
  • pprof:在url路径/debug/pprof下提供运行时的性能数据。
  • log:对dns查询进行日志记录。
  • errors:对错误信息进行日志记录。

4.2 插件配置

示例1:
  1 [root@k8smaster01 ~]# vi corednsconfigmap.yaml
  2 apiversion: v1
  3 kind: configmap
  4 metadata:
  5   name: coredns
  6   namespace: kube-system
  7   labels:
  8       addonmanager.kubernetes.io/mode: ensureexists
  9 data:
 10   corefile: |
 11     .:53 {
 12         errors
 13         health
 14         kubernetes cluster.local in-addr.arpa ip6.arpa {
 15             pods insecure
 16             upstream
 17             fallthrough in-addr.arpa ip6.arpa
 18         }
 19         prometheus :9153
 20         forward . /etc/resolv.conf
 21         cache 30
 22         loop
 23         reload
 24         loadbalance
 25     }
如上所示为域名“cluster.local”设置了一系列插件, 包括errors、health、kubernetes、prometheus、forward、cache、loop、reload和loadbalance,在进行域名解析时, 这些插件将以从上到下的顺序依次执行。
示例2:如下为使用etcd插件的配置示例,将以“.com”结尾的域名记录配置为从etcd中获取,并将域名记录保存在/skydns路径下。
  1 {
  2 etcd com {
  3 path /skydns
  4 endpoint http://192.168.18.3:2379
  5 upstream /etc/resolv.conf
  6 }
  7 cache 160 com
  8 loadbalance
  9 proxy . /etc/resolv.conf
 10 
 11 }
 12 [root@k8smaster01 ~]# etcdctl put /skydns/com/mycompany '{"host":"10.1.1.1","ttl":"60"}'	#测试插入
 13 [root@k8smaster01 ~]# nslookpu mycompany.com
提示:forward和proxy插件都可以用于配置上游dns服务器或其他dns服务器,当在coredns中查询不到域名时,会到其他dns服务器上进行查询。在实际环境中,可以将kubernetes集群外部的dns纳入coredns,进行统一的dns管理。

五 pod级别的dns设置

5.1 pod级别设置

集群的dns(coredns)配置之外,针对pod中也可以设置相应的dns策略。
示例1:
  1 [root@k8smaster01 study]# vi mywebapp.yaml
  2 apiversion: v1
  3 kind: pod
  4 metadata:
  5   name: webapp
  6 spec:
  7   containers:
  8   - name: webapp
  9     image: tomcat
 10   dnspolicy: default
 11 ……
目前可以设置的dns策略如下:
  • default:继承pod所在宿主机的dns设置。
  • clusterfirst:优先使用kubernetes环境的dns服务(如coredns提供的域名解析服务),将无法解析的域名转发到从宿主机继承的dns服务器。
  • clusterfirstwithhostnet:与clusterfirst相同,对于以hostnetwork模式运行的pod,应明确指定使用该策略。
  • none:忽略kubernetes环境的dns配置,通过spec.dnsconfig自定义dns配置。这个选项从kubernetes1.9版本开始引入,到kubernetes 1.10版本升级为beta版,到kubernetes1.14版本升级为稳定版。自定义dns配置可以通过spec.dnsconfig字段进行设置,可以设置下列信息。
    • nameservers:一组dns服务器的列表,最多可以设置3个。
    • searches:一组用于域名搜索的dns域名后缀,最多可以设置6个。
    • options:配置其他可选dns参数,例如ndots、timeout等,以name或name/value对的形式表示。
示例2:dnsconfig外部字段配置示例。
  1 [root@k8smaster01 study]# vi mywebapp.yaml
  2 apiversion: v1
  3 kind: pod
  4 metadata:
  5   namespace: default
  6   name: dns-example
  7 spec:
  8   containers:
  9   - name: test
 10     image: nginx
 11   dnspolicy: "none"
 12   dnsconfig:
 13     nameservers:
 14       - 223.5.5.5
 15     searches:
 16       - ns1.svc.cluster.local
 17       - my.dns.search.suffix
 18     options:
 19       - name: ndots
 20         value: "2"
 21       - name: edns0
  1 [root@k8smaster01 study]# kubectl create -f mywebapp.yaml
  2 [root@k8smaster01 study]# kubectl exec -ti dns-example -- cat /etc/resolv.conf		#确认查看
  3 nameserver 223.5.5.5
  4 search ns1.svc.cluster.local my.dns.search.suffix
  5 options ndots:2 edns0
提示:如上配置从而实现pod中自定义dns,而不再使用kubernetes环境的dns服务。