【问题标题】:How do I add a nameserver to all pods in Google Container Engine [GKE]?如何将名称服务器添加到 Google Container Engine [GKE] 中的所有 pod?
【发布时间】:2016-06-17 10:57:28
【问题描述】:

我正在尝试将我的本地集群迁移到 GKE。为了促进这种转变,我需要能够解析遗留服务的名称。

假设网络/VPN 是一个已解决的问题。

目前有没有办法用 GKE 做到这一点?

实际上我正在尝试向每个 /etc/resolv.conf 添加一个 NS

【问题讨论】:

    标签: kubernetes google-kubernetes-engine


    【解决方案1】:

    实际上没有。

    如果您修改节点的 resolv.conf,pod 将继承更改。

    但是,glibc 禁止使用超过 3 个名称服务器或超过 6 个搜索记录。

    GCE 虚拟机使用 2 个名称服务器和 3 个搜索来访问节点元数据和项目网络。 GKE 使用 1 个名称服务器和 3 个搜索。 剩下 0 个域名服务器和 0 个搜索。

    看到这个问题:https://github.com/kubernetes/kubernetes/issues/9079 还有这个问题:https://github.com/kubernetes/kubernetes/issues/9132

    【讨论】:

    • 但是,也许您可​​以将所有旧服务 DNS 记录复制到 Google Cloud DNS 中。 (cloud.google.com/dns/what-is-cloud-dns)。这将使它们在您的所有 GCP 项目实例和所有 GKE 容器中都可以解析。
    • 是的,但是如果 OP 使用内部 dns 而不是公共 dns 记录会怎样
    【解决方案2】:

    我想补充 Eric 所说的内容,并稍微改变一下。

    我们在 kubernetes 1.1“稳定期”中的一个认识是,对于 resolv.conf 和解析器的行为,并没有真正的规范。不同的解析器库做不同的事情,这给我们的用户带来了痛苦。

    具体来说,一些常见的解析器假定所有 nameservers 都是可替代的,如果您拥有处理 DNS 命名空间不同部分的名称服务器,它们就会中断。我们决定,对于 kube 1.2,我们不会将多个 nameserver 行传递到容器中。相反,我们只传递 kube-dns 服务器,它处理 cluster.local 查询并将任何其他查询转发到“上游”名称服务器。

    我们如何知道“上游”是什么?我们使用节点的nameservers。有一个 per-pod dnsPolicy 字段来管理此选择。最终结果是容器在我们拥有的 resolv.conf 中看到一个 nameserver,并且该名称服务器处理整个 DNS 命名空间。

    这实际上意味着你没有一个很好的钩子来插入你自己的名称服务器。您可以将 --cluster-dns 标志更改为 kubelets 以指向您自己的 DNS 服务器,然后转发到 kube-dns,然后转发到“上游”。问题是 GKE 并不真正支持以这种方式更改标志。如果/当节点更新时,该标志将消失以支持默认值。

    可能的解决方案:

    • 让 kubelet 从集群内配置中读取其标志。这已经是记录计划,但不在 v1.2 中

    • 让 kube-dns 使用一个标志来指示“上游”是什么。 Kube-dns 是一个“集群插件”,因此最终用户并不是真正可变的(我们将使用您的集群对其进行更新并丢失您的更改)。

    • 让 kube-dns 从集群内配置中读取其标志,并获取一个指示“上游”是什么的标志。这是一个可行的想法,但可能不适用于 v1.2(为时已晚)。 可能可以将其修补到 v1.2.x 中,但这并不是真正的错误修复,而是一项功能。

    • 将您自己的 DNS 服务器放入每个节点的 resolv.conf 中,以便 kube-dns 将您用作上游。我不认为 GKE 有办法配置它也不会在节点升级时丢失。您可以编写一个控制器,定期通过 SSH 连接到虚拟机并将其写出来,然后检查您的 kube-dns 容器的正确性。布莱赫。

    我认为正确的答案是使用集群内配置映射来通知 kubelet 或 DNS(或两者)。如果您认为这些可能是可行的答案(尽管存在时间框架问题),那么如果您打开一个 GitHub 问题进行讨论,那就太好了。它会在那里获得更多的知名度。

    【讨论】:

      【解决方案3】:

      我通过在 k8s 集群中设置 dnsmasq 服务并将除 dnsmasq 之外的所有 pod 名称服务器指向 dnsmasq 服务来解决此问题。
      dnsmasq 将根据域后缀将请求转发到正确的名称服务器。 所以内部和外部 vpn 查找都可以工作。

      1. 设置 dnsmasq 服务。
        pod 可能看起来像这样,确保它至少有 2 个 pod,因为它需要是 HA。

        apiVersion: v1
        kind: Pod
        metadata:
          name: dnsmasq
        spec:
          containers:
          - name: dnsmasq
            image: "andyshinn/dnsmasq:2.76"
            ports:
            - containerPort: 53
              hostPort: 53
              protocol: UDP
            - containerPort: 53
              hostPort: 53
              protocol: TCP
            args: [
              "-S", "/consul/10.3.20.86",
              "-S", "/consul/10.3.20.88",
              "-S", "/consul/10.3.20.90",
              "-S", "/your-vpn-domain.dom/10.3.128.22",
              "-S", "/your-vpn-domain.dom/10.3.128.23"
            ]
            securityContext:
              capabilities:
                add:
                - NET_ADMIN
        
      2. 添加一个 resolv-conf 配置映射。

        #!/bin/bash
        
        DNS_IP=$(kubectl get svc --template '{{.spec.clusterIP}}' dnsmasq)
        DNS_POD=$(kubectl get pod -n kube-system | grep -v kube-dns-autoscaler | grep ^kube-dns  | head -1 | awk '{ print $1; }')
        DOMAIN=$(kubectl describe -n kube-system pod/${DNS_POD} | grep -- --domain= | sed -Ee 's/.*--domain=(.*)\..*/\1/')
        SEARCH=$(kubectl exec -n kube-system  ${DNS_POD} -c kubedns -- cat /etc/resolv.conf | grep ^search | cut -d' '  -f2-)
        VPN_SEARCH="your-vpn-domain.dom"
        
        kubectl create -f - <<EOF
        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: resolv-conf
        data:
          resolv.conf: |
            # This file is created by resolv-conf config map and points to the dnsmasq service.
            search default.svc.${DOMAIN} svc.${DOMAIN} ${DOMAIN} ${SEARCH} ${VPN_SEARCH}
            nameserver ${DNS_IP}
            ndots:5
        EOF
        
      3. 在您的服务/pod 中安装 cfgmap。 将此添加到您的 pod 中

          volumeMounts:
          - mountPath: /etc/resolv.conf
            name: resolv-conf
            subPath: resolv.conf
            readOnly: true
        volumes:
          - name: resolv-conf
            configMap:
              name: resolv-conf
        

      这个解决方案可能会被认为有点丑陋,但目前没有很多其他选择。将来我希望看到向 Google Cloud 或 kube-dns 提供 dns 转发功能。

      Google Cloud 不为指定的域/区域提供 DNS 转发功能,这有点疯狂。

      【讨论】:

      • 这对blog.kubernetes.io/2017/04/…有帮助吗?
      • 看起来和我需要的 OP 完全一样。我将在 GKE 上对其进行测试并在之后报告。
      • 感谢 Raboo 的简洁解决方案。我喜欢它非常适合我的 kubernetes 工作流程,并且不需要在我的节点上进行配置管理。感谢 GoatWalker 的链接。我很高兴它现在已经出炉了。
      猜你喜欢
      • 2016-01-18
      • 2020-02-29
      • 1970-01-01
      • 2018-12-25
      • 1970-01-01
      • 2015-10-19
      • 2018-09-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多