Kubernetes技术分析之DNS
jopen
9年前
Docker的流行激活了一直不温不火的PaaS,随着而来的是各类Micro-PaaS的出现,Kubernetes是其中最具代表性的一员,它是 Google多年大规模容器管理技术的开源版本。本系列文章将逐一分析Kubernetes, 本文主要讲解如何开启DNS支持,以及其原理和使用方式。
1.开启DNS
Kubernetes支持2种服务发现方式,环境变量和DNS,其中环境变量是默认支持的,但是环境变量方式存在限制:Pod必须在Service之后创建,DNS则没有这个限制。DNS是一种Cluster Add-on, 它随Kubernetes部署,但是需要配置启动:
- cluster turn-up
如果使用cluster turn-up,需要配置cluster/gce/config-default.shENABLE_CLUSTER_DNS=true DNS_SERVER_IP="10.0.0.10" DNS_DOMAIN="cluster.local" DNS_REPLICAS=1
- 手动方式
首先启动DNS server ReplicationController和Service,配置文件模板:https://github.com/GoogleCloud ... s/dns
skydns-rc.yaml:
apiVersion: v1 kind: ReplicationController metadata: name: kube-dns-v6 namespace: kube-system labels: k8s-app: kube-dns version: v6 kubernetes.io/cluster-service: "true" spec: replicas: 1 selector: k8s-app: kube-dns version: v6 template: metadata: labels: k8s-app: kube-dns version: v6 kubernetes.io/cluster-service: "true" spec: containers: - name: etcd image: gcr.io/google_containers/etcd:2.0.9 resources: limits: cpu: 100m memory: 50Mi command: - /usr/local/bin/etcd - -listen-client-urls - http://127.0.0.1:2379,http://127.0.0.1:4001 - -advertise-client-urls - http://127.0.0.1:2379,http://127.0.0.1:4001 - -initial-cluster-token - skydns-etcd - name: kube2sky image: gcr.io/google_containers/kube2sky:1.11 resources: limits: cpu: 100m memory: 50Mi args: # command = "/kube2sky" - --kube_master_url=http://192.168.3.146:8080 #change to your master url - -domain=cluster.local - name: skydns image: gcr.io/google_containers/skydns:2015-03-11-001 resources: limits: cpu: 100m memory: 50Mi args: # command = "/skydns" - -machines=http://localhost:4001 - -addr=0.0.0.0:53 - -domain=cluster.local. ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP dnsPolicy: Default # Don't use cluster DNS.
skydns-svc.yaml:
apiVersion: v1 kind: Service metadata: name: kube-dns namespace: kube-system labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" kubernetes.io/name: "KubeDNS" spec: selector: k8s-app: kube-dns clusterIP: 10.254.210.250 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP
创建后可以查看:
$ kubectl --namespace="kube-system" get pods NAME READY STATUS RESTARTS AGE kube-dns-v6-5y317 3/3 Running 0 2d $ kubectl --namespace="kube-system" get services NAME LABELS SELECTOR IP(S) PORT(S) kube-dns k8s-app=kube-dns... k8s-app=kube-dns 10.254.210.250 53/UDP,53/TCP
DNS Server启动完成后,还需要配置kubelet:
--cluster_dns=10.254.210.250 #DNS service ip --cluster_domain=cluster.local #default local domain
部署好的话可以验证下,现有以下services:
$ kubectl get services NAME LABELS SELECTOR IP(S) PORT(S) frontend name=frontend name=frontend 10.254.159.131 80/TCP redis-master name=redis-master name=redis-master 10.254.169.230 6379/TCP redis-slave name=redis-slave name=redis-slave 10.254.70.184 6379/TCP
选择一个pod,进行DNS验证:
$ kubectl exec busybox -- nslookup frontend Server: 10.254.210.250 Address 1: 10.254.210.250 Name: frontend Address 1: 10.254.159.131 $ kubectl exec busybox -- nslookup redis-master Server: 10.254.210.250 Address 1: 10.254.210.250 Name: redis-master Address 1: 10.254.169.230 $ kubectl exec busybox -- nslookup redis-slave Server: 10.254.210.250 Address 1: 10.254.210.250 Name: redis-slave Address 1: 10.254.70.184
可以看到查询处理的ip和Service ip一致,说明DNS工作正常。
2.DNS说明
DNS Server包含3部分:- skyDNS: 提供DNS解析服务
- etcd:用于skyDNS的存储
- kube2sky:连接Kubernetes和skyDNS
实际上kube2sky会监听Kubernetes,当有新的Service创建时,就生成相应记录到skyDNS,一个Service包括2条记录:
<service_name>.<namespace_name>.<domain> <service_name>.<namespace_name>.svc.<domain>
然后kubelet会在容器启动的时候配置根据/etc/resolv.conf:
$ kubectl exec busybox cat /etc/resolv.conf nameserver 10.254.210.250 nameserver 218.85.157.99 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5
可以看到配置了DNS Service IP作为域名服务器,然后设置了default.svc.cluster.local svc.cluster.local cluster.local作为默认域名。
以redis-master service为例:
$ kubectl exec busybox -- nslookup redis-master Server: 10.254.210.250 Address 1: 10.254.210.250 Name: redis-master Address 1: 10.254.169.230 $ kubectl exec busybox -- nslookup redis-master.default.cluster.local Server: 10.254.210.250 Address 1: 10.254.210.250 Name: redis-master.default.cluster.local Address 1: 10.254.169.230 $ kubectl exec busybox -- nslookup redis-master.default.svc.cluster.local Server: 10.254.210.250 Address 1: 10.254.210.250 Name: redis-master.default.svc.cluster.local Address 1: 10.254.169.230
对于Headless services,域名则对于所有Endpoints:
$ kubectl describe service frontend-headless Name: frontend-headless Namespace: default Labels: name=frontend-headless Selector: name=frontend Type: ClusterIP IP: None Port: <unnamed> 80/TCP Endpoints: 10.1.14.19:80,10.1.79.47:80,10.1.79.48:80 Session Affinity: None No events. $ kubectl exec busybox -- nslookup frontend-headless Server: 10.254.210.250 Address 1: 10.254.210.250 Name: frontend-headless Address 1: 10.1.14.19 Address 2: 10.1.79.47 Address 3: 10.1.79.48