如何在Google Container Engine [GKE]的所有pod中添加名称服务器?

时间:2016-03-03 21:44:13

标签: kubernetes google-kubernetes-engine

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

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

目前GKE是否有办法做到这一点?

实际上我正在尝试为每个/etc/resolv.conf

添加一个NS

3 个答案:

答案 0 :(得分:3)

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

我们在kubernetes 1.1“解决期”中实现的一个实现是,没有像resolv.conf和resolver行为那样的实际规范。不同的解析器库会做不同的事情,这给我们的用户带来了痛苦。

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

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

这实际上意味着你没有一个很好的钩子来插入你自己的名字服务器。您可以将--cluster-dns标志更改为kubelet,以指向您自己的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连接到VM的控制器并将其写出来,然后检查您的kube-dns容器的正确性。布莱什。

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

答案 1 :(得分:1)

有效否。

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

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

GCE VM使用2个名称服务器和3个搜索来访问节点元数据和项目网络。 GKE使用1个名称服务器和3个搜索。 这样你就可以获得0个名字服务器和0个搜索。

请参阅此问题:https://github.com/kubernetes/kubernetes/issues/9079 这个问题:https://github.com/kubernetes/kubernetes/issues/9132

答案 2 :(得分:1)

我通过在k8s群集中设置dnsmasq服务并将除dnsmasq之外的所有pods名称服务器指向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。 将此添加到您的广告连播

      volumeMounts:
      - mountPath: /etc/resolv.conf
        name: resolv-conf
        subPath: resolv.conf
        readOnly: true
    volumes:
      - name: resolv-conf
        configMap:
          name: resolv-conf
    
  4. 这个解决方案可能会被认为有点难看,但目前还没有其他许多选择。在未来,我希望看到Google Cloud或kube-dns的dns转发功能。

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