Configura una Deployment personalizada de kube-dns

En este documento, se explica cómo personalizar la configuración de DNS en tu clúster estándar de Google Kubernetes Engine (GKE) reemplazando el kube-dns predeterminado administrado por GKE por tu propia implementación. Esto te brinda más control sobre el proveedor de DNS de tu clúster. Por ejemplo, puedes hacer lo siguiente:

  • Ajusta los recursos de CPU y memoria para los componentes de DNS.
  • Usa una versión de imagen kube-dns específica.
  • Implementa un proveedor de DNS alternativo, como CoreDNS, que cumpla con la especificación de DNS de Kubernetes.

Este documento solo se aplica a los clústeres de Standard, ya que Google administra la configuración de DNS en los clústeres de Autopilot. Para comprender mejor los proveedores de DNS en GKE, consulta Acerca del descubrimiento de servicios y kube-dns.

Precaución: Si ejecutas una implementación de DNS personalizada, eres responsable de su mantenimiento continuo. Esto incluye garantizar que las imágenes de contenedor de kube-dns y del escalador automático estén actualizadas con las versiones y los parches de seguridad más recientes. Para encontrar las imágenes recomendadas más recientes, inspecciona la implementación predeterminada de kube-dns en el espacio de nombres kube-system de un clúster de GKE.

Este documento está dirigido a los usuarios de GKE, incluidos los desarrolladores, los administradores y los arquitectos. Para obtener más información sobre los roles comunes y las tareas de ejemplo en Google Cloud, consulta Roles y tareas comunes del usuario de GKE.

En este documento, se supone que estás familiarizado con lo siguiente:

Configura una implementación personalizada de kube-dns

En esta sección, se explica cómo reemplazar el kube-dns administrado por GKE por tu propia implementación.

Crea e implementa el manifiesto personalizado

  1. Guarda el siguiente manifiesto Deployment como custom-kube-dns.yaml. En este manifiesto, se usa kube-dns.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: DNS_DEPLOYMENT_NAME
      namespace: kube-system
      labels:
        k8s-app: kube-dns
      annotations:
        deployment.kubernetes.io/revision: "1"
    spec:
      selector:
        matchLabels:
          k8s-app: kube-dns
      strategy:
        rollingUpdate:
          maxSurge: 10%
          maxUnavailable: 0
        type: RollingUpdate
      template:
        metadata:
          creationTimestamp: null
          labels:
            k8s-app: kube-dns
        spec:
          containers:
          - name: kubedns
            image: registry.k8s.io/dns/k8s-dns-kube-dns:1.22.28
            resources:
              limits:
                memory: '170Mi'
              requests:
                cpu: 100m
                memory: '70Mi'
            livenessProbe:
              httpGet:
                path: /healthcheck/kubedns
                port: 10054
                scheme: HTTP
              initialDelaySeconds: 60
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 5
            readinessProbe:
              httpGet:
                path: /readiness
                port: 8081
                scheme: HTTP
              initialDelaySeconds: 3
              timeoutSeconds: 5
            args:
            - --domain=cluster.local.
            - --dns-port=10053
            - --config-dir=/kube-dns-config
            - --v=2
            env:
            - name: PROMETHEUS_PORT
              value: "10055"
            ports:
            - containerPort: 10053
              name: dns-local
              protocol: UDP
            - containerPort: 10053
              name: dns-tcp-local
              protocol: TCP
            - containerPort: 10055
              name: metrics
              protocol: TCP
            volumeMounts:
            - name: kube-dns-config
              mountPath: /kube-dns-config
            securityContext:
              allowPrivilegeEscalation: false
              readOnlyRootFilesystem: true
              runAsUser: 1001
              runAsGroup: 1001
          - name: dnsmasq
            image: registry.k8s.io/dns/k8s-dns-dnsmasq-nanny:1.22.28
            livenessProbe:
              httpGet:
                path: /healthcheck/dnsmasq
                port: 10054
                scheme: HTTP
              initialDelaySeconds: 60
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 5
            args:
            - -v=2
            - -logtostderr
            - -configDir=/etc/k8s/dns/dnsmasq-nanny
            - -restartDnsmasq=true
            - --
            - -k
            - --cache-size=1000
            - --no-negcache
            - --dns-forward-max=1500
            - --log-facility=-
            - --server=/cluster.local/127.0.0.1#10053
            - --server=/in-addr.arpa/127.0.0.1#10053
            - --server=/ip6.arpa/127.0.0.1#10053
            ports:
            - containerPort: 53
              name: dns
              protocol: UDP
            - containerPort: 53
              name: dns-tcp
              protocol: TCP
            resources:
              requests:
                cpu: 150m
                memory: 20Mi
            volumeMounts:
            - name: kube-dns-config
              mountPath: /etc/k8s/dns/dnsmasq-nanny
            securityContext:
              capabilities:
                drop:
                - all
                add:
                - NET_BIND_SERVICE
                - SETGID
          - name: sidecar
            image: registry.k8s.io/dns/k8s-dns-sidecar:1.22.28
            livenessProbe:
              httpGet:
                path: /metrics
                port: 10054
                scheme: HTTP
              initialDelaySeconds: 60
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 5
            args:
            - --v=2
            - --logtostderr
            - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,SRV
            - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,SRV
            ports:
            - containerPort: 10054
              name: metrics
              protocol: TCP
            resources:
              requests:
                memory: 20Mi
                cpu: 10m
            securityContext:
              allowPrivilegeEscalation: false
              readOnlyRootFilesystem: true
              runAsUser: 1001
              runAsGroup: 1001
          dnsPolicy: Default
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          serviceAccount: kube-dns
          serviceAccountName: kube-dns
          terminationGracePeriodSeconds: 30
          tolerations:
          - key: CriticalAddonsOnly
            operator: Exists
          volumes:
          - configMap:
              defaultMode: 420
              name: kube-dns
              optional: true
            name: kube-dns-config
    

    Reemplaza DNS_DEPLOYMENT_NAME por el nombre de tu implementación de DNS personalizada.

  2. Aplica el manifiesto al clúster:

    kubectl create -f custom-kube-dns.yaml
    

Reducir la escala verticalmente de kube-dns administrado por GKE

Para evitar conflictos, inhabilita las implementaciones kube-dns y kube-dns-autoscaler administradas por GKE reduciendo su escala a cero réplicas:

kubectl scale deployment --replicas=0 kube-dns-autoscaler kube-dns --namespace=kube-system

Configura un escalador automático personalizado

El kube-dns-autoscaler predeterminado solo escala el Deployment de kube-dns administrado por GKE. Si tu proveedor de DNS personalizado requiere ajuste de escala automático, debes implementar un escalador automático independiente y otorgarle permisos para modificar tu implementación de DNS personalizada.

  1. Crea el siguiente manifiesto y guárdalo como custom-dns-autoscaler.yaml.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: custom-dns-autoscaler
      namespace: kube-system
    data:
      linear: |-
        {
          "coresPerReplica": 256,
          "nodesPerReplica": 16,
          "preventSinglePointFailure": true
        }
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: system:custom-dns-autoscaler
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:custom-dns-autoscaler
    subjects:
    - kind: ServiceAccount
      name: kube-dns-autoscaler
      namespace: kube-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: system:custom-dns-autoscaler
    rules:
    - apiGroups:
      - ""
      resources:
      - nodes
      verbs:
      - list
      - watch
    - apiGroups:
      - apps
      resourceNames:
      - DNS_DEPLOYMENT_NAME
      resources:
      - deployments/scale
      verbs:
      - get
      - update
    - apiGroups:
      - ""
      resources:
      - configmaps
      verbs:
      - get
      - create
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: custom-dns-autoscaler
      namespace: kube-system
      labels:
        k8s-app: custom-dns-autoscaler
    spec:
      selector:
        matchLabels:
          k8s-app: custom-dns-autoscaler
      template:
        metadata:
          labels:
            k8s-app: custom-dns-autoscaler
        spec:
          priorityClassName: system-cluster-critical
          securityContext:
            seccompProfile:
              type: RuntimeDefault
            supplementalGroups: [ 65534 ]
            fsGroup: 65534
          nodeSelector:
            kubernetes.io/os: linux
          containers:
          - name: autoscaler
            image: registry.k8s.io/autoscaling/cluster-proportional-autoscaler:1.8.9
            resources:
              requests:
                cpu: "20m"
                memory: "10Mi"
            command:
            - /cluster-proportional-autoscaler
            - --namespace=kube-system
            - --configmap=custom-dns-autoscaler
            - --target=Deployment/DNS_DEPLOYMENT_NAME
            - --default-params={"linear":{"coresPerReplica":256,"nodesPerReplica":16,"preventSinglePointFailure":true}}
            - --logtostderr=true
            - --v=2
          tolerations:
          - key: "CriticalAddonsOnly"
            operator: "Exists"
          serviceAccountName: kube-dns-autoscaler
    

    Reemplaza DNS_DEPLOYMENT_NAME en los campos resourceNames y command por el nombre de tu implementación de DNS personalizada.

  2. Aplica el manifiesto al clúster:

    kubectl create -f custom-dns-autoscaler.yaml
    

Verifica la implementación

Verifica que tus Pods de DNS personalizados se estén ejecutando:

kubectl get pods -n kube-system -l k8s-app=kube-dns

Debido a que ajustaste la escala de la implementación de kube-dns administrada por GKE a cero réplicas, solo los Pods de tu Deployment personalizada aparecen en el resultado. Verifica que su estado sea Running.

Restablece el kube-dns administrado por GKE

Si implementaste una configuración de kube-dns personalizada y necesitas volver a la configuración predeterminada administrada por GKE, debes borrar tus recursos personalizados y volver a habilitar la implementación de kube-dns administrada.

Sigue estos pasos para restablecer el kube-dns administrado por GKE:

  1. Borra la implementación de kube-dns personalizada y su escalador automático. Si guardaste los manifiestos como custom-kube-dns.yaml y custom-dns-autoscaler.yaml, ejecuta los siguientes comandos para borrar los recursos:

    kubectl delete -f custom-dns-autoscaler.yaml
    kubectl delete -f custom-kube-dns.yaml
    

    Si no guardaste los manifiestos, borra de forma manual el Deployment, el ClusterRole y el ClusterRoleBinding que creaste para tu implementación personalizada.

  2. Restablece el kube-dns-autoscaler administrado por GKE. Ejecuta el siguiente comando para volver a escalar la implementación de kube-dns-autoscaler a una réplica:

    kubectl scale deployment --replicas=1 kube-dns-autoscaler --namespace=kube-system
    

    Este comando vuelve a habilitar el kube-dns-autoscaler administrado, que luego ajusta automáticamente el escalado automático de la implementación del kube-dns administrado a la cantidad adecuada de réplicas para el tamaño de tu clúster.

  3. Verifica la restauración.

    Verifica los Pods kube-dns y kube-dns-autoscaler para asegurarte de que se ejecuten correctamente:

    kubectl get pods -n kube-system -l k8s-app=kube-dns
    

    El resultado debería mostrar que los Pods kube-dns administrados por GKE están en el estado Running.

¿Qué sigue?

  • Lee una descripción general de cómo GKE proporciona DNS administrado.
  • Lee la página sobre DNS para servicios y pods a fin de obtener una descripción general de cómo se usa DNS en los clústeres de Kubernetes.