KubernetesサービスディスカバリのためのCoreDNS、パート2

CoreDNSは、Kubernetes DNSサービスディスカバリ仕様に完全に準拠するようになりました。

数ヶ月前、Kubernetesでkube-dnsの代わりにCoreDNSを使用する方法に関するブログ記事を公開しました。それ以来、大きな進歩を遂げました。コミュニティと協力して[Kubernetes DNSベースのサービスディスカバリ] (https://github.com/kubernetes/dns/blob/master/docs/specification.md), の仕様を策定し、既存のKube-DNS実装とCoreDNSにおける新しい実装との互換性を確保することができました。この仕様のバージョン1.0.0は、主に現在のKube-DNSの動作に従っています。CoreDNSのバージョン0.5以上は、完全な仕様とさらなる機能を実装しています。

そのブログ記事を書いた時点では、CoreDNS Kubernetesプラグインは、通常のサービスのクラスタIPを使用してAレコードを提供することのみをサポートしていました。現在は以下を含みます。

  • 通常のサービスとヘッドレスサービスのASRV、およびPTRレコード
  • サービスの一部である名前付きエンドポイントのAレコード(つまり、「pets」のレコード)
  • 仕様に記載されているように、ポッドのAレコード(オプション)
  • 使用中のDNSスキーマバージョンを検出するためのTXTレコード

ポッドのAレコードのサポートは、すべてのクラスタで必要ではなく、デフォルトで無効になっています。さらに、このユースケースに対するCoreDNSのサポートは、Kube-DNSで見られる標準的な動作を超えています。Kube-DNSでは、これらのレコードはクラスタの状態を反映しません。w-x-y-z.namespace.pod.cluster.localへのクエリは、指定された名前空間、さらにはクラスタのアドレス空間にも属していないIPであっても、w.x.y.zを持つAレコードを返します。この背後にある元のアイデアは、*.namespace.pod.cluster.localのようなドメインに対してワイルドカードSSL証明書を使用できるようにすることでした。CoreDNSは、構成オプションpods insecureを使用してこの動作を複製できます。検証の欠如によりワイルドカード証明書のアイデンティティ保証が破られるため、「insecure」と見なしています。

CoreDNSの統合には、返されたIPアドレスw.x.y.zが実際には指定された名前空間内のポッドのIPであることを検証するオプションpods verifiedがあります。これにより、名前空間内のDNS名のスプーフィングを防ぎます。ただし、サービスエンドポイントだけでなく、すべてのポッドを監視する必要があるため、CoreDNSインスタンスのメモリフットプリントが大幅に増加する可能性があります。

さて、導入はここまで。それでは、展開方法を見てみましょう。前のブログと同様に、ConfigMapとDeploymentを使用します。さらに簡単にするために、ユーティリティスクリプトデプロイメントマニフェストテンプレートを作成しました。これらを使用するには、両方と同じディレクトリに配置し、サービスのCIDRを渡してdeploy.shスクリプトを実行するだけです。これにより、必要なCorefileを含むConfigMapが生成されます。また、既存のkube-dnsサービスのクラスタIPも検索します。たとえば、以下を実行すると

$ ./deploy.sh 10.3.0.0/24 cluster.local

クラスタIPが10.3.0.10のkube-dnsサービスを持つクラスタを指すkubectlを使用すると、以下のマニフェストファイルが生成されます。1

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        log
        health
        kubernetes cluster.local 10.3.0.0/24
        forward . /etc/resolv.conf
        cache 30
    }    
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: coredns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "CoreDNS"
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: coredns
  template:
    metadata:
      labels:
        k8s-app: coredns
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
        scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
    spec:
      containers:
      - name: coredns
        image: coredns/coredns:latest
        imagePullPolicy: Always
        args: [ "-conf", "/etc/coredns/Corefile" ]
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
      dnsPolicy: Default
      volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
            - key: Corefile
              path: Corefile
---
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: coredns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "CoreDNS"
spec:
  selector:
    k8s-app: coredns
  clusterIP: 10.3.0.10
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP

そのCorefileを詳しく見てみましょう。前のブログ記事のものと非常によく似ています。

.:53 {
    errors
    log
    health
    kubernetes cluster.local 10.3.0.0/24
    forward . /etc/resolv.conf
    cache 30
}

ただし、違いは10.3.0.0/24ゾーンの追加です。これは、Kubernetesプラグインに、リバースゾーン0.3.10.in-addr.arpa.のリバースPTR要求の提供を担当することを伝えます。言い換えれば、これはサービスのリバースDNS解決を可能にするものです。試してみましょう。

$ ./deploy.sh 10.3.0.0/24 | kubectl apply -f -
configmap "coredns" created
deployment "coredns" created
service "kube-dns" configured
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
Waiting for pod default/dnstools to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
/ # host kubernetes
kubernetes.default.svc.cluster.local has address 10.3.0.1
/ # host kube-dns.kube-system
kube-dns.kube-system.svc.cluster.local has address 10.3.0.10
/ # host 10.3.0.1
1.0.3.10.in-addr.arpa domain name pointer kubernetes.default.svc.cluster.local.
/ # host 10.3.0.10
10.0.3.10.in-addr.arpa domain name pointer kube-dns.kube-system.svc.cluster.local.
/ #

素晴らしい、動作しています。それでは、CoreDNSのログを見てみましょう。

$ kubectl get --namespace kube-system pods
NAME                                    READY     STATUS    RESTARTS   AGE
coredns-3558181428-0zhnh                1/1       Running   0          2m
coredns-3558181428-xri9i                1/1       Running   0          2m
heapster-v1.2.0-4088228293-a8gkc        2/2       Running   0          126d
kube-apiserver-10.222.243.77            1/1       Running   2          126d
kube-controller-manager-10.222.243.77   1/1       Running   2          126d
kube-proxy-10.222.243.77                1/1       Running   2          126d
kube-proxy-10.222.243.78                1/1       Running   0          126d
kube-scheduler-10.222.243.77            1/1       Running   2          126d
kubernetes-dashboard-v1.4.1-gi2xr       1/1       Running   0          24d
tiller-deploy-3299276078-e8phb          1/1       Running   0          24d
$ kubectl logs --namespace kube-system coredns-3558181428-0zhnh
2017/02/23 14:48:29 [INFO] Kubernetes plugin configured without a label selector. No label-based filtering will be performed.
.:53
2017/02/23 14:48:29 [INFO] CoreDNS-005
CoreDNS-005
10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "AAAA IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 107 544.128µs
10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "MX IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 107 7.576897ms
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "A IN kube-dns.kube-system.default.svc.cluster.local. udp 64 false 512" NXDOMAIN 117 471.176µs
23/Feb/2017:14:49:52 +0000 [ERROR 0 kube-dns.kube-system.default.svc.cluster.local. A] no items found
10.2.6.127 - [23/Feb/2017:14:50:00 +0000] "PTR IN 10.0.3.10.in-addr.arpa. udp 40 false 512" NOERROR 92 752.956µs
$ kubectl logs --namespace kube-system coredns-3558181428-xri9i
2017/02/23 14:48:29 [INFO] Kubernetes plugin configured without a label selector. No label-based filtering will be performed.
.:53
2017/02/23 14:48:29 [INFO] CoreDNS-005
CoreDNS-005
10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 70 1.10732ms
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "A IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 72 409.74µs
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "AAAA IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 109 210.817µs
10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "MX IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 109 796.703µs
10.2.6.127 - [23/Feb/2017:14:49:56 +0000] "PTR IN 1.0.3.10.in-addr.arpa. udp 39 false 512" NOERROR 89 694.649µs
$

ここで、クエリが2つのCoreDNSレプリカにロードバランスされていることがわかります。本番環境では、ロギングによりクエリが劇的に遅くなる(多くの場合、桁違いに)ため、すべてのクエリのロギングを無効にすることをお勧めします。そのためには、Corefileからlog行を削除するだけです。

CoreDNS GitHubで問題、質問、または機能に関するアイデアを自由に提出してください。


  1. 重要: Google Container Engineを使用している場合、kube-dnsデプロイメント(またはレプリケーションコントローラー)を置き換えることができない追加のプロセスがあります。上記の操作を試行すると、サービスは正常に変更されますが、すぐにCoreDNSデプロイメントがキルされ、Kube DNSレプリケーションコントローラーが再起動されます。サービスが更新されるため、サービスのサービスセレクターはKube DNSレプリケーションコントローラーによって作成されたポッドを指さなくなるため、実際にはクラスタでDNSが失われます。おそらく回避策があると思いますが、まだ修正方法を見つける機会がありません。↩︎

John Belamaric
公開日: 、タグ付き DiscoveryDocumentationKube-DNSKubernetesService、使用単語数 1224語。