3

我尝试构建一个运行需要的服务的 Pod:

  1. 由其 FQDN ( *.cluster.local) 解析和访问的集群内部服务,
  2. 同时还具有与远程集群的活动 OpenVPN 连接,并且来自该远程集群的服务将由其 FQDN ( *.cluster.remote) 解析和访问。

Pod 中没有 OpenVPN sidecar 的服务容器可以访问所有使用*.cluster.local命名空间提供 FQDN 的服务。这是/etc/resolv.conf在这种情况下:

nameserver 169.254.25.10
search default.cluster.local svc.cluster.local cluster.local
options ndots:5

当 OpenVPN sidecar 管理时resolv.conf

OpenVPN sidecar 的启动方式如下:

      containers:
        {{- if .Values.vpn.enabled }}
        - name: vpn
          image: "ghcr.io/wfg/openvpn-client"
          imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
          volumeMounts:
            - name: vpn-working-directory
              mountPath: /data/vpn
          env:
            - name: KILL_SWITCH
              value: "off"
            - name: VPN_CONFIG_FILE
              value: connection.conf
          securityContext:
            privileged: true
            capabilities:
              add:
                - "NET_ADMIN"
          resources:
            limits:
              cpu: 100m
              memory: 80Mi
            requests:
              cpu: 25m
              memory: 20Mi
        {{- end }}

OpenVPN 客户端配置包含以下几行:

        script-security 2
        up /etc/openvpn/up.sh
        down /etc/openvpn/down.sh

然后 OpenVPN 客户端将覆盖resolv.conf,使其包含以下内容:

nameserver 192.168.255.1
options ndots:5

在这种情况下,*.cluster.remote解析中的任何服务,但没有来自 的服务*.cluster.local。这是意料之中的。

当 OpenVPN sidecar 不管理resolv.conf,但spec.dnsConfig提供时

从 OpenVPN 客户端配置中删除以下行:

        script-security 2
        up /etc/openvpn/up.sh
        down /etc/openvpn/down.sh

提供spec.dnsConfig如下:


      dnsConfig:
        nameservers:
          - 192.168.255.1
        searches:
          - cluster.remote

然后,resolv.conf将是以下内容:

nameserver 192.168.255.1
nameserver 169.254.25.10
search default.cluster.local svc.cluster.local cluster.local  cluster.remote
options ndots:5

这适用于*.cluster.remote,但不适用于任何东西*.cluster.local,因为只要第一个超时,就会尝试第二个名称服务器。我注意到有些人会通过设置命名空间轮换和超时 1 秒来绕过这个限制,但是这种行为对我来说看起来很忙,我不会考虑这个,甚至不是一种解决方法。或者,也许我错过了一些东西。我的第一个问题是:在这种情况下轮换和超时可以工作吗?

我的第二个问题是:有什么方法可以使*.cluster.local*.cluster.remoteDNS 解析从 Pod 内的服务容器可靠地工作,无需使用类似的东西dnsmasq

我的第三个问题是:如果dnsmasq需要,我如何配置、提供和覆盖它,resolv.conf同时确保 Kubernetes 提供的名称服务器可以是任何东西(169.254.25.10在这种情况下)。

最好的,佐尔坦

4

2 回答 2

2

我宁愿通过运行一个边车 DNS 服务器来解决这个问题,因为:

  • 更易于实施、维护和理解;
  • 它毫无意外地工作。

这是一个示例 pod CoreDNS

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: default
spec:
  volumes:
  - name: config-volume
    configMap:
      name: foo-config
      items:
        - key: Corefile
          path: Corefile
  dnsPolicy: None # SIgnals Kubernetes that you want to supply your own DNS - otherwise `/etc/resolv.conf` will be overwritten by Kubernetes and there is then no way to update it.
  dnsConfig:
    nameservers:
      - 127.0.0.1 # This will set the local Core DNS as the DNS resolver. When `dnsPolicy` is set, `dnsConfig` must be provided.
  containers:
    - name: dns
      image: coredns/coredns
      env:
        - name: LOCAL_DNS
          value: 10.233.0.3 # insert local DNS IP address (see kube-dns service ClusterIp)
        - name: REMOTE_DNS
          value: 192.168.255.1 # insert remote DNS IP address
      args:
        - '-conf'
        - /etc/coredns/Corefile
      volumeMounts:
        - name: config-volume
          readOnly: true
          mountPath: /etc/coredns
    - name: test
      image: debian:buster
      command:
        - bash
        - -c
        - apt update && apt install -y dnsutils && cat /dev/stdout
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: foo-config
  namespace: default
data:
  Corefile: |
    cluster.local:53 {
      errors
      health
      forward . {$LOCAL_DNS}
      cache 30
    }
    cluster.remote:53 {
      errors
      health
      rewrite stop {
        # rewrite cluster.remote to cluster.local and back
        name suffix cluster.remote cluster.local answer auto
      }
      forward . {$REMOTE_DNS}
      cache 30
    }

上面的CoreDNS配置只是将cluster.local查询转发到本地服务和cluster.remote- 到远程服务。使用它,我能够解析kubernetes两个集群的服务 IP:

❯ k exec -it -n default foo -c test -- bash
root@foo:/# dig @localhost kubernetes.default.svc.cluster.local +short
10.100.0.1
root@foo:/# dig @localhost kubernetes.default.svc.cluster.remote +short
10.43.0.1

更新:

如果您需要访问互联网以及cluster.internal由 Kubernetes 本身提供,以下核心 DNS 配置可能就足够了:

.:53 {
  errors
  health
  forward . {$LOCAL_DNS}
  cache 30
}
cluster.remote:53 {
  errors
  health
  forward . {$REMOTE_DNS}
  cache 30
}
于 2021-08-16T13:00:04.733 回答
-1

广告 1.) 我不确定我理解命名空间轮换的含义(您是指轮询域轮换吗?),但您可以将超时设置为 0,因此解析器会立即将 dns 查询发送到名称服务器和返回更快的 dns 响应。

更好的想法是利用原生 kubernetes dns(coredns,kubedns)并在那里设置转发规则,根据文档,您可以在 kube-system 中的 coredns/kube-dns configmap 中添加类似这样的内容:

cluster.remote:53 {
        errors
        cache 30
        forward . <remote cluster dns ip>
    }

这样你根本不需要接触/etc/resolve.confpod,你只需要确保 kubedns 可以访问远程 dns 服务器......或者配置你的应用程序以进行迭代 dns 解析你可以在官方 kubernetes 文档中找到更多详细信息https: //kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/和 coredns https://coredns.io/plugins/forward/。当然,修改 kubedns/coredns 配置需要您在集群中拥有管理员权限。

于 2021-08-12T20:13:30.440 回答