Pesquisa de site

Como configurar uma entrada Nginx no Kubernetes usando o Helm


O autor selecionou o programa Write for DOnations.

Introdução

O Kubernetes Ingresses oferece uma maneira flexível de rotear o tráfego além do cluster para os serviços internos do Kubernetes. Ingress Recursos são objetos no Kubernetes que definem regras para roteamento de tráfego HTTP e HTTPS para Serviços. Para que funcionem, um Controlador do Ingress deve estar presente para implementar as regras, aceitando o tráfego (provavelmente por meio de um balanceador de carga) e roteando-o para os serviços apropriados. A maioria dos Ingress Controllers usa apenas um Load Balancer global para todos os Ingresses, o que é mais eficiente do que criar um Load Balancer para cada Serviço que você deseja expor.

Helm é um gerenciador de pacotes para gerenciamento do Kubernetes. O uso de gráficos do Helm com o Kubernetes fornece capacidade de configuração e gerenciamento do ciclo de vida para atualizar, reverter e excluir um aplicativo do Kubernetes.

Neste guia, você configurará o gerenciador de certificados mantido pelo Kubernetes em seu cluster para provisionar certificados Let's Encrypt TLS automaticamente que protegerão seus ingressos.

Pré-requisitos

  • Um cluster Kubernetes acima da versão 1.20, configurado com sua configuração de conexão definida como kubectl padrão. Esta configuração usará um início rápido do Kubernetes.
  • A ferramenta de linha de comando kubectl instalada em seu ambiente local e configurada para se conectar ao seu cluster. Você pode ler mais sobre a instalação do kubectl nos documentos Como se conectar a um Cluster Kubernetes da DigitalOcean.
  • O cliente de linha de comando da DigitalOcean, How To Use doctl para obter mais informações sobre como usar doctl.
  • O gerenciador de pacotes Helm 3 disponível em seu ambiente de desenvolvimento. Conclua a Etapa 1 do tutorial How To Install Software on Kubernetes Clusters with the Helm 3 Package Manager.
  • Um nome de domínio totalmente registrado com dois registros A disponíveis. Este tutorial usará hw1.your_domain e hw2.your_domain. Você pode comprar um nome de domínio no Freenom ou usar o registrador de domínio de sua escolha. Esses registros A serão direcionados para um Load Balancer que você criará na Etapa 2.

Etapa 1 — Configurando implantações do Hello World

Antes de implantar o Nginx Ingress, você implantará um aplicativo \Hello World chamado hello-kubernetes para ter alguns serviços para os quais você roteará o tráfego. Para confirmar se o Nginx Ingress funciona corretamente no Nas próximas etapas, você o implantará duas vezes, cada vez com uma mensagem de boas-vindas diferente que será exibida ao acessá-lo pelo navegador.

Você armazenará a configuração de implantação em sua máquina local. Se desejar, você também pode criar um diretório para este tutorial no qual armazenará a configuração. A primeira configuração de implantação estará em um arquivo chamado hello-kubernetes-first.yaml. Crie-o com seu editor de texto preferido:

  1. nano hello-kubernetes-first.yaml

Adicione as seguintes linhas:

apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes-first
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: hello-kubernetes-first
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-first
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes-first
  template:
    metadata:
      labels:
        app: hello-kubernetes-first
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.10
        ports:
        - containerPort: 8080
        env:
        - name: MESSAGE
          value: Hello from the first deployment!

Esta configuração define um Implantação e um Serviço. A Deployment consiste em três réplicas da imagem paulbouwer/hello-kubernetes:1.7 e uma variável de ambiente chamada MESSAGE (você verá seu valor quando você acessa o app). O Service aqui é definido para expor a Deployment in-cluster na porta 80.

Salve e feche o arquivo.

Em seguida, crie esta primeira variante do aplicativo hello-kubernetes no Kubernetes executando o seguinte comando:

  1. kubectl create -f hello-kubernetes-first.yaml

A opção -f direciona o comando create para usar o arquivo hello-kubernetes-first.yaml.

Você receberá a seguinte saída:

Output
service/hello-kubernetes-first created deployment.apps/hello-kubernetes-first created

Para verificar a criação do serviço, execute o seguinte comando:

  1. kubectl get service hello-kubernetes-first

A saída será a seguinte:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-kubernetes-first ClusterIP 10.245.124.46 <none> 80/TCP 7s

Você descobrirá que o serviço recém-criado tem um ClusterIP atribuído, o que significa que está funcionando corretamente. Todo o tráfego enviado para ele será encaminhado para a implantação selecionada na porta 8080. Agora que implantou a primeira variante do aplicativo hello-kubernetes, você trabalhará na segunda.

Crie um novo arquivo chamado hello-kubernetes-second.yaml:

  1. nano hello-kubernetes-second.yaml

Adicione as seguintes linhas:

apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes-second
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: hello-kubernetes-second
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-second
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes-second
  template:
    metadata:
      labels:
        app: hello-kubernetes-second
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.10
        ports:
        - containerPort: 8080
        env:
        - name: MESSAGE
          value: Hello from the second deployment!

Esta variante tem a mesma estrutura da configuração anterior. Para evitar colisões, você varia o name usado para os nomes de implantação e serviço. Você também atualiza o valor da mensagem que será carregada no navegador.

Salve e feche o arquivo.

Agora crie-o no Kubernetes com o seguinte comando:

  1. kubectl create -f hello-kubernetes-second.yaml

A saída será:

Output
service/hello-kubernetes-second created deployment.apps/hello-kubernetes-second created

Verifique se o segundo serviço está funcionando listando todos os seus serviços:

  1. kubectl get service

A saída será semelhante a esta:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-kubernetes-first ClusterIP 10.245.124.46 <none> 80/TCP 49s hello-kubernetes-second ClusterIP 10.245.254.124 <none> 80/TCP 10s kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 65m

Ambos hello-kubernetes-first e hello-kubernetes-second estão listados, o que significa que o Kubernetes os criou com sucesso.

Você criou duas implantações do aplicativo hello-kubernetes com os Serviços que o acompanham. Cada um tem um conjunto de mensagens diferente na especificação de implantação, diferenciando-os durante o teste. Na próxima etapa, você instalará o próprio Nginx Ingress Controller.

Etapa 2 — Instalando o Kubernetes Nginx Ingress Controller

Agora você instalará o Nginx Ingress Controller mantido pelo Kubernetes usando o Helm.

O Nginx Ingress Controller consiste em um pod e um serviço. O pod executa o controlador, que pesquisa constantemente o ponto de extremidade /ingresses no servidor de API do seu cluster para atualizações dos recursos de entrada disponíveis. O serviço é do tipo LoadBalancer. Como você o está implantando em um cluster Kubernetes da DigitalOcean, o cluster criará automaticamente um balanceador de carga da DigitalOcean por meio do qual todo o tráfego externo fluirá para o controlador. O Controlador então encaminhará o tráfego para os Serviços apropriados, conforme definido nos Recursos do Ingress.

Somente o LoadBalancer Service conhece o endereço IP do Load Balancer criado automaticamente. Alguns aplicativos (como ExternalDNS) precisam saber seu endereço IP, mas só podem ler a configuração de um Ingress. O Controlador pode ser configurado para publicar o endereço IP em cada Entrada definindo o parâmetro controller.publishService.enabled como true durante a instalação do helm. É recomendável habilitar essa configuração para oferecer suporte a aplicativos que podem depender do endereço IP do Load Balancer.

Para instalar o Nginx Ingress Controller em seu cluster, você primeiro precisará adicionar seu repositório ao Helm executando:

  1. helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

A saída será:

Output
"ingress-nginx" has been added to your repositories

Atualize seu sistema para informar ao Helm o que ele contém:

  1. helm repo update

Pode demorar um pouco para carregar:

Output
Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "ingress-nginx" chart repository Update Complete. ⎈Happy Helming!⎈

Por fim, execute o seguinte comando para instalar a entrada do Nginx:

  1. helm install nginx-ingress ingress-nginx/ingress-nginx --set controller.publishService.enabled=true

Este comando instala o Nginx Ingress Controller do repositório de gráficos stable, nomeia a versão do Helm nginx-ingress e define o parâmetro publishService como verdadeiro.

Depois de executado, você receberá uma saída semelhante a esta (esta saída foi truncada):

Output
NAME: nginx-ingress LAST DEPLOYED: Thu Dec 1 11:40:28 2022 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: ...

O Helm registrou quais recursos criou no Kubernetes como parte da instalação do gráfico.

Execute este comando para ver o balanceador de carga ficar disponível:

  1. kubectl --namespace default get services -o wide -w nginx-ingress-ingress-nginx-controller

Este comando busca o serviço Nginx Ingress no namespace default e gera suas informações, mas o comando não sai imediatamente. Com o argumento -w, ele observa e atualiza a saída quando ocorrem alterações.

Enquanto espera que o Load Balancer fique disponível, você pode receber uma resposta pending:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR nginx-ingress-ingress-nginx-controller LoadBalancer 10.245.3.122 <pending> 80:30953/TCP,443:30869/TCP 36s ...

Depois de algum tempo, o endereço IP do seu balanceador de carga recém-criado aparecerá:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR nginx-ingress-ingress-nginx-controller LoadBalancer 10.245.3.122 167.99.16.184 80:30953/TCP,443:30869/TCP 2m29s ...

Em seguida, você precisará garantir que seus dois domínios sejam apontados para o Load Balancer por meio de registros A. Isso é feito por meio do seu provedor de DNS. Para configurar seus registros DNS na DigitalOcean, consulte Como gerenciar registros DNS.

Você instalou o Nginx Ingress mantido pela comunidade Kubernetes. Ele roteará o tráfego HTTP e HTTPS do balanceador de carga para os serviços de back-end apropriados configurados nos recursos do Ingress. Na próxima etapa, você exporá as implantações do aplicativo hello-kubernetes usando um Ingress Resource.

Etapa 3 — Expondo o aplicativo usando um Ingress

Agora, você criará um Ingress Resource e o usará para expor as implantações do aplicativo hello-kubernetes nos domínios desejados. Em seguida, você o testará acessando-o em seu navegador.

Você armazenará o Ingress em um arquivo chamado hello-kubernetes-ingress.yaml. Crie-o usando seu editor:

  1. nano hello-kubernetes-ingress.yaml

Adicione as seguintes linhas ao seu arquivo:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: "hw1.your_domain_name"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-first
            port:
              number: 80
  - host: "hw2.your_domain_name"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-second
            port:
              number: 80

Você define um Ingress Resource com o nome hello-kubernetes-ingress. Em seguida, você especifica duas regras de host para que hw1.your_domain seja roteado para o serviço hello-kubernetes-first e hw2.your_domain é roteado para o serviço a partir da segunda implantação (hello-kubernetes-second).

Lembre-se de substituir os domínios destacados pelos seus, salve e feche o arquivo.

Crie-o no Kubernetes executando o seguinte comando:

  1. kubectl apply -f hello-kubernetes-ingress.yaml

Agora você pode navegar para hw1.your_domain em seu navegador. A primeira implantação será carregada:

A segunda variante (hw2.your_domain) exibirá uma mensagem diferente:

Você verificou que o Ingress Controller roteia corretamente as solicitações, neste caso, de seus dois domínios para dois serviços diferentes.

Você criou e configurou um Ingress Resource para servir as implantações do aplicativo hello-kubernetes em seus domínios. Na próxima etapa, você configurará o Cert-Manager para proteger seus recursos do Ingress com certificados TLS gratuitos da Let's Encrypt.

Passo 4 — Protegendo o Ingress usando o Cert-Manager

Para proteger seus recursos do Ingress, você instalará o Cert-Manager, criará um ClusterIssuer para produção e modificará a configuração do seu Ingress para usar os certificados TLS. Depois de instalado e configurado, seu aplicativo será executado por trás do HTTPS.

ClusterIssuers são recursos do Cert-Manager no Kubernetes que fornecem certificados TLS para todo o cluster. O ClusterIssuer é um tipo específico de Issuer.

Antes de instalar o Cert-Manager em seu cluster via Helm, você criará um namespace para ele:

  1. kubectl create namespace cert-manager

Você precisará adicionar o repositório Jetstack Helm ao Helm, que hospeda o gráfico Cert-Manager. Para fazer isso, execute o seguinte comando:

  1. helm repo add jetstack https://charts.jetstack.io

O Helm retornará a seguinte saída:

Output
"jetstack" has been added to your repositories

Em seguida, atualize o cache do gráfico do Helm:

  1. helm repo update

A atualização pode demorar um pouco:

Output
Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "ingress-nginx" chart repository ...Successfully got an update from the "jetstack" chart repository Update Complete. ⎈Happy Helming!⎈

Por fim, instale o Cert-Manager no namespace cert-manager executando o seguinte comando:

  1. helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.10.1 --set installCRDs=true

Nesse comando, você também define o parâmetro installCRDs como true para instalar os manifestos cert-manager CustomResourceDefinition durante a instalação do Helm. No momento da escrita, v1.10.1 era a versão mais recente. Você pode consultar o ArtifactHub para encontrar o número da versão mais recente.

Você receberá a seguinte saída:

Output
NAME: cert-manager LAST DEPLOYED: Wed Nov 30 19:46:39 2022 NAMESPACE: cert-manager STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: cert-manager v1.10.1 has been deployed successfully! ...

A saída indica que a instalação foi bem-sucedida.

O NOTES da saída (que foi truncado na exibição acima) afirma que você precisa configurar um Issuer para emitir certificados TLS.

Agora você criará um que emite certificados Let's Encrypt e armazenará sua configuração em um arquivo chamado production_issuer.yaml. Crie e abra este arquivo:

  1. nano production_issuer.yaml

Adicione as seguintes linhas:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # Email address used for ACME registration
    email: your_email_address
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # Name of a secret used to store the ACME account private key
      name: letsencrypt-prod-private-key
    # Add a single challenge solver, HTTP01 using nginx
    solvers:
    - http01:
        ingress:
          class: nginx

Essa configuração define um ClusterIssuer que entra em contato com a Let’s Encrypt para emitir certificados. Você precisará substituir your_email_address pelo seu endereço de e-mail para receber avisos sobre a segurança e expiração de seus certificados.

Salve e feche o arquivo.

Abra com kubectl:

  1. kubectl apply -f production_issuer.yaml

Você receberá a seguinte saída:

Output
clusterissuer.cert-manager.io/letsencrypt-prod created

Com o Cert-Manager instalado, você está pronto para introduzir os certificados no Ingress Resource definido na etapa anterior. Abra hello-kubernetes-ingress.yaml para edição:

  1. nano hello-kubernetes-ingress.yaml

Adicione as linhas destacadas:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
  kubernetes.io/ingress.class: nginx
  cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - hw1.your_domain
    - hw2.your_domain
    secretName: hello-kubernetes-tls
  rules:
  - host: "hw1.your_domain_name"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-first
            port:
              number: 80
  - host: "hw2.your_domain_name"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-second
            port:
              number: 80

O bloco tls em spec define qual segredo armazenará os certificados para seus sites (listados em hosts), que letsencrypt-prod ClusterIssuer problemas. O secretName deve ser diferente para cada Ingress que você criar.

Lembre-se de substituir hw1.your_domain e hw2.your_domain por seus próprios domínios. Quando terminar de editar, salve e feche o arquivo.

Aplique novamente essa configuração ao cluster executando o seguinte comando:

  1. kubectl apply -f hello-kubernetes-ingress.yaml

Você receberá a seguinte saída:

Output
ingress.networking.k8s.io/hello-kubernetes-ingress configured

Você precisará aguardar alguns minutos para que os servidores da Let’s Encrypt emitam um certificado para seus domínios. Enquanto isso, você pode acompanhar o progresso inspecionando a saída do seguinte comando:

  1. kubectl describe certificate hello-kubernetes-tls

O final da saída será semelhante a este:

Output
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Issuing 2m34s cert-manager-certificates-trigger Issuing certificate as Secret does not exist Normal Generated 2m34s cert-manager-certificates-key-manager Stored new private key in temporary Secret resource "hello-kubernetes-tls-hxtql" Normal Requested 2m34s cert-manager-certificates-request-manager Created new CertificateRequest resource "hello-kubernetes-tls-jnnwx" Normal Issuing 2m7s cert-manager-certificates-issuing The certificate has been successfully issued

Quando a última linha da saída for O certificado foi emitido com sucesso, você poderá sair pressionando CTRL + C.

Navegue até um de seus domínios em seu navegador. Você verá que o cadeado aparece ao lado da URL, significando que sua conexão agora está segura.

Nesta etapa, você instalou o Cert-Manager usando o Helm e criou um Let’s Encrypt ClusterIssuer. Em seguida, você atualizou seu Ingress Resource para aproveitar o Issuer para gerar certificados TLS. No final, você confirmou que o HTTPS funciona corretamente navegando para um de seus domínios em seu navegador.

Conclusão

Agora você configurou com êxito o Nginx Ingress Controller e o Cert-Manager em seu cluster DigitalOcean Kubernetes usando o Helm. Agora você pode expor seus aplicativos à Internet em seus domínios, protegidos por certificados Let's Encrypt TLS.

Para obter mais informações sobre o gerenciador de pacotes Helm, leia esta Introdução ao Helm.

Artigos relacionados: