Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Base de conhecimento da SomosBR

Bem vindo a base de conhecimento da SomosBR

Como usar esta documentação

O menu lateral à esquerda lista todos os capítulos. Clique no menu hambúrguer (☰) para mostrar ou ocultar.

Para navegar para o próximo ou capítulo anterior, use os botões de seta na lateral ou na parte inferior da página ou as teclas de seta para a esquerda e direita no teclado.

Você pode pesquisar por qualquer termo usando a barra de pesquisa (atalho S) no canto superior direito.

Produtos e serviços

Oferecemos uma variedade de produtos e serviços para ajudar você a modernizar sua infraestrutura e aplicações.

Kubernetes

O Kubernetes é a nossa principal ferramenta para orquestração de containers. Oferecemos serviços gerenciados de Kubernetes para garantir que suas aplicações sejam escaláveis, resilientes e seguras.

Kubernetes

Logo Kubernetes

O que é

Kubernetes (também conhecido como k8s) é uma plataforma de orquestração de contêineres de código aberto que automatiza a implantação, o dimensionamento e o gerenciamento de aplicativos em containers.

Originalmente desenvolvido pelo Google, o Kubernetes é agora mantido pela Cloud Native Computing Foundation (CNCF).

Se você não é familiarizado com contêineres, veja nossa seção Introdução a containers (Docker/Podman)

Nomenclaturas

TermoDescrição
ClusterUm conjunto de máquinas (nós) que executam aplicações em contêineres.
Nó (Node)Uma máquina de trabalho em um cluster Kubernetes.
PodA menor unidade de implantação no Kubernetes, que pode conter um ou mais contêineres.
Serviço (Service)Uma forma de expor uma aplicação executada em um conjunto de Pods como um serviço de rede.
DeploymentUm objeto que gerencia um conjunto de Pods replicados, garantindo que um número especificado de réplicas esteja sempre em execução.
NamespaceUma forma de dividir os recursos do cluster em escopos isolados.
StatefulSetUm objeto que gerencia um conjunto de Pods com estado, garantindo identidades de nome e de rede.
PersistentVolume (PV)Uma parte do armazenamento no cluster que foi provisionada por um administrador.
PersistentVolumeClaim (PVC)Uma solicitação de armazenamento por um usuário.

Esta é apenas uma lista de alguns dos recursos mais comuns do Kubernetes. Para uma lista completa, consulte a documentação oficial do Kubernetes.

SomosBR e Kubernetes

Na SomosBR, oferecemos serviços gerenciados de Kubernetes (KaaS) com escabilidade, segurança, alta disponibilidade e suporte de especialistas certificados.

Veja mais detalhes na nossa página de produtos e serviços:

https://somosbr.com.br/kubernetes

Primeiros passos

Veja nossos primeiros passos para começar a usar kubernetes localmente

Primeiros passos com Kubernetes

Introdução a Containers (Docker/Podman)

O que são containers?

Containers são uma tecnologia que permite empacotar e isolar aplicações com suas dependências em um ambiente de software contido. Isso garante que a aplicação funcione de forma consistente em diferentes ambientes de computação

Cada container executa um aplicativo ou serviço específico, como processo principal, em um ambiente isolado, mas compartilha o kernel do sistema operacional

Por que usar containers?

  • Portabilidade: As aplicações em containers podem ser executadas em qualquer lugar que suporte a tecnologia de container, sem a necessidade de reconfiguração
  • Eficiência: Os containers compartilham o kernel do sistema operacional do host, o que os torna mais leves e rápidos do que as máquinas virtuais
  • Isolamento: Os containers fornecem um ambiente isolado para cada aplicação, o que ajuda a evitar conflitos de dependência e a melhorar a segurança

Container vs VM

A diferença principal entre containers e máquinas virtuais (VMs) é que containers compartilham o kernel do sistema operacional, sendo assim mais leves e rápidos de iniciar, enquanto VMs incluem todo o sistema operacional, necessitando de mais recursos e ajustes

CaracterísticaContainersMáquinas Virtuais (VMs)
IsolamentoIsolamento de processosIsolamento completo do SO
RecursosCompartilham o SO do hostCada VM tem seu próprio SO
TamanhoLeves (megabytes)Pesadas (gigabytes)
InicializaçãoRápida (segundos)Lenta (minutos)
PortabilidadeAltaMédia
DesempenhoPróximo ao nativoMenor devido à sobrecarga

Quando usar cada um?

  • Use containers quando: você precisa executar várias aplicações em um único servidor, busca alta portabilidade e um ciclo de desenvolvimento rápido
  • Use VMs quando: você precisa de isolamento completo do sistema operacional, ou quando precisa executar aplicações que requerem um sistema operacional diferente do host

Primeiros passos com Docker

Dockerfile

Um Dockerfile é um arquivo de texto que contém os comandos para montar uma imagem de container. O Docker constrói imagens automaticamente lendo as instruções de um Dockerfile.

Exemplo: Nginx com index.html customizado

  1. Crie um arquivo index.html com o seguinte conteúdo:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Página customizada</title>
    </head>
    <body>
        <h1>Olá do container Nginx!</h1>
    </body>
    </html>
    
  2. Crie um Dockerfile no mesmo diretório:

    FROM nginx:alpine
    COPY index.html /usr/share/nginx/html
    
  3. Construa a imagem:

    docker build -t meu-nginx .
    
  4. Execute o container:

    docker run -d -p 8080:80 meu-nginx
    

Acesse http://localhost:8080 em seu navegador para ver a página customizada.

Docker Compose

O Docker Compose é uma ferramenta para definir e executar aplicações Docker multi-container. Com o Compose, você usa um arquivo YAML para configurar os serviços da sua aplicação. Em seguida, com um único comando, você cria e inicia todos os serviços a partir da sua configuração.

Mais detalhes na documentação oficial: https://docs.docker.com/compose/

Exemplo: docker-compose.yml

Usando o mesmo exemplo do Nginx, o arquivo docker-compose.yml seria assim:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "8080:80"

Para executar, use o comando:

docker compose up

Para executar em background, use:

docker compose up -d

Para parar os containers, use:

docker compose down -v

Primeiros passos com Kubernetes

Iniciando localmente com Docker e Minikube

Docker

Docker é uma plataforma de contêinerização que permite gerenciar e executar containers. Com ele, você pode criar, implantar e executar seus aplicativos localmente.

Para instalar o Docker, siga as instruções na documentação oficial.

Minikube

Minikube é uma ferramenta que facilita a execução do Kubernetes localmente.

Por padrão ele cria um cluster Kubernetes de nó único em sua máquina local via docker. E ajusta a config do kubectl para apontar para esse cluster.

Veja como instalar o Minikube na documentação oficial.

Kubectl

Kubectl é a ferramenta de linha de comando para interagir com clusters Kubernetes.

Veja como instalar o kubectl na documentação oficial.

Veja nossos exemplos de comandos kubectl na seção de Comandos kubectl.

Testando primeiro container

Após instalar o docker e o minikube, você pode testar criando um container simples.

Este container executa um servidor web simples que responde com “Hello, World!” para qualquer requisição HTTP.

Estamos especificando a porta 8080, que é a porta padrão usada pelo servidor web no container.

Executando o pod

kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.10 --port=8080

Resultado esperado do comando:

pod/hello-minikube created

Expondo o pod com service

kubectl expose pod hello-minikube --type=NodePort --port=8080

Resultado esperado do comando:

service/hello-minikube exposed

Acessando o serviço

minikube service hello-minikube

Resultado esperado do comando:

|-----------|----------------|-------------|---------------------------|
| NAMESPACE |      NAME      | TARGET PORT |            URL            |
|-----------|----------------|-------------|---------------------------|
| default   | hello-minikube |        8080 | http://192.168.49.2:30175 |
|-----------|----------------|-------------|---------------------------|
* Abrindo serviço default/hello-minikube no navegador padrão...

O navegador será aberto e você verá a seguinte resposta:

Hostname: hello-minikube

Pod Information:
 -no pod information available-

Server values:
 server_version=nginx: 1.13.3 - lua: 10008

Request Information:
 client_address=172.17.0.1
 method=GET
 real path=/
 query=
 request_version=1.1
 request_scheme=http
 request_uri=http://192.168.49.2:8080/

Request Headers:
 accept=*/*
 host=192.168.49.2:30175
 user-agent=curl/7.68.0

Request Body:
 -no body in request-

Comandos Imperativos vs. Arquivos de Configuração Declarativos

Existem duas maneiras de criar e gerenciar recursos no Kubernetes:

  • Comandos Imperativos: Como os que usamos acima (kubectl run, kubectl expose), onde dizemos ao Kubernetes o que fazer.
  • Arquivos de Configuração Declarativos: Onde descrevemos o estado desejado do sistema em um arquivo YAML, e o Kubernetes descobre como chegar lá.

Arquivos de configuração declarativos são a abordagem recomendada para gerenciar aplicações em produção, pois permitem:

  • Controle de versão: Os arquivos YAML podem ser armazenados em um sistema de controle de versão como o Git.
  • Repetibilidade: É fácil recriar o mesmo ambiente em diferentes clusters ou namespaces.
  • Colaboração: As equipes podem revisar as alterações antes de serem aplicadas.

Exemplo de Deployment com YAML

Abaixo está um exemplo de um arquivo de configuração YAML para um Deployment que cria 3 réplicas de um servidor Nginx e um Service para expor o Deployment.

nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort

Neste arquivo, temos dois objetos, separados por ---:

  • Deployment: O objeto Deployment gerencia a criação e a escalabilidade dos Pods. No exemplo, ele garante que 3 réplicas do container nginx estejam sempre em execução.
  • Service: O objeto Service expõe os Pods do Deployment como um serviço de rede. No exemplo, ele cria um serviço do tipo NodePort que expõe a porta 80 dos Pods em uma porta no nó do cluster.

Para aplicar este arquivo de configuração, use o comando kubectl apply:

kubectl apply -f nginx-deployment.yaml

Para verificar o status do deployment, use o comando kubectl get deployments:

kubectl get deployments

E para ver os pods criados pelo deployment, use o comando kubectl get pods:

kubectl get pods

Para acessar o serviço, você pode usar o comando minikube service:

minikube service nginx-service

Comandos kubectl

Veja vários exemplos de comandos kubectl para gerenciar clusters Kubernetes.

ComandoDescriçãoExemplo
kubectl get nodesLista todos os nós no cluster.kubectl get nodes
kubectl get podsLista todos os pods no namespace atual.kubectl get pods
kubectl get servicesLista todos os serviços no namespace atual.kubectl get services
kubectl describe pod <pod-name>Mostra informações detalhadas sobre um pod.kubectl describe pod web-pod
kubectl logs <pod-name>Exibe os logs de um pod.kubectl logs web-pod
kubectl apply -f <file.yaml>Cria ou atualiza recursos a partir de um arquivo de configuração.kubectl apply -f pod.yaml
kubectl delete -f <file.yaml>Exclui recursos a partir de um arquivo de configuração.kubectl delete -f pod.yaml
kubectl exec -it <pod-name> -- <command>Executa um comando em um container dentro de um pod.kubectl exec -it web-pod -- /bin/bash

Monitoramento de Recursos com kubectl top

O comando kubectl top permite visualizar o consumo de recursos (CPU e memória) de nós e pods.

Habilitando o Metrics Server

Para que o comando kubectl top funcione, você precisa ter o Metrics Server instalado no seu cluster. O Metrics Server coleta métricas de recursos dos nós e pods e as expõe através da API de métricas do Kubernetes.

Em clusters Minikube, você pode habilitar o Metrics Server com o seguinte comando:

minikube addons enable metrics-server

Comandos kubectl top

ComandoDescriçãoExemplo
kubectl top nodeExibe o consumo de CPU e memória de todos os nós.kubectl top node
kubectl top podExibe o consumo de CPU e memória de todos os pods no namespace atual.kubectl top pod
kubectl top pod <pod-name>Exibe o consumo de CPU e memória de um pod específico.kubectl top pod web-pod

Gateway API

Gateway API é a evolução do modelo de publicação de serviços HTTP/TCP no Kubernetes. Ela foi criada para resolver limitações do Ingress, separando melhor as responsabilidades entre quem opera a entrada do cluster e quem publica aplicações.

Enquanto o Ingress concentrava quase tudo em um único recurso, a Gateway API divide o problema em objetos com papéis mais claros:

  • GatewayClass: define qual controlador vai implementar o gateway.
  • Gateway: representa a entrada compartilhada do cluster.
  • HTTPRoute: define como cada aplicação será roteada para os serviços.

Na prática, a principal vantagem é esta: você deixa de repetir configuração de entrada em cada aplicação e passa a ter um Gateway compartilhado com várias rotas independentes.

Por que preferir Gateway API em vez de Ingress

  • Modelo mais moderno: foi desenhada para substituir os casos mais comuns de Ingress.
  • Separação de responsabilidades: infraestrutura e aplicações ficam mais desacopladas.
  • Mais extensível: middlewares, TLS e filtros ficam mais organizados.
  • Melhor migração incremental: você pode manter um único gateway e migrar serviço por serviço.

Traefik como provider de Gateway API

O Traefik é uma boa opção de provider para Gateway API porque tem instalação simples, integração madura com Kubernetes e suporte direto a Gateway e HTTPRoute.

Para ambientes simples, ele funciona muito bem com uma abordagem direta:

  • instalar o chart via Helm;
  • deixar o chart criar e publicar o gateway;
  • usar HTTPRoute para conectar cada serviço a esse gateway compartilhado.

Esse modelo costuma ser suficiente para laboratórios, ambientes internos e muitos cenários reais de produção sem precisar começar com manifests extras.

Instalação do Traefik com Gateway API

Certificado TLS

Em um listener HTTPS, o Traefik precisa de um certificado TLS para conseguir terminar a conexão segura. Sem isso, ele não consegue responder em HTTPS de forma correta para o domínio publicado.

No exemplo abaixo usamos um certificado self-signed apenas para laboratorio e testes locais. Isso funciona bem para ambientes como *.localhost, mas não deve ser a abordagem usada em produção.

Em ambiente produtivo, o normal é importar um certificado real emitido por uma autoridade certificadora ou gerenciado pelo time de infraestrutura. Se você já tiver os arquivos tls.crt e tls.key, basta criar o secret no namespace do Traefik:

kubectl create secret tls local-selfsigned-tls \
  --cert=tls.crt --key=tls.key \
  --namespace traefik

Se quiser usar um nome mais apropriado para produção, por exemplo app-tls, o comando fica assim:

kubectl create secret tls app-tls \
  --cert=tls.crt --key=tls.key \
  --namespace traefik

Nesse caso, lembre de ajustar o certificateRefs.name no values.yaml para apontar para o nome correto do secret.

Gerando um certificado self-signed

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

Criando o secret TLS no namespace do Traefik

kubectl create namespace traefik
kubectl create secret tls local-selfsigned-tls \
  --cert=tls.crt --key=tls.key \
  --namespace traefik

Adicionando o repositório do chart

helm repo add traefik https://traefik.github.io/charts
helm repo update

Instalando o Traefik

helm upgrade --install traefik traefik/traefik \
  --namespace traefik \
  --create-namespace \
  --values values.yaml

Exemplo de values.yaml

# Ajuste do Service para usar NodePort com externalTrafficPolicy Local
service:
  type: NodePort
  spec:
    externalTrafficPolicy: Local

# Configura as portas de rede e os EntryPoints.
# EntryPoints sao os listeners de rede para trafego de entrada.
ports:
  # Define o entry point HTTP chamado `web`.
  web:
    port: 8000
    nodePort: 30000
    # Redireciona todo o trafego desse entry point para `websecure`.
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true

  # Define o entry point HTTPS chamado `websecure`.
  websecure:
    port: 8443
    nodePort: 30001

# Vamos rotear usando Gateway API em vez de Ingress.
ingressClass:
  enabled: false

# Providers dizem ao Traefik onde encontrar a configuracao de roteamento.
providers:
  kubernetesIngress:
    enabled: false
  kubernetesGateway:
    enabled: true

# Listeners do Gateway.
gateway:
  listeners:
    web:
      # Listener HTTP que corresponde ao entryPoint `web`.
      port: 8000
      protocol: HTTP
      namespacePolicy:
        from: All

    websecure:
      port: 8443
      protocol: HTTPS
      namespacePolicy:
        from: All
      mode: Terminate
      certificateRefs:
        - kind: Secret
          name: local-selfsigned-tls
          group: ""

# Habilita observabilidade.
logs:
  general:
    level: INFO
  # Habilita access logs na saida padrao do Traefik.
  access:
    enabled: true

# Habilita metricas Prometheus.
metrics:
  prometheus:
    enabled: true

# Cabecalhos encaminhados confiaveis para quando o trafego vier do Cloudflare.
additionalArguments:
  - "--entrypoints.web.forwardedheaders.trustedips=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22"
  - "--entrypoints.websecure.forwardedheaders.trustedips=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22"

Com essa configuração, Traefik fica pronto para usar Gateway API e já expõe listeners HTTP e HTTPS no gateway principal.

Um único Gateway para vários serviços

Em vez de criar um Gateway para cada aplicação, o mais comum em cenários simples é ter um único gateway compartilhado e conectar vários HTTPRoute nele.

Esse é justamente o modelo mais natural de migração a partir de Ingress: você mantém uma entrada compartilhada e move as regras de roteamento para HTTPRoute.

Descobrindo o nome do Gateway criado pelo chart

Depois da instalação, veja os gateways disponíveis:

kubectl get gateway -A

Use o nome retornado por esse comando nos exemplos abaixo. Neste artigo vamos assumir o nome traefik-gateway no namespace traefik.

Expondo um serviço com HTTPRoute

Suponha um Service chamado whoami na porta 80, no namespace default. O HTTPRoute abaixo publica esse serviço usando o gateway compartilhado do Traefik:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami
  namespace: default
spec:
  parentRefs:
    - name: traefik-gateway
      namespace: traefik
  hostnames:
    - whoami.localhost
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: whoami
          port: 80

Aplicando:

kubectl apply -f httproute-whoami.yaml

Neste exemplo:

  • o gateway continua centralizado no namespace traefik;
  • a aplicação publica apenas o HTTPRoute no próprio namespace;
  • o tráfego de https://whoami.localhost/ vai para o Service whoami.

Expondo múltiplos serviços no mesmo Gateway

Aqui está o ponto mais importante da migração: o mesmo gateway pode atender várias aplicações diferentes sem precisar duplicar infraestrutura.

Exemplo com dois serviços

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app1
  namespace: default
spec:
  parentRefs:
    - name: traefik-gateway
      namespace: traefik
  hostnames:
    - app1.localhost
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: app1
          port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app2
  namespace: default
spec:
  parentRefs:
    - name: traefik-gateway
      namespace: traefik
  hostnames:
    - app2.localhost
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: app2
          port: 80

Nesse modelo, cada serviço só precisa declarar sua própria rota. O gateway continua único, compartilhado e muito mais fácil de operar.

Migração de Ingress para Gateway API

Uma migração comum é sair de vários recursos Ingress e manter apenas um gateway central.

Antes: um Ingress por aplicação

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app1
spec:
  ingressClassName: nginx
  rules:
    - host: app1.exemplo.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app1
                port:
                  number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app2
spec:
  ingressClassName: traefik
  rules:
    - host: app2.exemplo.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app2
                port:
                  number: 80

Depois: um Gateway compartilhado e várias rotas

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app1
spec:
  parentRefs:
    - name: traefik-gateway
      namespace: traefik
  hostnames:
    - app1.exemplo.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: app1
          port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app2
spec:
  parentRefs:
    - name: traefik-gateway
      namespace: traefik
  hostnames:
    - app2.exemplo.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: app2
          port: 80

A principal mudança conceitual é esta:

  • o gateway deixa de ser repetido por aplicação;
  • cada serviço passa a publicar só a sua rota;
  • a entrada HTTPS/HTTP continua centralizada no Traefik.

Middlewares com Traefik

O Traefik permite usar middlewares próprios junto com HTTPRoute. Isso é útil para reaproveitar comportamentos como CORS, autenticação básica, redirects e outras políticas de entrada.

Exemplo de CORS

Primeiro, crie um middleware:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: cors
  namespace: default
spec:
  headers:
    accessControlAllowMethods:
      - GET
      - POST
      - OPTIONS
    accessControlAllowOriginList:
      - https://app.exemplo.com
    accessControlAllowHeaders:
      - Authorization
      - Content-Type
    accessControlMaxAge: 100
    addVaryHeader: true

Agora associe esse middleware ao HTTPRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app1
  namespace: default
spec:
  parentRefs:
    - name: traefik-gateway
      namespace: traefik
  hostnames:
    - api.exemplo.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      filters:
        - type: ExtensionRef
          extensionRef:
            group: traefik.io
            kind: Middleware
            name: cors
      backendRefs:
        - name: app1
          port: 80

Exemplo de Basic Auth

Crie o secret com o conteúdo em formato compatível com htpasswd:

htpasswd -nb admin senha-forte

Exemplo de secret:

apiVersion: v1
kind: Secret
metadata:
  name: authsecret
  namespace: default
type: Opaque
stringData:
  users: |
    admin:$apr1$EXEMPLO$HASHGERADOAQUI

Depois crie o middleware:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: basic-auth
  namespace: default
spec:
  basicAuth:
    secret: authsecret

E use esse middleware na rota:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: painel
  namespace: default
spec:
  parentRefs:
    - name: traefik-gateway
      namespace: traefik
  hostnames:
    - painel.exemplo.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      filters:
        - type: ExtensionRef
          extensionRef:
            group: traefik.io
            kind: Middleware
            name: basic-auth
      backendRefs:
        - name: painel
          port: 80

Cert-manager

Em ambientes reais, o mais comum é substituir o certificado local por certificados emitidos pelo cert-manager.

A ideia geral continua a mesma:

  • o gateway permanece compartilhado;
  • o listener HTTPS referencia um Secret TLS;
  • o cert-manager passa a manter esse secret atualizado.

Se o seu ambiente já está funcionando com certificado local, faz sentido começar assim e só introduzir cert-manager quando houver necessidade de automatizar emissão e renovação.

Resumo

Para cenários simples, a abordagem mais limpa costuma ser esta:

  1. Instalar o Traefik com Helm.
  2. Deixar o chart criar o gateway principal.
  3. Publicar cada aplicação com um HTTPRoute.
  4. Reaproveitar o mesmo gateway para todos os serviços.
  5. Adicionar middlewares e TLS conforme a necessidade.

Esse modelo reduz a complexidade inicial e deixa a migração a partir de Ingress mais natural.

Referências

Ingress


IMPORTANTE

Ingress nginx foi decontinuado recomendamos usar Traefik com Gateway API

Na página do Gateway API há exemplos de migração de ingress para httproute


Um Ingress é um objeto do Kubernetes que gerencia o acesso externo aos serviços em um cluster, geralmente HTTP. Ele pode fornecer balanceamento de carga, terminação TLS e roteamento baseado em nome de host ou caminho.

Ingress Controller

Para que os recursos de Ingress funcionem, o cluster precisa ter um Ingress Controller em execução. O Ingress Controller é responsável por satisfazer as regras de Ingress. Existem vários Ingress Controllers disponíveis, como Nginx, Traefik e HAProxy.

Ingress NGINX

O Ingress NGINX é um dos Ingress Controllers mais populares. Ele usa o Nginx como um proxy reverso e balanceador de carga.

Instalação

Minikube

Em clusters Minikube, você pode habilitar o Ingress NGINX com o seguinte comando:

minikube addons enable ingress
Helm

Você pode instalar o Ingress NGINX usando o Helm:

helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace

Exemplo de Ingress

Abaixo está um exemplo de um recurso de Ingress que roteia o tráfego para dois serviços diferentes com base no caminho:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /testpath
            pathType: Prefix
            backend:
              service:
                name: test
                port:
                  number: 80
          - path: /anotherpath
            pathType: Prefix
            backend:
              service:
                name: another-test
                port:
                  number: 80

Neste exemplo:

  • O tráfego para http://<host>/testpath é roteado para o serviço test na porta 80.
  • O tráfego para http://<host>/anotherpath é roteado para o serviço another-test na porta 80.

PersistentVolumeClaim (PVC)

Por que o PVC é necessário?

Os containers são efêmeros, o que significa que, quando um container é reiniciado ou excluído, todos os dados armazenados dentro dele são perdidos. Para aplicações que precisam persistir dados (como bancos de dados, uploads de usuários, etc.), precisamos de uma maneira de armazenar dados fora do container, em um local que sobreviva ao ciclo de vida do container.

É aqui que entram os PersistentVolumeClaims (PVCs). Um PVC é uma solicitação de armazenamento que um Pod pode usar para montar um volume persistente. Isso permite que os dados sejam armazenados em um local duradouro, independentemente do que aconteça com o Pod.

O que é um PVC?

Um PersistentVolumeClaim (PVC) é uma solicitação de armazenamento por um usuário. É semelhante a um Pod. Os pods consomem recursos de nó e os PVCs consomem recursos de PersistentVolume (PV). Os pods podem solicitar níveis específicos de recursos (CPU e memória). As solicitações podem solicitar tamanho e modos de acesso específicos (por exemplo, podem ser montados uma vez para leitura/gravação ou muitas para somente leitura).

Ciclo de Vida

  • Provisionamento: O armazenamento pode ser provisionado estaticamente ou dinamicamente.

    • Estático: Um administrador de cluster cria vários PVs. Eles carregam os detalhes do armazenamento real que está disponível para uso pelos usuários do cluster. Eles existem na API do Kubernetes e estão disponíveis para consumo.
    • Dinâmico: Quando nenhum dos PVs estáticos criados pelo administrador corresponde a um PersistentVolumeClaim de um usuário, o cluster pode tentar provisionar dinamicamente um volume especialmente para o PVC. Este provisionamento é baseado em StorageClasses.
  • Binding: Um usuário cria, ou no caso de provisionamento dinâmico, já criou, um PersistentVolumeClaim com uma quantidade específica de armazenamento solicitada e com certos modos de acesso. Um loop de controle no mestre observa os novos PVCs, encontra um PV correspondente (se possível) e os vincula. Se um PV foi provisionado dinamicamente para um novo PVC, o loop sempre vinculará esse PV ao PVC.

  • Uso: Os pods usam as solicitações como volumes. O cluster inspeciona o PVC para encontrar o volume vinculado e monta esse volume para um Pod. Para volumes que suportam vários modos de acesso, o usuário especifica qual modo é desejado ao usar sua solicitação como um volume em um Pod.

Exemplos

Minikube

O Minikube vem com um provisionador de armazenamento padrão que provisiona dinamicamente PersistentVolumes.

  1. Crie um PersistentVolumeClaim:

    pvc.yaml

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: my-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    
  2. Crie o PVC:

    kubectl apply -f pvc.yaml
    
  3. Use o PVC em um Pod:

    pod.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    spec:
      containers:
        - name: my-container
          image: nginx
          volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: my-volume
      volumes:
        - name: my-volume
          persistentVolumeClaim:
            claimName: my-pvc
    
  4. Crie o Pod:

    kubectl apply -f pod.yaml
    

Longhorn

Longhorn é uma solução de armazenamento em bloco distribuído para Kubernetes. É a solução de armazenamento padrão para o SomosBR KaaS.

Para usar o Longhorn, você precisa ter um StorageClass do Longhorn. A StorageClass padrão do Longhorn é longhorn.

  1. Crie um PersistentVolumeClaim com a StorageClass do Longhorn:

    pvc-longhorn.yaml

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: my-longhorn-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      storageClassName: longhorn
      resources:
        requests:
          storage: 1Gi
    
  2. Crie o PVC:

    kubectl apply -f pvc-longhorn.yaml
    
  3. Use o PVC em um Pod (o mesmo pod.yaml do exemplo do Minikube, mas com o claimName alterado para my-longhorn-pvc):

    pod-longhorn.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    spec:
      containers:
        - name: my-container
          image: nginx
          volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: my-volume
      volumes:
        - name: my-volume
          persistentVolumeClaim:
            claimName: my-longhorn-pvc
    
  4. Crie o Pod:

    kubectl apply -f pod-longhorn.yaml
    

Ferramentas

Nesta seção, vamos explorar algumas ferramentas populares que facilitam o gerenciamento de aplicações no Kubernetes.

Kustomize

Kustomize é uma ferramenta de personalização de configuração do Kubernetes que permite que você personalize arquivos YAML brutos e sem templates, deixando a configuração original intocada.

Como funciona

O Kustomize funciona com um arquivo kustomization.yaml que define como personalizar os recursos do Kubernetes. Este arquivo pode:

  • Adicionar um namespace a todos os recursos.
  • Adicionar um prefixo ou sufixo aos nomes dos recursos.
  • Adicionar labels ou anotações a todos os recursos.
  • Mesclar patches com recursos existentes.

Exemplo

Suponha que você tenha um deployment.yaml e um service.yaml para uma aplicação.

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-app:1.0.0

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app: my-app
  ports:
  - port: 80

Agora, crie um arquivo kustomization.yaml para personalizar esses recursos para um ambiente de produção:

kustomization.yaml

resources:
- deployment.yaml
- service.yaml

namePrefix: prod-

commonLabels:
  env: prod

patchesStrategicMerge:
- |
  apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: my-app
  spec:
    replicas: 5

Para gerar os recursos personalizados, execute o comando kubectl kustomize:

kubectl kustomize .

Isso irá gerar os recursos com o prefixo prod-, o label env: prod e o número de réplicas do deployment aumentado para 5.

Helm

Helm é um gerenciador de pacotes para o Kubernetes. Ele ajuda você a gerenciar aplicações Kubernetes — Helm Charts — que são pacotes de recursos Kubernetes pré-configurados.

Conceitos Principais

  • Chart: Um pacote Helm que contém todos os recursos necessários para executar uma aplicação, ferramenta ou serviço dentro de um cluster Kubernetes.
  • Release: Uma instância de um chart em execução em um cluster Kubernetes.
  • Repositório: Um local onde os charts podem ser coletados e compartilhados.

Exemplo de Uso

Adicionando um Repositório

helm repo add stable https://charts.helm.sh/stable

Procurando por Charts

helm search repo stable

Instalando um Chart

Para instalar o chart do WordPress, por exemplo:

helm install wordpress stable/wordpress

Personalizando um Chart

Você pode personalizar a instalação de um chart usando o arquivo values.yaml ou passando os valores na linha de comando.

  1. Crie um arquivo my-values.yaml:

    service:
      type: NodePort
    
  2. Instale o chart com os valores personalizados:

    helm install -f my-values.yaml wordpress stable/wordpress
    

Gerenciando Releases

  • Listar releases: helm list
  • Atualizar um release: helm upgrade wordpress stable/wordpress
  • Reverter um release: helm rollback wordpress 1
  • Desinstalar um release: helm uninstall wordpress