作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,这就需要一个集群范围内的DNS服务来完成从服务名到ClusterIP地址的解析。
目前常用的dns组件有kube-dns和coredns两个,用于解析k8s集群中service name所对应得到IP地址。
DNS全称:service名.namespace名.svc.zzhz.local
修改每个Node上kubelet的启动参数,在其中加上以下两个参数:
--cluster-dns=169.169.0.100:为DNS服务的ClusterIP地址。
--cluster-domai目前常用的dns组件有kube-dns和coredns两个,用于解析k8s集群DNS全称:service名.namespace名.svc
一、kube-dns
KubeDNS组件由3个容器组成(kubedns、dnsmasq和sidecar),去掉了SkyDNS中的etcd存储,将DNS记录直接保存在内存中,以提高查询性能:
kubedns容器 :提供service name域名的解析,监控Kubernetes中Service资源的变化,根据Service的名称和IP地址生成DNS记录,并将DNS记录保存在内存中;
dnsmasq容器:从kubedns中获取DNS记录,提供DrS缓存,降低kubedns负载,提高性能,为客户端容器应用提供DNS查询服务;
sidecar容器:提供对kubedns和dnsmasq服务的健康检查功能。
#创建pod测试查看DNS地址和名称(域名无法ping通,是DNS没有设置)
kubectl run net-test1 --image=alpine --replicas=4 sleep 360000
[root@localhost7G ~]# docker exec -it k8s_net-test1_net-test1-5fcc69db59-v7zqg_ sh
/ # cat /etc/resolv.conf
nameserver 10.10.0.2 #定义的DNS地址
search default.svc.zzhz.local. svc.zzhz.local. zzhz.local. localdomain
options ndots:5
/ # ping 223.6.6.6
PING 223.6.6.6 (223.6.6.6): 56 data bytes
64 bytes from 223.6.6.6: seq=0 ttl=127 time=5.307 ms
64 bytes from 223.6.6.6: seq=1 ttl=127 time=7.684 ms
64 bytes from 223.6.6.6: seq=2 ttl=127 time=6.144 ms
/ # ping www.qq.com
ping: bad address 'www.qq.com'
#镜像制作
docker load -i k8s-dns-dnsmasq-nanny-amd64_1.14.13.tar.gz
docker load -i k8s-dns-kube-dns-amd64_1.14.13.tar.gz
docker load -i k8s-dns-sidecar-amd64_1.14.13.tar.gz
docker tag 333fb0833870 harbor.zzhz.com/baseimage/k8s-dns-sidecar-amd64:1.14.13
docker tag 82f954458b31 harbor.zzhz.com/baseimage/k8s-dns-kube-dns-amd64:1.14.13
docker tag 7b15476a7228 harbor.zzhz.com/baseimage/k8s-dns-dnsmasq-nanny-amd64:1.14.13
docker push harbor.zzhz.com/baseimage/k8s-dns-sidecar-amd64:1.14.13
docker push harbor.zzhz.com/baseimage/k8s-dns-dnsmasq-nanny-amd64:1.14.13
docker push harbor.zzhz.com/baseimage/k8s-dns-kube-dns-amd64:1.14.13
#查看配置文件
[root@localhost7C k8s]# cat kube-dns.yaml
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/name: "KubeDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.10.0.2 # Node上kubelet启动文件定义,或者创建pod测试查看DNS地址。
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-dns
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: EnsureExists
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
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.
strategy:
rollingUpdate:
maxSurge: 10%
maxUnavailable: 0
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
spec:
priorityClassName: system-cluster-critical
securityContext:
supplementalGroups: [ 65534 ]
fsGroup: 65534
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
volumes:
- name: kube-dns-config
configMap:
name: kube-dns
optional: true
containers:
- name: kubedns
image: harbor.zzhz.com/baseimage/k8s-dns-kube-dns-amd64:1.14.13 #
resources:
# TODO: Set memory limits when we've profiled the container for large
# clusters, then set request = limit to keep this container in
# guaranteed class. Currently, this container falls into the
# "burstable" category so the kubelet doesn't backoff from restarting it.
limits:
memory: 512Mi #硬件资源设置
requests:
cpu: 100m
memory: 70Mi
livenessProbe:
httpGet:
path: /healthcheck/kubedns
port: 10054
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /readiness
port: 8081
scheme: HTTP
# we poll on pod startup for the Kubernetes master service and
# only setup the /readiness HTTP server once that's available.
initialDelaySeconds: 3
timeoutSeconds: 5
args:
- --domain=zzhz.local. #二进制安装里的域名名称
- --dns-port=10053
- --config-dir=/kube-dns-config
- --v=2
env:
- name: PROMETHEUS_PORT
value: "10055"
ports:
- containerPort: 10053
name: dns-local
protocol: UDP
- containerPort: 10053
name: dns-tcp-local
protocol: TCP
- containerPort: 10055
name: metrics
protocol: TCP
volumeMounts:
- name: kube-dns-config
mountPath: /kube-dns-config
- name: dnsmasq
image: harbor.zzhz.com/baseimages/k8s-dns-dnsmasq-nanny-amd64:1.14.13 #
livenessProbe:
httpGet:
path: /healthcheck/dnsmasq
port: 10054
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
args:
- -v=2
- -logtostderr
- -configDir=/etc/k8s/dns/dnsmasq-nanny
- -restartDnsmasq=true
- --
- -k
- --cache-size=1000
- --no-negcache
- --dns-loop-detect
- --log-facility=-
- --server=/zzhz.local/127.0.0.1#10053 #zzhz.local 的域交给127.0.0.1 的100053端口去解析
#- --server=/zjol.com/6.6.6.6#10053 #zjol.com 的域交给6.6.6.6 的100053端口去解析
- --server=/in-addr.arpa/127.0.0.1#10053
- --server=/ip6.arpa/127.0.0.1#10053
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
# see: https://github.com/kubernetes/kubernetes/issues/29055 for details
resources:
requests:
cpu: 150m
memory: 20Mi
volumeMounts:
- name: kube-dns-config
mountPath: /etc/k8s/dns/dnsmasq-nanny
- name: sidecar
image: harbor.zzhz.com/baseimages/k8s-dns-sidecar-amd64:1.14.13 #
livenessProbe:
httpGet:
path: /metrics
port: 10054
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
args:
- --v=2
- --logtostderr
- --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.zzhz.local,5,SRV #
- --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.zzhz.local,5,SRV #
ports:
- containerPort: 10054
name: metrics
protocol: TCP
resources:
requests:
memory: 20Mi
cpu: 10m
dnsPolicy: Default # Don't use cluster DNS.
serviceAccountName: kube-dns
#部署
kubectl apply -f kube-dns.yaml
#测试
[root@localhost7G ~]# docker exec -it k8s_net-test1_net-test1-5fcc69db59-v7zqg_ sh
/ # ping www.qq.com
PING www.qq.com (101.91.42.232): 56 data bytes
64 bytes from 101.91.42.232: seq=0 ttl=127 time=12.003 ms
64 bytes from 101.91.42.232: seq=1 ttl=127 time=12.686 ms
64 bytes from 101.91.42.232: seq=2 ttl=127 time=12.697 ms
#测试
kubectl exec busybox --nslookup “DNS全称:service名.namespace名.svc.zzhz.local”
二、coredns
从Kubernetes1.11版本开始,Kubernetes集群的DNS服务由CoreDNS提供:
它是由go语言实现的一套高性能、插件式,易于扩展的DNS服务端;
解决了KubeDNS的一些问题, 例如dnsmasq的安全漏洞、externalName不能使用stubDomains进行设置等等;
支持自定义DNS记录及配置upstream DNS Server,可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS;
它没有使用多个容器的架构,只用一个容器便实现了KubeDNS内3个容器的全部功能。
部署CoreDNS服务时需要创建3个资源对象:1个ConfigMap、1个Deployment和1个Service。
在启用了RBAC的集群中,还可以设置ServiceAccount、ClusterRole 、ClusterRoleBinding对CoreDNS容器进行权限设置。
#查看配置文件
[root@localhost7C k8s]# cat coredns.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: coredns
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:coredns
rules:
- apiGroups:
- ""
resources:
- endpoints
- services
- pods
- namespaces
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:coredns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:coredns
subjects:
- kind: ServiceAccount
name: coredns
namespace: kube-system
---
#ConfigMap 的 "coredns" 主要设置CoreDNS的主配置文件Corefile的内容,其中可以定义各种域名的解析方式和使用的插件,示例如下:
#在下面的示例中为域名 “.:53”(也可以设置zzhz.local) 设置了一系列插件,包括errors、 health、ready、kubernetes、prometheus、forward、cache、loop、reload和 loadbalance,
#在进行域名解析时,这些插件将以从上到下的顺序依次执行:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data: #设置名称和Forward
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
#DNS名称
kubernetes zzhz.local in-addr.arpa ip6.arpa {
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
#forward插件用于配置上游DNS服务器或其他DNS服务器,当在CoreDNS中查询不到域名时,会到其他DNS服务器上进行查询
forward . 223.6.6.6
#forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
---
#Deployment 的“coredns” 主要设置CoreDNS容器应用的内容
#其中,replicas副本的数量通常应该根据集群的规模和服务数量确定,如果单个CoreDNS进程不足以支撑整个集群的DNS查询,则可以通过水平扩展提高查询能力。
#由于DNS服务是Kubernetes集群的关键核心服务,所以建议为其Deployment设置自动扩缩容控制器,自动管理其副本数量。
#另外,对资源限制部分(CPU限制和内存限制)的设置也应根据实际环境进行调整:
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/name: "CoreDNS"
spec:
# replicas: not specified here:
# 1. Default is 1.
# 2. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
spec:
priorityClassName: system-cluster-critical
serviceAccountName: coredns
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
nodeSelector:
kubernetes.io/os: linux
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: k8s-app
operator: In
values: ["kube-dns"]
topologyKey: kubernetes.io/hostname
containers:
- name: coredns
image: coredns/coredns:1.6.7 #镜像地址
imagePullPolicy: IfNotPresent
resources:
limits:
memory: 700Mi #资源限制
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
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- all
readOnlyRootFilesystem: true
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /ready
port: 8181
scheme: HTTP
dnsPolicy: Default
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
---
#service配置
#Service“kube-dns” 是DNS服务的配置,这个服务需要设置固定的ClusterIP地址,也需要将所有Node上的kubelet启动参数--cluster-dns都设置为这个ClusterIP
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"
kubernetes.io/name: "CoreDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.10.0.2 #DNS IP
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
- name: metrics
port: 9153
protocol: TCP
测试:
[root@localhost7C ~]# cat busybox.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- name: busybox
image: gcr.io/google containers/busybox
command:
- sleep
- "3600"
kubectl exec busybox --nslookup “DNS全称:service名.namespace名.svc.zzhz.local”
--------------------------------------------------------------------------------------------
CoreDNS的主要功能是通过插件系统实现的,CoreDNS实现了一种链式插件结构,将DNS的逻辑抽象成了一个个插件,能够灵活组合使用。
ConfigMap 的 "coredns" 主要设置CoreDNS的主配置文件Corefile常用的插件如下:
loadbalance 提供基于DNS的负载均衡功能
loop 检测在DNS解析过程中出现的简单循环问题
cache 提供前端缓存功能
health 对Endpoint进行健康检查
kubernetes 从Kubernetes中读取zone数据
etcd 从etcd中读取zone数据,可用于自定义域名记录
file 从RFC 1035格式文件中读取zone数据
hosts 使用/etc/hosts文件或者其他文件读取zone数据,可用于自定义域名记录
auto 从磁盘中自动加载区域文件
reload 定时自动重新加载Corefile配置文件的内容
forward 转发域名查询到上游DNS服务器上
prometheus 为Prometheus系统提供采集性能指标数据的URL
pprof 在URL路径/debug/pprof下提供运行时的性能数据
log 对DNS查询进行日志记录
errors 对错误信息进行日志记录