DNS组件
DNS组件:
k8s集群内部全局域名解析格式:
用于不在同一个namespace中,但要解析ip时
svc名称.ns名称.svc.域名
ngx.defauls.svc.hj.local
dns配置文件官网下载:
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns
kube-dns:
3个容器:
- kube-dns 提供service name域名的解析
- dns-dnsmasq 提供dns缓存,降低负载,提高性能
- dns-sidecar 定期检查kube-dns和dnsmasq的健康状态
配置模版修改:
全局修改:
{{ TER_DNS_SVC_IP }} #改为自己的svc的网段的ip,如果之前有dns插件,需要改为之前dns的ip
10.10.1.254
{{ CLUSTER_DNS_DOMAIN }} #改为自己k8s的集群dns解析域
hj.local
dnsmasq容器部分:
spec.containers:
- name: dnsmasq
args:
...
#将部分域名转给外部dns服务器,请求*.hj.com的域名,都给2.2.2.10:53处理
- --server=/hj.com/2.2.2.10#53
部署测试:
kubectl -f kubedns.yaml
kubectl run t1 --image=apline
kubectl exec -it t1 sh
vim /etc/resolv.conf
#改dns主机为kube-dns的svc地址
nameserver 10.10.1.254
ping t1
ping kubernetes-dashboard.kube-system.svc.hj.local
conredns:
官方部署:
实际上是shell脚本生成yml文件
https://github.com/coredns/deployment
配置解读:
参考阿里云文档: https://help.aliyun.com/document_detail/380963.html
Corefile: |
.:53 {
errors #错误信息标准输出
health { #自身健康状态检测,默认监听8080
lameduck 5s
}
ready #插件状态报告,默认监听端口8181,一般用来做可读性检查。通过http://localhost:8181/ready获取可读状态。当所有插件都运行后,ready状态为200
kubernetes {{ CLUSTER_DNS_DOMAIN }} in-addr.arpa ip6.arpa { #k8s插件,提供集群内部解析功能
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153 #自身的metrics数据接口,通过http://localhost:9153/metrics获取prometheus格式的监控数据
forward . /etc/resolv.conf { #将域名查询请求转到预定义的DNS服务器。默认配置中,当域名不在Kubernetes域时,将请求转发到预定义的解析器(/etc/resolv.conf)中。默认使用宿主机的/etc/resolv.conf配置
max_concurrent 1000 #最大同时处理请求
}
cache 30 #dns缓存
reload #允许自动重新加载已更改的Corefile。编辑ConfigMap配置后,请等待两分钟以使更改生效
loadbalance #A记录轮询返回
loop #环路检测,如果检测到环路,则停止CoreDNS
}
配置案例1: 将请求自建域名 www.hj.com 的请求转发到自建dns服务器
.:53 {
...
}
hj.com:53 {
errors
cache 30
forward . 2.2.2.10
}
配置案例2: 将非k8s集群内部的域名都转给自建dns(需要自建dns开启递归查询才能转到互联网)
Corefile: |
.:53 {
errors
health {
lameduck 15s
}
ready
kubernetes hj.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . 2.2.2.10 2.2.2.20 {
prefer_udp
}
cache 30
loop
reload
loadbalance
}
配置案例3: 将公网域名的请求转到k8s集群,通过cname记录实现
使用rewrite插件,转成cname
Corefile: |
.:53 {
errors
health {
lameduck 15s
}
ready
rewrite stop {
name regex www.hj.com hj-svc.default.svc.hj.local #www.hj.com的cname记录
answer name hj-svc.default.svc.hj.local www.hj.com #由hj-svc.default.svc.hj.local应答
}
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
prefer_udp
}
cache 30
loop
reload
loadbalance
}
配置案例4: 禁止解析ipv6的A记录
Corefile: |
.:53 {
......
template IN AAAA . #新增Template插件,其它数据请保持不变
}
部署:
git clone https://github.com/coredns/deployment.git
./deployment/kubernetes/deploy.sh > coredns.yml
#如果之前是kube-dns,则删除相关内容后再创建coredns
kubectl delete --namespace=kube-system deployment kube-dns
kubectl -f coredns.yml
NodeLocal DNS Cache:
NodeLocal DNSCache通过在集群节点上作为DaemonSet运行DNS缓存代理来提高集群DNS性能
内部基于kube-dns容器实现dns缓存,默认缓存10000条记录,占用30M内存
DNS本地缓存组成:
DaemonSet、DNSConfig动态注入控制器Deployment
- DNSConfig动态注入控制器Deployment,基于Admission Webhook机制拦截Pod创建的请求,自动注入使用DNS缓存的Pod DNSConfig信息
- DNS缓存DaemonSet可以在每个节点上创建一个虚拟网络接口(默认监听IP 169.254.20.10),配合Pod的DNSConfig和节点上的网络配置,Pod内产生的DNS请求会被该DaemonSet服务所代理
注意: DaemonSet服务内同样基于CoreDNS提供服务,但其仅具有代理和缓存的功能,请勿启用额外的插件能力(如Hosts、Rewrite等)
工作原理:
序号 | 描述 |
---|---|
① | 已注入DNS优先使用本地缓存配置的Pod,默认会通过NodeLocal DNSCache监听于节点上的IP(169.254.20.10)解析域名 |
② | NodeLocal DNSCache本地若无缓存应答解析请求,则会通过kube-dns服务请求CoreDNS进行解析 |
③ | CoreDNS对于非集群内域名,会通过VPC DNS服务器进行解析 |
④ | 已注入DNS本地缓存的Pod,当无法连通NodeLocal DNSCache时,会继而直接通过kube-dns服务连接到CoreDNS进行解析,此链路为备用链路 |
⑤ | 未注入DNS本地缓存的Pod,会通过标准的kube-dns服务链路连接到CoreDNS进行解析 |
部署Nodelocal DNSCache:
1)下载配置清单
git clone https://github.com/kubernetes/kubernetes.git
cd kubernetes-master/cluster/addons/dns/nodelocaldns
2)修改配置
#获取转发dns的ip地址,用于节点缓存dns没有记录时,请求转发,一般转给上游的kube-dns或coredns
kubedns=`kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}`
#k8s集群的域名
domain=hj.local
#节点本地缓存dns的ip监听地址
localdns=169.254.20.10
#kube-proxy是ipvs模式
sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; \
s/__PILLAR__DNS__DOMAIN__/$domain/g; \
s/,__PILLAR__DNS__SERVER__//g; \
s/__PILLAR__CLUSTER__DNS__/$kubedns/g" \
nodelocaldns.yaml
#kube-proxy是iptables模式
sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; \
s/__PILLAR__DNS__DOMAIN__/$domain/g; \
s/__PILLAR__DNS__SERVER__/$kubedns/g" \
nodelocaldns.yaml
#改镜像源为docker官网的,如果docker运行时可以加上ssr的代理后不用修改此,containerd的不知道怎么加
sed -ri 's#(^[[:space:]]+image:).*#\1 docker.io/kubesphere/k8s-dns-node-cache:1.21.1#' nodelocaldns.yaml
3)运行pod
kubectl apply -f nodelocaldns.yaml
4)开启节点dns配置的动态注入pod配置
方法1: 为namespace添加自动注入标签
加上: node-local-dns-injection=enabled ,会自动将创建在此ns中的pod的dns解析地址增加169.254.20.10
#整个ns加上自动注入标签
kubectl label namespace default node-local-dns-injection=enabled
#为单个pod取消注入标签,加上禁用标签即可
deploy.spec.template.metedata.labels:
node-local-dns-injection=disabled
方法2: 配置kubelet启动参数
--cluster-dns、--cluster-domain两个参数来控制全局的dns配置
此方法只建议在初始化集群,部署k8s时使用。已经在运行的k8s集群会在修改期间不可用!!
vim /etc/systemd/system/kubelet.service
ExecStart=/opt/kube/bin/kubelet \
--cluster-dns=169.254.20.10 \
--cluster-dns=kube-dns的ip \
--cluster-domain=hj.local
systemctl daemon-reload && systemctl restart kubelet