CodeDNS与CoreFile

一、CodeDNS介绍

       DNS作为服务发现机制的基本功能, 在集群内需要能够通过服务名对服务进行访问, 这就需要一个集群范围内的DNS服务来完成从服务名到ClusterIP地址的解析。 DNS服务在Kubernetes的发展过程中经历了3个阶段, 接下来进行讲解。
       在Kubernetes 1.2版本时, DNS服务是由SkyDNS提供的, 它由4个容器组成: kube2sky、 skydns、 etcd和healthz。 kube2sky容器监控Kubernetes中Service资源的变化, 根据Service的名称和IP地址信息生成DNS记录, 并将其保存到etcd中; skydns容器从etcd中读取DNS记录, 并为客户端容器应用提供DNS查询服务; healthz容器提供对skydns服务的健康检查功能。

SkyDNS的总体架构

      从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的总体架构

     从Kubernetes 1.11版本开始, Kubernetes集群的DNS服务便由CoreDNS提供。 CoreDNS是CNCF基金会孵化的一个项目, 是用Go语言实现的高性能、 插件式、 易扩展的DNS服务端, 目前已毕业。 CoreDNS解决了KubeDNS的一些问题, 例如dnsmasq的安全漏洞、 externalName不能使用stubDomains进行设置, 等等。 CoreDNS支持自定义DNS记录及配置upstream DNS Server, 可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS。 它没有使用多个容器的架构, 只用一个容器便实现了KubeDNS内3个容器的全部功能。

CoreDNS的总体架构

二、Corefile配置说明

root@easzlab-deploy:~/jiege-k8s# cat coredns-v1.9.3.yaml 

# __MACHINE_GENERATED_WARNING__
apiVersion: v1
kind: ServiceAccount
metadata:
  name: coredns
  namespace: kube-system
  labels:
      kubernetes.io/cluster-service: "true"
      addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
    addonmanager.kubernetes.io/mode: Reconcile
  name: system:coredns
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  - services
  - pods
  - namespaces
  verbs:
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
- apiGroups:
  - discovery.k8s.io
  resources:
  - endpointslices
  verbs:
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
    addonmanager.kubernetes.io/mode: EnsureExists
  name: system:coredns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:coredns
subjects:
- kind: ServiceAccount
  name: coredns
  namespace: kube-system
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
  labels:
      addonmanager.kubernetes.io/mode: EnsureExists
data:
  Corefile: |
    .:53 {
        errors  #将错误日志发往标准输出stdout
        health { #在CoreDNS的 http://localhost:8080/health 端口提供 CoreDNS 服务的健康报告。
            lameduck 5s 
        }
        ready #待所有插件就绪后通过8181端口响应“200 OK”以报告就绪状态,访问该接口会返回 200 OK。
        kubernetes magedu.local in-addr.arpa ip6.arpa {  #CoreDNS 将基于 kubernetes service name进行 DNS 查询并返回查询记录给客户端.
            pods insecure
            fallthrough in-addr.arpa ip6.arpa
            ttl 30
        }
        prometheus :9153  #CoreDNS 的度量指标数据以 Prometheus 的key-value的格式在http://localhost:9153/metrics URI上提供。
        #forward . /etc/resolv.conf {
        forward . 223.6.6.6 {  #不是Kubernetes 集群内的其它任何域名查询都将转发到 预定义的目的
            max_concurrent 1000
        }
        cache 600 #启用 service解析缓存, 单位为秒。
        loop #检测域名解析是否有死循环, 如coredns转发给内网DNS服务器, 而内网DNS服务器又转发给coredns, 如果发现解析是死循环, 则强制中止 CoreDNS 进程(kubernetes会重建)。
        reload #检测corefile是否更改,在重新编辑configmap 配置后, 默认2分钟后会优雅的自动加载。
        loadbalance #轮训DNS域名解析, 如果一个域名存在多个记录则轮训解析。
    }
        myserver.online {
          forward . 172.16.88.254:53
        }
--- apiVersion: apps/v1 kind: Deployment metadata: name: coredns namespace: kube-system labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "CoreDNS" 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. replicas: 2 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 selector: matchLabels: k8s-app: kube-dns template: metadata: labels: k8s-app: kube-dns spec: securityContext: seccompProfile: type: RuntimeDefault priorityClassName: system-cluster-critical serviceAccountName: coredns affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: k8s-app operator: In values: ["kube-dns"] topologyKey: kubernetes.io/hostname tolerations: - key: "CriticalAddonsOnly" operator: "Exists" nodeSelector: kubernetes.io/os: linux containers: - name: coredns image: harbor.magedu.net/baseimages/coredns:1.9.3 imagePullPolicy: IfNotPresent resources: limits: memory: 256Mi cpu: 200m 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 livenessProbe: httpGet: path: /health port: 8080 scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /ready port: 8181 scheme: HTTP securityContext: allowPrivilegeEscalation: false capabilities: add: - NET_BIND_SERVICE drop: - all readOnlyRootFilesystem: true dnsPolicy: Default volumes: - name: config-volume configMap: name: coredns items: - key: Corefile path: Corefile --- 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" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "CoreDNS" spec: selector: k8s-app: kube-dns clusterIP: 10.100.0.2 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP - name: metrics port: 9153 protocol: TCP

CoreDNS的主要功能是通过插件系统实现的。CoreDNS实现了一种链式插件结构,将DNS的逻辑抽象成了一个个插件,能够灵活组合使用。
常用的插件如下。

  • errors: 将错误日志发往标准输出stdout
  • health: 在CoreDNS的 http://localhost:8080/health 端口提供 CoreDNS 服务的健康报告。
  • ready: 待所有插件就绪后通过8181端口响应“200 OK”以报告就绪状态,访问该接口会返回 200 OK。
  • kubernetes: CoreDNS 将基于 kubernetes service name进行 DNS 查询并返回查询记录给客户端.
  • prometheus: CoreDNS 的度量指标数据以 Prometheus 的key-value的格式在http://localhost:9153/metrics URI上提供。
  • forward: 不是Kubernetes 集群内的其它任何域名查询都将转发到 预定义的目的
  • server, 如 (/etc/resolv.conf或IP(如8.8.8.8)).
  • cache: 启用 service解析缓存, 单位为秒。
  • loop: 检测域名解析是否有死循环, 如coredns转发给内网DNS服务器, 而内网DNS服务器又转发给coredns, 如果发现解析是死循环, 则强制中止 CoreDNS 进程(kubernetes会重建)。
  • reload: 检测corefile是否更改,在重新编辑configmap 配置后, 默认2分钟后会优雅的自动加载。
  • loadbalance: 轮训DNS域名解析, 如果一个域名存在多个记录则轮训解析。
  • etcd: 从etcd中读取zone数据, 可用于自定义域名记录。
  • hosts: 使用/etc/hosts文件或者其他文件读取zone数据, 可用于自定义域名记录。
  • file: 从RFC1035格式文件中读取zone数据。
  • auto: 从磁盘中自动加载区域文件。
  • pprof: 在URL路径/debug/pprof下提供运行时的性能数据。
  • log: 对DNS查询进行日志记录。

三、Pod之间访问流程

CodeDNS解析流程:

  • 当podA需要访问podB时,podA会在本地/etc/hosts查找podB信息,如果能查到相关信息,就会直接访问;
  • 如果查询不到,会去找与之相邻上一级CoreDNS,CoreDNS会通过自己身缓存信息查找与podB相关信息;
  • 如果查询不到,会找etcd服务查找有关podB信息,然后将其反馈给podA;
  • 如果etcd没有查到,就会通过CodeDNS服务访问外部公网,在互联网查找与之相匹配的信息。

 

posted @ 2022-10-20 10:29  cyh00001  阅读(302)  评论(0编辑  收藏  举报