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 dokubectl
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
ehw2.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:
- 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:
- 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:
Outputservice/hello-kubernetes-first created
deployment.apps/hello-kubernetes-first created
Para verificar a criação do serviço, execute o seguinte comando:
- kubectl get service hello-kubernetes-first
A saída será a seguinte:
OutputNAME 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
:
- 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:
- kubectl create -f hello-kubernetes-second.yaml
A saída será:
Outputservice/hello-kubernetes-second created
deployment.apps/hello-kubernetes-second created
Verifique se o segundo serviço está funcionando listando todos os seus serviços:
- kubectl get service
A saída será semelhante a esta:
OutputNAME 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:
- 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:
- helm repo update
Pode demorar um pouco para carregar:
OutputHang 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:
- 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):
OutputNAME: 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:
- 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
:
OutputNAME 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á:
OutputNAME 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:
- 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:
- 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:
- 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:
- 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:
- helm repo update
A atualização pode demorar um pouco:
OutputHang 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:
- 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:
OutputNAME: 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:
- 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
:
- kubectl apply -f production_issuer.yaml
Você receberá a seguinte saída:
Outputclusterissuer.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:
- 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:
- kubectl apply -f hello-kubernetes-ingress.yaml
Você receberá a seguinte saída:
Outputingress.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:
- kubectl describe certificate hello-kubernetes-tls
O final da saída será semelhante a este:
OutputEvents:
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.