大纲
CoreDNS 在Kubernetes1.12版本之后成为了默认的DNS服务,作为一个域名服务CoreDNS可以完成最基本的域名服务功能
同时CoreDNS能够与Kubernetes Docker良好的配合,是云原生环境下的一款优秀的DNS服务
官方网站:https://coredns.io/
下载地址 https://github.com/coredns/coredns/releases
已上传到百度云盘 /常用软件/CoreDNS
选择 coredns_1.10.1_linux_amd64.tgz 下载使用
tar -zxvf coredns_1.10.1_linux_amd64.tgz
解压后得到 coredns ,coredns便是CoreDNS的运行程序
默认情况下会读取coredns程序所在文件夹下的Corefile配置文件做为CoreDNS的配置信息
注意ubuntu18系统上可能出现53端口被占用的情况
原因是ubuntu自带一个resolve域名服务
systemctl stop systemd-resolved
systemctl disable systemd-resolved
关闭自带的DNS服务
一般使用CoreDNS域名服务时会有两种配置文件
Corefile配置文件会使用file ,auto 插件来读取【db.*】 中配置的域名信息
DNS server 内的每一个域名都有自己的域文件( zone file ), zone file 是由多个记录组成的,每一个记录就被称为资源记录( Resource Record ,简称 RR )。
常用的资源记录(Resource Record )有如下类型
【db.*】 域名资源记录文件一般格式如下
【名称】【TTL时间】【CLASS 只有一个IN类型】【RR类型例如A MX CNAME】 【记录值 例如IP】
例如有 db.mygrpc.com 域名资源记录文件内容如下
@ 1800 IN SOA ns.mygrpc.com. liuyijiang3430.qq.com. (
1231 ; serial number
1h ; refresh interval
10m ; retry interval
3w ; expiry period
1h ; negative TTL
)
grpc 1800 IN A 192.168.0.211
1800 IN A 192.168.0.210
即配置了一个 grpc.mygrpc.com的域名 对应两个A记录IP 192.168.0.211 192.168.0.210
注意:第一条记录为SOA起始授权记录。一个区域解析库有且仅能有一个SOA记录,而必须为解析库的第一条记录
coredns 默认读取当前文件夹下的Corefile配置文件,可以使用–conf 指定配置文件
Corefile由一个或多个条目组成,条目本身则由标签和定义组成
除非只有一个条目,否则条目的定义必须包含在花括号{} 中,用于划分边界
左边花括号“{” 必须出现在以标签开头的行末尾 右边花括号“}” 必须单独出现在一行上,
{}之间的文件被叫做块
注释以#号开头
Corefile中一个条目可以有多个标签开头,空格分开 例如:
my.com test.com {
}
Corefile中如果标签跨行可以使用,号分开 但最后一个不能有逗号 例如:
my.com , test.com ,
grpc.com {
}
Corefile中参数定义 单行 多行 例如:
grpc.com {
directive1 agr1 agr2 #单行参数
directive1 { #多行参数使用{}
agr1
agr2
}
}
Corefile中可以使用环境变量
grpc.com_{$ENV_WAR_1} {
directive1 {$ENV_WAR_2}
}
windows 中使用 %ENV_WAR%
Corefile中可以使用重复代码块
使用()为代码段提供名称 然后使用import 导入
(item1) {
grpc.com {
directive1 agr1 agr2
}
}
import item1
导入文件
可以使用 import 导入文件 ,import可以接收路径名称或Glob模式路径参数
import item1
import common.conf
import config/*.conf
# 匹配作用于所有以aaa.com结尾的域名查询
aaa.com {
}
# 如果有更具体的服务块能够被匹配例如bbb.aaa.com
bbb.aaa.com {
}
# 多个域名匹配一个块
ccc.net fff.com {
}
CoreDNS中使用最长匹配原则
例如有aaa.com 和 bbb.aaa.com两个块 如果发起bbb.aaa.com查询,优先匹配 bbb.aaa.com
使用非默认端口时,在域名标签后加冒号以及端口
.:1053 {
}
CoreDNS插件文档地址 https://coredns.io/plugins/
常用插件如下
再正式开始使用CoreDNS前需要修改本地配置,使用自己搭建的CoreDNS
如下是在windows11上修改DNS服务器地址
注意 云服务服务商(例如腾讯云)上是不能使用53端口的,在这些云服务器上运行CoreDNS 会被封53端口
file插件的作用是从RFC 1035风格的配置文件中获取区域数据。
file有一个reload参数可以使用,定期查询配置文件是否变更了,如果配置文件中SOA序列号增加了就重新加载配置
例如Corefile中配置
mygrpc.com {
root /ops/coreDNS/db #使用root插件 指定域名配置文件的放置的文件夹
file db.mygrpc.com #使用file插件 读取db.mygrpc.com 域名配置文件
reload 10s #使用reload插件 可自动重新加载区域数据配置 可以使用单位 "s"秒 "m"分钟 “h”小时
loadbalance round_robin #loadbalance插件 实现db.mygrpc.com配置文件中域名对应的ip的负载均衡
}
db.mygrpc.com中配置
@ 1800 IN SOA ns.mygrpc.com. liuyijiang3430.qq.com. (
1121 ; serial number 每次调整后需要增加
1h ; refresh interval
10m ; retry interval
3w ; expiry period
1h ; negative TTL
)
grpc 1800 IN A 192.168.0.211
1800 IN A 192.168.0.210
1800 IN A 192.168.0.209
注意 每次调整db.mygrpc.com配置文件后需要增加serial number 才能触发CoreDNS重新加载
官方资料
https://coredns.io/plugins/file/
https://coredns.io/plugins/root/
auto 自动插件可以一次性从多个区域数据文件中加载大量数据,可以减少Corefile的长度
例如 /medcrab/coreDNS/db 文件夹下有如下两个文件
CoreDNS中 Corefile的配置如下
test.com { #所有查询test.com域
auto {
directory /medcrab/coreDNS/db #指定加载/medcrab/coreDNS/db文件下所有的以 db.*开头的区域数据文件
reload 10s
}
}
这样CoreDNS就可以加载db.dev.test.com db.prod.test.com配置文件并创建dev.test.com和prod.test.com两个区域
另外一个例子CoreDNS中 Corefile的配置如下
. { #对所有域名的查询
auto { #加载/medcrab/coreDNS/db文件夹下的配置文件 这样就可以管理dev.test.com prod.test.com两个域
directory /medcrab/coreDNS/db
reload 10s
}
forward . 114.114.114.114 8.8.8.8 { #其余的域名查询都转发到114.114.114.114 和 8.8.8.8
policy round_robin
}
}
官方资料 https://coredns.io/plugins/auto/
hosts主机插件实现IP与域名的绑定 同时会加重主机 /etc/hosts配置文件中的内容
CoreDNS中 Corefile的配置如下
. {
hosts { #加载 /etc/hosts配置文件中的内容
192.168.0.206 inner-middle-ware.medcrab.com #同时实现192.168.0.206与inner-middle-ware.medcrab.com绑定
192.168.0.207 inner-middle-ware.medcrab.com #同时实现192.168.0.207与inner-middle-ware.medcrab.com绑定
fallthrough #如果失败则会执行另外的插件
}
forward . 114.114.114.114 8.8.8.8 {
policy round_robin
}
loadbalance round_robin #loadbalance插件实现负载均衡
}
官方教程 https://coredns.io/plugins/hosts/
forward转发插件可以将域名查询请求转发给其他的解析器(或者其他的DNS服务处理)
forward的格式如下
forward FROM TO... { FROM是域名 TO可以有多个 空格分开
except IGNORED_NAMES... 排查的域名 可以有多个 空格分开
force_tcp 使用TCP转发
prefer_udp 使用UDP转发
expire DURATION 连接过期时间 默认10s
max_fails INTEGER 连续失败的健康检查次数 默认2次
tls CERT KEY CA
tls_servername NAME
policy random|round_robin|sequential 转发策略
health_check DURATION [no_rec] [domain FQDN] 健康检查默认0.5s
max_concurrent MAX
}
FROM是域名 TO可以有多个(空格分开)以下是TO的格式
example.com {
forward . 127.0.0.1 不带端口默认使用53
forward . 127.0.0.1:9005 带端口(注意对应ip的域名服务的端口需要调整)
forward . 114.114.114.114 8.8.8.8 指定多个DNS服务器
forward . /etc/resolv.conf 使用本机的resolv.conf DNS服务器配置文件
}
policy 转发策略
例如有两个域名服务分别部署在 1.117.218.253 ,47.108.136.120 两台机器上
47.108.136.120上Corefile配置 (客户端会查询此域名解析服务)
mygrpc.com {
forward mygrpc.com 1.117.218.253 { #所有查询mygrpc.com域名的(包括子域名)都转发到1.117.218.253
health_check 5s #健康检查1.117.218.253 这台机器
}
}
. {
forward . 114.114.114.114 8.8.8.8 { #其他所有域名查询都 转发到114.114.114.114 和 8.8.8.8域名服务器
except baidu.com #排除对baidu.com查询的转发
policy round_robin #使用轮询策略转发,即轮询114.114.114.114 和8.8.8.8
}
}
1.117.218.253上Corefile配置
mygrpc.com {
root /ops/coreDNS/db #指定域名配置文件的放置的文件夹
file db.mygrpc.com #读取db.mygrpc.com 域名配置文件
reload 10s #可以使用单位 "s"秒 "m"分钟 “h”小时
}
可以看到由于 except baidu.com 所以百度是无法获取IP的
官方资料 https://coredns.io/plugins/forward/
cache 缓存插件
cache缓存插件 的作用是控制缓存
基本语法格式
cache [时间 单位秒] [zones]
errors 错误插件
errors错误插件可以打印CoreDNS查询过程中遇到的错误信息,并打印到标准输出
log 日志插件
log日志插件 可以打印运行日志,并输出到标准输出
import插件
import插件 可以导入文件或可重用代码块 ,import可以接收路径名称或Glob模式路径参数
例如 CoreDNS中 Corefile的配置如下
(common) { #创建一个名叫common的可重用代码块
cache 60 #设置缓存
log #使用log日志插件
errors #使用errors错误插件
}
. {
hosts {
192.168.0.206 inner-middle-ware.medcrab.com
192.168.0.207 inner-middle-ware.medcrab.com
}
forward . 114.114.114.114 8.8.8.8 {
policy round_robin
}
loadbalance round_robin
import common #使用import 导入可重用代码块 common
}
可以看到运行coreDNS可以显示日志
官方资料
https://coredns.io/plugins/cache/
https://coredns.io/plugins/log/
https://coredns.io/plugins/errors/
health ready prometheus 这三个插件主要是偏向运维
health插件 启动一个http服务,暴露CoreDNS健康状态 默认端口8080
ready插件 启动一个http服务,暴露CoreDNS是否已经完全就绪 默认端口8181
prometheus插件 暴露CoreDNS的监控指标 默认端口9253
例如 CoreDNS中 Corefile的配置如下
. {
health :8199 #暴露健康状态并指定端口8199 http://ip:8199/health
ready :8289 #暴露否已经完全就绪指定端口8289 http://ip:8289/ready
prometheus :8389 #暴露CoreDNS的监控指标 http://ip:8389/metrics
forward . 114.114.114.114
cache 30
errors
log
}
访问 http://1.117.218.253:8099/health
访问 http://1.117.218.253:8289/ready
访问 http://1.117.218.253:8389/metrics
官方资料
https://coredns.io/plugins/health/
https://coredns.io/plugins/metrics/
https://coredns.io/plugins/ready/
使用CoreDNS提供的etcd插件可以实现读取保存在etcd中的域名,动态的修改etcd中的内容实现域名的发现,让CoreDNS实现简单的注册中心的功能
etcd插件的格式如下
etcd [ZONES...] {
fallthrough [ZONES...] #如果失败则会执行另外的插件
path PATH #指定path 默认/skydns
endpoint ENDPOINT... 指定etcd 默认http://localhost:2379
credentials USERNAME PASSWORD #账号密码
tls CERT KEY CACERT
}
测试etcd插件 前先确保已经安装 etcd3
使用etcd3的接口 需要先在环境变量中设置 export ETCDCTL_API=3
etcd中保存的数据格式就是SkyDNS message格式 https://github.com/skynetservices/skydns/blob/2fcff74cdc9f9a7dd64189a447ef27ac354b725f/msg/service.go#L26
{"host":"192.168.0.210","port":18181,"priority":10,"weight":20}
CoreDNS中 Corefile的配置如下
example.com { #所有查询example.com的域名都去etcd中查询
etcd
}
在etcd中添加数据
./etcdctl put /skydns/com/example/services/users '{"host":"192.168.0.210","port":18181,"priority":10,"weight":20}'
这个表示 users.services.example.com 域名对应的IP是192.168.0.210
注意开头为/skydns etcd插件默认的path就是/skydns
nslookup users.services.example.com 查看域名
测试管理order.services.my.com这个域名,并给order.services.my.com配置两个IP(可以配置多个)
CoreDNS中 Corefile的配置如下
my.com { #所有查询my.com的域名都去etcd中查询
etcd {
path /grpc #指定etcd中根path为grpc
endpoint http://localhost:2379 #指定etcd
fallthrough #如果失败则会执行另外的插件
}
loadbalance round_robin #实现DNS轮询
}
在etcd中添加数据
./etcdctl put /grpc/com/my/services/order/aa-xx-ss '{"host":"192.168.0.110","port":18181,"priority":10,"weight":20}'
./etcdctl put /grpc/com/my/services/order/bb-ff-12 '{"host":"192.168.0.170","port":18181,"priority":10,"weight":20}'
order.services.my.com 域名下绑定两个IP 192.168.0.110 192.168.0.170
注意aa-xx-ss bb-ff-12可以使用UUID保证两者不同即可
nslookup order.services.my.com 查看域名
kubernetes集群创建完成后,默认使用CoreDNS作为 DNS服务器,会创建对应的Pod与Service
Kubelet 为每个 Pod 配置/etc/resolv.conf文件,默认情况下创建的Pod的DNS策略都使用集群内部的CoreDNS。
可使用dnsPolicy来配置Pod的dns策略 默认策略为ClusterFirst
参考 《k8s-Pod域名学习总结》
spec:
restartPolicy: Always
# 配置dns策略
dnsPolicy: ClusterFirst
containers:
- image: registry.cn-hangzhou.aliyuncs.com/jimliu/order-service:latest
name: order-service
k8s 默认的集群域是 cluster.local
kubernetes集群内部会对Services和Pods创建DNS记录
kubernetes会为Service创建域名,其域名格式为
【servic名称】.【命名空间】.svc.cluster.local
cluster.local是k8s默认的集群域
例如 有my-quarkus-demo-service(普通Service) 和 order-service-inner-domain(无头Service)
在集群内部使用nslookup 查看
kubernetes会为Pod创建域名,其域名默认格式为
【pod-ip-address】.【命名空间】.pod.cluster.local
例如 Pod的IP是 10.244.1.66 那么它的域名则为
10-244-1-66.default.pod.cluster.local
可以使用 hostname 和 subdomain 配置自定义的DNS域名但需要Headless Service的配合
官方文档 https://kubernetes.io/zh-cn/docs/concepts/services-networking/dns-pod-service/
nameserver 10.96.0.10 #指定域名服务器地址10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local #搜索主机名查找列表。搜索列表目前仅限于6个域名,共计256个字符
options ndots:5 #开启搜索主机名的阈值
resolv.conf内容说明
FQDN总是以主机名开始并且以顶级域名结束,“.”是指根域名服务器。
例如
搜索的名称是order-service-host时,通常认为是一个主机搜索,此时如果resolv.conf中配置了search则会去追加
搜索的名称是order-service-host.时, 通常认为是一个完全限定域名(FQDN)搜索,会直接使用order-service-host查询
实例测试 (注意容器内可能需要安装以下软件)
apt-get update
apt-get install host
apt-get install inetutils-ping
apt-get install dnsutils (nslookup)
search的作用是在域名查询时把对应的配置添加在查询内容后面,ndots是一个控制添加的阈值
例如已经部署好一个 order-service Pod 并配置好对应的域名 《k8s-Pod域名学习总结-自定义Pod的域名章节》
order-service yaml配置
spec:
# hostname + subdomain 自定义Pod的域名
hostname: order-service-host
subdomain: order-service-inner-domain
这样Pod的完整域名就是 order-service-host.order-service-inner-domain.default.svc.cluster.local
由于 resolv.conf 中配置 search搜索域,则可以直接使用order-service-host.order-service-inner-domain 即yaml中配置的
hostname.subdomain 完成域名的查询
调整 ndots配置 改为ndots:1 这样resolv.conf 中配置 search搜索域就无效了
CoreDNS 提供kubernetes插件 实现对集群中Pod Service的域名查询
使用如下命令查看配置
kubectl -n kube-system describe cm coredns
kubernetes插件 格式
kubernetes [ZONES...] {
endpoint URL #指定k8s集群地址 一般用于CoreDNS部署在k8s集群外部
tls CERT KEY CACERT #指定访问集群的证书 一般用于CoreDNS部署在k8s集群外部
kubeconfig KUBECONFIG [CONTEXT]
namespaces NAMESPACE... #指定命名空间 默认是所有命名空间
labels EXPRESSION
pods POD-MODE
endpoint_pod_names
ttl TTL
noendpoints
fallthrough [ZONES...]
ignore empty_service
}
例如
#处理cluster.local域下DNS查询 in-addr.arpa ip6.arpa响应k8s集群中的PTR请求
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure #兼容老版本kube-dns
fallthrough in-addr.arpa ip6.arpa
ttl 30
}