环境准备
-
下载k8s包
https://dl.k8s.io/v1.6.4/kubernetes.tar.gz
-
解压
解压后在kubernetes/cluster/addons/dns目录下有kubedns的部署文件
文件说明
-
kubedns-cm.yaml和kubedns-sa.yaml
kubedns-cm.yaml和kubedns-sa.yaml无须修改,直接使用。 -
kubedns-svc.yaml
kubedns-svc.yaml有三种类型的模板文件,我们使用kubedns-svc.yaml.sed文件来生成kubedns-svc.yaml文件,替换$DNS_SERVER_IP为指定K8s DNS IP(默认为apiserver ip 加 1,即apiserver中的clusterip),我们使用169.169.0.2。
cp kubedns-svc.yaml.sed kubedns-svc.yaml
sed -i 's/$DNS_SERVER_IP/169.169.0.2/g' kubedns-svc.yaml -
kubedns-controller.yaml
kubedns-controller.yaml有三种类型的模板文件,我们使用kubedns-controller.yaml.sed文件来生成kubedns-controller.yaml文件,替换$DNS_DOMAIN为cluster.local.(在与kube-apiserver定义的一致)。
cp kubedns-controller.yaml.sed kubedns-controller.yaml
sed -i 's/$DNS_DOMAIN/cluster.local./g' kubedns-controller.yaml
启动kubedns服务
- kubectl create -f kubedns-cm.yaml
- kubectl create -f kubedns-sa.yaml
- kubectl create -f kubedns-svc.yaml
- kubectl create -f kubedns-controller.yaml
启动报错
查看dns报错的方式
- describe镜像
- kubectl logs
* kubectl logs -n kube-system kube-dns-5b58959c58-jfx6w -c kubedns
* kubectl logs -n kube-system kube-dns-5b58959c58-jfx6w -c sidecar
* kubectl logs -n kube-system kube-dns-5b58959c58-jfx6w -c dnsmasq
下载镜像失败
通过kubectl describe发现报错为Failed to pull image "gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.1": rpc error: code = 2 desc = Get https://gcr.io/v1/_ping: dial tcp 108.177.125.82:443: i/o timeout
* docker pull registry.cn-beijing.aliyuncs.com/yzx/k8s-dns-kube-dns-amd64:1.14.1
* docker tag registry.cn-beijing.aliyuncs.com/yzx/k8s-dns-kube-dns-amd64:1.14.1 gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.1
* docker pull registry.cn-beijing.aliyuncs.com/yzx/k8s-dns-dnsmasq-nanny-amd64:1.14.1
* docker tag registry.cn-beijing.aliyuncs.com/yzx/k8s-dns-dnsmasq-nanny-amd64:1.14.1 gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.1
* docker pull registry.cn-beijing.aliyuncs.com/yzx/k8s-dns-sidecar-amd64:1.14.1
* docker tag registry.cn-beijing.aliyuncs.com/yzx/k8s-dns-sidecar-amd64:1.14.1 gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.1
启动报错,分别查看三个容器报错
- 查看kubedns报错
[root@k8s-master yaml]# kubectl logs -n kube-system --tail=20 kube-dns-5b58959c58-jfx6w -c kubedns
I1111 14:41:28.703893 1 dns.go:49] version: v1.5.2-beta.0+$Format:%h$
F1111 14:41:28.704003 1 server.go:57] Failed to create a kubernetes client: open /var/run/secrets/kubernetes.io/serviceaccount/token: no such file or directory
解决方案:
* apiserver的配置中添加ServiceAccount
* 在controller-manager的配置中添加--root-ca-file=/run/kubernetes/apiserver.crt --service-account-private-key-file=/run/kubernetes/apiserver.key
* 重启apiserver 和 controller-manager
* 重新创建kubedns-sa.yaml和kubedns-controller.yaml
修改kubelet启动参数
- kubelet启动参数添加
--cluster-dns=169.169.0.2 --cluster-domain=cluster.local
- 进入某个pod中的容器内查看其
/etc/resolv.conf
文件
root@jekins:~# cat /etc/resolv.conf
nameserver 10.254.0.2
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
如上所示,根据kubelet的启动参数,kubelet会在每个pod中设置DNS域名解析文件/etc/resolv.conf,加入了nameser和search搜索域。最后应用程序就能够像访问网站一样,仅仅通过服务的名字就能访问到服务了。
- 重新创建pod
- 在pod中ping服务名已能解析,但是网络不通
root@nginx-deployment-5487769f48-fq6hn:/# ping nginx-service
PING nginx-service.default.svc.cluster.local (169.169.201.158): 48 data bytes
dns解析的为service名,service和pod仅通过label关联,所以service name和与之关联的pod name不一定相同
dns正常网络不通问题
1. 未安装flannel网络服务,多节点间不通
详见 k8s集群搭建之网络处理
2. bad address 'nginx'
[root@localhost deployment]# kubectl exec -it busybox-786cfc6cb7-6trsz sh
/ # wget nginx
wget: bad address 'nginx'
重新创建dns-controller
3. Could not resolve host: nginx
- k8s node节点上的kube-proxy调整参数,添加proxy-mode=iptables
KUBE_PROXY_ARGS="--master=http://10.254.0.53:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2 --proxy-mode=iptables "
- 重启kube-proxy
- 重新生成 deployment
- 重新生成service
- 若仍不通,则参考文档中在配置文件proxy中添加
--cluster-cidr=169.169.0.0/16
- 若仍存在问题则执行在node节点上
iptables -nvL
然后执行iptables -P KUBE-FIREWALL ACCEPT
设置接受 - 1master 1node时可通过service name连接服务,多node时不可调用
发现去掉proxy-mode=iptables,通过wget仍能够联调其它service
4. Failed to list *v1.Endpoints: Unauthorized
kubectl logs kube-dns-5b58959c58-rwzcg -n kube-system kubedns报错
E1118 16:04:24.248560 1 reflector.go:199] k8s.io/dns/vendor/k8s.io/client-go/tools/cache/reflector.go:94: Failed to list *v1.Service: Unauthorized
E1118 16:04:24.250134 1 reflector.go:199] k8s.io/dns/vendor/k8s.io/client-go/tools/cache/reflector.go:94: Failed to list *v1.Endpoints: Unauthorized
I1118 16:04:24.558926 1 dns.go:174] DNS server not ready, retry in 500 milliseconds
F1118 16:04:25.058985 1 dns.go:168] Timeout waiting for initialization
重新创建sa和controller-manager
参考kube-system下的pod只能通过kube-system下的sa请求apiserver
5. 如果容器网络包括访问service ip是正常的,并且dns容器也启动正常
查看kubelet中配置的--cluster-dns是否为dns容器对应的service ip
目前除了 kube-dns的方案还有一个coredns的方案,待以后研究