1、CoreDNS簡介php
Kubernetes包括用於服務發現的DNS服務器Kube-DNS。 該DNS服務器利用SkyDNS的庫來爲Kubernetes pod和服務提供DNS請求。SkyDNS2的做者,Miek Gieben,建立了一個新的DNS服務器,CoreDNS,它採用更模塊化,可擴展的框架構建。 Infoblox已經與Miek合做,將此DNS服務器做爲Kube-DNS的替代品。html
CoreDNS利用做爲Web服務器Caddy的一部分而開發的服務器框架。該框架具備很是靈活,可擴展的模型,用於經過各類中間件組件傳遞請求。這些中間件組件根據請求提供不一樣的操做,例如記錄,重定向,修改或維護。雖然它一開始做爲Web服務器,可是Caddy並非專門針對HTTP協議的,而是構建了一個基於CoreDNS的理想框架。node
在這種靈活的模型中添加對Kubernetes的支持,至關於建立了一個Kubernetes中間件。該中間件使用Kubernetes API來知足針對特定Kubernetes pod或服務的DNS請求。並且因爲Kube-DNS做爲Kubernetes的另外一項服務,kubelet和Kube-DNS之間沒有緊密的綁定。您只須要將DNS服務的IP地址和域名傳遞給kubelet,而Kubernetes並不關心誰在實際處理該IP請求。linux
2、CoreDNS支持的行爲nginx
1.0.0版本主要遵循Kube-DNS的當前行爲。 CoreDNS的005及更高版本實現了完整的規範和更多功能。git
全部羣集中不須要pod A記錄支持,默認狀況下禁用。 此外,CoreDNS對此用例的支持超出了在Kube-DNS中找到的標準行爲。github
在Kube-DNS中,這些記錄不反映集羣的狀態,例如,對w-x-y-z.namespace.pod.cluster.local的任何查詢將返回帶有w.x.y.z(ip)的A記錄,即便該IP不屬於指定的命名空間,甚至不屬於集羣地址空間。最初的想法是啓用對* .namespace.pod.cluster.local這樣的域使用通配符SSL證書。web
CoreDNS集成了提供pod驗證的選項,驗證返回的IP地址w.x.y.z其實是指定命名空間中的pod的IP。他防止在命名空間中欺騙DNS名稱。 然而,它確實會大大增長CoreDNS實例的內存佔用,由於如今它須要觀察全部的pod,而不只僅是服務端點。docker
3、在kubernetes中部署corednsapache
一、下載coredns部署包:
https://github.com/coredns/deployment/tree/master/kubernetes
主要有幾個文件:
deploy.sh是一個便捷的腳本,用於生成用於在當前運行標準kube-dns的集羣上運行CoreDNS的清單。使用coredns.yaml.sed文件做爲模板,它建立一個ConfigMap和一個CoreDNS deployment,而後更新 Kube-DNS service selector以使用CoreDNS deployment。 經過從新使用現有服務,服務請求不會中斷。
腳本不會刪除kube-dns的deployment或replication controller - 您必須手動執行:
kubectl delete --namespace=kube-system deployment kube-dns
要使用它,只需將它們放在同一目錄中,而後運行deploy.sh腳本,將其傳遞給您的服務CIDR(10.3.0.0/24)。 這將生成具備必要Corefile的ConfigMap。 它還將查找現有的kube-dns服務的集羣IP。
(注意:以上原始腳本只適用於當前kubernetes集羣含有kube-dns的狀況,若是沒有須要修改下腳本)
#!/bin/bash # Deploys CoreDNS to a cluster currently running Kube-DNS. SERVICE_CIDR=$1 CLUSTER_DOMAIN=${2:-cluster.local} YAML_TEMPLATE=${3:-`pwd`/coredns.yaml.sed} YAML=${4:-`pwd`/coredns.yaml} if [[ -z $SERVICE_CIDR ]]; then echo "Usage: $0 SERVICE-CIDR [ CLUSTER-DOMAIN ] [ YAML-TEMPLATE ] [ YAML ]" exit 1 fi #CLUSTER_DNS_IP=$(kubectl get service --namespace kube-system kube-dns -o jsonpath="{.spec.clusterIP}") CLUSTER_DNS_IP=10.3.0.10 sed -e s/CLUSTER_DNS_IP/$CLUSTER_DNS_IP/g -e s/CLUSTER_DOMAIN/$CLUSTER_DOMAIN/g -e s?SERVICE_CIDR?$SERVICE_CIDR?g $YAML_TEMPLATE
默認狀況下CLUSTER_DNS_IP是自動獲取kube-dns的集羣ip的,可是因爲沒有部署kube-dns因此只能手動指定一個集羣ip了。
coredns.yaml.sed的內容以下:
apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors log stdout health kubernetes CLUSTER_DOMAIN SERVICE_CIDR proxy . /etc/resolv.conf cache 30 } --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: coredns namespace: kube-system labels: k8s-app: coredns kubernetes.io/cluster-service: "true" kubernetes.io/name: "CoreDNS" spec: replicas: 1 selector: matchLabels: k8s-app: coredns template: metadata: labels: k8s-app: coredns annotations: scheduler.alpha.kubernetes.io/critical-pod: '' scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]' spec: containers: - name: coredns image: coredns/coredns:latest imagePullPolicy: Always args: [ "-conf", "/etc/coredns/Corefile" ] volumeMounts: - name: config-volume mountPath: /etc/coredns ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP livenessProbe: httpGet: path: /health port: 8080 scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 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 labels: k8s-app: coredns kubernetes.io/cluster-service: "true" kubernetes.io/name: "CoreDNS" spec: selector: k8s-app: coredns clusterIP: CLUSTER_DNS_IP ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP
執行:
./deploy.sh 10.3.0.0/24 cluster.local
以上腳本執行後能夠看到預覽的效果:
apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors log stdout health kubernetes cluster.local 10.3.0.0/24 proxy . /etc/resolv.conf cache 30 } --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: coredns namespace: kube-system labels: k8s-app: coredns kubernetes.io/cluster-service: "true" kubernetes.io/name: "CoreDNS" spec: replicas: 1 selector: matchLabels: k8s-app: coredns template: metadata: labels: k8s-app: coredns annotations: scheduler.alpha.kubernetes.io/critical-pod: '' scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]' spec: containers: - name: coredns image: coredns/coredns:latest imagePullPolicy: Always args: [ "-conf", "/etc/coredns/Corefile" ] volumeMounts: - name: config-volume mountPath: /etc/coredns ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP livenessProbe: httpGet: path: /health port: 8080 scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 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 labels: k8s-app: coredns kubernetes.io/cluster-service: "true" kubernetes.io/name: "CoreDNS" spec: selector: k8s-app: coredns clusterIP: 10.3.0.10 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP
仔細觀察上面的Corefile部分,這是一個在端口53上運行CoreDNS併爲Kubernetes提供cluster.local域的示例
.:53 { errors log stdout health kubernetes cluster.local 10.3.0.0/24 proxy . /etc/resolv.conf cache 30 }
1)errors官方沒有明確解釋,後面研究
2)log stdout:日誌中間件配置爲將日誌寫入STDOUT
3)health:健康檢查,提供了指定端口(默認爲8080)上的HTTP端點,若是實例是健康的,則返回「OK」。
4)cluster.local:CoreDNS爲kubernetes提供的域,10.3.0.0/24這告訴Kubernetes中間件它負責爲反向區域提供PTR請求0.0.3.10.in-addr.arpa ..換句話說,這是容許反向DNS解析服務(咱們常用到得DNS服務器裏面有兩個區域,即「正向查找區域」和「反向查找區域」,正向查找區域就是咱們一般所說的域名解析,反向查找區域便是這裏所說的IP反向解析,它的做用就是經過查詢IP地址的PTR記錄來獲得該IP地址指向的域名,固然,要成功獲得域名就必須要有該IP地址的PTR記錄。PTR記錄是郵件交換記錄的一種,郵件交換記錄中有A記錄和PTR記錄,A記錄解析名字到地址,而PTR記錄解析地址到名字。地址是指一個客戶端的IP地址,名字是指一個客戶的徹底合格域名。經過對PTR記錄的查詢,達到反查的目的。)
5)proxy:這能夠配置多個upstream 域名服務器,也能夠用於延遲查找 /etc/resolv.conf 中定義的域名服務器
6)cache:這容許緩存兩個響應結果,一個是確定結果(即,查詢返回一個結果)和否認結果(查詢返回「沒有這樣的域」),具備單獨的高速緩存大小和TTLs。
二、如今安裝coredns到kubernetes中
[root@dev-master CoreDNS]# ./deploy.sh 10.3.0.0/24 cluster.local | kubectl apply -f - configmap "coredns" created deployment "coredns" created service "kube-dns" created
[root@dev-master CoreDNS]# kubectl get pods --namespace=kube-system NAME READY STATUS RESTARTS AGE coredns-512496995-c1x9g 1/1 Running 0 5m default-http-backend-905355492-nrt1z 1/1 Running 0 23h heapster-2450140206-dw408 1/1 Running 2 23h kube-apiserver-172.16.71.200 1/1 Running 3 7d kube-controller-manager-172.16.71.200 1/1 Running 10 8d kube-proxy-172.16.71.200 1/1 Running 49 37d kube-scheduler-172.16.71.200 1/1 Running 300 14d kubernetes-dashboard-654048359-p73r9 1/1 Running 0 23h monitoring-grafana-438219031-32btw 1/1 Running 1 5d monitoring-influxdb-3584808869-s6sh1 1/1 Running 2 23h nginx-ingress-controller-1644785683-9fxsp 1/1 Running 4 26d nginx-ingress-controller-1644785683-mw7nx 1/1 Running 2 23h tiller-deploy-411327518-q9zn3 1/1 Running 2 23h
[root@dev-master CoreDNS]# kubectl logs -f coredns-512496995-c1x9g --namespace=kube-system .:53 2017/09/13 02:36:31 [INFO] CoreDNS-011 2017/09/13 02:36:31 [INFO] linux/amd64, go1.9, 1b60688d CoreDNS-011 linux/amd64, go1.9, 1b60688d
三、修改master節點和全部node節點的/etc/systemd/system/kube-kubelet.service,修改內容如紅色所注,與上面的Corefile中的值對應。
[Unit] Description=Kubernetes Kubelet Master Documentation=https://github.com/GoogleCloudPlatform/kubernetes [Service] Environment=KUBELET_IMAGE_TAG=v1.6.2 ExecStartPre=/usr/bin/mkdir -p /var/log/containers ExecStart=/opt/bin/kubelet \ --api-servers=http://127.0.0.1:8080 \ --register-schedulable=false \ --cni-conf-dir=/etc/kubernetes/cni/net.d \ --container-runtime=docker \ --allow-privileged=true \ --pod-manifest-path=/etc/kubernetes/manifests \ --hostname-override=172.16.71.200 \ --pod-infra-container-image=172.16.80.94/mir/pause-amd64:3.0 \ --v=3 \ --cluster-dns=10.3.0.10 \ --cluster-domain=cluster.local. \ --resolv-conf=/etc/resolv.conf \ Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
四、測試CoreDNS是否起做用
如今咱們來建立一個nginx的pod和service,測試一下coredns是否起做用
apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: 172.16.71.199/common/nginx:1.8.1 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: nginx
[root@dev-master CoreDNS]# kubectl create -f nginx.yaml pod "nginx" created service "nginx" created
[root@dev-master CoreDNS]# kubectl get pod NAME READY STATUS RESTARTS AGE load-generator-1962471460-6v7lb 1/1 Running 3 22d nginx 1/1 Running 0 1m php-apache-1106203038-w51jw 1/1 Running 3 22d
用curl測試,首先進入這個集羣內的另外一個pod(這個pod是在修改master節點和node節點的/etc/systemd/system/kube-kubelet.service以後建立的),在pod內部訪問剛纔建立的
nginx
[root@mir2-handler-deployment-3595565332-bqk3t /]# <5332-bqk3t /]# curl nginx.default.svc.cluster.local <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
實驗證實用:my-svc.my-namespace.svc.cluster.local的方式能夠訪問服務。