k8s DNS
作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,这就需要一个集群范围内的DNS服务来完成从服务名到ClusterIP地址的解析。 目前常用的dns组件有kube-dns和coredns两个,用于解析k8s集群中service name所对应得到IP地址。 DNS全称:service名.namespace名.svc.zzhz.local 修改每个Node上kubelet的启动参数,在其中加上以下两个参数: --cluster-dns=169.169.0.100:为DNS服务的ClusterIP地址。 --cluster-domai目前常用的dns组件有kube-dns和coredns两个,用于解析k8s集群DNS全称:service名.namespace名.svc
一、kube-dns
KubeDNS组件由3个容器组成(kubedns、dnsmasq和sidecar),去掉了SkyDNS中的etcd存储,将DNS记录直接保存在内存中,以提高查询性能: kubedns容器 :提供service name域名的解析,监控Kubernetes中Service资源的变化,根据Service的名称和IP地址生成DNS记录,并将DNS记录保存在内存中; dnsmasq容器:从kubedns中获取DNS记录,提供DrS缓存,降低kubedns负载,提高性能,为客户端容器应用提供DNS查询服务; sidecar容器:提供对kubedns和dnsmasq服务的健康检查功能。 #创建pod测试查看DNS地址和名称(域名无法ping通,是DNS没有设置) kubectl run net-test1 --image=alpine --replicas=4 sleep 360000 [root@localhost7G ~]# docker exec -it k8s_net-test1_net-test1-5fcc69db59-v7zqg_ sh / # cat /etc/resolv.conf nameserver 10.10.0.2 #定义的DNS地址 search default.svc.zzhz.local. svc.zzhz.local. zzhz.local. localdomain options ndots:5 / # ping 223.6.6.6 PING 223.6.6.6 (223.6.6.6): 56 data bytes 64 bytes from 223.6.6.6: seq=0 ttl=127 time=5.307 ms 64 bytes from 223.6.6.6: seq=1 ttl=127 time=7.684 ms 64 bytes from 223.6.6.6: seq=2 ttl=127 time=6.144 ms / # ping www.qq.com ping: bad address 'www.qq.com' #镜像制作 docker load -i k8s-dns-dnsmasq-nanny-amd64_1.14.13.tar.gz docker load -i k8s-dns-kube-dns-amd64_1.14.13.tar.gz docker load -i k8s-dns-sidecar-amd64_1.14.13.tar.gz docker tag 333fb0833870 harbor.zzhz.com/baseimage/k8s-dns-sidecar-amd64:1.14.13 docker tag 82f954458b31 harbor.zzhz.com/baseimage/k8s-dns-kube-dns-amd64:1.14.13 docker tag 7b15476a7228 harbor.zzhz.com/baseimage/k8s-dns-dnsmasq-nanny-amd64:1.14.13 docker push harbor.zzhz.com/baseimage/k8s-dns-sidecar-amd64:1.14.13 docker push harbor.zzhz.com/baseimage/k8s-dns-dnsmasq-nanny-amd64:1.14.13 docker push harbor.zzhz.com/baseimage/k8s-dns-kube-dns-amd64:1.14.13 #查看配置文件 [root@localhost7C k8s]# cat kube-dns.yaml 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.10.0.2 # Node上kubelet启动文件定义,或者创建pod测试查看DNS地址。 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP --- apiVersion: v1 kind: ServiceAccount metadata: name: kube-dns namespace: kube-system labels: kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile --- apiVersion: v1 kind: ConfigMap metadata: name: kube-dns namespace: kube-system labels: addonmanager.kubernetes.io/mode: EnsureExists --- apiVersion: apps/v1 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: '' seccomp.security.alpha.kubernetes.io/pod: 'docker/default' spec: priorityClassName: system-cluster-critical securityContext: supplementalGroups: [ 65534 ] fsGroup: 65534 tolerations: - key: "CriticalAddonsOnly" operator: "Exists" volumes: - name: kube-dns-config configMap: name: kube-dns optional: true containers: - name: kubedns image: harbor.zzhz.com/baseimage/k8s-dns-kube-dns-amd64:1.14.13 # 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: 512Mi #硬件资源设置 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=zzhz.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: harbor.zzhz.com/baseimages/k8s-dns-dnsmasq-nanny-amd64:1.14.13 # 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 - --no-negcache - --dns-loop-detect - --log-facility=- - --server=/zzhz.local/127.0.0.1#10053 #zzhz.local 的域交给127.0.0.1 的100053端口去解析 #- --server=/zjol.com/6.6.6.6#10053 #zjol.com 的域交给6.6.6.6 的100053端口去解析 - --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: harbor.zzhz.com/baseimages/k8s-dns-sidecar-amd64:1.14.13 # 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.zzhz.local,5,SRV # - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.zzhz.local,5,SRV # ports: - containerPort: 10054 name: metrics protocol: TCP resources: requests: memory: 20Mi cpu: 10m dnsPolicy: Default # Don't use cluster DNS. serviceAccountName: kube-dns #部署 kubectl apply -f kube-dns.yaml #测试 [root@localhost7G ~]# docker exec -it k8s_net-test1_net-test1-5fcc69db59-v7zqg_ sh / # ping www.qq.com PING www.qq.com (101.91.42.232): 56 data bytes 64 bytes from 101.91.42.232: seq=0 ttl=127 time=12.003 ms 64 bytes from 101.91.42.232: seq=1 ttl=127 time=12.686 ms 64 bytes from 101.91.42.232: seq=2 ttl=127 time=12.697 ms #测试 kubectl exec busybox --nslookup “DNS全称:service名.namespace名.svc.zzhz.local”
二、coredns
从Kubernetes1.11版本开始,Kubernetes集群的DNS服务由CoreDNS提供: 它是由go语言实现的一套高性能、插件式,易于扩展的DNS服务端; 解决了KubeDNS的一些问题, 例如dnsmasq的安全漏洞、externalName不能使用stubDomains进行设置等等; 支持自定义DNS记录及配置upstream DNS Server,可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS; 它没有使用多个容器的架构,只用一个容器便实现了KubeDNS内3个容器的全部功能。 部署CoreDNS服务时需要创建3个资源对象:1个ConfigMap、1个Deployment和1个Service。 在启用了RBAC的集群中,还可以设置ServiceAccount、ClusterRole 、ClusterRoleBinding对CoreDNS容器进行权限设置。 #查看配置文件 [root@localhost7C k8s]# cat coredns.yaml apiVersion: v1 kind: ServiceAccount metadata: name: coredns namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: kubernetes.io/bootstrapping: rbac-defaults name: system:coredns rules: - apiGroups: - "" resources: - endpoints - services - pods - namespaces verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:coredns roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:coredns subjects: - kind: ServiceAccount name: coredns namespace: kube-system --- #ConfigMap 的 "coredns" 主要设置CoreDNS的主配置文件Corefile的内容,其中可以定义各种域名的解析方式和使用的插件,示例如下: #在下面的示例中为域名 “.:53”(也可以设置zzhz.local) 设置了一系列插件,包括errors、 health、ready、kubernetes、prometheus、forward、cache、loop、reload和 loadbalance, #在进行域名解析时,这些插件将以从上到下的顺序依次执行: apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: #设置名称和Forward Corefile: | .:53 { errors health { lameduck 5s } ready #DNS名称 kubernetes zzhz.local in-addr.arpa ip6.arpa { fallthrough in-addr.arpa ip6.arpa } prometheus :9153 #forward插件用于配置上游DNS服务器或其他DNS服务器,当在CoreDNS中查询不到域名时,会到其他DNS服务器上进行查询 forward . 223.6.6.6 #forward . /etc/resolv.conf cache 30 loop reload loadbalance } --- #Deployment 的“coredns” 主要设置CoreDNS容器应用的内容 #其中,replicas副本的数量通常应该根据集群的规模和服务数量确定,如果单个CoreDNS进程不足以支撑整个集群的DNS查询,则可以通过水平扩展提高查询能力。 #由于DNS服务是Kubernetes集群的关键核心服务,所以建议为其Deployment设置自动扩缩容控制器,自动管理其副本数量。 #另外,对资源限制部分(CPU限制和内存限制)的设置也应根据实际环境进行调整: apiVersion: apps/v1 kind: Deployment metadata: name: coredns namespace: kube-system labels: k8s-app: kube-dns kubernetes.io/name: "CoreDNS" spec: # replicas: not specified here: # 1. Default is 1. # 2. Will be tuned in real time if DNS horizontal auto-scaling is turned on. strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 selector: matchLabels: k8s-app: kube-dns template: metadata: labels: k8s-app: kube-dns spec: priorityClassName: system-cluster-critical serviceAccountName: coredns tolerations: - key: "CriticalAddonsOnly" operator: "Exists" nodeSelector: kubernetes.io/os: linux affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: k8s-app operator: In values: ["kube-dns"] topologyKey: kubernetes.io/hostname containers: - name: coredns image: coredns/coredns:1.6.7 #镜像地址 imagePullPolicy: IfNotPresent resources: limits: memory: 700Mi #资源限制 requests: cpu: 100m memory: 70Mi args: [ "-conf", "/etc/coredns/Corefile" ] volumeMounts: - name: config-volume mountPath: /etc/coredns readOnly: true ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP - containerPort: 9153 name: metrics protocol: TCP securityContext: allowPrivilegeEscalation: false capabilities: add: - NET_BIND_SERVICE drop: - all readOnlyRootFilesystem: true livenessProbe: httpGet: path: /health port: 8080 scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /ready port: 8181 scheme: HTTP dnsPolicy: Default volumes: - name: config-volume configMap: name: coredns items: - key: Corefile path: Corefile --- #service配置 #Service“kube-dns” 是DNS服务的配置,这个服务需要设置固定的ClusterIP地址,也需要将所有Node上的kubelet启动参数--cluster-dns都设置为这个ClusterIP apiVersion: v1 kind: Service metadata: name: kube-dns namespace: kube-system annotations: prometheus.io/port: "9153" prometheus.io/scrape: "true" labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" kubernetes.io/name: "CoreDNS" spec: selector: k8s-app: kube-dns clusterIP: 10.10.0.2 #DNS IP ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP - name: metrics port: 9153 protocol: TCP 测试: [root@localhost7C ~]# cat busybox.yaml apiVersion: v1 kind: Pod metadata: name: busybox namespace: default spec: containers: - name: busybox image: gcr.io/google containers/busybox command: - sleep - "3600" kubectl exec busybox --nslookup “DNS全称:service名.namespace名.svc.zzhz.local” -------------------------------------------------------------------------------------------- CoreDNS的主要功能是通过插件系统实现的,CoreDNS实现了一种链式插件结构,将DNS的逻辑抽象成了一个个插件,能够灵活组合使用。 ConfigMap 的 "coredns" 主要设置CoreDNS的主配置文件Corefile常用的插件如下: loadbalance 提供基于DNS的负载均衡功能 loop 检测在DNS解析过程中出现的简单循环问题 cache 提供前端缓存功能 health 对Endpoint进行健康检查 kubernetes 从Kubernetes中读取zone数据 etcd 从etcd中读取zone数据,可用于自定义域名记录 file 从RFC 1035格式文件中读取zone数据 hosts 使用/etc/hosts文件或者其他文件读取zone数据,可用于自定义域名记录 auto 从磁盘中自动加载区域文件 reload 定时自动重新加载Corefile配置文件的内容 forward 转发域名查询到上游DNS服务器上 prometheus 为Prometheus系统提供采集性能指标数据的URL pprof 在URL路径/debug/pprof下提供运行时的性能数据 log 对DNS查询进行日志记录 errors 对错误信息进行日志记录