Configurando Servidores de DNS para Clusters do Kubernetes

Descubra como configurar servidores DNS para clusters do Kubernetes que você criou usando o Kubernetes Engine (OKE).

Configurando Servidores de DNS Incorporados (kube-dns, CoreDNS)

Os clusters criados pelo Kubernetes Engine incluem um servidor de DNS como serviço incorporado do Kubernetes que é acionado automaticamente. O processo kubelet em cada nó de trabalho direciona contêineres individuais para o servidor de DNS para conversão de nomes de DNS em endereços IP.

Antes do Kubernetes versão 1.14, o Kubernetes Engine criava clusters com kube-dns como servidor DNS. No entanto, a partir do Kubernetes versão 1.14 em diante, o Kubernetes Engine cria clusters com CoreDNS como o servidor DNS. O CoreDNS é um servidor de DNS de autoridade, para finalidades gerais, que é modular e plugável.

O comportamento padrão do CoreDNS é controlado por um arquivo de configuração conhecido como Corefile. O Corefile é um ConfigMap do Kubernetes, com uma seção Corefile que define o comportamento do CoreDNS. Você não pode modificar o Corefile diretamente. Se você precisar personalizar o comportamento do CoreDNS, crie e aplique seu próprio ConfigMap para substituir as definições no Corefile (conforme descrito neste tópico). Observe que com clusters básicos, se você personalizar o comportamento padrão CoreDNS, as personalizações serão excluídas periodicamente durante atualizações internas para o cluster (com clusters aprimorados, as personalizações não serão excluídas).

Quando você faz upgrade de um cluster criado pelo Kubernetes Engine de uma versão anterior para o Kubernetes 1.14 ou mais recente, o servidor kube-dns do cluster é substituído automaticamente pelo servidor CoreDNS. Observe que se você personalizou o comportamento do kube-dns usando o ConfigMap do kube-dns original, essas personalizações não serão transportadas para o ConfigMap do CoreDNS. Você terá de criar e aplicar um novo ConfigMap contendo as personalizações para substituir as definições no Corefile do CoreDNS.

Para obter mais informações sobre a personalização CoreDNS e o Kubernetes, consulte a documentação do Kubernetes e a documentação do plug-in CoreDNS.

Para criar um ConfigMap para substituir as definições no Corefile do CoreDNS:

  1. Defina um ConfigMap em um arquivo yaml, no formato:

    apiVersion: v1
    kind: ConfigMap
    metadata:  
      name: coredns-custom  
      namespace: kube-system 
    data:
      <customization-options>

    Por exemplo:

    apiVersion: v1
    kind: ConfigMap
    metadata:  
      name: coredns-custom  
      namespace: kube-system 
    data:
      example.server: | # All custom server files must have a ".server" file extension. 
        # Change example.com to the domain you wish to forward.
        example.com {
          # Change 1.1.1.1 to your customer DNS resolver.
          forward . 1.1.1.1
        }

    Para obter mais informações sobre as opções ConfigMap a serem usadas para personalizar o comportamento do CoreDNS, consulte a documentação do Kubernetes e a documentação do plug-in CoreDNS.

  2. Crie o ConfigMap digitando:

    kubectl apply -f <filename>.yaml
  3. Verifique se as personalizações foram aplicadas digitando:

    kubectl get configmaps --namespace=kube-system coredns-custom -o yaml
  4. Force o CoreDNS a recarregar o ConfigMap digitando:

    kubectl delete pod --namespace kube-system -l k8s-app=kube-dns

Configurando o ExternalDNS para usar o Oracle Cloud Infrastructure DNS

O ExternalDNS é um complemento do Kubernetes que pode criar registros do DNS para serviços em provedores de DNS externos ao Kubernetes. Ele configura registros de DNS em um provedor de DNS externo para tornar os serviços do Kubernetes detectáveis por meio desse provedor de DNS e permite que você controle os registros do DNS dinamicamente. Consulte ExternalDNS para obter mais informações.

Depois de implantar o ExternalDNS em um cluster, você pode expor um serviço executado no cluster adicionando a anotação external-dns.alpha.kubernetes.io/hostname ao serviço. O ExternalDNS cria um registro de DNS para o serviço no provedor de DNS externo que você configurou para o cluster.

O ExternalDNS não é em si um servidor DNS como o CoreDNS, mas uma forma de configurar outros provedores de DNS externos. O Oracle Cloud Infrastructure DNS é um desses provedores externos de DNS. Consulte Visão Geral do DNS.

Por conveniência, as instruções são incluídas abaixo para configurar o ExternalDNS em um cluster e configurá-lo para usar o Oracle Cloud Infrastructure DNS. Essas instruções são resumidas com base no tutorial Configurando o ExternalDNS para o Oracle Cloud Infrastructure (OCI), que está disponível no GitHub.

Para configurar o ExternalDNS em um cluster e configurá-lo para usar o Oracle Cloud Infrastructure DNS:

  1. Crie uma nova zona de DNS no Oracle Cloud Infrastructure DNS para conter os registros de DNS que o ExternalDNS criará para o cluster. Consulte Criando uma Zona.
  2. Se você ainda não tiver feito isso, siga as etapas para configurar o arquivo de configuração kubeconfig do cluster e (se necessário) defina a variável de ambiente KUBECONFIG para apontar para o arquivo. Observe que você deve configurar seu próprio arquivo kubeconfig. Não é possível acessar um cluster usando um arquivo kubeconfig que outro usuário tenha configurado. Consulte Configurando o Acesso ao Cluster.
  3. Crie um segredo Kubernetes contendo os detalhes de autenticação do usuário do Oracle Cloud Infrastructure para que o ExternalDNS use ao estabelecer conexão com a API do Oracle Cloud Infrastructure para inserir e atualizar registros de DNS na zona de DNS que você acabou de criar.
    1. Em um editor de texto, crie um arquivo de credenciais contendo as credenciais do usuário do Oracle Cloud Infrastructure a serem usadas para acessar a zona do DNS:
      auth:
        region: <region-identifier>
        tenancy: <tenancy-ocid>
        user: <user-ocid>
        key: |
          -----BEGIN RSA PRIVATE KEY-----
         <private-key>
          -----END RSA PRIVATE KEY-----
        fingerprint: <fingerprint>
        # Omit if there is not a password for the key
        passphrase: <passphrase>
      compartment: <compartment-ocid>

      em que:

      • <<region-identifer> identifica a região do usuário. Por exemplo, us-phoenix-1
      • <tenancy-ocid> é o OCID da tenancy do usuário. Por exemplo, ocid1.tenancy.oc1..aaaaaaaap...keq (abreviado para facilitar a leitura).
      • <user-ocid> é o OCID do usuário. Por exemplo, ocid1.user.oc1..aaaaa...zutq (abreviado para facilitar a leitura).
      • <private-key> é uma chave RSA.
      • passphrase: <passphrase> fornece opcionalmente a frase-senha para a chave, se existir uma
      • <compartment-ocid> é o OCID do compartimento ao qual a zona do DNS pertence
      Por exemplo:
      auth:
        region: us-phoenix-1
        tenancy: ocid1.tenancy.oc1..aaaaaaaap...keq
        user: ocid1.user.oc1..aaaaa...zutq
        key: |
          -----BEGIN RSA PRIVATE KEY-----
          this-is-not-a-secret_Ef8aiAk7+I0...
          -----END RSA PRIVATE KEY-----
        fingerprint: bg:92:82:9f...
        # Omit if there is not a password for the key
        passphrase: Uy2kSl...
      compartment: ocid1.compartment.oc1..aaaaaaaa7______ysq
    2. Salve o arquivo de credenciais com um nome de sua escolha (por exemplo, oci-creds.yaml).
    3. Crie um segredo do Kubernetes usando o arquivo de credenciais que você acabou de criar, digitando:
      kubectl create secret generic <secret-name> --from-file=<credential-filename>

      Por exemplo:

      kubectl create secret generic external-dns-config --from-file=oci-creds.yaml
  4. Implante o ExternalDNS no cluster.
    1. Em um editor de texto, crie um arquivo de configuração (por exemplo, chamado external-dns-deployment.yaml) para criar a implantação do ExternalDNS e especifique o nome do segredo do Kubernetes que você acabou de criar. Por exemplo:
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: external-dns
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: external-dns
      rules:
      - apiGroups: [""]
        resources: ["services","endpoints","pods"]
        verbs: ["get","watch","list"]
      - apiGroups: ["extensions","networking.k8s.io"]
        resources: ["ingresses"]
        verbs: ["get","watch","list"]
      - apiGroups: [""]
        resources: ["nodes"]
        verbs: ["list"]
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: external-dns-viewer
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: external-dns
      subjects:
      - kind: ServiceAccount
        name: external-dns
        namespace: default
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: external-dns
      spec:
        strategy:
          type: Recreate
        selector:
          matchLabels:
            app: external-dns
        template:
          metadata:
            labels:
              app: external-dns
          spec:
            serviceAccountName: external-dns
            containers:
            - name: external-dns
              image: k8s.gcr.io/external-dns/external-dns:v0.7.3
              args:
              - --source=service
              - --source=ingress
              - --provider=oci
              - --policy=upsert-only # prevent ExternalDNS from deleting any records, omit to enable full synchronization
              - --txt-owner-id=my-identifier
              volumeMounts:
                - name: config
                  mountPath: /etc/kubernetes/
            volumes:
            - name: config
              secret:
                secretName: external-dns-config
    2. Salve e feche o arquivo de configuração.
    3. Aplique o arquivo de configuração para implantar o ExternalDNS digitando:
      kubectl apply -f <filename>

      em que <filename> corresponde ao nome do arquivo criado anteriormente. Por exemplo:

      kubectl apply -f external-dns-deployment.yaml

      A saída do comando acima confirma a implantação:

      serviceaccount/external-dns created
      clusterrole.rbac.authorization.k8s.io/external-dns created
      clusterrolebinding.rbac.authorization.k8s.io/external-dns-viewer created
      deployment.apps/external-dns created
      
  5. Verifique se o ExternalDNS foi implantado com sucesso e se pode inserir registros na zona do DNS criada anteriormente no Oracle Cloud Infrastructure, criando uma implantação do nginx e um serviço nginx:
    1. Em um editor de texto, crie um arquivo de configuração (por exemplo, chamado nginx-externaldns.yaml) para criar uma implantação do nginx e um serviço nginx que inclua a anotação external-dns.alpha.kubernetes.io/hostname. Por exemplo:
      apiVersion: v1
      kind: Service
      metadata:
        name: nginx
        annotations:
          external-dns.alpha.kubernetes.io/hostname: example.com
      spec:
        type: LoadBalancer
        ports:
        - port: 80
          name: http
          targetPort: 80
        selector:
          app: nginx
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx
      spec:
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - image: nginx
              name: nginx
              ports:
              - containerPort: 80
                name: http
    2. Aplique o arquivo de configuração para criar o serviço nginx e a implantação digitando:
      kubectl apply -f <filename>

      em que <filename> corresponde ao nome do arquivo criado anteriormente. Por exemplo:

      kubectl apply -f nginx-externaldns.yaml

      A saída do comando acima confirma a implantação:

      service/nginx created
      deployment.apps/nginx created
      
    3. Aguarde alguns minutos e, em seguida, verifique se um registro de DNS foi criado para o serviço nginx na zona do Oracle Cloud Infrastructure DNS (consulte Zonas).