目录

CoreDNS是DNS服务器软件,通常用于在容器化环境(尤其是Kubernetes管理的环境)中支持服务发现功能。
与BIND的配置文件的语法相比,CoreDNS的Corefile(称为)非常简单。基本的基于CoreDNS的DNS服务器的Corefile通常只有几行,而且相对而言,易于阅读。
CoreDNS使用插件来提供DNS功能。因此,有一个用于缓存的插件和一个用于转发的插件,一个用于配置从文件读取区域数据的主DNS服务器的插件,以及一个插件用于配置辅助DNS服务器。不仅可以直接配置每个插件(请参阅上一段落),而且,如果不需要插件,则无需配置它,也不会执行其代码。这使CoreDNS更快,更安全。
coredns和其他的诸如bind、knot、powerdns、unbound等DNS服务不同的是:coredns非常的灵活,并且几乎把所有的核心功能实现都外包给了插件。比如说如果你想要在coredns中加入Prometheus的监控支持,那么只需要安装对应的prometheus插件并且启用即可,因此官方也说coredns是由插件驱动的。
CoreDNS不仅是灵活,安全的DNS服务器,而且还直接与包括Kubernetes在内的许多容器编排系统集成。这意味着容器化应用程序的管理员可以轻松地设置DNS服务器来调解和促进容器之间的通信。
CoreDNS目前确实存在一些重大限制,并且它并不适用于所有可能的DNS服务器。其中最主要的是CoreDNS(至少在撰写本文时为最新版本)不支持完全递归。换句话说,CoreDNS无法处理查询,方法是从DNS名称空间的根目录开始,查询根DNS服务器并遵循引用,直到从权威DNS服务器之一获得答案为止。相反,它依赖于其他DNS服务器(通常称为转发器)。
coreDNS 是一个灵活可扩展的 DNS 服务器,通常用于在容器化环境(尤其是kubernetes管理的环境)中支持服务发现功能,可以作为 Kubernetes 集群 DNS,在Kubernetes1.12版本之后成为了默认的DNS服务。 与 Kubernetes 一样,coreDNS 项目由 CNCF 托管。
coredns在K8S中的用途,主要是用作服务发现,也就是服务(应用)之间相互定位的过程。
在k8s中,用service资源代理pod,通过暴露service资源的固定地址(集群IP),来解决以上POD资源变化产生的IP变动问题,但是针对service还存在以下问题:
- service IP地址难以记忆
- service资源可能也会被销毁和创建
- pod ip本身也有需要暴漏的需求
为了解决以上问题,引入了coredns,在K8S,其主要用于服务发现,也就是服务(应用)之间相互定位的过程。
我们使用声明式向k8s中交付容器的方式,来部署服务
以下操作可以在任意节点上完成,推荐在master上做,因为接下来制作coredns的k8s配置清单也是在运维主机master上创建后,再到node节点上应用
- docker pull docker.io/coredns/coredns:1.6.1
- docker tag coredns:1.6.1 harbor.od.com/public/coredns:v1.6.1
- docker push harbor.od.com/public/coredns:v1.6.1
- 配置nginx虚拟主机
- vim /etc/nginx/conf.d/k8s-yaml.od.com.conf
- server {
- listen 80;
- server_name k8s-yaml.od.com;
-
- location / {
- autoindex on;
- default_type text/plain;
- root /data/k8s-yaml;
- }
- }
-
- mkdir /data/k8s-yaml;
- nginx -qt && nginx -s reload
配置dns解析node节点
- vim /var/named/od.com.zone
- $ORIGIN od.com.
- $TTL 600 ; 10 minutes
- @ IN SOA dns.od.com. dnsadmin.od.com. (
- 2020070603 ; serial
- 10800 ; refresh (3 hours)
- 900 ; retry (15 minutes)
- 604800 ; expire (1 week)
- 86400 ; minimum (1 day)
- )
- NS dns.od.com.
- $TTL 60 ; 1 minute
- dns A 10.4.7.11
- harbor A 10.4.7.200
- k8s-yaml A 10.4.7.200
-
- systemctl restart named
以下资源配置清单,都是参考官网改出来的
mkdir -p /data/k8s-yaml/coredns
清单文件存放到 master主机data/k8s-yaml/coredns/coredns_1.6.1/
- cat >/data/k8s-yaml/coredns/rbac.yaml <
- 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
- ---
- 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
- EOF
4.2.2configmap配置清单
- cat >/data/k8s-yaml/coredns/cm.yaml <<EOF
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: coredns
- namespace: kube-system
- data:
- Corefile: |
- .:53 {
- errors
- log
- health
- ready
- kubernetes cluster.local 192.168.0.0/16 #service资源cluster地址
- forward . 10.4.7.11 #上级DNS地址
- cache 30
- loop
- reload
- loadbalance
- }
- EOF
4.2.3depoly控制器清单
- cat >/data/k8s-yaml/coredns/dp.yaml <
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: coredns
- namespace: kube-system
- labels:
- k8s-app: coredns
- kubernetes.io/name: "CoreDNS"
- spec:
- replicas: 1
- selector:
- matchLabels:
- k8s-app: coredns
- template:
- metadata:
- labels:
- k8s-app: coredns
- spec:
- priorityClassName: system-cluster-critical
- serviceAccountName: coredns
- containers:
- - name: coredns
- image: harbor.od.com/public/coredns:v1.6.1
- args:
- - -conf
- - /etc/coredns/Corefile
- volumeMounts:
- - name: config-volume
- mountPath: /etc/coredns
- 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
- dnsPolicy: Default
- volumes:
- - name: config-volume
- configMap:
- name: coredns
- items:
- - key: Corefile
- path: Corefile
- EOF
4.2.4service资源清单
-
- cat >/data/k8s-yaml/coredns/svc.yaml <
- apiVersion: v1
- kind: Service
- metadata:
- name: coredns
- namespace: kube-system
- labels:
- k8s-app: coredns
- kubernetes.io/cluster-service: "true"
- kubernetes.io/name: "CoreDNS"
- spec:
- selector:
- k8s-app: coredns
- clusterIP: 192.168.0.2
- ports:
- - name: dns
- port: 53
- protocol: UDP
- - name: dns-tcp
- port: 53
- - name: metrics
- port: 9153
- protocol: TCP
- EOF
4.3创建资源并验证
在任意NODE节点执行配置都可以
4.3.1验证服务能够访问
dig -t A harbor.od.com +short
4.3.2创建资源
- kubectl create -f http://k8s-yaml.od.com/coredns/rbac.yaml
- kubectl create -f http://k8s-yaml.od.com/coredns/cm.yaml
- kubectl create -f http://k8s-yaml.od.com/coredns/dp.yaml
- kubectl create -f http://k8s-yaml.od.com/coredns/svc.yaml
4.3.3查看创建情况
- kubectl get all -n kube-system
- kubectl get svc -o wide -n kube-system
- dig -t A www.baidu.com @192.168.0.2 +short
4.3.4使用dig测试解析
- dig -t A www.baidu.com @192.168.137.20 +short
-
- dig -t A harbor.od.com @192.168.137.20 +short
4.3.5创建一个service资源来验证
先查看kube-public名称空间有没有pod
kubectl get pod -n kube-public
如果没有则先创建pod
- kubectl create deployment nginx-dp --image=harbor.zq.com/public/nginx:v1.17.9 -n kube-public
-
- ~]# kubectl get deployments -n kube-public
- NAME READY UP-TO-DATE AVAILABLE AGE
- nginx-dp 1/1 1 1 35s
-
- ~]# kubectl get pod -n kube-public
- NAME READY STATUS RESTARTS AGE
- nginx-dp-568f8dc55-rxvx2 1/1 Running 0 56s
给pod创建一个service
- kubectl expose deployment nginx-dp --port=80 -n kube-public
-
- ~]# kubectl -n kube-public get service
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- nginx-dp ClusterIP 192.168.63.255 <none> 80/TCP 11s
验证是否可以解析
- ~]# dig -t A nginx-dp @192.168.137.20 +short
- # 发现无返回数据,难道解析不了
- # 其实是需要完整域名:服务名.名称空间.svc.cluster.local.
-
- ~]# dig -t A nginx-dp.kube-public.svc.cluster.local. @192.168.137.20 +short
可以看到我们没有手动添加任何解析记录,我们nginx-dp的service资源的IP,已经被解析了:
进入到pod内部再次验证
- ~]# kubectl -n kube-public exec -it nginx-dp-568f8dc55-rxvx2 /bin/bash
- -qjwmz:/# apt update && apt install curl
- -qjwmz:/# ping nginx-dp
为什么在容器中不用加全域名?
- -qjwmz:/# cat /etc/resolv.conf
- nameserver 192.168.137.20
- search kube-public.svc.cluster.local svc.cluster.local cluster.local host.com
- options ndots:5
当我进入到pod内部以后,会发现我们的dns地址是我们的coredns地址,以及搜索域中已经添加了搜索域:kube-public.svc.cluster.local
五:coredns配置
5.1K8sDNS策略
Kubernetes 中 Pod 的 DNS 策略有四种类型:
- Default(默认预设):Pod 继承所在主机上的 DNS 配置;
- ClusterFirst(集群优先):K8s 的默认设置;先在 K8s 集群配置的 coreDNS 中查询,查不到的再去继承自主机的上游 nameserver 中查询;
- ClusterFirstWithHostNet(宿主机与k8s共存):对于网络配置为 hostNetwork 的 Pod 而言,其 DNS 配置规则与 ClusterFirst 一致;
- None(无策略):忽略 K8s 环境的 DNS 配置,只认 Pod 的 dnsConfig 设置。
5.2resolv.conf
在部署 pod 的时候,如果用的是 K8s 集群的 DNS,那么 kubelet 在起 pause 容器的时候,会将其 DNS 解析配置初始化成集群内的配置。
如创建了一个叫 my-nginx 的 deployment,其 pod 中的 resolv.conf 文件如下:
- # DNS 服务的 IP,即coreDNS 的 clusterIP
- nameserver 169.254.25.10
-
- # DNS search 域。解析域名的时候,将要访问的域名依次带入 search 域,进行 DNS 查询
- # 比如访问your-nginx,其进行的 DNS 域名查询的顺序是:your-nginx.default.svc.cluster.local. -> your-nginx.svc.cluster.local. -> your-nginx.cluster.local.
- search default.svc.cluster.local svc.cluster.local cluster.local
-
- # 其他项,最常见的是 dnots。dnots 指的是如果查询的域名包含的点 “.” 小于 5,则先走search域,再用绝对域名;如果查询的域名包含点数大于或等于 5,则先用绝对域名,再走search域
- # K8s 中默认的配置是 5。
- options ndots:5
5.3coreDNSCorefile文件
coreDNS 实现了应用的插件化,用户可以选择所需的插件编译到可执行文件中;CoreDNS 的配置文件是 Corefile 形式的,coreDNS 的 configMap如下所示:
- apiVersion: v1
- data:
- Corefile: |
- .:53 {
- errors
- health
- # 指明 cluster.local 后缀的域名,都是 kubernetes 内部域名,coredns 会监听 service 的变化来维护域名关系,所以cluster.local 相关域名都在这里解析
- kubernetes cluster.local in-addr.arpa ip6.arpa {
- pods insecure
- upstream
- fallthrough in-addr.arpa ip6.arpa
- }
-
- # CoreDNS 的监控地址为:http://localhost:9153/metrics
- prometheus :9153
-
- # proxy 指 coredns 中没有找到记录,则去 /etc/resolv.conf 中的 nameserver 请求解析,而 coredns 容器中的 /etc/resolv.conf 是继承自宿主机的。
- # 实际效果是如果不是 k8s 内部域名,就会去默认的 dns 服务器请求解析,并返回给 coredns 的请求者。
- forward . /etc/resolv.conf
-
- cache 30 # 允许缓存
- loop # 如果找到循环,则检测简单的转发循环并停止 CoreDNS 进程
- reload # 允许 Corefile 的配置自动更新。在更改 ConfigMap 后两分钟,修改生效
- loadbalance # 这是一个循环 DNS 负载均衡器,可以在答案中随机化 A,AAAA 和 MX 记录的顺序
- }
- kind: ConfigMap
- metadata:
- creationTimestamp: "2019-06-10T03:19:01Z"
- name: coredns
- namespace: kube-system
六:node local dns
6.1DNS间歇性5秒延迟
由于 Linux 内核中的缺陷,在 Kubernetes 集群中你很可能会碰到恼人的 DNS 间歇性 5 秒延迟问题。
原因是镜像底层库 DNS 解析行为默认使用 UDP 在同一个 socket 并发 A 和 AAAA 记录请求,由于 UDP 无状态,两个请求可能会并发创建 conntrack 表项,如果最终 DNAT 成同一个集群 DNS 的 Pod IP 就会导致 conntrack 冲突,由于 conntrack 的创建和插入是不加锁的,最终后面插入的 conntrack 表项就会被丢弃,从而请求超时,默认 5s 后重试,造成现象就是 DNS 5 秒延时。
具体原因可参见:
6.2NodeLocal DNSCache
NodeLocal DNSCache通过在集群上运行一个dnsCache daemonset来提高clusterDNS性能和可靠性。相比于纯coredns方案,nodelocaldns + coredns方案能够大幅降低DNS查询timeout的频次,提升服务稳定性。
nodelocaldns配置如下,nodelocaldns只配置了一个server,监听默认的UDP 53端口,4个zone。域名后缀为cluster.local的所有域名以及in-addr.arpa和ip6.arpa形式域名走coredns进行域名解析,其他外部域名使用宿主机的/etc/resolv.conf文件配置的nameserver进行解析。
缓存分为 256 个分片,每个分片默认最多可容纳 39 个项目 - 总大小为 256 * 39 = 9984 个项目。
- # 其中cluster.local、in-addr.arpa、ip6.arpa表示kubernetes插件会处理域名后缀为cluster.local的所有域名以及处理所有的in-addr.arpa中的反向dns查找和ip6.arpa形式域名,其中kuberne# 集群域名后缀是在kubelet参数中配置的,默认值为cluster.local
-
- apiVersion: v1
- data:
- Corefile: |
- cluster.local:53 {
- errors
- cache {
- success 9984 30 # 对于成功的缓存最多缓存9984条域名解析记录,缓存时间为30s
- denial 9984 5 # 对于失败的缓存最多缓存9984条域名解析记录,缓存时间为5s
- }
- reload
- loop
- bind 169.254.25.10
- forward . 10.233.0.3 {
- force_tcp
- }
- prometheus :9253
- health 169.254.25.10:9254
- }
- in-addr.arpa:53 {
- errors
- cache 30
- reload
- loop
- bind 169.254.25.10
- forward . 10.233.0.3 {
- force_tcp
- }
- prometheus :9253
- }
- ip6.arpa:53 {
- errors
- cache 30
- reload
- loop
- bind 169.254.25.10
- forward . 10.233.0.3 {
- force_tcp
- }
- prometheus :9253
- }
- .:53 {
- errors
- cache 30
- reload
- loop
- bind 169.254.25.10
- forward . /etc/resolv.conf
- prometheus :9253
- }
- kind: ConfigMap
nodelocaldns + coredns方案,DNS查询流程如下所示:

-
相关阅读:
将C语言中的命名格式改为Java中的驼峰式命名
ubuntu 安装 mariadb,如何创建用户,并远程连接
【知识专栏丨python数分实战】电商数据分析案例
硬件系统工程师宝典(45)-----电源、时钟电路布局小技巧
Vue3中使用el-table遇到的问题
抖音短视频所有问题的详细攻略——今抖云创
Java网关的统一异常处理
这是什么APP?有谁知道的嘛?
高并发场景中,数据库都有哪些优化手段?不会还有人不知道吧
年龄越大,越要小心逢九年
-
原文地址:https://blog.csdn.net/ver_mouth__/article/details/126138729