Exemplo: Configurando um Controlador de Entrada Nginx em um Cluster

Descubra como configurar e usar um exemplo de controlador de entrada Nginx em um cluster que você criou usando o Container Engine for Kubernetes (OKE).

Você pode configurar diferentes controladores de entrada de código-fonte aberto em clusters criados com o Serviço Container Engine for Kubernetes para gerenciar o tráfego de aplicativos do Kubernetes.

Este tópico explica como configurar um exemplo de controlador de entrada Nginx junto com o controle de acesso correspondente em um cluster existente. Depois de configurar o controlador de entrada, este tópico descreve como usar o controlador de entrada com um exemplo de backend hello-world e como verificar se o controlador de entrada está funcionando conforme esperado. Se você quiser continuar usando o exemplo de controlador de entrada, siga as instruções de upgrade. E quando você não tem mais uso para o exemplo de controlador de entrada, este tópico mostra como excluí-lo.

Exemplo de Componentes

O exemplo inclui um controlador de entrada e um backend hello-world.

Componentes do Controlador de Entrada

O controlador de entrada compreende:

  • Uma implantação do controlador de entrada chamada ingress-nginx-controller. A implantação implementa uma imagem que contém o arquivo binário do controlador de entrada e o Nginx. O arquivo binário manipula e recarrega o arquivo de configuração /etc/nginx/nginx.conf quando uma entrada é criada no Kubernetes. Os upstreams do Nginx apontam para serviços que correspondem aos seletores especificados.
  • Um serviço do controlador de entrada chamado ingress-nginx-controller. O serviço expõe a implantação do controlador de entrada como um serviço do tipo LoadBalancer. Como o Serviço Container Engine for Kubernetes usa uma integração/provedor de nuvem do Oracle Cloud Infrastructure, um balanceador de carga será criado dinamicamente com os nós corretos configurados como um conjunto de backend.

Componentes de Backend

O backend hello-world compreende:

  • Uma implantação de backend chamada docker-hello-world. A implantação trata roteamentos padrão para verificações de integridade e respostas 404. Isso é feito usando uma imagem hello-world que atende aos roteamentos mínimos necessários para um backend padrão.
  • Um serviço de backend chamado docker-hello-world-svc. O serviço expõe a implantação de backend para consumo pela implantação do controlador de entrada.

Configurando o Exemplo de Controlador de Entrada

Nesta seção, você cria as regras de acesso para entrada. Em seguida, você cria os componentes do exemplo de controlador de entrada e confirma que eles estão em execução.

Criando as Regras de Acesso para o Controlador de Entrada

  1. 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.
  2. Se o usuário do Oracle Cloud Infrastructure for um administrador da tenancy, ignore a próxima etapa e vá direto para Implantando o Controlador de Entrada e os recursos associados.
  3. Se o usuário do Oracle Cloud Infrastructure não for um administrador da tenancy, em uma janela de terminal, conceda ao usuário a clusterrole de administrador do cluster do Kubernetes RBAC no cluster, informando:

    kubectl create clusterrolebinding <my-cluster-admin-binding> --clusterrole=cluster-admin --user=<user-OCID>

    em que:

    • <my-cluster-admin-binding> é uma string à sua escolha a ser usada como o nome para o binding entre o usuário e o clusterrole de administrador de cluster do Kubernetes RBAC. Por exemplo, jdoe_clst_adm
    • <user-OCID> é o OCID do usuário (obtido na Console). Por exemplo, ocid1.user.oc1..aaaaa...zutq (abreviado para facilitar a leitura).

    Por exemplo:

    kubectl create clusterrolebinding jdoe_clst_adm --clusterrole=cluster-admin --user=ocid1.user.oc1..aaaaa...zutq

Implantando o Controlador de Entrada e recursos associados

Como implantar o controlador de entrada e os recursos associados (incluindo as atribuições e associações RBAC do Kubernetes, e o serviço do controlador de entrada ingress-nginx-controller do tipo LoadBalancer) depende de você estar implantando em um cluster com nós gerenciados/autogerenciados ou em um cluster com nós virtuais:

  • Nós gerenciados e nós autogerenciados

    Para implantar o controlador de entrada Nginx, execute o seguinte comando:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v<vnum>/deploy/static/provider/cloud/deploy.yaml

    em que <vnum> corresponde ao número da versão mais recente do script de implantação do controlador de entrada ingress-nginx-controller. Por exemplo, no momento da gravação, a versão mais recente do script tem o número de versão 1.1.3, de modo que o comando a ser executado é:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/cloud/deploy.yaml

    Para descobrir o número da versão mais recente do script, consulte a documentação do kubernetes/ingress-nginx em GitHub.

  • Nós virtuais

    Em nós virtuais, você precisa modificar o manifesto de implantação do controlador de entrada e comentar os contextos de segurança fsgroup, allowprivilegeEscalation e capabilities. Para obter um exemplo desse manifesto de implantação modificado, consulte https://github.com/oracle-devrel/oci-oke-virtual-nodes/tree/main/ingress-nginx.

    Para implantar o controlador de entrada Nginx com base nesse manifesto modificado, execute o seguinte comando:

    kubectl apply -f https://raw.githubusercontent.com/oracle-devrel/oci-oke-virtual-nodes/main/ingress-nginx/deploy.yaml

Verificando se o Serviço do Controlador de Entrada ingress-nginx-controller está em Execução como um Serviço do Balanceador de Carga

  1. Exiba a lista de serviços em execução digitando:

    kubectl get svc -n ingress-nginx

    A saída do comando acima mostra os serviços que estão em execução:

    
    NAME                       TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                       AGE
    ingress-nginx-controller   LoadBalancer   10.96.229.38   <pending>      80:30756/TCP,443:30118/TCP    1h
    

    O EXTERNAL-IP do serviço do controlador de entrada ingress-nginx-controller é mostrado como <pending> até que o balanceador de carga tenha sido totalmente criado no Oracle Cloud Infrastructure.

  2. Repita o comando kubectl get svc até que um EXTERNAL-IP seja exibido para o serviço do controlador de entrada ingress-nginx-controller:

    kubectl get svc -n ingress-nginx
    

    A saída do comando acima mostra o EXTERNAL-IP do serviço do controlador de entrada ingress-nginx-controller:

    
    NAME                       TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)                       AGE
    ingress-nginx-controller   LoadBalancer   10.96.229.38   129.146.214.219   80:30756/TCP,443:30118/TCP    1h

Criando o Segredo TLS

Um segredo TLS é usado para encerramento do SSL no controlador de entrada.

  1. Gere uma nova chave para um arquivo. Por exemplo, informando:

    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"

    Para gerar o segredo para este exemplo, um certificado autoassinado foi usado. Apesar de servir para teste, para produção, use um certificado assinado por uma Autoridade de Certificação.

    Observação

    No Windows, talvez seja necessário substituir "/CN=nginxsvc/O=nginxsvc" por "//CN=nginxsvc\O=nginxsvc". Por exemplo, isso será necessário se você executar o comando openssl de um shell do Bash Git.
  2. Crie o segredo do TLS digitando:

    kubectl create secret tls tls-secret --key tls.key --cert tls.crt

Configurando o Exemplo de Backend

Nesta seção, você define um serviço de backend hello-world e uma implantação.

Criando a Definição do Serviço docker-hello-world

  1. Crie o arquivo hello-world-ingress.yaml contendo o código a seguir. Esse código usa uma imagem hello-world disponível publicamente no Docker Hub. Você pode substituir outra imagem à sua escolha que pode ser executada de maneira semelhante.

    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: docker-hello-world
      labels:
        app: docker-hello-world
    spec:
      selector:
        matchLabels:
          app: docker-hello-world
      replicas: 3
      template:
        metadata:
          labels:
            app: docker-hello-world
        spec:
          containers:
          - name: docker-hello-world
            image: scottsbaldwin/docker-hello-world:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: docker-hello-world-svc
    spec:
      selector:
        app: docker-hello-world
      ports:
        - port: 8088
          targetPort: 80
      type: ClusterIP
    

    Observe que o tipo do serviço docker-hello-world é ClusterIP, em vez de LoadBalancer, porque esse serviço terá um proxy do serviço do controlador de entrada ingress-nginx-controller. O serviço docker-hello-world não precisa de acesso público diretamente a ele. Em vez disso, o acesso público será roteado do balanceador de carga para o controlador de entrada e do controlador de entrada para o serviço de upstream.

  2. Crie a nova implantação e o serviço hello-world nos nós do cluster executando o seguinte comando:

    kubectl create -f hello-world-ingress.yaml

Usando o Exemplo de Controlador de Entrada para Acessar o Exemplo de Backend

Nesta seção, você cria uma entrada para acessar o backend usando o controlador de entrada.

Criando o Recurso de Entrada

  1. Crie o arquivo ingress.yaml e preencha-o com este código:

    
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hello-world-ing
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      tls:
      - secretName: tls-secret
      rules:
      - http:
          paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: docker-hello-world-svc
                  port:
                    number: 8088
    

    Observe que o exemplo acima YAML funciona com clusters que executam o Kubernetes versão 1.19.x e posterior.

  2. Crie o recurso digitando:

    kubectl create -f ingress.yaml

Verificando se os Exemplos de Componentes estão Funcionando conforme Esperado

Nesta seção, você confirma que todos os exemplos de componentes foram criados com sucesso e estão funcionando conforme esperado. O serviço docker-hello-world-svc deve estar em execução como um serviço ClusterIP e o serviço ingress-nginx-controller deve estar em execução como um serviço LoadBalancer. As solicitações enviadas ao controlador de entrada devem ser roteadas para os nós no cluster.

Obtendo o Endereço IP Externo do Balanceador de Carga

Para confirmar que o serviço ingress-nginx-controller está em execução como um serviço LoadBalancer, obtenha seu endereço IP externo informando:

kubectl get svc --all-namespaces

A saída do comando acima mostra os serviços que estão em execução:


NAMESPACE       NAME                          TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                      AGE
default         docker-hello-world-svc      ClusterIP      10.96.83.247    <none>           8088/TCP                     16s
default         kubernetes                  ClusterIP      10.96.0.1       <none>           443/TCP                      1h
ingress-nginx   ingress-nginx-controller    LoadBalancer   10.96.229.38    129.146.214.219  80:30756/TCP,443:30118/TCP   5m			
kube-system     kube-dns                    ClusterIP      10.96.5.5       <none>           53/UDP,53/TCP                1h

Enviando Solicitações de cURL para o Balanceador de Carga

  1. Use o endereço IP externo do serviço ingress-nginx-controller (por exemplo, 129.146.214.219) para usar o comando curl em uma solicitação http digitando:

    curl -I http://129.146.214.219
    

    Exemplo de saída do comando acima:

    HTTP/1.1 301 Moved Permanently
    Via: 1.1 10.68.69.10 (McAfee Web Gateway 7.6.2.10.0.23236)
    Date: Thu, 07 Sep 2017 15:20:16 GMT
    Server: nginx/1.13.2
    Location: https://129.146.214.219/
    Content-Type: text/html
    Content-Length: 185
    Proxy-Connection: Keep-Alive
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    

    A saída mostra um redirecionamento 301 e um cabeçalho de Local que sugerem que o tráfego http está sendo redirecionado para https.

  2. Use o comando curl de acordo com o url https ou adicione a opção -L para seguir automaticamente o cabeçalho do local. A opção -k instrui o cURL a não verificar os certificados SSL. Por exemplo, informando:
    curl -ikL http://129.146.214.219

    Exemplo de saída do comando acima:

    HTTP/1.1 301 Moved Permanently
    Via: 1.1 10.68.69.10 (McAfee Web Gateway 7.6.2.10.0.23236)
    Date: Thu, 07 Sep 2017 15:22:29 GMT
    Server: nginx/1.13.2
    Location: https://129.146.214.219/
    Content-Type: text/html
    Content-Length: 185
    Proxy-Connection: Keep-Alive
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    
    HTTP/1.0 200 Connection established
    
    HTTP/1.1 200 OK
    Server: nginx/1.13.2
    Date: Thu, 07 Sep 2017 15:22:30 GMT
    Content-Type: text/html
    Content-Length: 71
    Connection: keep-alive
    Last-Modified: Thu, 07 Sep 2017 15:17:24 GMT
    ETag: "59b16304-47"
    Accept-Ranges: bytes
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-0ztkm</h1>
    

    A última linha da saída mostra o HTML que é retornado do pod cujo nome do host é docker-hello-world-1732906117-0ztkm.

  3. Emita a solicitação de cURL várias vezes para ver o nome do host na alteração de saída HTML, demonstrando que o balanceamento de carga está ocorrendo:

    $ curl -k https://129.146.214.219
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-6115l</h1>
    
    $ curl -k https://129.146.214.219
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-7r89v</h1>
    
    $ curl -k https://129.146.214.219
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-0ztkm</h1>

Inspecionando o nginx.conf

A implantação do controlador de entrada ingress-nginx-controller manipula o arquivo nginx.conf no pod no qual ele está sendo executado.

  1. Localize o nome do pod que está executando a implantação do controlador de entrada ingress-nginx-controller digitando:

    kubectl get po -n ingress-nginx
    

    A saída do comando acima mostra o nome do pod que está executando a implantação do controlador de entrada ingress-nginx-controller:

    
    NAME                                       READY     STATUS    RESTARTS   AGE
    ingress-nginx-controller-110676328-h86xg   1/1       Running   0          1h
    
  2. Use o nome do pod que está executando a implantação do controlador de entrada ingress-nginx-controller para mostrar o conteúdo do nginx.conf informando o seguinte comando kubectl exec:

    kubectl exec -n ingress-nginx -it ingress-nginx-controller-110676328-h86xg -- cat /etc/nginx/nginx.conf
    
  3. Procure proxy_pass na saída. Haverá um para o backend padrão e outro que se assemelhará a:

    proxy_pass http://upstream_balancer;
    

    Isso mostra que o Nginx está fazendo proxy de solicitações para um upstream chamado upstream_balancer.

  4. Localize a definição de upstream na saída. Será semelhante a:

    upstream upstream_balancer {
                    server 0.0.0.1:1234; # placeholder
    
                    balancer_by_lua_block {
                            tcp_udp_balancer.balance()
                    }
            }
    
    

    O upstream está fazendo proxy via Lua.

(Opcional) Upgrade do Exemplo de Controlador de Entrada

Nesta seção opcional, você descobrirá como continuar usando o controlador de entrada de exemplo para gerenciamento de tráfego de aplicativos Kubernetes, em vez de removê-lo imediatamente.

Se quiser, você poderá continuar usando o exemplo de controlador de entrada criado anteriormente. No entanto, observe que as novas versões do Nginx são liberadas periodicamente. Portanto, se você continuar usando o controlador de entrada de exemplo, precisará fazer upgrade periódico da versão do Nginx usada pelo controlador de entrada. Normalmente, você preservará o endereço EXTERNAL-IP existente do controlador de entrada ao fazer upgrade do Nginx.

Para fazer upgrade do controlador de entrada existente sem excluir o balanceador de carga existente do Oracle Cloud Infrastructure (e assim preservar seu endereço EXTERNAL-IP existente), siga as instruções Fazendo Upgrade do Nginx Sem Helm na documentação do Nginx.

Para determinar qual imagem do Nginx fazer referência ao fazer upgrade do Nginx, consulte o Nginx Changelog na documentação do Nginx.

(Opcional) Removendo o Exemplo de Controlador de Entrada

Nesta seção opcional, você remove o exemplo de controlador de entrada criado anteriormente, incluindo:

  • a implantação do controlador de entrada ingress-nginx-controller
  • as atribuições e associações do Kubernetes RBAC
  • o serviço do controlador de entrada ingress-nginx-controller do tipo LoadBalancer

Observe que, se posteriormente você decidir aplicar o script de implantação do controlador de entrada pela segunda vez para recriar o controlador de entrada de exemplo, um novo serviço ingress-nginx-controller do tipo LoadBalancer será criado com um endereço EXTERNAL-IP diferente do serviço anterior.

Você não precisará remover o controlador de entrada de exemplo se quiser continuar usando-o. No entanto, se você continuar usando o controlador de entrada de exemplo, precisará fazer upgrade periódico da versão do Nginx usada pelo controlador de entrada. Consulte (Opcional) Upgrade do Exemplo de Controlador de Entrada.

Removendo o Exemplo de Controlador de Entrada

  1. Execute o seguinte comando para remover o controlador de entrada de exemplo criado anteriormente:

    kubectl delete -f <deployment-script-location>

    em que <deployment-script-location> é a localização do script de implantação que você usou anteriormente para criar o controlador de entrada de exemplo.

    Por exemplo:

    kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/cloud/deploy.yaml