Kubernetes技術分析之DNS

jopen 9年前發布 | 95K 次閱讀 Kubernetes

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/GoogleCloud ... s/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</pre>
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</pre>
可以看到查詢處理的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</pre>
對于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</pre>

參考

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!