向Kubernetes添加名称服务器

6

我在AWS上使用部署了kube-up.sh的Kubernetes v1.0.6版本。
集群正在使用kube-dns

$ kubectl get svc kube-dns --namespace=kube-system
NAME       LABELS                                                                           SELECTOR           IP(S)       PORT(S)
kube-dns   k8s-app=kube-dns,kubernetes.io/cluster-service=true,kubernetes.io/name=KubeDNS   k8s-app=kube-dns   10.0.0.10   53/UDP

这很好用。

$ kubectl exec busybox -- nslookup kubernetes.default
Server:    10.0.0.10
Address 1: 10.0.0.10 ip-10-0-0-10.eu-west-1.compute.internal

Name:      kubernetes.default
Address 1: 10.0.0.1 ip-10-0-0-1.eu-west-1.compute.internal

这是一个 pod 的 resolv.conf
$ kubectl exec busybox -- cat /etc/resolv.conf
nameserver 10.0.0.10
nameserver 172.20.0.2
search default.svc.cluster.local svc.cluster.local cluster.local eu-west-1.compute.internal

是否可以让容器使用额外的命名服务器?

我有一个基于辅助DNS的服务发现(比如说192.168.0.1),我希望我的Kubernetes容器能够使用它来进行DNS解析。

备注:对于Kubernetes 1.1版本的解决方案也可以接受。

非常感谢您的提前帮助,George


一种安全的方法可能是在skydns的配置中添加名称服务器,但不确定在通过kube-up/push自动化集群创建/升级时如何完成此操作。 - George Antoniadis
5个回答

2

DNS插件自述文件中有一些详细信息。基本上,Pod将继承它所运行的节点的resolv.conf设置,因此您可以将额外的DNS服务器添加到节点的/etc/resolv.conf中。另外,kubelet还接受一个--resolv-conf参数,可能为您注入额外的DNS服务器提供了更明确的方法。然而,我还没有在任何地方看到该标志的文档。


有没有一种方法可以自动化这些过程,或者将它们作为kube-up/kube-push的一部分,以便将来对它们的更新不会破坏一切? - George Antoniadis
此外,将额外的名称服务器添加到/etc/resolvconf/resolv.conf.d/base中确实会使它们出现在容器的/etc/resolv.conf文件中,但由于kube注入的前两个名称服务器正在运行,新的名称服务器将永远不会被查询。 - George Antoniadis
我不再使用kube-up.sh进程,所以请对我的话持保留态度(是的,我刚刚开了个玩笑)。但我认为要自动化这个过程,你可能需要维护一个修改过的Salt模板版本,位于cluster/saltbase/salt/kubelet/default,该模板设置master_kubelet_args的期望选项。长期来看可能不是理想的解决方案,但在你确定它是否可行时可能会有所帮助。 - rwehner

1

对于使用 Kubernetes 的用户,标志 -nameservers 和环境变量 SKYDNS_NAMESERVERS 在使用 kube-dns 时不再可用。

Usage of /kube-dns:
  --alsologtostderr                  log to standard error as well as files
  --config-map string                config-map name. If empty, then the config-map will not used. Cannot be  used in conjunction with federations flag. config-map contains dynamically adjustable configuration.
  --config-map-namespace string      namespace for the config-map (default "kube-system")
  --dns-bind-address string          address on which to serve DNS requests. (default "0.0.0.0")
  --dns-port int                     port on which to serve DNS requests. (default 53)
  --domain string                    domain under which to create names (default "cluster.local.")
  --healthz-port int                 port on which to serve a kube-dns HTTP readiness probe. (default 8081)
  --kube-master-url string           URL to reach kubernetes master. Env variables in this flag will be expanded.
  --kubecfg-file string              Location of kubecfg file for access to kubernetes master service; --kube-master-url overrides the URL part of this; if neither this nor --kube-master-url are provided, defaults to service account tokens
  --log-backtrace-at traceLocation   when logging hits line file:N, emit a stack trace (default :0)
  --log-dir string                   If non-empty, write log files in this directory
  --log-flush-frequency duration     Maximum number of seconds between log flushes (default 5s)
  --logtostderr                      log to standard error instead of files (default true)
  --stderrthreshold severity         logs at or above this threshold go to stderr (default 2)
  -v, --v Level                      log level for V logs
  --version version[=true]           Print version information and quit
  --vmodule moduleSpec               comma-separated list of pattern=N settings for file-filtered logging

现在,您可以将名称服务器放在主机的resolv.conf上,以便从节点继承DNS,或者使用自定义resolv.conf并使用标志--resolv-conf将其添加到Kubelet中,如此处所述。

1
你需要知道你的Core DNS的IP地址,以将其设置为次要DNS。
运行以下命令以获取CoreDNS IP:
kubectl -n kube-system get svc
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
kube-dns         ClusterIP   172.20.0.10      <none>        53/UDP,53/TCP   43d
metrics-server   ClusterIP   172.20.232.147   <none>        443/TCP         43d

这是我在我的部署yaml中设置DNS的方式。

我发布了Google DNS IP(为了清晰起见)和我的CoreDNS IP,但你应该使用你的VPC DNS和你的CoreDNS服务器。

      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 8080
      dnsPolicy: None
      dnsConfig:
        nameservers:
          - 8.8.8.8
          - 172.20.0.10
        searches:
          - 1b.svc.cluster.local
          - svc.cluster.local
          - cluster.local
          - ec2.internal
        options:
          - name: ndots
            value: "5"

1
在Kubernetes(可能)1.2中,我们将采用一种假设nameservers是可互换的模型。有太多的解析器在不同的nameservers为DNS的不同子集提供服务时会出现问题,并且在这里没有真正的规范可以指向。
换句话说,我们将开始从容器合并的resolv.conf中删除主机的nameserver记录,并使我们自己的DNS服务器成为唯一的nameserver行。我们的DNS将能够将请求转发到上游nameservers。

true,但你可以让两个服务器拥有相同的数据...我现在使用10.3.0.10和10.3.0.11上的两个服务运行kube-dns。每个服务都有一个或多个pod副本,这并不重要。这解决了我们的dns问题,因为当pod被重新定位时,一些请求在转换期间会失败,但是客户端pod的操作系统会尝试另一个服务器,应用程序不会看到故障。我们遇到的问题是让kubelet将这两个名称服务器提供给pod。我考虑过提供整个resolv.conf文件,但那样我们会错过依赖于命名空间的搜索字段。 - caiman
问题,我可以创建一个自定义的resolv.conf文件,并使用8.8.8.8和我的kube dns服务IP吗? - Jonathan
目前没有一种方法可以手动为Pod配置resolv.conf。@caiman - 我很好奇为什么具有不同IP的多个服务与多个副本不同?这是否仅仅是因为某些解析器会并行尝试它们?我非常关注我们可以做些什么来使DNS更具弹性和可靠性。 - Tim Hockin
嗨,Tim,由于某些原因,在VMWare Ubuntu映像中似乎无法正常工作。 VMWare决定通过某种虚拟设置提供dns(老实说我不知道他们在做什么),但是kubernetes无法识别它。在这种奇怪的设置中能够添加另一个名称服务器也将是很好的选择。 - erikbstack
@TimHockin 我刚才说的话我收回了。这篇博客文章实际上解决了所有可能出现的问题。真的非常感谢。唯一剩下的问题是很难找到这样的工程和文档宝藏。 ;) - erikbstack
显示剩余4条评论

1
我最终通过配置SkyDNS添加一个额外的名称服务器来轻松解决了这个问题,您可以在SkyDNS复制控制器中添加环境变量SKYDNS_NAMESERVERS,如SkyDNS文档所定义。它对节点更改等没有影响。
    env:
    - name: SKYDNS_NAMESERVERS
      value: 10.0.0.254:53,10.0.64.254:53

嘿,有没有一种方法可以在不必自己定义整个kube-dns复制控制器的情况下添加/设置/修改此环境变量? - Tony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接