Kubernetes把一个实际的服务抽象为pod和service资源,pod是后端,负责处理业务逻辑,后端的pod可以有很多,有些pod可能异常被controller回收或者动态缩放,pod的ip都是动态分配的,所以需要抽象出service把pod提供的服务开放出来,这样我们就不需要管后端pod的ip变化。那service本身的ip我们怎么知道呢?k8s使用DNS解决这个问题。 K8s的DNS服务之前使用etcd + kube2sky + skydns搭建,在之后改为kubedns + dnsmasq,本文当然基于kubedns搭建。
ps:最新版推荐CoreDNS
搭建kubeDNS kubeDNS容器监听apiserver的服务变化,但service和endpoints出现更新时,把名字和IP在内存中存储起来,对外使用dnsmasq提供DNS服务。 在kubernetes源码包cluster/addons/dns目录中有DNS服务需要的yaml文件,可以使用这些文件略加修改搭建DNS。kubedns-sa.yaml
1 2 3 4 5 6 7 8 apiVersion: v1 kind: ServiceAccount metadata: name: kube-dns namespace: kube-system labels: kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile
kubedns-cm.yaml
1 2 3 4 5 6 7 apiVersion: v1 kind: ConfigMap metadata: name: kube-dns namespace: kube-system labels: addonmanager.kubernetes.io/mode: EnsureExists
ConfigMap文件中可以配置自定义DNS和上游DNS,自定义DNS指对特定域名查询特定的DNS服务器,上游DNS指外部的DNS服务器,不指定的话就从主机/etc/resolv.conf继承。 下面这个文件设置了域名out-of.k8s的查询会被发送到10.11.33.44服务器。上游DNS指定了8.8.8.8和114.114.114.114
1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: v1 kind: ConfigMap metadata: name: kube-dns namespace: kube-system labels: addonmanager.kubernetes.io/mode: EnsureExists data: stubDomains: | {"out-of.k8s": ["10.11.33.44"]} upstreamNameservers: | ["8.8.8.8","114.114.114.114"]
kubedns-deployment.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 apiVersion: extensions/v1beta2 kind: Deployment metadata: name: kube-dns namespace: kube-system labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile spec: # replicas: not specified here: # 1. In order to make Addon Manager do not reconcile this replicas parameter. # 2. Default is 1. # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on. strategy: rollingUpdate: maxSurge: 10% maxUnavailable: 0 selector: matchLabels: k8s-app: kube-dns template: metadata: labels: k8s-app: kube-dns annotations: scheduler.alpha.kubernetes.io/critical-pod: '' spec: tolerations: - key: "CriticalAddonsOnly" operator: "Exists" volumes: - name: kube-dns-config configMap: name: kube-dns optional: true containers: - name: kubedns image: registry.cn-hangzhou.aliyuncs.com/szss_k8s/k8s-dns-kube-dns-amd64:1.14.5 resources: # TODO: Set memory limits when we've profiled the container for large # clusters, then set request = limit to keep this container in # guaranteed class. Currently, this container falls into the # "burstable" category so the kubelet doesn't backoff from restarting it. limits: memory: 170Mi requests: cpu: 100m memory: 70Mi livenessProbe: httpGet: path: /healthcheck/kubedns port: 10054 scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: httpGet: path: /readiness port: 8081 scheme: HTTP # we poll on pod startup for the Kubernetes master service and # only setup the /readiness HTTP server once that's available. initialDelaySeconds: 3 timeoutSeconds: 5 args: - --domain=wx-dev.local. - --dns-port=10053 - --config-dir=/kube-dns-config - --v=2 env: - name: PROMETHEUS_PORT value: "10055" ports: - containerPort: 10053 name: dns-local protocol: UDP - containerPort: 10053 name: dns-tcp-local protocol: TCP - containerPort: 10055 name: metrics protocol: TCP volumeMounts: - name: kube-dns-config mountPath: /kube-dns-config - name: dnsmasq image: registry.cn-hangzhou.aliyuncs.com/szss_k8s/k8s-dns-dnsmasq-nanny-amd64:1.14.5 livenessProbe: httpGet: path: /healthcheck/dnsmasq port: 10054 scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 args: - -v=2 - -logtostderr - -configDir=/etc/k8s/dns/dnsmasq-nanny - -restartDnsmasq=true - -- - -k - --cache-size=1000 - --log-facility=- - --server=/wx-dev.local/127.0.0.1#10053 - --server=/in-addr.arpa/127.0.0.1#10053 - --server=/ip6.arpa/127.0.0.1#10053 ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP # see: https://github.com/kubernetes/kubernetes/issues/29055 for details resources: requests: cpu: 150m memory: 20Mi volumeMounts: - name: kube-dns-config mountPath: /etc/k8s/dns/dnsmasq-nanny - name: sidecar image: registry.cn-hangzhou.aliyuncs.com/szss_k8s/k8s-dns-sidecar-amd64:1.14.5 livenessProbe: httpGet: path: /metrics port: 10054 scheme: HTTP initialDelaySeconds: 60 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 args: - --v=2 - --logtostderr - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.wx-dev.local,5,A - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.wx-dev.local,5,A ports: - containerPort: 10054 name: metrics protocol: TCP resources: requests: memory: 20Mi cpu: 10m dnsPolicy: Default # Don't use cluster DNS. serviceAccountName: kube-dns
把配置中wx-dev.local改成你的域名
这个配置中镜像地址都换成了阿里的registry.cn-hangzhou.aliyuncs.com/szss_k8s
创建出的deployment:
1 2 3 ubuntu@ubuntu1:~$ sudo kubectl get deployments --namespace=kube-system NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE kube-dns 1 1 1 1 9d
kubedns-svc.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 apiVersion: v1 kind: Service metadata: name: kube-dns namespace: kube-system labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/name: "KubeDNS" spec: selector: k8s-app: kube-dns clusterIP: 169.169.0.2 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP
clusterIP是DNS服务端ip,与集群同网段
创建出的service:
1 2 3 ubuntu@ubuntu1:~$ sudo kubectl get svc --namespace=kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 169.169.0.2 <none> 53/UDP,53/TCP 9d
修改kubelet参数 在集群中每个node节点的kubelet服务添加启动参数指定DNS地址。
1 --cluster-dns=169.169.0.2 --cluster-domain=wx-dev.local
测试 我们之前已经创建好一个nginx的pod和service了
1 2 3 4 ubuntu@ubuntu1:~$ sudo kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 169.169.0.1 <none> 443/TCP 20d nginx-service NodePort 169.169.181.54 <none> 80:8081/TCP 10d
现在我们要使用dns方式,通过查询nginx-service得到对应的ip。 先创建一个基础的busybox运行nslookup命令 busybox.yaml:
1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: v1 kind: Pod metadata: name: busybox namespace: default spec: containers: - name: busybox image: registry.cn-hangzhou.aliyuncs.com/qinyujia-test/busybox command: - sleep - "3600"
运行命令得到结果
1 2 3 4 5 ubuntu@ubuntu1:~$ sudo kubectl exec busybox -- nslookup nginx-service Server: 169.169.0.2 Address 1: 169.169.0.2 kube-dns.kube-system.svc.wx-dev.local Name: nginx-service Address 1: 169.169.181.54 nginx-service.default.svc.wx-dev.local
证明在同一个k8s集群内,dns能准确找出service name和ip的对应关系。