将 NetScaler CPX 部署为 Kubernetes 节点的本地 DNS 缓存

Kubernetes 集群中的应用程序 Pod 依赖 DNS 与其他应用程序 Pod 进行通信。来自 Kubernetes 集群内部应用程序的 DNS 请求由 Kubernetes DNS (kube-dns) 处理。由于微服务架构的广泛采用,Kubernetes 集群内部的 DNS 请求速率正在增加。因此,Kubernetes DNS (kube-dns) 负担过重。现在,您可以将 NetScaler CPX 作为本地 DNS 缓存部署在每个 Kubernetes 节点上,并将节点中应用程序 Pod 的 DNS 请求转发到 NetScaler CPX。因此,您可以更快地解析 DNS 请求,并显著减轻 Kubernetes DNS 的负载。

为了部署 NetScaler CPX,使用 Kubernetes DaemonSet 实体在 Kubernetes 集群的每个节点上调度 NetScaler CPX Pod。Kubernetes DaemonSet 确保集群中每个 Kubernetes 节点上都有一个 NetScaler CPX 实例。 为了使应用程序 Pod 将流量直接发送到 CPX DNS Pod,您需要创建一个 Kubernetes 服务,并将 NetScaler CPX Pod 作为其端点。此服务的集群 IP 将用作应用程序 Pod 的 DNS 端点。为确保应用程序 Pod 使用 NetScaler CPX 服务集群 IP 地址进行 DNS 解析,您需要在每个节点上使用 NetScaler CPX 服务集群 IP 更新 kubelet 配置文件。

引入以下环境变量以支持将 NetScaler CPX 部署为节点本地 DNS 缓存:

  • KUBE_DNS_SVC_IP:指定 kube-dns 服务的集群 IP 地址,这是触发 NetScaler CPX Pod 配置的强制参数。当 NetScaler CPX 缓存中没有 DNS 查询响应时,NetScaler CPX Pod 会将 DNS 查询定向到此 IP 地址。

  • CPX_DNS_SVC_IP:指定 NetScaler CPX 服务的集群 IP 地址。CPX_DNS_SVC_IP 环境变量用于在节点上配置本地 DNS。当您配置此变量时,会添加一个 iptables 规则,将源自应用程序 Pod 的 DNS 请求定向到节点内的本地 NetScaler CPX Pod。

  • NS_DNS_FORCE_TCP:此环境变量强制对 DNS 请求使用 TCP,即使查询是通过 UDP 接收的。

  • NS_DNS_EXT_RESLV_IP:指定外部名称服务器的 IP 地址,用于将特定域的 DNS 请求定向到该服务器。

  • NS_DNS_MATCH_DOMAIN:指定要匹配的外部域字符串,用于将查询定向到外部名称服务器。

将 NetScaler CPX 部署为节点上的 DNS 缓存

将 NetScaler CPX 部署为 Kubernetes 集群的本地 DNS 缓存包括以下任务:

在主节点上:

  • 创建一个以 NetScaler CPX Pod 作为端点的 Kubernetes 服务

  • 创建一个 ConfigMap 以定义 NetScaler CPX Pod 的环境变量

  • 使用 Kubernetes DaemonSet 在 Kubernetes 集群的每个节点上调度 NetScaler CPX Pod。

在工作节点上:

  • 修改 kubelet 配置文件,使用 NetScaler CPX 服务的集群 IP 地址将 DNS 请求转发到 NetScaler CPX。

Kubernetes 主节点上的配置

在 Kubernetes 主节点上执行以下步骤,以将 NetScaler CPX 部署为节点的本地 DNS 缓存:

  1. 使用 cpx_dns_svc.yaml 文件创建一个以 NetScaler CPX Pod 作为端点的服务。

    kubectl apply -f cpx_dns_svc.yaml
    

    cpx_dns_svc.yaml 文件提供如下:

            apiVersion: v1
            kind: Service
            metadata:
              name: cpx-dns-svc
              labels:
                app: cpxd
            spec:
              ports:
              - protocol: UDP
                port: 53
                name: dns
              - protocol: TCP
                port: 53
                name: dns-tcp
              selector:
                app: cpx-daemon
    
  2. 获取 NetScaler CPX 服务的 IP 地址。

    kubectl get svc cpx-dns-svc
    
  3. 获取 Kube DNS 服务的 IP 地址。

    kubectl get svc -n kube-system
    
  4. 创建一个 ConfigMap,用于定义 NetScaler CPX Pod 的环境变量。这些环境变量用于传递 NetScaler CPX 服务和 Kube DNS 服务的 IP 地址。在此步骤中,使用文件中指定为数据(键值对)的环境变量创建了一个示例 ConfigMap cpx-dns-cache

    kubectl create configmap cpx-dns-cache --from-file <path-to-file>
    

    以下是一个包含作为键值对的环境变量的示例文件。

      CPX_DNS_SVC_IP: 10.111.95.145
      EULA: "yes"
      KUBE_DNS_SVC_IP: 10.96.0.10
      NS_CPX_LITE: "1"
      NS_DNS_EXT_RESLV_IP: 10.102.217.142
      NS_DNS_MATCH_DOMAIN: citrix.com
      PLATFORM: CP1000
    

    以下是一个示例 ConfigMap:

    apiVersion: v1
    data:
      CPX_DNS_SVC_IP: 10.111.95.145
      EULA: "yes"
      KUBE_DNS_SVC_IP: 10.96.0.10
      NS_CPX_LITE: "1"
      NS_DNS_EXT_RESLV_IP: 10.102.217.142
      NS_DNS_MATCH_DOMAIN: citrix.com
      PLATFORM: CP1000
    kind: ConfigMap
    metadata:
      creationTimestamp: "2019-10-15T07:45:54Z"
      name: cpx-dns-cache
      namespace: default
      resourceVersion: "8026537"
      selfLink: /api/v1/namespaces/default/configmaps/cpx-dns-cache
      uid: 8d06f6ee-133b-4e1a-913c-9963cbf4f48
    
  5. 在主节点上为 NetScaler CPX 创建一个 Kubernetes DaemonSet。

    kubectl apply -f cpx_daemonset.yaml
    

    cpx_daemonset.yaml 文件提供如下:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: cpx-daemon
      labels:
            app: cpxd
    spec:
       selector:
            matchLabels:
              app: cpx-daemon
    template:
       metadata:
            labels:
              app: cpx-daemon
       spec:
           containers:
           - name: cpxd
            imagePullPolicy: IfNotPresent
            image: localhost:5000/dev/cpx
            volumeMounts:
             - mountPath: /netns/default/
            name: test-vol
            ports:
            - containerPort: 53
       envFrom:
           - configMapRef:
           name: cpx-dns-cache
       securityContext:
       privileged: true
       allowPrivilegeEscalation: true
       capabilities:
        add: ["NET_ADMIN"]
       volumes:
          -  name: test-vol
          hostPath:
          path: /proc/1/ns
          type: Directory
    

Kubernetes 集群中工作节点上的配置

在主节点上完成配置后,在工作节点上执行以下步骤:

  1. 修改 kubelet 配置文件,以便应用程序 Pod 可以使用 NetScaler CPX 服务集群 IP 进行 DNS 解析,方法如下:

    • 按照 重新配置节点的 kubelet 中的步骤,并按以下格式修改 --cluster-dns 参数值。

           --cluster-dns=<CPX_DNS_SVC_IP>,<KUBE_DNS_SVC_IP>
      

    • 编辑 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 文件,并按照以下步骤修改 --cluster-dns 参数。

      1. 编辑 kubelet 配置,并为 --cluster-dns 参数指定 NetScaler CPX 服务的集群 IP 地址和 kube-dns 服务 IP 地址。

         root@node:~# cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf | grep KUBELET\_DNS\_ARGS
        
         Environment="KUBELET_DNS_ARGS=--cluster-dns=10.111.95.145,10.96.0.10 --cluster-domain=cluster.local"
         ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_DNS_ARGS
        
      2. 使用以下命令重新加载节点的 kubelet:

         # systemctl daemon-reload
         # service kubelet restart
        
将 NetScaler CPX 部署为 Kubernetes 节点的本地 DNS 缓存