为什么要引入DNS
kubernetes中的DNS
kubernetes中以插件的方式使用skydns作为DNS服务器。并且引入了一个另外一个组件kube2sky用来创建和删除域名解析记录。它目前仅支持两种解析A记录、SRV记录,在集群中对于域名的创建遵循一个规则:
对于A记录:
SERVICENAME.NAMESPACENAME.svc.CLUSTERDOMAIN
- SERVICENAME:每个Service的名字
- NAMESPACENAME:Service所属的namespace的名字
- svc:固定值
- CLUSTERDOMAIN:集群内部的域名
PS:由于老版本的原因,用户应该避免创建名为svc的namespace,否则会有你意想不到的事情发生
对于SRV记录:
- _PORTNAME:服务端口名字
- PORTPROTOCOL:服务端口的协议类型
解析特点:
工作原理:
kube2sky在启动的时候需要指定集群的域名,需要指定etcd的API接口,需要指定kube-apiserver的接口地址,启动之后 kube2sky会通过apiserver监听所有service的创建、删除、修改等操作,在etcd中写入对应的域名解析记录。另一方面 kubernetes集群中,kubelet需要配置skydns的解析地址,在kubelet创建的每一个container时,都会将dns指向到 skydns,在container中进行解析时,解析请求会发送到skydns,skydns会通过etcd中的解析记录进行查找返回对应的解析结果。
安装与配置:
概况
- kube-apiserver: 10.10.2.120:8080
- etcd: 10.10.2.120:4001
- 集群域名: coocla.org
1. 编译kube2sky和skydns
大家可以直接下载我已经编译好的kube2sky、skydns
编译skydns
# yum install go
# mkdir /tmp/kube2sky
# export GOPATH=/tmp/kube2sky
# cd /tmp/kube2sky
# go get githu.com/skynetservices/skydns
# cd $GOPATH/src/github.com/skynetservices/skydns
# go build -v
# cp $GOPATH/bin/skydns /usr/bin
需要把skydns运行在哪台机器上,就把编译后的skydns拷贝到哪台机器上即可,下面的kube2sky也一样,我这里就运行在编译的这台机器上,
编译kube2sky
# mkdir /tmp/skydns
# go get github.com/tools/godep
# go get -d github.com/GoogleCloudPlatform/kubernetes/cluster/addons/dns/kube2sky
# cd /go/src/github.com/GoogleCloudPlatform/kubernetes/cluster/addons/dns/kube2sky
# make kube2sky
# cp kube2sky /usr/bin
2. 配置skydns
# etcdctl mk /skydns/config '{“dns-addr”: “10.10.2.120:53”, “ttl”: 3600, “domain”: “coocla.org.”, “nameservers”: [“223.5.5.5:53”, “114.114.114.114:53"]}'
- dns-addr: 指定skydns启动时的监听地址
- ttl: 指域名的缓存的超时时间,单位秒
- domain: 集群中的私有域名,这里如果不指定,默认为skydns.local. ,注意最后的一个点
- nameservers:域名转发的dns列表,用来解析集群外部的域名
关于etcd的集群这里我采用集群原本存在的,详情可以参考:Kubernetes技术学习之—搭建kubernetes集群。因此这里不再赘述etcd的搭建过程
3. 启动skydns
# skydns -machines=http://10.10.2.120:4001 &
4. 启动kube2sky
# kube2sky -domain=coocla.org -etcd-server=http://10.10.2.120:4001 -kube_master_url=http://10.10.2.120:8080 &
5. 配置kubelet
指定kubelet的集群域名及集群内部的DNS(skydns)地址
在kubelet的配置文件(/etc/kubernetes/kubelet)中KUBELET_ARGS添加以下两个参数:
KUBELET_ARGS="--cluster-dns=10.10.2.120 --cluster-domain=coocla.org"
重启kubelet以使配置生效。
6. 验证
验 证方法:创建一个新的namespace,在default的namespace中创建两个Pod,一个为nginx server,一个为client1,在新的namespace中创建一个pod为client2,为default namespace中的nginx server创建一个service,分别使用client1和client2对新创建的service进行A记录和SRV记录解析,并解析外部域名的解 析地址。
# cat valid_skydns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: coocla
---
apiversion: v1
kind: Pod
metadata:
name: nginx-server
label:
app: nginx
spec:
containers:
- name: nginx
image: nginx
---
apiVersion: v1
kind: Pod
metadata:
name: client
spec:
containers:
- name: client
image: busybox
command:
- sleep
- "360000"
---
apiVersion: v1
kind: Pod
metadata:
name: client-coocla
namespace: coocla
spec:
containers:
- name: client-coocla
image: busybox
command:
- sleep
- "360000"
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
ports:
- port: 7878
targetPort: 80
protocol: TCP
name: web80
selector:
app: nginx
# kubectl create -f valid_skydns.yaml
namespaces/coocla
pods/nginx-server
pods/client
pods/client-coocla
services/web
在service创建的过程,我看可以看到kube2sky的日志如下:
接下才我们首先验证Service对应的A记录是否正常:
从上图可以看出跨namespace时则至少需要加上service所在的namespace。
我们再来验证SRV记录的解析:
最后验证集群外部的域名解析:
至此可以看出skydns + kube2sky已经正常的工作在kubernetes集群中。
查看原文:http://www.zoues.com/index.php/2016/02/27/dcos%e4%b9%8bskydns/