參考文檔:
- kubernetes插件:https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/coredns
- 自定義dns服務:https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/
- CoreDNS提供直接替換kube-dns的部署方式,請見:https://github.com/coredns/deployment/tree/master/kubernetes
從功能角度來看,CoreDNS 更像是一個通用 DNS 方案(類似於 BIND),然后通過插件模式來極大地擴展自身功能,可以適用於不同的場景(比如 Kubernetes)。
一.環境
kubernetes集群已提前部署完成:https://www.cnblogs.com/netonline/tag/kubernetes/
組件版本如下:
組件 |
版本 |
Remark |
kubernetes |
v1.9.2 |
|
CoreDNS |
v1.2.2 |
二.部署CoreDNS
1. coredns范本
# 下載 [root@kubenode1 coredns]# cd ~ [root@kubenode1 ~]# mkdir -p /usr/local/src/yaml/coredns [root@kubenode1 ~]# cd /usr/local/src/yaml/coredns [root@kubenode1 coredns]# wget -O coredns.yaml https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/coredns/coredns.yaml.base # 本實驗使用yaml文件(修改版,供參考):https://github.com/Netonline2016/kubernetes/tree/master/addons/coredns
2. 配置coredns.yaml
# coredns所有相關資源通過1個yaml文件下發,注意紅色加粗字體部分即需要根據規划修改; # 將”ConfigMap”資源抽出來單獨做1個yaml文件,方便后續修改上游dns服務器或自定義dns記錄; # 除”ConfigMap”資源抽出外,主要修改兩處:”Deployment”資源的”image”與”Service”中的”clusterip”; # 在deployment中設置pod的副本數為2(可選) [root@kubenode1 coredns]# vim coredns.yaml # Warning: This is a file generated from the base underscore template file: coredns.yaml.base apiVersion: v1 kind: ServiceAccount metadata: name: coredns namespace: kube-system labels: kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: kubernetes.io/bootstrapping: rbac-defaults addonmanager.kubernetes.io/mode: Reconcile name: system:coredns rules: - apiGroups: - "" resources: - endpoints - services - pods - namespaces verbs: - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" labels: kubernetes.io/bootstrapping: rbac-defaults addonmanager.kubernetes.io/mode: EnsureExists name: system:coredns roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:coredns subjects: - kind: ServiceAccount name: coredns namespace: kube-system --- apiVersion: extensions/v1beta1 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: 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. replicas: 2 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: serviceAccountName: coredns tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule - key: "CriticalAddonsOnly" operator: "Exists" containers: - name: coredns image: netonline/coredns:1.2.2 imagePullPolicy: IfNotPresent resources: limits: memory: 170Mi 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 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: true 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 annotations: prometheus.io/port: "9153" prometheus.io/scrape: "true" labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "CoreDNS" spec: selector: k8s-app: kube-dns clusterIP: 169.169.0.11 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP
3. 配置coredns-cm.yaml
# 單列ConfigMap資源,方便后續設置上游dns服務器與自定義dns記錄; # coredns通過corefie控制dns記錄,kubernetes中采用ConfigMap將corefile文件映射到pod中,可以發現coredns “Deployment”資源中掛載了相應的”ConfigMap”,必須設置; # corefile格式如下: # ZONE:[PORT] { # [PLUGIN] ... # } # ZONE:定義 server 負責的 zone,PORT 是可選項,默認為 53; # PLUGIN:定義 server 所要加載的 plugin,如errors,health等均屬於plugin,相關注解請見:https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#coredns; [root@kubenode1 coredns]# cat coredns-cm.yaml apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system labels: addonmanager.kubernetes.io/mode: EnsureExists data: Corefile: | .:53 { errors health kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure # 用於解析外部主機主機(外部服務) upstream 114.114.114.114 223.5.5.5 fallthrough in-addr.arpa ip6.arpa } prometheus :9153 # 任何不在集群域內的查詢將轉發到預定義的解析器,默認:/etc/resolv.conf; # 在coredns “Deployment”資源中“dnsPolicy“設置為”Default”,即提供dns服務的pod從所在節點繼承/etc/resolv.conf,如果節點的上游解析地址與”upstream”一致,則設置任意一個參數即可 proxy . 114.114.114.114 223.5.5.5 cache 30 loop reload loadbalance } # 自定義dns記錄,對應kube-dns中的stubdomains; # 每條記錄,單獨設置1各zone out.kubernetes:53 { errors cache 30 proxy . 172.30.200.15 }
4. 啟動coredns
# 刪除kube-dns相關資源 [root@kubenode1 coredns]# kubectl delete -f /usr/local/src/yaml/kubedns/kube-dns.yaml # 啟動coredns; # coredns pod需要掛載”ConfigMap”資源,需要同時或提前下發相關資源 [root@kubenode1 coredns]# kubectl create -f coredns-cm.yaml configmap "coredns" created [root@kubenode1 coredns]# kubectl create -f coredns.yaml
三.驗證
1. 自定義dns服務器
# ”ConfigMap” 中自定義的dns記錄指向172.30.200.15,在其上安裝dnsmasq服務 [root@salt-master01 ~]# yum install dnsmasq -y # 生成自定義的DNS記錄文件 [root@salt-master01 ~]# echo "192.168.100.11 server.out.kubernetes" > /tmp/hosts # 啟動DNS服務; # -q:輸出查詢記錄; # -d:以debug模式啟動,前台運行,觀察輸出日志; # -h:不使用/etc/hosts; # -R:不使用/etc/resolv.conf; # -H:使用自定義的DNS記錄文件; # 啟動輸出日志中warning提示沒有設置上游DNS服務器;同時讀入自定義DNS記錄文件 [root@salt-master01 ~]# dnsmasq -q -d -h -R -H /tmp/hosts
# iptables放行udp 53端口 [root@salt-master01 ~]# iptables -I INPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
2. 啟動驗證Pod
# 下載鏡像 [root@kubenode1 ~]# docker pull busybox # 配置Pod yaml文件; # dnsPolicy設置為ClusterFirst,默認也是ClusterFirst [root@kubenode1 ~]# touch dnstest.yaml [root@kubenode1 ~]# vim dnstest.yaml apiVersion: v1 kind: Pod metadata: name: dnstest namespace: default spec: dnsPolicy: ClusterFirst containers: - name: busybox image: busybox command: - sleep - "3600" imagePullPolicy: IfNotPresent restartPolicy: Always # 創建Pod [root@kubenode1 ~]# kubectl create -f dnstest.yaml
3. 驗證
# 分別針對3各域名進行nslookup查詢 [root@kubenode1 ~]# kubectl exec -it dnstest -- nslookup kubernetes.default [root@kubenode1 ~]# kubectl exec -it dnstest -- nslookup www.baidu.com [root@kubenode1 ~]# kubectl exec -it dnstest -- nslookup server.out.kubernetes
觀察172.30.200.15上dnsmasq服務的輸出:kube節點172.30.200.22與172.30.200.23(Pod所在的節點,flannel網絡,snat出節點)對server.out.kubenetes的查詢,dnsmasq返回預定義的主機地址。