DevOps & CI/CD

Kubernetes Fundamentos: Arquitetura, Componentes e kubectl na Prática: Do Básico ao Avançado

19 min de leitura

Kubernetes Fundamentos: Arquitetura, Componentes e kubectl na Prática: Do Básico ao Avançado

Entendendo Kubernetes: O Orquestrador de Contêineres Kubernetes é uma plataforma de código aberto que automatiza a implantação, o dimensionamento e a gestão de aplicações em contêineres. Seu nome vem do grego antigo, significando "timoneiro" ou "capitão do navio" — uma metáfora perfeita para seu papel em guiar contêineres por um ambiente distribuído. Diferentemente de simplesmente rodar Docker localmente, Kubernetes resolve problemas reais que enfrentamos em produção: como garantir alta disponibilidade, distribuir carga entre múltiplos servidores, fazer rollback automático de falhas e escalar aplicações conforme a demanda. A adoção de Kubernetes é hoje um padrão na indústria porque resolve o problema central da computação moderna: gerenciar centenas ou milhares de contêineres espalhados em múltiplas máquinas simultaneamente. Sem Kubernetes, você precisaria de scripts manuais, monitoramento constante e decisões humanas para colocar contêineres online, detectar falhas e realocá-los. Kubernetes faz isso automaticamente, declarativamente — você descreve o estado desejado e a plataforma trabalha para mantê-lo. Arquitetura do Kubernetes: A Visão Geral A Estrutura

<h2>Entendendo Kubernetes: O Orquestrador de Contêineres</h2>

<p>Kubernetes é uma plataforma de código aberto que automatiza a implantação, o dimensionamento e a gestão de aplicações em contêineres. Seu nome vem do grego antigo, significando &quot;timoneiro&quot; ou &quot;capitão do navio&quot; — uma metáfora perfeita para seu papel em guiar contêineres por um ambiente distribuído. Diferentemente de simplesmente rodar Docker localmente, Kubernetes resolve problemas reais que enfrentamos em produção: como garantir alta disponibilidade, distribuir carga entre múltiplos servidores, fazer rollback automático de falhas e escalar aplicações conforme a demanda.</p>

<p>A adoção de Kubernetes é hoje um padrão na indústria porque resolve o problema central da computação moderna: gerenciar centenas ou milhares de contêineres espalhados em múltiplas máquinas simultaneamente. Sem Kubernetes, você precisaria de scripts manuais, monitoramento constante e decisões humanas para colocar contêineres online, detectar falhas e realocá-los. Kubernetes faz isso automaticamente, declarativamente — você descreve o estado desejado e a plataforma trabalha para mantê-lo.</p>

<h2>Arquitetura do Kubernetes: A Visão Geral</h2>

<h3>A Estrutura Mestre-Nó (Control Plane e Workers)</h3>

<p>Kubernetes funciona com uma arquitetura de cluster baseada em dois tipos principais de máquinas: o <strong>Control Plane</strong> (antigo &quot;master&quot;) e os <strong>Nós Worker</strong>. O Control Plane é o &quot;cérebro&quot; do cluster — ele toma todas as decisões sobre o que rodar, onde rodar e como gerenciar a aplicação. Os Nós Worker são as &quot;mãos&quot; — máquinas que realmente executam os contêineres, sob as ordens do Control Plane.</p>

<p>Essa separação é fundamental para escalabilidade. Um Control Plane pode gerenciar dezenas ou centenas de Nós Worker. Enquanto o Control Plane é responsável por manter o estado desejado através de loops de reconciliação, os Worker Nodes são stateless — podem ser adicionados ou removidos sem prejudicar o cluster, desde que haja replicação adequada das aplicações.</p>

<h3>Componentes do Control Plane</h3>

<p>O Control Plane é composto por quatro componentes principais que trabalham em harmonia:</p>

<p><strong>kube-apiserver</strong> é o ponto de entrada para toda comunicação com o cluster. Ele expõe a API REST do Kubernetes através da qual você submete manifestos YAML, consulta o status de recursos e modifica configurações. Toda requisição passa por aqui, incluindo autenticação e autorização. É stateless, o que significa você pode ter múltiplas instâncias rodando atrás de um load balancer para alta disponibilidade.</p>

<p><strong>etcd</strong> é um banco de dados de chave-valor distribuído que armazena o estado completo do cluster. Cada objeto criado em Kubernetes (Pods, Services, ConfigMaps, etc.) é persistido aqui. É crítico fazer backup regularmente do etcd, pois perder seu conteúdo significa perder toda a configuração do cluster. Kubernetes usa etcd como fonte única de verdade.</p>

<p><strong>kube-scheduler</strong> é responsável por decidir em qual Nó Worker um novo Pod será executado. Ele analisa os requisitos do Pod (limites de CPU, memória, afinidade de nó), o estado dos Nós disponíveis e aplica algoritmos de agendamento para fazer a melhor escolha. Se nenhum Nó atender os requisitos, o Pod fica em estado &quot;Pending&quot; até que um Nó adequado fique disponível.</p>

<p><strong>kube-controller-manager</strong> executa múltiplos controladores que funcionam em loops contínuos verificando o estado desejado versus o estado atual. O ReplicationController, por exemplo, garante que o número correto de replicas de um Pod esteja rodando. Se um Pod falhar, o controlador cria um novo. Se houver Pods extras, ele remove os excedentes.</p>

<h3>Componentes dos Nós Worker</h3>

<p>Cada Nó Worker executa dois componentes essenciais para se comunicar com o Control Plane e rodar containers:</p>

<p><strong>kubelet</strong> é um agente que roda em cada Nó Worker. Ele recebe instruções do Control Plane via API e garante que os contêineres especificados estejam realmente rodando no Nó. O kubelet monitora continuamente a saúde dos Pods — se um contêiner falhar, ele tenta reiniciá-lo conforme a política de restart definida.</p>

<p><strong>kube-proxy</strong> mantém regras de rede no Nó para que os Pods possam se comunicar entre si e com o mundo externo. Ele implementa o modelo de serviço do Kubernetes, garantindo que requisições chegem ao Pod correto através de abstrações como Services.</p>

<h2>Componentes Fundamentais: Recursos do Kubernetes</h2>

<h3>Pod: A Unidade Fundamental</h3>

<p>Um Pod é a menor unidade que você cria em Kubernetes. Não é um contêiner — é um wrapper ao redor de um ou mais contêineres que compartilham espaço de rede. Na maioria dos casos, um Pod contém apenas um contêiner, mas a possibilidade de múltiplos contêineres no mesmo Pod existe para casos especiais onde você precisa de &quot;sidecars&quot; — contêineres auxiliares que enriquecem a aplicação principal.</p>

<p>O que torna um Pod especial é que seus contêineres compartilham um namespace de rede. Isso significa que eles têm o mesmo IP, podem se comunicar via localhost e compartilham volumes. Se você tem dois contêineres em um Pod e um deles faz um bind na porta 8080, o outro não pode fazer o mesmo. Pods são efêmeros — quando terminam, não há persistência automática. Para aplicações stateless, isso é perfeito. Para dados que precisam sobreviver, você usa Volumes.</p>

<pre><code class="language-yaml">apiVersion: v1

kind: Pod

metadata:

name: nginx-pod

labels:

app: web

spec:

containers:

  • name: nginx

image: nginx:latest

ports:

  • containerPort: 80

resources:

requests:

memory: &quot;64Mi&quot;

cpu: &quot;250m&quot;

limits:

memory: &quot;128Mi&quot;

cpu: &quot;500m&quot;</code></pre>

<p>Este manifesto cria um Pod simples rodando Nginx. O campo <code>resources</code> é crítico — <code>requests</code> diz ao scheduler quanto de CPU e memória o Pod necessita, enquanto <code>limits</code> previne que um Pod consumir mais que o permitido e seja evicted (removido) de um Nó quando há pressão de recursos.</p>

<h3>Deployment: Gerenciando Múltiplas Replicas</h3>

<p>Um Deployment é o tipo de objeto que você usa na maioria dos casos em produção. Ele gerencia uma ou mais replicas de Pods e fornece atualização declarativa. Em vez de criar Pods manualmente, você define um Deployment, especifica quantas replicas deseja e o Deployment garante que esse número esteja sempre rodando.</p>

<p>Deployments oferecem estratégias de atualização poderosas. A estratégia padrão é RollingUpdate, que gradualmente substitui Pods antigos por novos, garantindo que a aplicação nunca fique completamente offline durante uma atualização. Você também pode usar Recreate, que mata todos os Pods de uma vez e depois cria novos — mais rápido mas com downtime.</p>

<pre><code class="language-yaml">apiVersion: apps/v1

kind: Deployment

metadata:

name: nginx-deployment

spec:

replicas: 3

selector:

matchLabels:

app: web

strategy:

type: RollingUpdate

rollingUpdate:

maxSurge: 1

maxUnavailable: 0

template:

metadata:

labels:

app: web

spec:

containers:

  • name: nginx

image: nginx:1.14.2

ports:

  • containerPort: 80

livenessProbe:

httpGet:

path: /

port: 80

initialDelaySeconds: 10

periodSeconds: 10

readinessProbe:

httpGet:

path: /

port: 80

initialDelaySeconds: 5

periodSeconds: 5</code></pre>

<p>Este Deployment cria 3 replicas de Nginx. O campo <code>selector.matchLabels</code> conecta o Deployment aos Pods — ele gerencia qualquer Pod com label <code>app: web</code>. As probes (livenessProbe e readinessProbe) são críticas: livenessProbe reinicia o Pod se ele não responder, readinessProbe remove o Pod do tráfego se não estiver pronto. Com <code>maxSurge: 1</code> e <code>maxUnavailable: 0</code>, durante uma atualização, Kubernetes cria um novo Pod antes de matar um antigo, mantendo sempre 3 ou mais Pods disponíveis.</p>

<h3>Service: Expondo Pods para Comunicação</h3>

<p>Um Service é uma abstração que fornece um ponto de acesso estável para um conjunto de Pods. Pods têm IPs dinâmicos — quando um Pod é recriado, seu IP muda. Um Service fornece um nome DNS fixo (por exemplo, <code>nginx-service.default.svc.cluster.local</code>) e um IP virtual que permanece constante, roteando requisições para os Pods corretos automaticamente.</p>

<p>Existem três tipos principais de Service: <strong>ClusterIP</strong> (padrão, acesso apenas dentro do cluster), <strong>NodePort</strong> (expõe em uma porta em cada Nó do cluster) e <strong>LoadBalancer</strong> (provisiona um load balancer externo, funciona bem em clouds públicas).</p>

<pre><code class="language-yaml">apiVersion: v1

kind: Service

metadata:

name: nginx-service

spec:

type: ClusterIP

selector:

app: web

ports:

  • protocol: TCP

port: 80

targetPort: 80</code></pre>

<p>Este Service roteia tráfego na porta 80 para qualquer Pod com label <code>app: web</code>. Dentro do cluster, qualquer Pod pode acessar este serviço fazendo requisições para <code>nginx-service.default.svc.cluster.local:80</code>. O Service atua como um load balancer interno, distribuindo requisições entre todas as replicas disponíveis.</p>

<h3>ConfigMap e Secret: Gerenciando Configuração</h3>

<p>ConfigMap armazena dados de configuração em pares chave-valor, enquanto Secret faz o mesmo mas com dados sensíveis (senhas, tokens, chaves). A diferença principal é que Secrets são codificados em base64 no etcd (não realmente criptografados por padrão — use encryption at rest em produção) e há convenção de que dados sensíveis vão lá.</p>

<pre><code class="language-yaml">apiVersion: v1

kind: ConfigMap

metadata:

name: app-config

data:

LOG_LEVEL: &quot;info&quot;

DATABASE_HOST: &quot;postgres.default.svc.cluster.local&quot;

DATABASE_PORT: &quot;5432&quot;

---

apiVersion: v1

kind: Secret

metadata:

name: app-secret

type: Opaque

data:

DATABASE_PASSWORD: cG9zdGdyZXM= # base64 encoded &quot;postgres&quot;

API_KEY: c2VjcmV0LWtleQ== # base64 encoded &quot;secret-key&quot;</code></pre>

<p>Você injeta esses valores em Pods de duas formas: como variáveis de ambiente ou como arquivos montados em volumes. A segunda forma é preferida para dados grandes ou que mudam com frequência, pois permite recarregamento sem reiniciar o Pod.</p>

<h2>kubectl: Interagindo com o Cluster na Prática</h2>

<h3>Configuração e Contextos</h3>

<p><code>kubectl</code> é a ferramenta de linha de comando para interagir com Kubernetes. Ela se comunica com o kube-apiserver do cluster. Sua configuração é armazenada em <code>~/.kube/config</code>, um arquivo YAML que define clusters, usuários e contextos.</p>

<pre><code class="language-bash"># Listar todos os contextos disponíveis

kubectl config get-contexts

Mudar para um contexto específico

kubectl config use-context meu-cluster

Ver o contexto atual

kubectl config current-context

Visualizar a configuração completa

kubectl config view</code></pre>

<p>Um contexto conecta um cluster a um usuário (credenciais). Se você trabalha com múltiplos clusters (desenvolvimento, staging, produção), você provavelmente tem múltiplos contextos. Uma prática segura é sempre verificar o contexto atual antes de executar comandos destrutivos em produção.</p>

<h3>Operações Básicas com kubectl</h3>

<p>As operações fundamentais em Kubernetes seguem um padrão: <code>kubectl [verbo] [tipo-de-recurso] [nome] [flags]</code>. Você pode criar recursos a partir de arquivos YAML, deletá-los, verificar seu status e modificá-los.</p>

<pre><code class="language-bash"># Criar recursos a partir de um arquivo YAML

kubectl apply -f deployment.yaml

Listar todos os Pods no namespace padrão

kubectl get pods

Listar todos os Pods em todos os namespaces

kubectl get pods --all-namespaces

Obter informações detalhadas de um Pod específico

kubectl describe pod nginx-pod

Ver os logs de um Pod

kubectl logs nginx-pod

Ver logs em tempo real (follow)

kubectl logs -f nginx-pod

Deletar um Pod

kubectl delete pod nginx-pod

Deletar todos os recursos definidos em um arquivo

kubectl delete -f deployment.yaml

Verificar eventos do cluster

kubectl get events</code></pre>

<p>Quando você aplica um manifesto com <code>kubectl apply</code>, Kubernetes verifica se o recurso já existe. Se existir, ele atualiza. Se não existir, cria. Isso torna fácil fazer alterações incrementais — você só edita o arquivo YAML e aplica novamente.</p>

<h3>Debugging e Troubleshooting</h3>

<p>Quando algo dá errado, você precisa de habilidades de debugging. Os comandos abaixo são seus aliados:</p>

<pre><code class="language-bash"># Descrever um recurso para ver seu status e eventos

kubectl describe pod meu-pod

Executar um comando dentro de um Pod (como docker exec)

kubectl exec -it meu-pod -- /bin/bash

Fazer port-forward de um Pod para sua máquina local

kubectl port-forward pod/meu-pod 8080:8080

Ver eventos do cluster em tempo real

kubectl get events --sort-by=&#039;.lastTimestamp&#039; --watch

Verificar a saúde dos nós

kubectl get nodes

kubectl describe node meu-node

Ver métricas de uso (requer metrics-server instalado)

kubectl top nodes

kubectl top pods</code></pre>

<p><code>kubectl exec</code> é particularmente poderoso para debugging — você acessa o shell do contêiner para verificar configurações, testar conectividade ou investigar por que a aplicação não está funcionando. <code>port-forward</code> é útil para acessar uma aplicação rodando em um Pod sem expô-la publicamente.</p>

<h3>Atualizações Declarativas e Rollback</h3>

<p>Uma das vantagens de Kubernetes é que você descreve o estado desejado e aplica, não importa qual era o estado anterior. Isso significa que atualizações são naturalmente replicáveis.</p>

<pre><code class="language-bash"># Atualizar a imagem de um Deployment (imperativo, não recomendado em produção)

kubectl set image deployment/nginx-deployment nginx=nginx:1.16.0

Melhor: editar o manifesto e aplicar novamente

kubectl apply -f deployment.yaml

Ver o histórico de rollouts

kubectl rollout history deployment/nginx-deployment

Reverter para a revisão anterior

kubectl rollout undo deployment/nginx-deployment

Reverter para uma revisão específica

kubectl rollout undo deployment/nginx-deployment --to-revision=2

Ver o status de um rollout em andamento

kubectl rollout status deployment/nginx-deployment</code></pre>

<p>Em produção, você sempre deve usar <code>kubectl apply -f</code> com manifestos no controle de versão (Git), nunca usar <code>kubectl set image</code>. Isso garante que o histórico completo de mudanças está registrado, e qualquer desenvolvedor pode ver exatamente o que foi alterado e quando.</p>

<h2>Exemplo Prático Completo: Deploy de uma Aplicação Real</h2>

<p>Para consolidar o aprendizado, vamos deployar uma aplicação real — uma API Node.js simples com um banco de dados PostgreSQL. Este exemplo cobre Deployment, Service, ConfigMap, Secret e Volume.</p>

<pre><code class="language-yaml"># namespace.yaml - Criar um namespace separado para a aplicação

apiVersion: v1

kind: Namespace

metadata:

name: producao

---

configmap.yaml - Configurações gerais

apiVersion: v1

kind: ConfigMap

metadata:

name: api-config

namespace: producao

data:

NODE_ENV: &quot;production&quot;

LOG_LEVEL: &quot;info&quot;

DATABASE_HOST: &quot;postgres.producao.svc.cluster.local&quot;

DATABASE_PORT: &quot;5432&quot;

DATABASE_NAME: &quot;app_db&quot;

---

secret.yaml - Dados sensíveis

apiVersion: v1

kind: Secret

metadata:

name: api-secret

namespace: producao

type: Opaque

stringData:

DATABASE_USER: &quot;postgres&quot;

DATABASE_PASSWORD: &quot;securepassword123&quot;

JWT_SECRET: &quot;sua-chave-secreta-super-segura&quot;

---

postgres-pvc.yaml - Volume persistente para o banco

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: postgres-pvc

namespace: producao

spec:

accessModes:

  • ReadWriteOnce

resources:

requests:

storage: 10Gi

---

postgres-deployment.yaml - Deploy do PostgreSQL

apiVersion: apps/v1

kind: Deployment

metadata:

name: postgres

namespace: producao

spec:

replicas: 1

selector:

matchLabels:

app: postgres

template:

metadata:

labels:

app: postgres

spec:

containers:

  • name: postgres

image: postgres:13

ports:

  • containerPort: 5432

env:

  • name: POSTGRES_USER

valueFrom:

secretKeyRef:

name: api-secret

key: DATABASE_USER

  • name: POSTGRES_PASSWORD

valueFrom:

secretKeyRef:

name: api-secret

key: DATABASE_PASSWORD

  • name: POSTGRES_DB

valueFrom:

configMapKeyRef:

name: api-config

key: DATABASE_NAME

volumeMounts:

  • name: postgres-storage

mountPath: /var/lib/postgresql/data

subPath: postgres

resources:

requests:

memory: &quot;256Mi&quot;

cpu: &quot;100m&quot;

limits:

memory: &quot;512Mi&quot;

cpu: &quot;500m&quot;

volumes:

  • name: postgres-storage

persistentVolumeClaim:

claimName: postgres-pvc

---

postgres-service.yaml - Service para o PostgreSQL (ClusterIP)

apiVersion: v1

kind: Service

metadata:

name: postgres

namespace: producao

spec:

type: ClusterIP

selector:

app: postgres

ports:

  • protocol: TCP

port: 5432

targetPort: 5432

---

api-deployment.yaml - Deploy da aplicação Node.js

apiVersion: apps/v1

kind: Deployment

metadata:

name: api

namespace: producao

spec:

replicas: 3

strategy:

type: RollingUpdate

rollingUpdate:

maxSurge: 1

maxUnavailable: 0

selector:

matchLabels:

app: api

template:

metadata:

labels:

app: api

spec:

containers:

  • name: api

image: minha-api:1.0.0

imagePullPolicy: IfNotPresent

ports:

  • name: http

containerPort: 3000

envFrom:

  • configMapRef:

name: api-config

  • secretRef:

name: api-secret

livenessProbe:

httpGet:

path: /health

port: http

initialDelaySeconds: 30

periodSeconds: 10

timeoutSeconds: 5

failureThreshold: 3

readinessProbe:

httpGet:

path: /ready

port: http

initialDelaySeconds: 10

periodSeconds: 5

timeoutSeconds: 3

failureThreshold: 2

resources:

requests:

memory: &quot;128Mi&quot;

cpu: &quot;100m&quot;

limits:

memory: &quot;256Mi&quot;

cpu: &quot;500m&quot;

affinity:

podAntiAffinity:

preferredDuringSchedulingIgnoredDuringExecution:

  • weight: 100

podAffinityTerm:

labelSelector:

matchExpressions:

  • key: app

operator: In

values:

  • api

topologyKey: kubernetes.io/hostname

---

api-service.yaml - Service para expor a API (NodePort ou LoadBalancer)

apiVersion: v1

kind: Service

metadata:

name: api

namespace: producao

spec:

type: LoadBalancer

selector:

app: api

ports:

  • name: http

protocol: TCP

port: 80

targetPort: http</code></pre>

<p>Para aplicar este exemplo em um cluster real:</p>

<pre><code class="language-bash"># Criar todos os recursos de uma vez

kubectl apply -f namespace.yaml

kubectl apply -f configmap.yaml

kubectl apply -f secret.yaml

kubectl apply -f postgres-pvc.yaml

kubectl apply -f postgres-deployment.yaml

kubectl apply -f postgres-service.yaml

kubectl apply -f api-deployment.yaml

kubectl apply -f api-service.yaml

Ou aplicar um diretório inteiro (se todos os arquivos estão em uma pasta)

kubectl apply -f ./producao/

Verificar o status

kubectl get pods -n producao

kubectl get services -n producao

kubectl describe deployment api -n producao

Ver logs de um Pod específico

kubectl logs -f deployment/api -n producao

Acessar o shell de um Pod para debug

kubectl exec -it -n producao $(kubectl get pods -n producao -l app=api -o jsonpath=&#039;{.items[0].metadata.name}&#039;) -- /bin/bash</code></pre>

<p>Este exemplo real cobre cenários práticos: uso de ConfigMap para configuração, Secret para dados sensíveis, PersistentVolumeClaim para persistência, probes para health checks, anti-afinidade para distribuir Pods entre nós, e limites de recursos para evitar que um Pod domine a máquina.</p>

<h2>Conclusão</h2>

<p>Você agora domina os três pilares fundamentais de Kubernetes: <strong>Arquitetura</strong>, compreendendo como o Control Plane orquestra Nós Worker através de componentes como scheduler, controller-manager e API server; <strong>Componentes</strong>, sabendo que Pods são efêmeros, Deployments garantem replicação confiável, Services fornecem pontos de acesso estáveis, e ConfigMaps/Secrets gerenciam configuração; e <strong>kubectl</strong>, podendo criar, atualizar, debugar e gerenciar recursos através de manifestos YAML aplicados declarativamente.</p>

<p>A lição mais importante não é memorizar cada flag ou componente — é entender que Kubernetes oferece primitivas simples que você compõe para resolver problemas complexos de orquestração. Cada recurso (Pod, Deployment, Service) resolve um problema específico, e você aprende combinando-os. Comece pequeno, deployando aplicações simples em um cluster local (minikube, kind ou Docker Desktop), e gradualmente explore cenários mais avançados como Ingress, StatefulSets, Jobs e Custom Resources conforme sua confiança cresce.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://kubernetes.io/docs/" target="_blank" rel="noopener noreferrer">Documentação Oficial do Kubernetes</a></li>

<li><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/" target="_blank" rel="noopener noreferrer">Kubernetes API Reference</a></li>

<li><a href="https://kubernetes.io/docs/concepts/configuration/overview/" target="_blank" rel="noopener noreferrer">Best Practices for Kubernetes in Production</a></li>

<li><a href="https://www.thekubernetesbook.com/" target="_blank" rel="noopener noreferrer">The Kubernetes Book por Nigel Poulton</a></li>

<li><a href="https://www.cncf.io/projects/kubernetes/" target="_blank" rel="noopener noreferrer">CNCF Kubernetes Project</a></li>

</ul>

<p>&lt;!-- FIM --&gt;</p>

Comentários

Mais em DevOps & CI/CD

O que Todo Dev Deve Saber sobre ELK Stack: Elasticsearch, Logstash e Kibana para Logs Centralizados
O que Todo Dev Deve Saber sobre ELK Stack: Elasticsearch, Logstash e Kibana para Logs Centralizados

Introdução ao ELK Stack O ELK Stack é uma solução de código aberto composta p...

Feature Flags: como realizar deploys mais seguros e confiáveis
Feature Flags: como realizar deploys mais seguros e confiáveis

A gestão de mudanças no código-fonte de um sistema é uma tarefa constante e d...

Boas Práticas de Terraform Fundamentos: Providers, Resources, State e Plan para Times Ágeis
Boas Práticas de Terraform Fundamentos: Providers, Resources, State e Plan para Times Ágeis

Introdução ao Terraform Terraform é uma ferramenta de Infrastructure as Code...