Configurar un despliegue personalizado de kube-dns

En este documento se explica cómo personalizar la configuración de DNS en un clúster Estándar de Google Kubernetes Engine (GKE) sustituyendo el kube-dns predeterminado gestionado por GKE por tu propia implementación. De esta forma, tendrás más control sobre el proveedor de DNS de tu clúster. Por ejemplo, puedes:

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

Este documento solo se aplica a los clústeres estándar. Google gestiona la configuración de DNS en los clústeres de Autopilot. Para obtener más información sobre los proveedores de DNS en GKE, consulta los artículos 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 asegurarse de que las imágenes de contenedor de kube-dns y del escalador automático estén actualizadas con las últimas versiones y parches de seguridad. Para encontrar las imágenes recomendadas más recientes, inspecciona la implementación kube-dns predeterminada en el espacio de nombres kube-system de un clúster de GKE.

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

En este documento se da por hecho que conoces los siguientes conceptos:

Configurar un despliegue personalizado de kube-dns

En esta sección se explica cómo sustituir el kube-dns gestionado por GKE por tu propia implementación.

Crear y desplegar el manifiesto personalizado

  1. Guarda el siguiente manifiesto Deployment como custom-kube-dns.yaml. Este manifiesto 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
    

    Sustituye DNS_DEPLOYMENT_NAME por el nombre de tu implementación de DNS personalizado.

  2. Aplica el manifiesto al clúster:

    kubectl create -f custom-kube-dns.yaml
    

Reducir el tamaño del kube-dns gestionado por GKE

Para evitar conflictos, inhabilita las implementaciones kube-dns y kube-dns-autoscaler gestionadas por GKE reduciendo su número de réplicas a cero:

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

Configurar un escalador automático personalizado

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

  1. Crea el siguiente archivo de 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
    

    Sustituye DNS_DEPLOYMENT_NAME en el campo resourceNames y en el campo 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
    

Verificar 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

Como has escalado a cero réplicas la implementación gestionada por GKE kube-dns, en el resultado solo aparecen los pods de tu implementación personalizada. Verifica que su estado sea Running.

Restaurar kube-dns gestionado por GKE

Si has implementado una configuración kube-dns personalizada y necesitas volver a la configuración predeterminada gestionada por GKE, debes eliminar tus recursos personalizados y volver a habilitar la implementación gestionada kube-dns.

Sigue estos pasos para restaurar el kube-dns gestionado por GKE:

  1. Elimina la implementación kube-dns personalizada y su herramienta de escalado automático. Si has guardado los manifiestos como custom-kube-dns.yaml y custom-dns-autoscaler.yaml, ejecuta los siguientes comandos para eliminar los recursos:

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

    Si no has guardado los manifiestos, elimina manualmente los objetos Deployment, ClusterRole y ClusterRoleBinding que hayas creado para tu implementación personalizada.

  2. Restaura el kube-dns-autoscaler gestionado por GKE. Ejecuta el siguiente comando para reducir el escalado de 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 gestionado, que, a continuación, ajusta automáticamente la escala de la implementación del kube-dns gestionado al número adecuado de réplicas para el tamaño de tu clúster.

  3. Verifica la restauración.

    Comprueba los pods kube-dns y kube-dns-autoscaler para asegurarte de que se ejecutan correctamente:

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

    En la salida se debe mostrar que los pods kube-dns gestionados por GKE están en el estado Running.

Siguientes pasos

  • Consulta una descripción general de cómo proporciona GKE DNS gestionado.
  • Consulta DNS para servicios y pods para obtener una descripción general de cómo se usa el DNS en los clústeres de Kubernetes.