【问题标题】:kubernetes dns search domain appended in some queries某些查询中附加了 kubernetes dns 搜索域
【发布时间】:2019-06-24 13:23:24
【问题描述】:

我正在运行一个包含一个主节点和 2 个工作节点的 kubernetes 集群。

root@kube-master:~# kubectl get nodes
NAME           STATUS   ROLES    AGE     VERSION
kube-master    Ready    master   4d19h   v1.14.3
kube-node-01   Ready    <none>   4d18h   v1.14.3
kube-node-02   Ready    <none>   6h3m    v1.14.3

现在我的 traefik 入口控制器无法解析 dns 查询。

/ # nslookup acme-v02.api.letsencrypt.org
nslookup: can't resolve '(null)': Name does not resolve

Name:      acme-v02.api.letsencrypt.org
Address 1: <my.public.ip> mail.xxx.xxx

现在在我的 opnsense 框上使用 tcpdump,我收到查询,其中我的内部搜索域附加解析到我的公共 ip,这是错误的。

但由于某种原因......启动一个busybox测试吊舱正在工作......

/ # nslookup acme-v02.api.letsencrypt.org
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      acme-v02.api.letsencrypt.org
Address 1: 2a02:26f0:ef:197::3a8e g2a02-26f0-00ef-0197-0000-0000-0000-3a8e.deploy.static.akamaitechnologies.com
Address 2: 2a02:26f0:ef:181::3a8e g2a02-26f0-00ef-0181-0000-0000-0000-3a8e.deploy.static.akamaitechnologies.com
Address 3: 104.74.120.43 a104-74-120-43.deploy.static.akamaitechnologies.com

两个 /etc/resolve.conf 文件都是相同的,除了 namespace

自从 kubernetes 1.11 coredns 是默认的 dns 解析系统。在this 使用 coredns 调试 dns 系统的页面上说我应该使用

root@kube-master:~# kubectl get pods --namespace=kube-system -l k8s-app=coredns
No resources found.

但这不会返回任何东西!使用 kube-dns 返回 coredns pod!

root@kube-master:~# kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
NAME                      READY   STATUS    RESTARTS   AGE
coredns-fb8b8dccf-jmhdm   1/1     Running   5          4d19h
coredns-fb8b8dccf-tfw7v   1/1     Running   5          4d19h

这是怎么回事?!文档有误还是我的集群内部有问题?

【问题讨论】:

    标签: kubernetes coredns


    【解决方案1】:

    默认的 ndots:n 是 5。这意味着如果名称中包含的点少于 5 个,系统调用将尝试依次通过所有本地搜索域来解析它,并且 - 如果没有成功 - 将解析它最后只作为绝对名称。

    【讨论】:

    • 当与包含通配符条目的搜索域结合使用时,这也是一个问题 - 所有外部请求都会得到通配符答案
    【解决方案2】:

    我将使用 nginx 入口控制器示例向您展示和解释。我相信 traefik 入口控制器的情况是一样的。

    首先 - 关于kube-dnscoredns 你所描述的混乱: 这是通过设计实现的。你可以参考github coredns is still labeled as kube-dns issue阅读更多内容。

    在我的集群中,我还有一个名为 kube-dnscoredns 服务,它指的是具有 k8s-app=kube-dns 标签的 coredns pod

    kubectl describe service kube-dns -n kube-system
    Name:              kube-dns
    Namespace:         kube-system
    Labels:            k8s-app=kube-dns
                       kubernetes.io/cluster-service=true
                       kubernetes.io/name=KubeDNS
    Annotations:       prometheus.io/port: 9153
                       prometheus.io/scrape: true
    Selector:          k8s-app=kube-dns
    Type:              ClusterIP
    IP:                10.96.0.10
    Port:              dns  53/UDP
    TargetPort:        53/UDP
    Endpoints:         10.32.0.2:53,10.32.0.9:53
    Port:              dns-tcp  53/TCP
    TargetPort:        53/TCP
    Endpoints:         10.32.0.2:53,10.32.0.9:53
    Port:              metrics  9153/TCP
    TargetPort:        9153/TCP
    Endpoints:         10.32.0.2:9153,10.32.0.9:9153
    Session Affinity:  None
    Events:            <none>
    
    kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
    NAME                      READY   STATUS    RESTARTS   AGE     IP          NODE                     NOMINATED NODE   READINESS GATES
    coredns-fb8b8dccf-42285   1/1     Running   0          3h26m   10.32.0.9   kubernetessandbox-1-vm   <none>           <none>
    coredns-fb8b8dccf-87j5v   1/1     Running   0          3h26m   10.32.0.2   kubernetessandbox-1-vm   <none>           <none>
    

    当我启动新的busybox pod时-它有/etc/resolv.conf指向服务kube-dns(10.96.0.10)并且有正确的搜索:

    cat /etc/resolv.conf
    search kube-system.svc.cluster.local svc.cluster.local cluster.local c.myproj.internal. google.internal.
    nameserver 10.96.0.10
    options ndots:5
    

    但同时我的 nginx 入口控制器 pod 有 nameserver 169.254.169.254 并且也无法 nslookup 甚至 kubernetes.default

    cat /etc/resolv.conf
    search c.myproj.internal. google.internal.
    nameserver 169.254.169.254
    

    不确定您在 traefic pod 上的 /etc/resolv.conf 中有什么,但问题就在那里。而您拥有的 /etc/resolv.conf 来自您的节点

    设置 dnsPolicy: ClusterFirstWithHostNet 而不是 dnsPolicy: 如果 ingress 使用 hostNetwork,ClusterFirst 应该可以解决这个问题。

    来自dns-pod-service documentation

    “ClusterFirstWithHostNet”:对于使用 hostNetwork 运行的 Pod,您 应明确设置其 DNS 策略“ClusterFirstWithHostNet”。

    编辑 nginx-ingress-controller 部署后
      dnsPolicy: ClusterFirst
      hostNetwork: true
    

      dnsPolicy: ClusterFirstWithHostNet
      hostNetwork: true
    

    pod 已使用所需的 /etc/resolv.conf 重新创建:

    cat /etc/resolv.conf
    search kube-system.svc.cluster.local svc.cluster.local cluster.local c.myproj.internal. google.internal.
    nameserver 10.96.0.10
    options ndots:5
    
    nslookup kubernetes.default
    Server:         10.96.0.10
    Address:        10.96.0.10#53
    
    Name:   kubernetes.default.svc.cluster.local
    Address: 10.96.0.1
    

    为您提供一些与 hostNetwork/dnsPolicy 相关的问题和解释的网址。这是正确配置 Traefik 的重要部分:

    1) Traefik on k8s not listening externally without changing deployment

    2)Stack traefik question

    3)Ingress with Traefik文章:

    dnsPolicy: ClusterFirstWithHostNet
    

    此设置很重要。它将配置 Traefik pod 以使用 Kubernetes 集群内部 DNS 服务器(很可能是 KubeDNS 或 也许是 CoreDNS)。这意味着 pod /etc/resolv.conf 将是 配置为使用 Kubernetes DNS 服务器。否则 DNS 服务器 将使用 Kubernetes 节点的 (基本上 /etc/resolv.conf 的 工作节点,但无法解析 cluster.local DNS,例如)。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-15
      • 2013-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多