Implantar Aplicações no Kubernetes

KubernetesBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá como implantar aplicações em um cluster Kubernetes. Começaremos configurando um ambiente Kubernetes usando Minikube. Em seguida, você explorará comandos essenciais do kubectl para interagir com seu cluster e gerenciar recursos Kubernetes. Depois, você criará um arquivo YAML simples, o aplicará ao seu cluster e verificará o status da implantação. Finalmente, você aprenderá como acessar sua aplicação implantada usando kubectl proxy.

Este laboratório cobrirá habilidades fundamentais do Kubernetes, incluindo configuração de cluster, gerenciamento básico de recursos e implantação de aplicações. Ao final deste laboratório, você terá uma compreensão sólida de como trabalhar com o Kubernetes e implantar suas próprias aplicações.

Este é um Lab Guiado, que fornece instruções passo a passo para ajudá-lo a aprender e praticar. Siga as instruções cuidadosamente para completar cada etapa e ganhar experiência prática. Dados históricos mostram que este é um laboratório de nível iniciante com uma taxa de conclusão de 82%. Recebeu uma taxa de avaliações positivas de 97% dos estudantes.

Iniciar o Cluster Kubernetes

Nesta etapa, iniciaremos um cluster Kubernetes usando Minikube. Minikube é uma ótima ferramenta para desenvolvimento e aprendizado de Kubernetes, pois permite executar um cluster Kubernetes de nó único em um ambiente virtualizado. Em seguida, verificaremos se o cluster está rodando corretamente e pronto para uso.

Primeiro, abra seu terminal. É aqui que você digitará comandos para interagir com seu computador. Para iniciar o cluster Minikube, digite o seguinte comando e pressione Enter:

minikube start

Este comando iniciará o processo de criação e inicialização do seu cluster Kubernetes. O Minikube baixará os componentes necessários e configurará seu cluster. Você verá a saída no seu terminal enquanto o Minikube inicia. Aqui está um exemplo de como a saída pode parecer:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Automatically selected the docker driver
📌  Using Docker driver with root permissions
🔥  Creating kubernetes in kubernetes cluster
🔄  Restarting existing kubernetes cluster
🐳  Preparing Kubernetes v1.26.1 on Docker 20.10.23 ...
🚀  Launching Kubernetes ...
🌟  Enabling addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace

Assim que o Minikube iniciar, vamos verificar se ele está rodando e se o cluster Kubernetes está pronto. Execute os seguintes comandos um após o outro, pressionando Enter após cada comando:

minikube status
kubectl get nodes

O comando minikube status informará o status do próprio Minikube. O comando kubectl get nodes se comunicará com seu cluster Kubernetes e recuperará informações sobre os nós (computadores) do seu cluster. Como o Minikube é um cluster de nó único, você deverá ver um nó listado.

Aqui está um exemplo da saída que você pode ver:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

Vamos detalhar o que essa saída nos diz:

  1. O status do minikube mostra Running para host, kubelet e apiserver. Isso indica que os componentes principais do Minikube estão rodando corretamente.
  2. kubectl get nodes mostra um nó chamado minikube com um STATUS de Ready. Ready significa que este nó está pronto para executar aplicações. control-plane em ROLES indica que este nó está atuando como o plano de controle (control plane) para o cluster Kubernetes, gerenciando e orquestrando o cluster.

Esses comandos confirmam que:

  1. O Minikube está rodando no ambiente de máquina virtual.
  2. Um cluster Kubernetes foi criado e configurado pelo Minikube.
  3. O cluster Kubernetes está em um estado Ready e pronto para uso.
  4. Você tem um cluster Kubernetes de nó único onde o nó minikube está atuando como o plano de controle.

Aprender Comandos e Sintaxe Básicos do kubectl

Nesta etapa, você explorará comandos fundamentais do kubectl. O kubectl é a ferramenta de linha de comando que permite interagir com seu cluster Kubernetes. É essencial para gerenciar recursos Kubernetes. Demonstraremos como usar o kubectl para visualizar recursos e entender o gerenciamento básico de objetos Kubernetes.

Vamos começar explorando os namespaces dentro do seu cluster Kubernetes. Namespaces são uma forma de organizar seus recursos Kubernetes. Por padrão, os clusters Kubernetes possuem vários namespaces para componentes de sistema e recursos de usuário. Para ver uma lista de namespaces, execute o seguinte comando:

kubectl get namespaces

Este comando listará todos os namespaces disponíveis no seu cluster. Exemplo de saída:

NAME              STATUS   AGE
default           Active   10m
kube-node-lease   Active   10m
kube-public       Active   10m
kube-system       Active   10m

Normalmente, você verá pelo menos estes namespaces padrão:

  • default: O namespace padrão para recursos criados pelo usuário se nenhum outro namespace for especificado.
  • kube-node-lease: Usado para "leases" de nós (node leases), que ajudam o plano de controle a rastrear a saúde dos nós.
  • kube-public: Destinado a recursos que devem ser publicamente acessíveis (embora raramente seja usado para informações sensíveis).
  • kube-system: Contém recursos de nível de sistema, como componentes centrais do Kubernetes.

Em seguida, vamos visualizar os componentes do sistema rodando no namespace kube-system. Muitos componentes centrais do Kubernetes rodam como pods dentro deste namespace. Para visualizar pods em um namespace específico, use o flag -n ou --namespace seguido pelo nome do namespace. Execute o seguinte comando para ver os pods no namespace kube-system:

kubectl get pods -n kube-system

Este comando listará todos os pods rodando no namespace kube-system. Exemplo de saída:

NAME                               READY   STATUS    RESTARTS   AGE
coredns-787d4945fb-j8rhx           1/1     Running   0          15m
etcd-minikube                       1/1     Running   0          15m
kube-apiserver-minikube             1/1     Running   0          15m
kube-controller-manager-minikube    1/1     Running   0          15m
kube-proxy-xb9rz                    1/1     Running   0          15m
kube-scheduler-minikube             1/1     Running   0          15m
storage-provisioner                 1/1     Running   0          15m

Esta saída mostra os nomes dos pods, seu status READY (quantos contêineres no pod estão prontos dos totais), seu STATUS (por exemplo, Running), quantas vezes eles foram RESTARTED e sua AGE. Estes são os componentes essenciais que fazem o Kubernetes funcionar.

Agora, vamos explorar alguns padrões básicos de comandos do kubectl. A sintaxe geral para comandos kubectl é:

kubectl [command] [TYPE] [NAME] [flags]

Vamos detalhar isso:

  • kubectl: A própria ferramenta de linha de comando.
  • [command]: Especifica qual ação você deseja realizar. Comandos comuns incluem:
    • get: Exibir um ou mais recursos.
    • describe: Mostrar detalhes sobre um recurso específico.
    • create: Criar um novo recurso.
    • delete: Excluir recursos.
    • apply: Aplicar uma configuração a um recurso. Usaremos isso bastante mais tarde.
  • [TYPE]: Especifica o tipo de recurso Kubernetes com o qual você deseja interagir. Tipos de recursos comuns incluem:
    • pods: As menores unidades implantáveis no Kubernetes.
    • deployments: Gerenciar conjuntos de pods para escalonamento e atualizações.
    • services: Expor aplicações rodando em pods.
    • nodes: As máquinas de trabalho no seu cluster Kubernetes.
    • namespaces: Agrupamentos lógicos de recursos.
  • [NAME]: O nome de um recurso específico. Isso é opcional; se você omitir o nome, o kubectl operará em todos os recursos do tipo especificado.
  • [flags]: Flags opcionais para modificar o comportamento do comando (por exemplo, -n <namespace>, -o wide).

Vamos ver alguns exemplos:

## Obter todos os recursos no namespace padrão
kubectl get all

## Descrever um tipo de recurso específico (o nó 'minikube')
kubectl describe nodes minikube

O comando kubectl get all recuperará informações sobre todos os tipos de recursos (serviços, deployments, pods, etc.) no namespace default. A saída de exemplo pode ser algo como:

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   20m

Isso mostra que, no namespace default, temos um service chamado kubernetes.

O comando kubectl describe nodes minikube fornecerá muitas informações detalhadas sobre o nó minikube, incluindo seu status, capacidade, endereços e muito mais. Isso é útil para entender o estado e a configuração dos seus nós.

Esses comandos ajudam você a:

  1. Visualizar os recursos dentro do seu cluster Kubernetes.
  2. Obter informações detalhadas sobre os componentes do cluster e seu status atual.
  3. Entender a estrutura básica de comandos e a sintaxe do kubectl.

Criar um Manifest YAML Simples

Antes de criar seu primeiro manifest YAML, é importante entender os principais objetos do Kubernetes com os quais você trabalhará. Esses objetos são os blocos de construção para gerenciar e orquestrar suas aplicações dentro do Kubernetes.

Entendendo Objetos do Kubernetes

  • Pod: A unidade mais básica no Kubernetes. Um pod é como uma caixa que pode conter um ou mais contêineres. Esses contêineres dentro de um pod compartilham a mesma rede e armazenamento. Pense em um pod como representando uma única instância da sua aplicação.
  • Deployment: Deployments são usados para gerenciar pods. Eles garantem que um número desejado de réplicas de pod esteja rodando o tempo todo. Se um pod falhar, um deployment o substituirá automaticamente. Deployments também lidam com atualizações da sua aplicação de forma controlada, como atualizações graduais (rolling updates).
  • Service: Services fornecem uma maneira estável de acessar sua aplicação rodando em pods. Como pods podem ser criados e destruídos, seus endereços IP podem mudar. Um service fornece um endereço IP fixo e um nome DNS que sempre aponta para o conjunto de pods que ele gerencia. Isso permite que outras partes da sua aplicação, ou usuários externos, acessem sua aplicação de forma confiável sem precisar rastrear IPs de pods individuais.

Aqui está um diagrama para ilustrar as relações entre esses objetos:

graph TD; A[Deployment] -->|Manages| B[Pods] B -->|Contains| C[Containers] B -->|Communicates via| D[Services] D -->|Exposes| E[External Clients]

Entender esses objetos é crucial porque você definirá seu estado desejado e configuração usando manifestos YAML.

Visão Geral do Manifest YAML

Um manifesto YAML no Kubernetes é um arquivo escrito no formato YAML que descreve os objetos Kubernetes que você deseja criar ou gerenciar. YAML é uma linguagem de serialização de dados legível por humanos. Usar YAML para manifestos Kubernetes tem várias vantagens:

  1. Gerenciamento Declarativo: Você descreve o estado desejado dos seus recursos no arquivo YAML (por exemplo, "Quero 3 réplicas da minha aplicação rodando"). O Kubernetes então trabalha para fazer com que o estado real corresponda ao seu estado desejado. Isso é chamado de gerenciamento declarativo.
  2. Controle de Versão: Arquivos YAML são baseados em texto e podem ser facilmente armazenados em sistemas de controle de versão como o Git. Isso permite que você rastreie alterações nas suas configurações Kubernetes ao longo do tempo, reverta para configurações anteriores e colabore com outras pessoas.
  3. Reutilização e Portabilidade: Você pode reutilizar manifestos YAML em diferentes ambientes (desenvolvimento, testes, produção) com alterações mínimas. Isso torna suas implantações mais consistentes e reproduzíveis.

Agora que você entende os conceitos básicos de objetos Kubernetes e manifestos YAML, está pronto para criar seu primeiro manifesto.

Criando um Manifest YAML

Primeiro, navegue até o diretório do seu projeto. Assume-se que você tenha um diretório project no seu diretório home (~). Se você não o tiver, crie-o agora usando mkdir project. Em seguida, altere seu diretório atual para project usando cd project:

cd ~/project

Em seguida, crie um novo diretório para armazenar seus manifestos Kubernetes. Vamos chamá-lo de k8s-manifests. Use o comando mkdir para criar o diretório e depois cd para entrar nele:

mkdir -p k8s-manifests
cd k8s-manifests

Agora, você criará seu primeiro arquivo de manifesto YAML. Vamos começar com um manifesto simples para um pod NGINX. NGINX é um servidor web popular. Criaremos um pod que executa um único contêiner NGINX. Use o editor de texto nano para criar um arquivo chamado nginx-pod.yaml:

nano nginx-pod.yaml

nano é um editor de texto simples que roda no seu terminal. Assim que o nano abrir, cole o seguinte conteúdo no arquivo:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80

Vamos entender cada parte deste manifesto YAML:

  • apiVersion: v1: Especifica a versão da API Kubernetes a ser usada para criar este objeto. v1 é o grupo de API principal e é usado para objetos fundamentais como pods, services e namespaces.
  • kind: Pod: Indica que você está definindo um recurso Pod.
  • metadata:: Contém dados sobre o Pod, como seu nome e labels.
    • name: nginx-pod: Define o nome do Pod como nginx-pod. É assim que você se referirá a este pod dentro do Kubernetes.
    • labels:: Labels são pares chave-valor que são anexados a objetos. Eles são usados para organizar e selecionar subconjuntos de objetos. Aqui, estamos adicionando um label app: nginx a este pod.
  • spec:: Descreve o estado desejado do Pod.
    • containers:: Uma lista de contêineres a serem executados dentro do Pod. Neste caso, temos apenas um contêiner.
      • - name: nginx: Define o nome do contêiner como nginx.
      • image: nginx:latest: Especifica a imagem do contêiner a ser usada. nginx:latest refere-se à versão mais recente da imagem Docker NGINX do Docker Hub.
      • ports:: Uma lista de portas que este contêiner exporá.
        • - containerPort: 80: Especifica que o contêiner exporá a porta 80. A porta 80 é a porta HTTP padrão.

Após colar o conteúdo, salve o arquivo e saia do nano. Para fazer isso, pressione Ctrl+X (sair), digite Y (sim para salvar) e, finalmente, pressione Enter para confirmar o nome do arquivo e salvar.

Agora que você criou seu arquivo nginx-pod.yaml, precisa aplicá-lo ao seu cluster Kubernetes para criar o pod. Use o comando kubectl apply com o flag -f, que especifica o arquivo contendo o manifesto:

kubectl apply -f nginx-pod.yaml

Este comando envia o manifesto para o seu cluster Kubernetes, e o Kubernetes criará o pod conforme definido. Você deverá ver uma saída semelhante a esta:

pod/nginx-pod created

Para verificar se o pod foi criado e está rodando, use o comando kubectl get pods. Isso listará todos os pods no namespace padrão. Você também pode usar kubectl describe pod nginx-pod para obter informações detalhadas sobre o nginx-pod. Execute estes comandos:

kubectl get pods
kubectl describe pod nginx-pod

Exemplo de saída para kubectl get pods:

NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          1m

Esta saída mostra que o nginx-pod está READY (1 de 1 contêiner está pronto) e seu STATUS é Running. Isso significa que seu pod NGINX foi criado com sucesso e está rodando.

Agora, vamos criar um manifesto para um recurso mais complexo: um Deployment. Um Deployment gerenciará um conjunto de pods, garantindo que o número desejado de réplicas esteja rodando. Crie um novo arquivo chamado nginx-deployment.yaml usando nano:

nano nginx-deployment.yaml

Cole o seguinte conteúdo em 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:latest
          ports:
            - containerPort: 80

Vamos destacar as principais diferenças e novas partes em comparação com o manifesto nginx-pod.yaml:

  • apiVersion: apps/v1: Para Deployments, você usa a versão da API apps/v1, que faz parte do grupo de API apps e lida com recursos de gerenciamento de aplicações de nível superior.
  • kind: Deployment: Indica que você está definindo um recurso Deployment.
  • spec:: A seção spec para um Deployment é mais complexa porque define como o Deployment deve gerenciar os pods.
    • replicas: 3: Isso é novo. Especifica que você deseja que 3 réplicas (cópias) do seu pod estejam rodando. O Deployment garantirá que sempre haja 3 pods correspondendo aos critérios definidos no template.
    • selector:: Um seletor é usado pelo Deployment para identificar quais pods ele deve gerenciar.
      • matchLabels:: Define os labels que os pods devem ter para serem selecionados por este Deployment. Aqui, ele seleciona pods com o label app: nginx.
    • template:: O template define a especificação do pod que o Deployment usará para criar novos pods. É essencialmente a mesma definição de pod do nosso exemplo nginx-pod.yaml, incluindo metadata.labels e spec.containers. Importante: Os labels definidos aqui em template.metadata.labels devem corresponder aos selector.matchLabels para que o Deployment possa gerenciar esses pods.

Salve e saia do nano (Ctrl+X, Y, Enter).

Agora, aplique este manifesto de Deployment ao seu cluster:

kubectl apply -f nginx-deployment.yaml

Você deverá ver uma saída como:

deployment.apps/nginx-deployment created

Verifique o Deployment e os pods que ele criou. Use kubectl get deployments para verificar o status do Deployment e kubectl get pods para ver os pods.

kubectl get deployments
kubectl get pods

Exemplo de saída:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           1m

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          1m
nginx-deployment-xxx-zzz            1/1     Running   0          1m
nginx-deployment-xxx-www            1/1     Running   0          1m
  • kubectl get deployments mostra que o nginx-deployment tem READY 3/3, UP-TO-DATE 3 e AVAILABLE 3. Isso significa que o Deployment criou e está gerenciando com sucesso 3 pods, e todos eles estão prontos e disponíveis.
  • kubectl get pods agora lista três pods com nomes começando com nginx-deployment-. Estes são os pods criados e gerenciados pelo seu nginx-deployment.

Aplicar o Manifest YAML

Nesta etapa, você explorará o comando kubectl apply com mais detalhes e aprenderá diferentes maneiras de aplicar manifestos Kubernetes. Com base nos arquivos YAML da etapa anterior, demonstraremos várias técnicas para aplicar manifestos.

Primeiro, certifique-se de estar no diretório correto:

cd ~/project/k8s-manifests

Vamos criar um novo subdiretório para organizar ainda mais nossos manifestos. Crie um diretório chamado manifests e navegue até ele:

mkdir -p manifests
cd manifests

Agora, vamos criar um manifesto para uma aplicação web simples que inclui tanto um Deployment quanto um Service em um único arquivo. Crie um novo arquivo chamado web-app.yaml usando nano:

nano web-app.yaml

Adicione o seguinte conteúdo a web-app.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

Este manifesto define dois recursos Kubernetes em um único arquivo, separados por ---. Esta é uma maneira comum de agrupar recursos relacionados. Vamos detalhar o que há de novo:

  • Múltiplos Recursos em um Único Arquivo: O arquivo web-app.yaml agora contém duas definições de recursos Kubernetes separadas: um Deployment e um Service. O separador --- é usado para distingui-los.
  • kind: Service: Isso define um recurso Service.
    • spec.selector.app: web: Este Service terá como alvo pods que possuem o label app: web. Isso corresponde aos labels que definimos para os pods criados pelo Deployment web-app.
    • spec.type: ClusterIP: Especifica o tipo de serviço como ClusterIP. Isso significa que o serviço será exposto em um endereço IP interno dentro do cluster e é tipicamente usado para comunicação entre serviços dentro do cluster.
    • spec.ports: Define como o serviço mapeia portas para os pods de destino.
      • port: 80: A porta no próprio Service à qual você acessará.
      • targetPort: 80: A porta nos pods de destino para a qual o serviço encaminhará o tráfego.

Agora, vamos aplicar este manifesto usando diferentes métodos.

Método 1: Aplicar o arquivo inteiro

Esta é a maneira mais comum de aplicar um manifesto. Use kubectl apply -f seguido pelo nome do arquivo:

kubectl apply -f web-app.yaml

Este comando criará tanto o Deployment quanto o Service definidos em web-app.yaml. Você deverá ver uma saída como:

deployment.apps/web-app created
service/web-service created

Método 2: Aplicar de um diretório

Você pode aplicar todos os manifestos em um diretório de uma vez. Se você tiver vários arquivos de manifesto no diretório manifests, pode aplicá-los todos especificando o diretório em vez de um arquivo específico:

kubectl apply -f .

O . representa o diretório atual. O kubectl procurará arquivos YAML neste diretório e aplicará todos eles. Isso é útil quando você organizou seus manifestos em vários arquivos dentro de um diretório.

Método 3: Aplicar de uma URL (Opcional)

O kubectl apply também pode aplicar manifestos diretamente de uma URL. Isso é útil para implantar rapidamente aplicações de exemplo ou configurações hospedadas online. Por exemplo, você pode implantar o deployment master do Redis do repositório de exemplos do Kubernetes:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/redis-master-deployment.yaml

Isso baixará o manifesto da URL e o aplicará ao seu cluster. Nota: Tenha cuidado ao aplicar manifestos de URLs não confiáveis, pois eles podem potencialmente modificar seu cluster.

Vamos explorar algumas opções adicionais para kubectl apply.

Dry Run

Você pode usar o flag --dry-run=client para simular a aplicação de um manifesto sem realmente fazer alterações no cluster. Isso é útil para verificar se o seu manifesto é válido e para ver quais recursos seriam criados ou modificados:

kubectl apply -f web-app.yaml --dry-run=client

Este comando exibirá o que seria criado ou alterado, mas não aplicará realmente as alterações ao seu cluster.

Saída Verbosa

Para uma saída mais detalhada do kubectl apply, você pode usar o flag -v seguido por um nível de verbosidade (por exemplo, -v=7). Níveis de verbosidade mais altos fornecem informações mais detalhadas, o que pode ser útil para depuração:

kubectl apply -f web-app.yaml -v=7

Isso imprimirá muito mais informações sobre as requisições da API que estão sendo feitas e o processamento do manifesto.

Verifique os recursos criados aplicando web-app.yaml. Use kubectl get deployments e kubectl get services para listar os Deployments e Services no seu cluster:

## Listar deployments
kubectl get deployments

## Listar services
kubectl get services

## Descrever o deployment para ver mais detalhes
kubectl describe deployment web-app

Exemplo de saída para kubectl get deployments:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           3m33s
redis-master       0/1     1            0           23s
web-app            2/2     2            2           42s

Exemplo de saída para kubectl get services:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   8m28s
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    46s

Observe que agora você tem um Deployment web-app com 2/2 réplicas READY e um web-service do tipo ClusterIP.

Vamos discutir brevemente a diferença entre gerenciamento declarativo e imperativo no Kubernetes, especialmente no contexto de kubectl apply e kubectl create.

  • kubectl apply: Usa uma abordagem declarativa. Você define o estado desejado em seus arquivos de manifesto, e o kubectl apply tenta alcançar esse estado. Se você executar kubectl apply várias vezes com o mesmo manifesto, o Kubernetes fará alterações apenas se houver diferenças entre o estado desejado no manifesto e o estado atual no cluster. O kubectl apply é geralmente recomendado para gerenciar recursos Kubernetes porque é mais robusto e fácil de gerenciar alterações ao longo do tempo. Ele rastreia a configuração dos seus recursos e permite atualizações incrementais.
  • kubectl create: Usa uma abordagem imperativa. Você instrui diretamente o Kubernetes a criar um recurso. Se você tentar executar kubectl create para um recurso que já existe, geralmente resultará em um erro. O kubectl create é menos flexível para gerenciar atualizações e alterações em comparação com o kubectl apply.

Na maioria dos casos, especialmente para gerenciar implantações de aplicações, kubectl apply é o método preferido e recomendado devido à sua natureza declarativa e melhor tratamento de atualizações e gerenciamento de configuração.

Verificar o Status do Deployment

Nesta etapa, você aprenderá como inspecionar e verificar o status de deployments Kubernetes e outros recursos usando vários comandos kubectl. Você explorará diferentes maneiras de coletar informações sobre suas aplicações em execução e sua saúde dentro do cluster Kubernetes.

Primeiro, certifique-se de estar no diretório manifests dentro do seu projeto:

cd ~/project/k8s-manifests/manifests

Vamos começar listando todos os deployments no namespace atual (que é default, a menos que você o tenha alterado). Use kubectl get deployments:

kubectl get deployments

Este comando fornece uma visão geral concisa dos seus deployments. Exemplo de saída:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           4m44s
redis-master       1/1     1            1           94s
web-app            2/2     2            2           113s

Aqui está o que cada coluna significa:

  • NAME: O nome do deployment.
  • READY: Mostra o número de réplicas prontas versus o número desejado de réplicas (por exemplo, 3/3 significa que 3 réplicas desejadas estão prontas).
  • UP-TO-DATE: Indica quantas réplicas foram atualizadas para o estado desejado mais recente.
  • AVAILABLE: Mostra quantas réplicas estão atualmente disponíveis para atender tráfego.
  • AGE: Há quanto tempo o deployment está em execução.

Para obter informações mais detalhadas em um formato mais amplo, você pode usar o flag -o wide com kubectl get deployments:

kubectl get deployments -o wide

Exemplo de saída:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                      SELECTOR
nginx-deployment   3/3     3            3           4m58s   nginx        nginx:latest                app=nginx
redis-master       1/1     1            1           108s    master       registry.k8s.io/redis:e2e   app=redis,role=master,tier=backend
web-app            2/2     2            2           2m7s    web          nginx:alpine                app=web

A saída -o wide inclui colunas adicionais como CONTAINERS, IMAGES e SELECTOR, fornecendo mais contexto sobre o deployment.

Para inspecionar os pods que fazem parte de um deployment específico, você pode usar labels. Lembre-se de que em nosso manifesto web-app Deployment, definimos o label app: web para os pods. Você pode usar este label para filtrar pods usando kubectl get pods -l <label_selector>. Para ver os pods associados ao deployment web-app, execute:

kubectl get pods -l app=web

Exemplo de saída:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          10m
web-app-xxx-zzz           1/1     Running   0          10m

Isso lista os pods que correspondem ao seletor de label app=web, que são os pods gerenciados pelo Deployment web-app.

Para informações detalhadas sobre um deployment específico, use kubectl describe deployment <deployment_name>. Vamos descrever o deployment web-app:

kubectl describe deployment web-app

O kubectl describe fornece uma riqueza de informações sobre o deployment, incluindo:

  • Name, Namespace, CreationTimestamp, Labels, Annotations: Metadados básicos sobre o deployment.
  • Selector: O seletor de label usado para identificar os pods gerenciados por este deployment.
  • Replicas: Contagens de réplicas desejadas, atualizadas, totais, disponíveis e indisponíveis.
  • StrategyType, RollingUpdateStrategy: Detalhes sobre a estratégia de atualização (por exemplo, RollingUpdate).
  • Pod Template: A especificação usada para criar pods para este deployment.
  • Conditions: Condições que indicam o status do deployment (por exemplo, Available, Progressing).
  • Events: Uma lista de eventos relacionados ao deployment, que podem ser úteis para solução de problemas.

Observe as seções Conditions e Events na saída do describe. Essas seções geralmente fornecem pistas se houver problemas com seu deployment. Por exemplo, se um deployment não estiver se tornando Available, os Events podem mostrar erros relacionados à puxada de imagem, falhas na criação de pods, etc.

Para verificar o status do Service, você pode usar comandos semelhantes. Primeiro, liste todos os services:

kubectl get services

Exemplo de saída:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   10m
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    2m47s

Isso mostra o web-service juntamente com seu TYPE (ClusterIP), CLUSTER-IP e PORT(S) expostos.

Para mais detalhes sobre um serviço, use kubectl describe service <service_name>:

kubectl describe service web-service

A saída do describe service inclui:

  • Name, Namespace, Labels, Annotations: Metadados básicos.
  • Selector: O seletor de label usado para identificar os pods de destino.
  • Type: O tipo de serviço (ClusterIP neste caso).
  • IP, IPs: O endereço IP do cluster atribuído ao serviço.
  • Port, TargetPort: Mapeamentos de porta definidos para o serviço.
  • Endpoints: Mostra os endereços IP e portas dos pods que estão atualmente suportando este serviço. Isso é muito importante. Se você não vir nenhum endpoint, significa que o serviço não está conectado corretamente a nenhum pod, provavelmente devido a uma incompatibilidade de seletor.
  • Session Affinity, Events: Outras configurações e eventos do serviço.

Ao verificar o status do deployment, os pontos-chave a serem observados são:

  • Status READY do Deployment: Certifique-se de que ele mostre o número desejado de réplicas (por exemplo, 2/2 para web-app).
  • STATUS do Pod: Todos os pods devem estar no status Running.
  • Endpoints do Serviço: Verifique se o serviço tem endpoints e se eles correspondem aos endereços IP dos seus pods em execução. Se não houver endpoints, solucione o seletor do serviço e os labels dos pods.
  • Verifique avisos ou erros: Examine a saída de kubectl describe deployment <deployment_name> e kubectl describe service <service_name> em busca de quaisquer condições ou erros incomuns nas seções Events.

Ao usar esses comandos kubectl, você pode monitorar e verificar efetivamente o status de seus deployments e serviços no Kubernetes, garantindo que suas aplicações estejam rodando conforme o esperado.

Acessar a Aplicação usando kubectl proxy

Nesta etapa, você aprenderá como acessar suas aplicações Kubernetes usando kubectl proxy. kubectl proxy cria uma conexão proxy segura com o servidor de API do Kubernetes, permitindo que você acesse serviços e pods do cluster a partir do seu ambiente atual. Isso é muito útil para desenvolvimento e depuração, especialmente quando você deseja acessar serviços que não estão expostos externamente.

Primeiro, certifique-se de estar no diretório do projeto:

cd ~/project/k8s-manifests/manifests

Inicie o kubectl proxy em segundo plano. Este comando executará o proxy em um processo separado, permitindo que você continue usando seu terminal.

kubectl proxy --port=8080 &

O & no final do comando o executa em segundo plano. Você deverá ver uma saída como:

Starting to serve on 127.0.0.1:8080

Se o seu terminal parecer travar após executar este comando, talvez seja necessário pressionar Ctrl+C uma vez para retornar ao prompt. O proxy ainda deve estar rodando em segundo plano.

Agora, vamos encontrar os nomes dos pods que fazem parte do seu deployment web-app. Você pode usar kubectl get pods -l app=web novamente:

## Get pod names for the 'web-app'
kubectl get pods -l app=web

Exemplo de saída:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          20m
web-app-xxx-zzz           1/1     Running   0          20m

Anote um dos nomes dos pods, por exemplo, web-app-xxx-yyy. Você usará este nome de pod para construir o caminho da API para acessar o servidor web NGINX rodando nesse pod.

Os recursos da API do Kubernetes são acessíveis através de caminhos específicos. Para acessar um pod através do kubectl proxy, você precisa construir uma URL como esta:

http://localhost:8080/api/v1/namespaces/<namespace>/pods/<pod_name>/proxy/

Vamos detalhar esta URL:

  • http://localhost:8080: O endereço onde o kubectl proxy está rodando. Por padrão, ele escuta na porta 8080 no seu ambiente atual.
  • /api/v1: Especifica a versão da API do Kubernetes (v1).
  • /namespaces/<namespace>: O namespace onde seu pod está rodando. No nosso caso, é default.
  • /pods/<pod_name>: O nome do pod que você deseja acessar. Substitua <pod_name> pelo nome real do seu pod (por exemplo, web-app-xxx-yyy).
  • /proxy/: Indica que você deseja fazer um proxy de uma conexão para o pod.

Para facilitar o uso do nome do pod na URL, vamos armazenar o nome do primeiro pod em uma variável de shell. Execute este comando, que usa kubectl get pods e jsonpath para extrair o nome do primeiro pod com o label app=web:

## Get the name of the first pod with label 'app=web'
POD_NAME=$(kubectl get pods -l app=web -o jsonpath='{.items[0].metadata.name}')
echo $POD_NAME ## Optional: print the pod name to verify

Agora, você pode usar a variável $POD_NAME no seu comando curl para acessar a página padrão do NGINX servida pelo seu pod. Use curl para enviar uma requisição HTTP para a URL do proxy. Substitua ${POD_NAME} na URL pela variável que acabamos de definir:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}/proxy/

Se tudo estiver funcionando corretamente, este comando deverá retornar o conteúdo HTML da página de boas-vindas padrão do NGINX. O exemplo de saída será o conteúdo HTML começando com:

<!doctype html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    ...
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    ...
  </body>
</html>

Esta saída confirma que você acessou com sucesso o servidor web NGINX rodando dentro do seu pod através do kubectl proxy.

Vamos explorar mais algumas coisas que você pode fazer com kubectl proxy.

Listar todos os pods no namespace padrão via proxy:

Você pode acessar a API do Kubernetes diretamente através do proxy. Por exemplo, para listar todos os pods no namespace default, você pode usar esta URL:

curl http://localhost:8080/api/v1/namespaces/default/pods/

Isso retornará uma resposta JSON contendo informações sobre todos os pods no namespace default.

Obter informações detalhadas sobre um pod específico via proxy:

Para obter informações detalhadas sobre um pod específico (semelhante a kubectl describe pod), você pode acessar o endpoint da API do pod diretamente:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}

Isso retornará uma resposta JSON com informações detalhadas sobre o pod especificado.

Parando kubectl proxy:

Quando terminar de usar o kubectl proxy, você deve pará-lo. Como o iniciamos em segundo plano, você precisa encontrar seu ID de processo (PID) e terminá-lo. Você pode usar o comando jobs para listar processos em segundo plano:

jobs

Isso mostrará os processos em segundo plano em execução a partir da sua sessão de terminal atual. Você deverá ver kubectl proxy listado. Para pará-lo, você pode usar o comando kill seguido pelo ID do processo. Por exemplo, se jobs mostrar [1] Running kubectl proxy --port=8080 &, então o ID do processo é 1. Você usaria:

kill %1

Substitua %1 pelo ID do job mostrado pelo comando jobs. Alternativamente, você pode encontrar o ID do processo usando ps aux | grep kubectl proxy e depois usar kill <PID>.

Pontos-chave a serem lembrados sobre kubectl proxy:

  • kubectl proxy cria uma conexão segura e autenticada com o servidor de API do Kubernetes.
  • Ele permite que você acesse recursos do cluster (pods, services, etc.) do seu ambiente atual como se estivesse dentro da rede do cluster.
  • É muito útil para depuração, desenvolvimento e exploração da API do Kubernetes.
  • Por razões de segurança, kubectl proxy só é acessível em localhost (127.0.0.1). Ele não se destina a ser usado para expor serviços publicamente.

Resumo

Neste laboratório, você aprendeu com sucesso como implantar aplicações em um cluster Kubernetes usando Minikube. Você começou configurando um cluster Kubernetes com Minikube e verificou seu status. Em seguida, explorou comandos essenciais do kubectl para interagir com seu cluster e gerenciar recursos. Você aprendeu a listar namespaces, obter detalhes sobre nós e pods, e entender a estrutura básica de comandos do kubectl. Esses passos forneceram uma base sólida para trabalhar com Kubernetes.

Você prosseguiu para criar manifestos YAML simples para um Pod e um Deployment, aplicou-os ao seu cluster usando kubectl apply e verificou o status da implantação usando vários comandos kubectl como get e describe. Essa experiência prática permitiu que você entendesse a abordagem declarativa para implantar aplicações no Kubernetes e como interagir efetivamente com o cluster.

Finalmente, você aprendeu como acessar sua aplicação implantada usando kubectl proxy, que fornece uma maneira segura de interagir com a API do seu cluster e acessar serviços e pods do seu ambiente atual. Esta é uma técnica valiosa para desenvolvimento, depuração e exploração do seu ambiente Kubernetes.

Ao concluir este laboratório, você adquiriu experiência prática com conceitos e ferramentas essenciais do Kubernetes, colocando você no caminho para implantar e gerenciar aplicações mais complexas no Kubernetes.