Kubernetes技术分析之DNS
概述Docker的流行激活了一直不温不火的PaaS,随着而来的是各类Micro-PaaS的出现,Kubernetes是其中最具代表性的一员,它是Google多年大规模容器管理技术的开源版本。本系列文章将逐一分析Kubernetes, 本文主要讲解如何开启DNS支持,以及其原理和使用方式。
概述
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.sh
ENABLE_CLUSTER_DNS=true
DNS_SERVER_IP="10.0.0.10"
DNS_DOMAIN="cluster.local"
DNS_REPLICAS=1
- 手动方式
首先启动DNS server ReplicationController和Service,
配置文件模板:https://github.com/GoogleCloudPlatform/kubernetes/tree/v1.0.1/cluster/addons/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
参考
- https://github.com/GoogleCloudPlatform/kubernetes/blob/v1.0.1/docs/services.md#discovering-services
- https://github.com/GoogleCloudPlatform/kubernetes/blob/v1.0.1/docs/dns.md
作者简介
吴龙辉,现任网宿科技高级运营工程师,致力于云计算PaaS的研究和实践,活跃于CloudFoundry,Docker,Kubernetes等开源社区,贡献代码和撰写技术文档。
邮箱:wulh@chinanetcenter.com/wlh6666@qq.com
更多推荐
所有评论(0)