1 前言
如果说service解决了pod 服务发现和负载均衡的问题,那么kube-dns则是为了解决service的发现问题而诞生的。试想下这样一个场景,当不知道service ip 的情况下,应用程序如果想要访问后端服务,只有用kubectl get svc -n namespace来查询service对应的IP和端口,再改配置,这样每新建一个服务就要改一次配置,也是够折腾的。那么这个问题如果解决,这就是本文所要将的内容。
2 使用kube-dns发现service
kube-dns插件提供了三个容器功能如下:
kubedns容器
监视kubernetes service资源并更新DNS记录
替换etcd,使用TreeCache数据结构保存DNS记录并实现skydns的backend接口
接入skydns,对dnsmasq提供DNS查询服务
dnsmasq容器
对集群提供DNS查询服务
设置kubedns为upstream
提供DNS缓存,降低kubedns负载,提高性能
exechealthz容器
定期检查kubedns和dnsmasq的监控状态
为kubernetes的活性检测提供HTTP API
3 kubedns,dnsmasq,exechealthz原理图
4 kube-dns插件安装
kube-dns的安装其实就是启动三个容器:kubedns,dnsmasq,exechealthz
先创建一个kube-dns service
cat kubedns-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.10.10.10 #和各个节点的kubelet启动参数的--cluster-dns保持一致**
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
创建kube-dns RC,创建三个容器
cat kubedns-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
spec:
containers:
- name: kubedns
image: siriuszg/kubedns-amd64:latest
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 100m
memory: 50Mi
livenessProbe:
httpGet:
path: /healthz-kubedns
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /readiness
port: 8081
scheme: HTTP
initialDelaySeconds: 3
timeoutSeconds: 5
args:
- --domain=cluster.local. #和各个节点的kubelet中的启动参数--cluster-domain保持一致,cluster.local后面有个“.”**
- --dns-port=10053
- --kube-master-url=http://192.168.100.20:8080
ports:
- containerPort: 10053
name: dns-local
protocol: UDP
- name: kube-dnsmasq
image: ist0ne/kube-dnsmasq-amd64:latest
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /healthz-dnsmasq
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
args:
- --cache-size=1000
- --no-resolv
- --server=127.0.0.1#10053
- --log-facility=-
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
- name: healthz
image: ist0ne/exechealthz-amd64:latest
imagePullPolicy: IfNotPresent
resources:
limits:
memory: 50Mi
requests:
cpu: 10m
memory: 50Mi
args:
- --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null
- --url=/healthz-dnsmasq
- --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1:10053 >/dev/null
- --url=/healthz-kubedns
- --port=8080
- --quiet
ports:
- containerPort: 8080
protocol: TCP
dnsPolicy: Default
注意:各个节点的kubelet启动参数中要加上--cluster-dns和--cluster-domain,--cluster-dns的值就是service中的clusterIP: 10.10.10.10,--cluster-domain就是rc中的- --domain=cluster.local
这样容器启动就自动在/etc/resolv.conf中添加如下字段
分别执行kubectl create -f kubedns-svc.yaml ,kubectl create -f kubedns-rc.yaml 创建kubedns的service和pod
5 验证
通过上述各步的操作,kube-dns的插件就安装好了,先来看看我们都安装了什么,可以通过kubectl也可以通过dashboard来查看我们创建的service,rc和pod,下面的截图是通过kubectl来查看的
从图中可以看出启动了kube-dns-v6-41d2c这个pod,启在192.168.100.93这个节点上,分配的IP是172.17.2.5,共启了3个容器,这三个容器共享IP。
从default namespace中找一个pod,用这个pod验证kube-dns
选择 tomcat-gllz3这个pod,理由是这个pod中的容器装有nslookup。
从图中可以看出所有的service都可以通过kubedns解析出来
注意:kubedns的域名规则是service-name.namespace.svc.domain
service-name 即为某个service的name
namespace 为该service所在的namespace
svc 为固定字符
domain 为创建kubedns pod时指定的domain也就是各节点kubelete启动参数中的--cluster-domain,本文是cluster.local
不要试图去ping service ip ,可以telnet 或是nslookup去验证service是否有效。