一、coredns
从Kubernetes v1.12开始,CoreDNS是推荐的DNS服务器,取代了kube-dns。但是,默认情况下仍可以使用某些Kubernetes安装程序工具安装kube-dns。
CoreDNS部署作为具有静态IP的Kubernetes服务公开。CoreDNS和kube-dns服务都kube-dns在该metadata.name字段中命名。这样做可以使依赖于旧kube-dns服务名称的工作负载具有更强的互操作性,以解析集群内部的地址。它抽象出了DNS提供程序在该公共端点后面运行的实现细节。kubelet将DNS传递给带有--cluster-dns=<dns-service-ip>标志的每个容器。
CoreDNS是一个通用的权威DNS服务器,可以作为集群DNS,符合DNS规范。
代码地址:https://github.com/coredns/coredns
一)kubernetes服务注册与发现组件coredns
1、架构原理
整个 CoreDNS 服务都建立在一个使用 Go 编写的 HTTP/2 Web 服务器 Caddy 上,CoreDNS 整个项目可以作为一个 Caddy 的教科书用法。
CoreDNS 的大多数功能都是由插件来实现的,插件和服务本身都使用了 Caddy 提供的一些功能,所以项目本身也不是特别的复杂。作为基于 Caddy 的 Web 服务器,CoreDNS 实现了一个插件链的架构,将很多 DNS 相关的逻辑都抽象成了一层一层的插件,包括 Kubernetes 等功能。在这种灵活的模型中添加对Kubernetes支持,相当于创建了一个Kubernetes中间件。该中间件使用Kubernetes API来满足针对特定Kubernetes pod或服务的DNS请求。
errors: 错误消息
health: coreDNS 的健康情况 http://localhost:8080/health.
kubernetes: CoreDNS将根据Kubernetes服务和pod的IP回复DNS查询。
prometheus: coreDNS 的监控 http://localhost:9153/metrics .
forward: 任何不存在kubernets内的查询,都要转到forward预定义的解析器
cache: 启用前端缓存.
loop: 该环插件将随机探头查询发送给自己,然后将跟踪的多少次,我们看到它。如果我们看到它超过两次,我们假设CoreDNS已经看到转发循环,我们停止该过程
reload: 此插件允许自动重新加载已更改的Corefile,要启用区域文件更改的自动重新加载,请使用该auto插件
loadbalance: 一个负载均衡的插件
2、Corefile
CoreDNS 的特点就是它能够通过简单易懂的 DSL 定义 DNS 服务,在 Corefile 中就可以组合多个插件对外提供服务
coredns.io:5300 {
file db.coredns.io
}
example.io:53 {
log
errors
file db.example.io
}
example.net:53 {
file db.example.net
}
.:53 {
kubernetes
proxy . 8.8.8.8
log
errors
cache
}
对于以上的配置文件,CoreDNS 会根据每一个代码块前面的区和端点对外暴露两个端点提供服务:
该配置文件对外暴露了两个 DNS 服务,其中一个监听在 5300 端口,另一个在 53 端口,请求这两个服务时会根据不同的域名选择不同区中的插件进行处理。
3、yaml文件
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
log stdout
health
kubernetes CLUSTER_DOMAIN SERVICE_CIDR
proxy . /etc/resolv.conf
cache 30
}
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: coredns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "CoreDNS"
spec:
replicas: 1
selector:
matchLabels:
k8s-app: coredns
template:
metadata:
labels:
k8s-app: coredns
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
spec:
containers:
- name: coredns
image: coredns/coredns:latest
imagePullPolicy: Always
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
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
---
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: coredns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "CoreDNS"
spec:
selector:
k8s-app: coredns
clusterIP: CLUSTER_DNS_IP
ports:
#coreDNS 支持TCP、UDP、HTTP、TTL四种协议
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
二)coredns版本选择
低版本CoreDNS(1.4及之前的版本)存在的以下两个问题,影响了ACK 1.16以前版本集群内域名解析服务的稳定性:
- 因为CoreDNS需要通过watch apiserver拿到Service数据,所以health插件会检查CoreDNS与apiserver的连通性。如果连通性不正常(如网络抖动、apiserver重启等情况),健康检查接口会报错。CoreDNS在3次健康检查失败后会重启,重启过程中将导致服务不可以用。详情请参见coredns。
- CoreDNS会受到klog缺陷的影响:CoreDNS与apiserver断连后,klog尝试向一个不存在的目录/tmp写错误日志,此行为会失败并进一步导致CoreDNS奔溃。详情请参见add mount of /tmp #137。
您可以选择以下两种升级方案以解决低版本CoreDNS带来的稳定性问题:
- 长期解决方案:升级Kubernetes集群到1.16及以上版本,集群升级时会自动将CoreDNS升级到1.6.2及以上版本。有关在控制台中升级集群的具体操作步骤,请参见升级集群;有关通过API升级集群的详细信息,请参见升级集群。
- 短期解决方案:如果不方便升级集群版本,您可以选择手动升级CoreDNS到1.6.2及以上版本。有关如何手动升级CoreDNS版本的具体步骤,请参见本文升级步骤。
三)kubernetes和coredns
本兼容情况如下表(Kubernetes 1.11/1.12/1.14/1/16均兼容CoreDNS 1.6.2版本)。
版本 兼容信息
Kubernetes版本 1.11 1.12 1.14 1.16
CoreDNS 1.6.2 1.6.2 1.6.2 1.6.2
1、查看coredns的版本
kubectl get deployment coredns -n kube-system -o jsonpath="{.spec.template.spec.containers[0].image}"
2、pod的四种DNS策略
- Default :Pod直接继承Node节点的域名解析配置。在ACK集群即直接使用ECS的/etc/resolv.conf文件,文件内配置的是宿主机DNS服务。
- ClusterFirst:通过CoreDNS来做集群内外部域名的服务发现,Pod内/etc/resolv.conf配置的DNS服务地址是集群DNS服务的地址core-dns
- 目前,在ClusterFirst模式下,2次(1次IPv4,1次IPv6)集群外部域名查询产生8次(4次IPv4,4次IPv6)查询请求。例如,解析www.aliyun.com域名,会先分别携带三个集群主域名后缀,产生六次无效查询请求,这样会导致集群DNS QPS放大三倍,影响性能
- ClusterFirstWithHostNetwork:强制在hostNetWork网络模式下使用ClusterFirst策略(默认使用Default策略)
- None:忽略集群DNS策略,需要用户提供dnsConfig字段来指定DNS配置信息
二、coredns的高级用法
一)使用coredns实现内外流量分离
1、场景
- 旧业务固定了域名,无法通过内部service直接访问服务
- 需要实现内部流量和外部流量自动拆分
2、实现
- 通过coredns的rewrite功能实现以上能力,如以下内部访问tenant.msa.devops.com域名时,会将流量转发到 tenantapi.dev.svc.cluster.local域名,实现内外域名访问一致。
- 部分版本nginx配置时候可能遇见无法访问的情况
[root@k8s-master1 ingress]# cat coredns.yaml
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health
rewrite name tenant.msa.devops.com tenantapi.dev.svc.cluster.local
rewrite name console.msa.devops.com console.dev.svc.cluster.local
rewrite name user.msa.devops.com userapi.dev.svc.cluster.local
rewrite name lims.msa.devops.com lims.dev.svc.cluster.local
rewrite name labapp.msa.devops.com limsapp.dev.svc.cluster.local
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
kind: ConfigMap
metadata:
creationTimestamp: "2021-04-02T04:57:19Z"
name: coredns
namespace: kube-system
resourceVersion: "197"
selfLink: /api/v1/namespaces/kube-system/configmaps/coredns
uid: cb686453-5503-11e9-8ea6-005056be93f5
3、检查
[root@k8s-master1 ingress]# kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
dnstools# ping tenant.msa.devops.com
PING tenant.msa.devops.com (10.98.220.54): 56 data bytes
^C
--- tenant.msa.devops.com ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
二)coredns实现kubernetes内部host功能
1、场景
- 通过kubernetes的coredns实现子域名解析
- 实现kubernetes内部 hosts绑定功能
2、实现
方式一:创建pod时声明hosts(不推荐)
root@k8s-master-1 coredns]# kubectl explain pods.spec.hostAliases
KIND: Pod
VERSION: v1
RESOURCE: hostAliases <[]Object>
DESCRIPTION:
HostAliases is an optional list of hosts and IPs that will be injected into
the pod's hosts file if specified. This is only valid for non-hostNetwork
pods.
HostAlias holds the mapping between IP and hostnames that will be injected
as an entry in the pod's hosts file.
FIELDS:
hostnames <[]string>
Hostnames for the above IP address.
ip <string>
IP address of the host file entry.
方式二:coredns的hosts特性声明
hosts 字段部分指明了三个域名的解析地址
[root@k8s-master-1 coredns]# cat coredns-cm.yaml
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health
hosts {
100.64.139.66 minio.devops.com
100.64.139.66 registry.devops.com
100.64.139.66 gitlab.devops.com
fallthrough
}
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
方式三:根据域名指定上游dns服务器
devops.com 字段指明了解析该域名的dns服务器地址
[root@k8s-master-1 coredns]# cat coredns-cm.yaml
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
devops.com {
forward . 100.64.134.250:53
}
kind: ConfigMap
metadata:
name: coredns
3、检查
[root@k8s-master-1 coredns]# kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
dnstools# host 0DJ01YUR.sobeydemo.com
0DJ01YUR.sobeydemo.com has address 100.64.148.116
0DJ01YUR.sobeydemo.com has IPv6 address 2002:6440:9474::6440:9474
dnstools# host minio.devops.com
minio.devops.com has address 100.64.139.66
Host minio.devops.com not found: 3(NXDOMAIN)
Host minio.devops.com not found: 3(NXDOMAIN)
dnstools#