DNS服务搭建和配置指南
作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,这就需要一个集群范围内的DNS服务来完成从服务名到ClusterIP的解析。
DNS服务在Kubernetes的发展过程中经历了3个阶段,接下来会继续讲解。
在k8s1.2版本时,DNS服务是由SkyDNS提供的,它由4个容器组成:kube2sky、skydns、etcd和healthz。
kube2sky容器监听k8s中Service资源的变化,根据Service的名称和IP地址信息生成DNS记录,并将其保存到etcd中;
skydns容器从etcd中读取DNS记录,并为客户端容器应用提供DNS查询服务;
healthz容器提供对skydns服务的健康检查功能。
从Kubernetes1.4版本开始,SkyDNS组件被KubeDNS替换,主要考虑是SkyDNS组件之间通信较多,整体性能不高。KubeDNS由3个容器组成:kubedns、dnsmasq和sidecar,去掉了SkyDNS中的etcd存储,将DNS记录直接保存在内存中,以提高查询性能好。kubedns容器监控Kubernetes中Service资源的变化,根据Service的名称和IP地址生成DNS记录,并将DNS记录保存在内存中;dnsmasq容器从kubedns中获取DNS记录,提供DNS缓存,为客户端容器提供DNS查询服务;sidecar提供对kubedns和dnsmasq服务的健康检查功能。
从Kubernetes 1.11版本开始,kubernetes集群的DNS服务由CoreDNS提供。CoreDNS是CNCF基金会的一个项目,是用GO语言实现的高性能、插件式、易扩展的DNS服务端。CoreDNS解决了KubeDNS的一些问题,例如dnsmasq的安全漏洞、externalName不能使用stubDomains设置,等等。
CoreDNS支持自定义DNS记录及配置upstream DNS Server,可以统一管理Kubernetes基于服务的内容DNS和数据中心的物理DNS。
CoreDNS 没有使用多个容器的架构,只有一个容器便实现了KubeDNS内3个容器的全部功能。
下面以CoreDNS为例说明Kubernetes集群DNS服务的搭建过程。
在创建DNS服务之前修改每个Node上kubelet的启动参数
修改每个Node上Kubelet的启动参数,加上以下两个参数。
◎ --cluster-dns=169.169.0.100:为DNS服务的ClusterIP地址。
◎ --cluster-domain=cluster.local:为在DNS服务中设置的域名。
然后重启kubelet服务。
我们使用kubeadm安装的时候,已经安装了coredns
kubelet 的启动参数在此目录下修改,或者在config.yaml下面修改,图片上面有。
在此处添加:
Environment="KUBELET_DNS_ARGS=--cluster-dns=10.96.0.10 --cluster-domain=cluster.local"
创建CoreDNS应用
在部署CoreDNS应用前,至少需要创建一个ConfigMap、一个Deployment和一个Service共3个资源对象。在启用了RBAC的集群中,还可以设置ServiceAccount、ClusterRole、ClusterRoleBinding对CoreDNS容器进行权限设置。
ConfigMap“coredns”主要设置CoreDNS的主要配置文件Corefile的内容,其中可以定义各种域名的解析方式和使用插件,示例如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
cluster.local {
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
}
. {
cache 30
loadbalance
forward . /etc/resolv.conf
}
由于Kubeadm已经为我们安装了coreDNS,所以我们可以直接查看对于的yaml文件:
Deployment “coredns” 主要设置CoreDNS容器应用的内容,示例如下。
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/name: "CoreDNS"
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
annotations:
seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
spec:
priorityClassName: system-cluster-critical
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
nodeSelector:
beta.kubernetes.io/os: linux
containers:
- name: coredns
image: coredns/coredms:1.3.1
imagePullPolicy: IfNotPresent
resources:
limits:
memory: 170Mi
requests:
cpu: 100m
memonry: 70Mi
args: ["-conf", "/etc/coredns/Corefile"]
volumeMounts:
- name: config-volume
mountPath: /etc/coredns
readOnly: ture
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
protocol: TCP
name: dns-tcp
- containerPort: 9153
name: metrics
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- all
readOnlyRootFilesystem: ture
dnsPolicy: Default
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
其中,replicas副本的数量通常应该根据集群的规模和服务数量确定,如果单个CoreDNS进程不足以支撑整个集群的DNS查询,则可以通过水平扩展提高查询能力。由于DNS服务是Kubernetes集群的关键核心服务,所以建议为其Deployment设置自动扩缩容控制器,自动管理其副本数量。另外,对资源限制部分(CPU限制和内存限制)的设置也应根据实际环境进行调整。
ps: yaml文件以下面的为主
kubectl get deployment -n kube-system coredns -o yaml得到如下结果:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2019-07-30T02:19:22Z"
generation: 1
labels:
k8s-app: kube-dns
name: coredns
namespace: kube-system
resourceVersion: "898"
selfLink: /apis/extensions/v1beta1/namespaces/kube-system/deployments/coredns
uid: 71ce85cd-b270-11e9-b560-005056944210
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kube-dns
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
k8s-app: kube-dns
spec:
containers:
- args:
- -conf
- /etc/coredns/Corefile
image: docker.io/dustise/coredns:1.3.1
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 5
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
name: coredns
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
- containerPort: 9153
name: metrics
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /health
port: 8080
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
memory: 170Mi
requests:
cpu: 100m
memory: 70Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- all
procMount: Default
readOnlyRootFilesystem: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/coredns
name: config-volume
readOnly: true
dnsPolicy: Default
nodeSelector:
beta.kubernetes.io/os: linux
priorityClassName: system-cluster-critical
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: coredns
serviceAccountName: coredns
terminationGracePeriodSeconds: 30
tolerations:
- key: CriticalAddonsOnly
operator: Exists
- effect: NoSchedule
key: node-role.kubernetes.io/master
volumes:
- configMap:
defaultMode: 420
items:
- key: Corefile
path: Corefile
name: coredns
name: config-volume
status:
availableReplicas: 2
conditions:
- lastTransitionTime: "2019-07-30T02:25:38Z"
lastUpdateTime: "2019-07-30T02:25:38Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2019-07-30T02:19:28Z"
lastUpdateTime: "2019-07-30T02:25:42Z"
message: ReplicaSet "coredns-6897bd7b5" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 1
readyReplicas: 2
replicas: 2
updatedReplicas: 2
Service“kube-dns”是DNS服务的配置,示例如下:
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: KubeDNS
name: kube-dns
namespace: kube-system
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.96.0.10
ports:
- name: dns
port: 53
protocol: UDP
targetPort: 53
- name: dns-tcp
port: 53
protocol: TCP
targetPort: 53
- name: metrics
port: 9153
protocol: TCP
这个服务需要设置固定的ClusterIP,也需要将所有Node上的kubelet启动参数--cluster-dns设置为这个ClusterIP。
如果没有安装CoreDNS的小伙伴,可以通过上面的yaml创建安装哦
服务名的DNS解析
接下来使用一个带有nslookup工具的Pod来验证DNS服务能否正常工作:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- name: busybox
image: busybox
command:
- sleep
- "3600"
创建busybox并验证DNS服务器
在使用nslookup工具验证DNS服务能否正常工作:
kubectl exec busybos -- nslookup <namespaces>.<podname>
如果某个Service属于不同的命名空间,那么在进行Service查找时,需要补充Namespace的名称,组合成完整的域名。下面以查找kube-dns服务为例,将其所在的Namespace“kube-system”补充在服务名之后,用“.”连接为“kube-dns.kube-system”,即可查询成功。
小结:
今天的内容到此结束,明天我们接着讲解DNS服务。
谢谢大家的支持,喜欢的话可以点关注哦~