• CoreDNS for kubernetes Service Discovery


    一、CoreDNS简介

           Kubernetes包括用于服务发现的DNS服务器Kube-DNS。 该DNS服务器利用SkyDNS的库来为Kubernetes pod和服务提供DNS请求。SkyDNS2的作者,Miek Gieben,创建了一个新的DNS服务器,CoreDNS,它采用更模块化,可扩展的框架构建。 Infoblox已经与Miek合作,将此DNS服务器作为Kube-DNS的替代品。

          CoreDNS利用作为Web服务器Caddy的一部分而开发的服务器框架。该框架具有非常灵活,可扩展的模型,用于通过各种中间件组件传递请求。这些中间件组件根据请求提供不同的操作,例如记录,重定向,修改或维护。虽然它一开始作为Web服务器,但是Caddy并不是专门针对HTTP协议的,而是构建了一个基于CoreDNS的理想框架。

          在这种灵活的模型中添加对Kubernetes的支持,相当于创建了一个Kubernetes中间件。该中间件使用Kubernetes API来满足针对特定Kubernetes pod或服务的DNS请求。而且由于Kube-DNS作为Kubernetes的另一项服务,kubelet和Kube-DNS之间没有紧密的绑定。您只需要将DNS服务的IP地址和域名传递给kubelet,而Kubernetes并不关心谁在实际处理该IP请求。

    二、CoreDNS支持的行为

    1.0.0版本主要遵循Kube-DNS的当前行为。 CoreDNS的005及更高版本实现了完整的规范和更多功能。

    • A记录(正常的Service分配了一个名为my-svc.my-namespace.svc.cluster.local的DNS A记录。 这解决了服务的集群IP)
    • “headless”(没有集群IP)的Service也分配了一个名为my-svc.my-namespace.svc.cluster.local的DNS A记录。 与普通服务不同,这解决了Service选择了pods的一组IP。 客户预计将从这ip集合中消耗集合或使用标准循环选择。
    • 针对名为正常或无头服务的端口创建的SRV记录,对于每个命名的端口,SRV记录的格式为_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local。对于常规服务,这将解析为端口号和CNAME:my-svc.my-namespace.svc.cluster.local;对于无头服务,这解决了多个答案,一个用于支持服务的每个pod,并包含端口号还有格式为auto-generated-name.my-svc.my-namespace.svc.cluster.local 的pod的CNAME 。SRV记录包含它们中的“svc”段,对于省略“svc”段的旧式CNAME不支持。
    • 作为Service一部分的endpoints的A记录(比如“pets”的记录)
    • pod的Spec中描述的A记录
    • 还有就是用来发现正在使用的DNS模式版本的TXT记录

          所有群集中不需要pod A记录支持,默认情况下禁用。 此外,CoreDNS对此用例的支持超出了在Kube-DNS中找到的标准行为。

         在Kube-DNS中,这些记录不反映集群的状态,例如,对w-x-y-z.namespace.pod.cluster.local的任何查询将返回带有w.x.y.z(ip)的A记录,即使该IP不属于指定的命名空间,甚至不属于集群地址空间。最初的想法是启用对* .namespace.pod.cluster.local这样的域使用通配符SSL证书。

        CoreDNS集成了提供pod验证的选项,验证返回的IP地址w.x.y.z实际上是指定命名空间中的pod的IP。他防止在命名空间中欺骗DNS名称。 然而,它确实会大大增加CoreDNS实例的内存占用,因为现在它需要观察所有的pod,而不仅仅是服务端点。

      

    三、在kubernetes中部署coredns

    1、下载coredns部署包:

    https://github.com/coredns/deployment/tree/master/kubernetes

    主要有几个文件:

          deploy.sh是一个便捷的脚本,用于生成用于在当前运行标准kube-dns的集群上运行CoreDNS的清单。使用coredns.yaml.sed文件作为模板,它创建一个ConfigMap和一个CoreDNS  deployment,然后更新 Kube-DNS service selector以使用CoreDNS deployment。 通过重新使用现有服务,服务请求不会中断。

        脚本不会删除kube-dns的deployment或replication controller - 您必须手动执行:

    kubectl delete --namespace=kube-system deployment kube-dns

    要使用它,只需将它们放在同一目录中,然后运行deploy.sh脚本,将其传递给您的服务CIDR(10.3.0.0/24)。 这将生成具有必要Corefile的ConfigMap。 它还将查找现有的kube-dns服务的集群IP。 

    (注意:以上原始脚本只适用于当前kubernetes集群含有kube-dns的情况,如果没有需要修改下脚本)

    #!/bin/bash
    
    # Deploys CoreDNS to a cluster currently running Kube-DNS.
    
    SERVICE_CIDR=$1
    CLUSTER_DOMAIN=${2:-cluster.local}
    YAML_TEMPLATE=${3:-`pwd`/coredns.yaml.sed}
    YAML=${4:-`pwd`/coredns.yaml}
    
    if [[ -z $SERVICE_CIDR ]]; then
            echo "Usage: $0 SERVICE-CIDR [ CLUSTER-DOMAIN ] [ YAML-TEMPLATE ] [ YAML ]"
            exit 1
    fi
    
    #CLUSTER_DNS_IP=$(kubectl get service --namespace kube-system kube-dns -o jsonpath="{.spec.clusterIP}")
    
    CLUSTER_DNS_IP=10.3.0.10
    
    sed -e s/CLUSTER_DNS_IP/$CLUSTER_DNS_IP/g -e s/CLUSTER_DOMAIN/$CLUSTER_DOMAIN/g -e s?SERVICE_CIDR?$SERVICE_CIDR?g $YAML_TEMPLATE

    默认情况下CLUSTER_DNS_IP是自动获取kube-dns的集群ip的,但是由于没有部署kube-dns所以只能手动指定一个集群ip了。

    coredns.yaml.sed的内容如下:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns
      namespace: kube-system
    data:
      Corefile: |
        .:53 {
            errors
            log stdout
            health
            kubernetes CLUSTER_DOMAIN SERVICE_CIDR
            proxy . /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: CLUSTER_DNS_IP
      ports:
      - name: dns
        port: 53
        protocol: UDP
      - name: dns-tcp
        port: 53
        protocol: TCP

     执行:

    ./deploy.sh 10.3.0.0/24 cluster.local

    以上脚本执行后可以看到预览的效果:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns
      namespace: kube-system
    data:
      Corefile: |
        .:53 {
            errors
            log stdout
            health
            kubernetes cluster.local 10.3.0.0/24
            proxy . /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上运行CoreDNS并为Kubernetes提供cluster.local域的示例

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

    1)errors官方没有明确解释,后面研究

    2)log stdout:日志中间件配置为将日志写入STDOUT

    3)health:健康检查,提供了指定端口(默认为8080)上的HTTP端点,如果实例是健康的,则返回“OK”。

    4)cluster.local:CoreDNS为kubernetes提供的域,10.3.0.0/24这告诉Kubernetes中间件它负责为反向区域提供PTR请求0.0.3.10.in-addr.arpa ..换句话说,这是允许反向DNS解析服务(我们经常使用到得DNS服务器里面有两个区域,即“正向查找区域”和“反向查找区域”,正向查找区域就是我们通常所说的域名解析,反向查找区域即是这里所说的IP反向解析,它的作用就是通过查询IP地址的PTR记录来得到该IP地址指向的域名,当然,要成功得到域名就必需要有该IP地址的PTR记录。PTR记录是邮件交换记录的一种,邮件交换记录中有A记录和PTR记录,A记录解析名字到地址,而PTR记录解析地址到名字。地址是指一个客户端的IP地址,名字是指一个客户的完全合格域名。通过对PTR记录的查询,达到反查的目的。

    5)proxy:这可以配置多个upstream 域名服务器,也可以用于延迟查找 /etc/resolv.conf 中定义的域名服务器

    6)cache:这允许缓存两个响应结果,一个是肯定结果(即,查询返回一个结果)和否定结果(查询返回“没有这样的域”),具有单独的高速缓存大小和TTLs。

    2、现在安装coredns到kubernetes中

    [root@dev-master CoreDNS]# ./deploy.sh 10.3.0.0/24 cluster.local | kubectl apply -f -
    configmap "coredns" created
    deployment "coredns" created
    service "kube-dns" created
    [root@dev-master CoreDNS]# kubectl get pods --namespace=kube-system
    NAME                                        READY     STATUS    RESTARTS   AGE
    coredns-512496995-c1x9g                     1/1       Running   0          5m
    default-http-backend-905355492-nrt1z        1/1       Running   0          23h
    heapster-2450140206-dw408                   1/1       Running   2          23h
    kube-apiserver-172.16.71.200                1/1       Running   3          7d
    kube-controller-manager-172.16.71.200       1/1       Running   10         8d
    kube-proxy-172.16.71.200                    1/1       Running   49         37d
    kube-scheduler-172.16.71.200                1/1       Running   300        14d
    kubernetes-dashboard-654048359-p73r9        1/1       Running   0          23h
    monitoring-grafana-438219031-32btw          1/1       Running   1          5d
    monitoring-influxdb-3584808869-s6sh1        1/1       Running   2          23h
    nginx-ingress-controller-1644785683-9fxsp   1/1       Running   4          26d
    nginx-ingress-controller-1644785683-mw7nx   1/1       Running   2          23h
    tiller-deploy-411327518-q9zn3               1/1       Running   2          23h
    [root@dev-master CoreDNS]# kubectl logs -f  coredns-512496995-c1x9g --namespace=kube-system
    .:53
    2017/09/13 02:36:31 [INFO] CoreDNS-011
    2017/09/13 02:36:31 [INFO] linux/amd64, go1.9, 1b60688d
    CoreDNS-011
    linux/amd64, go1.9, 1b60688d

    3、修改master节点和所有node节点的/etc/systemd/system/kube-kubelet.service,修改内容如红色所注,与上面的Corefile中的值对应。

    [Unit]
    Description=Kubernetes Kubelet Master
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    
    
    
    
    [Service]
    Environment=KUBELET_IMAGE_TAG=v1.6.2
    ExecStartPre=/usr/bin/mkdir -p /var/log/containers
    ExecStart=/opt/bin/kubelet 
      --api-servers=http://127.0.0.1:8080 
      --register-schedulable=false 
      --cni-conf-dir=/etc/kubernetes/cni/net.d 
      --container-runtime=docker 
      --allow-privileged=true 
      --pod-manifest-path=/etc/kubernetes/manifests 
      --hostname-override=172.16.71.200 
      --pod-infra-container-image=172.16.80.94/mir/pause-amd64:3.0 
      --v=3 
      --cluster-dns=10.3.0.10 
      --cluster-domain=cluster.local. 
      --resolv-conf=/etc/resolv.conf 
    Restart=always
    RestartSec=10
    
    [Install]
    WantedBy=multi-user.target

    4、测试CoreDNS是否起作用

    现在我们来创建一个nginx的pod和service,测试一下coredns是否起作用

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: 172.16.71.199/common/nginx:1.8.1
        ports:
        - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: nginx
    [root@dev-master CoreDNS]# kubectl create -f nginx.yaml 
    pod "nginx" created
    service "nginx" created
    [root@dev-master CoreDNS]# kubectl get pod
    NAME                              READY     STATUS    RESTARTS   AGE
    load-generator-1962471460-6v7lb   1/1       Running   3          22d
    nginx                             1/1       Running   0          1m
    php-apache-1106203038-w51jw       1/1       Running   3          22d

    用curl测试,首先进入这个集群内的另一个pod(这个pod是在修改master节点和node节点的/etc/systemd/system/kube-kubelet.service之后创建的),在pod内部访问刚才创建的

    nginx

    [root@mir2-handler-deployment-3595565332-bqk3t /]# 
    <5332-bqk3t /]# curl nginx.default.svc.cluster.local
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
             35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

    实验证明用:my-svc.my-namespace.svc.cluster.local的方式可以访问服务。

  • 相关阅读:
    Pascal Analyzer 4 代码分析使用简要说明
    界面动态配置:持久化反持久化
    (Sql Server)数据的拆分和合并
    javascript中的promise和deferred:实践(二)
    对面向接口编程、按分层建项目的反思和新的分层结构思路
    revel框架教程之权限控制
    等待与通知机制
    实现代码编辑器
    自定义html标签
    javascript生成自定义的arcgis simpletoolbar
  • 原文地址:https://www.cnblogs.com/boshen-hzb/p/7511432.html
Copyright © 2020-2023  润新知