[PT-BR] Tudo que você, desenvolvedor, precisa saber sobre Pods no Kubernetes
Tags: kubernetes, devops, development, webdev
Published: 2024-02-01 15:00:49

> _Imagem do banner obtida no Pixabay, autor lucasbieri_.

Se destacar no mercado de trabalho depende de muitas variáveis e diferentes decisões ao longo da jornada profissional. Atualmente, no momento da escrita deste conteúdo, uma tecnologia vem se destacando forte no mercado e caso você, desenvolvedor, não saiba utilizá-la, com certeza ficará para trás.

O **Kubernetes** é uma plataforma _open-source_ voltada para a orquestração de _containers_ (e caso você não sabe o que é um _container_, e lembrando que _container_ não é Docker, recomendo você deixar esta aba aberta e ir dar uma estudada rápida sobre _containers_ antes de iniciar essa leitura) que automatiza o processo implantação, dimensionamento e operação dos aplicativos nos _containers_.

Este conteúdo faz parte de uma série de artigos onde é abordado todos os principais recursos do **Kubernetes** aos quais você deverá conhecer. E para começar essa série com o pé direito, seria impossível não começar com ele, a menor unidade do **Kubernetes**. Venha comigo aprender sobre os **Pods**.

O **Pod**, como mencionado anteriormente, representa a menor unidade de implantação no ecossistema do **Kubernetes**. Ele desempenha um papel crucial ao servir como um ambiente isolado que abriga um ou mais _containers_. É fundamental entender que o **Kubernetes** gerencia as aplicações em unidades chamadas **Pods**, e é dentro desses objetos do **Kubernetes** que os _containers_ realmente operam.

Cada **Pod** possui seus próprios recursos dedicados, que incluem um endereço IP exclusivo, alocação de memória, capacidade de CPU e outros recursos essenciais. Esses recursos são alocados de forma independente para cada **Pod**, garantindo assim o isolamento e a autonomia das aplicações em execução.

Para aqueles que já possuem familiaridade com o conceito de _containers_, a transição para o entendimento dos **Pods** será bastante natural. No entanto, é crucial não confundir um **Pod** com um _container_ individual, uma vez que os **Pods podem conter um ou mais containers em seu interior.** Vale ressaltar que, quando um **Pod** abriga mais de um container, esses containers operam em estreita colaboração, compartilhando os recursos alocados pelo **Pod**. Isso significa que eles compartilham o mesmo endereço IP, CPU e memória, tornando essencial a coordenação entre os _containers_ dentro do mesmo **Pod** para garantir o funcionamento harmonioso da aplicação como um todo. Essa prática pode até parecer inicialmente um pouco estranha, porém é algo muito comum de ser feita.

O ciclo de vida de um **Pod** possui exatos 7 fases que podem ser encontradas abaixo:

- **Pending**: O **Pod** é criado, porém os _containers_ internos a ele ainda não foram inicializados ou agendados para execução em um nó;
- **ContainerCreating**: Os _containers_ estão sendo inicializados dentro do **Pod**;
- **Running**: O **Pod** está ativo, sem problemas, e processando as solicitações recebidas;
- **Terminated**: Todos os _containers_ presentes dentro de um **Pod** foram encerrados ou o **Pod** sofreu uma falha;
- **Succeeded**: Fase posterior à _Terminated_, onde todos os _containers_ dentro de um **Pod** foram concluídos com êxito;
- **Failed**: Pelo menos um _container_ presente no **Pod** falhou;
- **Unknown**: O estado de vida do **Pod** não pôde ser identificado, ou seja, algo na comunicação com o nó sofreu falhas ou há problemas no _cluster_.

Agora que você tem uma noção sobre o que é um **Pod** e qual a função dele nesse ecossistema **Kubernetes**, vamos ao que você provavelmente entrou aqui procurando: **"Como eu gerencio um Pod no Kubernetes?".**

## Gerenciando um Pod no Kubernetes

A primeira coisa que você deve ter instalado em sua máquina é a interface do **kubectl**. Com ela, é possível gerenciar tudo relacionado ao seu **Kubernetes** pelo terminal de forma simples. Caso você não a tenha, deixo abaixo um link para a documentação de como realizar essa instalação. O processo é bem simples e intuitivo!

[Link para instalação do kubectl](https://kubernetes.io/docs/tasks/tools/
)

Com ela instalada, se conecte ao seu ambiente de produção caso seja seu caso, ou caso queira criar um ambiente para estudos, recomendo a utilização do **Minikube**. Essa ferramenta permite a criação de um ambiente **Kubernetes** local onde você poderá testar e estudar todos os comandos. Deixo abaixo o link para instalação da mesma na sua máquina.

[Link para instalação do Minikube](https://minikube.sigs.k8s.io/docs/start/)

Antes de iniciarmos o aprendizado sobre gerenciamento de _Pods_, deixa eu te passar alguns comandos essenciais para te ajudar no processo de entendimento do **Kubernetes**.

### Obter informações sobre o **Cluster Kubernetes** ao qual você está utilizando:

```
kubectl cluster-info
```

### Obter todos os contextos configurados no _kubeconfig_:

```
kubectl config get-contexts
```

Contextos são os ambientes configurados aos quais a interface do **kubectl** pode gerenciar. Imagine que você trabalhe para uma empresa que possui um ambiente **Kubernetes** e queira, em casa, ter além da conexão com o ambiente da empresa, ter também um ambiente local com **Minikube** para estudar **Kubernetes**. Os contextos separam esses dois ambientes e você pode utilizá-los de forma única, a partir da seleção de um contexto que pode ser feito utilizando o comando abaixo:

```
kubectl config use-context CONTEXT_NAME
```

### Obter o contexto atual em execução:

```
kubectl config current-context
```

Agora que você já tem uma base legal sobre _Pods_ e inicialização do seu ambiente **Kubernetes**, vamos iniciar o estudo de gerenciamento dos _Pods_.

Caso você queira visualizar os Pods presentes no seu cluster Kubernetes, utilize:

```
kubectl get pods
```

Esse comando retorna todos os Pods presentes no namespace atual ao qual você está trabalhando. Caso queira especificar um namespace, basta utilizar a flag **-n seguida do nome do namespace** conforme abaixo:

```
kubectl get pods -n NAMESPACE_NAME
```

Caso queira visualizar todos os _Pods_ presentes em todos os namespaces, basta utilizar da flag -A ou --all-namespaces conforme apresentado abaixo:

```
kubectl get pods -A

kubectl get pods --all-namespaces
```

Para visualizar um Pod específico, utilizamos:

```
kubectl get pods -n NAMESPACE_NAME POD_NAME
```

Ainda temos uma outra opção bem legal. Você deve ter percebido que, ao utilizar algum dos comandos acima, o resultado é uma tabela com as colunas _Namespace, Name, Ready, Status, Restarts e Age_. Porém, ainda é possível visualizar informações super importantes como o IP do Pod e o _Node_ em que aquele _Pod_ está sendo executado. Para isso, utilize da flag **-o seguida do valor wide** conforme apresentado abaixo:

```
kubectl get pods -o wide
```

Legal né? Agora vamos adentrar mais ainda no gerenciamento. Existem diversos momentos em que é necessário visualizar informações mais específicas de um _Pod_ em execução. Para isso, utilize abaixo:

```
kubectl describe pods NOME_POD
```

Esse comando acima retornará diversas informações do _Pod_ especificado, como endereço IP, configurações do mesmo e muitas outras. Continuando, uma outra prática interessante é visualizar o manifesto daquele _Pod_, ou seja, o arquivo **.yaml (ou JSON)** que define as configurações e parâmetros do mesmo. Para realizar isso é bem simples:

```
kubectl get pods POD_NAME -o yaml
```

Uma prática muito comum na criação dos _Pods_ é atribuir a eles _Labels_. Para buscar os _Pods_ de uma label específica é muito simples. Basta utilizar da flag **-L seguida do nome da label.**

```
kubectl get pods -L LABEL_NAME
```

Agora vamos para outra operação além de visualizar. Para você deletar um _Pod_ existente, utilize do comando abaixo:

```
kubectl delete pods POD_NAME
```

E para criar um _Pod_, como eu faço? Para essa operação, existem algumas formas de realizá-la. Vamos passo a passo listando elas.

A primeira, e mais simples talvez, é utilizar diretamente uma imagem e as configurações default para um _Pod_. Para isso, basta executar o comando abaixo:

```
kubectl run POD_NAME --image IMAGE_NAME -n NAMESPACE_NAME
```

Algumas imagens pedem flags específicas, como por exemplo, um _webserver_ como o **NGINX** solicita como flag a porta ao qual o _Pod_ utilizará. Para criar um **NGINX** por exemplo, você pode fazer da seguinte forma:

```
kubectl run POD_NAME --image nginx --port 80 -n NAMESPACE_NAME
```

**OBS.: Sempre busque a forma de criação para a imagem ao qual você deseja utilizar.**

A segunda forma de criação, e a mais utilizada pelo mercado, é através de um manifesto, ou seja, um arquivo **.yaml (ou JSON)** que define as configurações do _Pod_ que será criado. Veja um exemplo simples abaixo:

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
spec:
  containers:
  - name: cont-nginx
    image: nginx
    ports:
      - containerPort: 80
```

**Analisando o manifesto acima, temos:**

- **apiVersion:** Versão da API do **Kubernetes**;
- **kind:** Tipo do objeto **Kubernetes**, nesse caso, Pod;
- **metadata:** Dados do _Pod_ que será criado, como o name, labels, etc.
- **spec:** Configurações do _Pod_ que será criado, como por exemplo, os dados do(s) container(s) em execução dentro do Pod.

Ainda existem diversas outras definições que podem ser inseridas dentro deste manifesto. Irei deixar abaixo um link para a documentação do **Kubernetes** onde você pode encontrá-las. Porém saiba que criar Pods desta forma que estamos informando não é comum, para ser sincero é legal saber como funciona mas você nem vai utilizar dessa maneira no seu dia a dia. A criação dos Pods utilizam de outros objetos do **Kubernetes** que vão deixar todo o processo mais inteligente, como os **ReplicaSets** e os **Deployments** que serão explicados em outros artigos dessa série.

[Link para a documentação dos Pods](https://kubernetes.io/docs/concepts/workloads/pods/)

Continuando, _"eu criei um arquivo .yaml, mas como crio o Pod necessariamente com isso?"_. Simples, basta executar o comando abaixo:

```
kubectl apply -f FILE_NAME.yaml
```

Esse comando aplica as configurações do manifesto definido no **Cluster Kubernetes**. Para visualizar seu _Pod_ em execução, você pode usar algum dos comandos que listam os Pods citados acima ou pode usar o comando abaixo:

```
kubectl get all
```

Esse comando vai retornar todos os objetos presentes no ambiente **Kubernetes**, como os _Pods_, _Deployments_, etc.
Assim como no **Docker**, utilizando **Kubernetes** você também pode criar um container e interagir com ele acessando-o. Para isso, utilize da flag **-ti** para acessar o modo interativo.

```
kubectl run -ti POD_NAME --image NOME_IMAGE
```

Um exemplo para você testar é usar a imagem alpine e acessar seu bash:

```
kubectl run -ti POD_NAME --image alpine
```

Porém, você não vai em diversos momentos criar um Pod e acessar um container dele na mesma hora. Os comandos acima fazem isso (criam e acessam). Você pode, quando quiser, acessar um container que já está em execução. Para isso, basta utilizar do comando abaixo para "atachar" em um container dentro de um Pod:

```
kubectl attach POD_NAME -c CONTAINER_NAME -ti
```

Aqui nós temos um ponto super importante para comentar. O comando **attach** se conecta ao processo principal do _container_. Em _containers_ que utilizam imagens que não são destinadas a servir como um ambiente de linha de comando, a conexão ocorre conforme o esperado. No entanto, em _containers_ que são executados como **daemons**, ou seja, em que o processo principal do _container_ não é um ambiente de linha de comando (como o _shell bash_), mas sim um serviço em segundo plano, como é o caso do **NGINX**, a conexão se comporta de maneira "anômala" porque não há um _shell bash_ disponível nesse contexto. Nestes casos, recorremos para outro comando, o **exec**. Com ele é possível realizar a execução de comandos dentro do container. Nos exemplos abaixo, podemos utilizar o **exec** para acessar o _shell bash_ de um container **NGINX** ou visualizar o conteúdo da página HTML respectivamente, em vez de nos conectarmos diretamente ao processo principal.

```
kubectl exec -ti CONTAINER_NAME -- bash

kubectl exec -ti CONTAINER_NAME -- cat /usr/share/nginx/html/index.html
```

As coisas estão ficando legais em! Mas calma que ainda temos muito conteúdo pela frente!

Continuando, vamos falar agora sobre uma flag com um comportamento que inicialmente pode causar estranheza, mas que depois você entenderá um de seus usos. A flag **dry-run=client** simula a execução de algo, ou seja, ela mostra o resultado da execução porém não faz a execução do comando em si. Estranho né? Mas vamos pensar no seguinte contexto. Imagina que você quer criar um manifesto de um _Pod_ a partir de uma imagem e não sabe por onde começar. Seria muito legal ter um escopo base, porém como ter esse escopo sem ter que criar um _Pod_ e visualizar seu manifesto? Simples, utilizando a flag **dry-run=client** você vai simular a criação do container e assim, visualizar seu manifesto sem tê-lo criado.

```
kubectl run POD_NAME --image IMAGE_NAME --dry-run=client -o yaml
```

Caso queira salvar o manifesto em algum arquivo, basta executar o comando no formato abaixo:

```
kubectl run POD_NAME --image IMAGE_NAME --dry-run=client -o yaml > manifesto.yaml
```

Perceba que o comando acima gera um arquivo **.yaml** no final. Caso o manifesto que você queira salvar seja em **JSON**, altere o comando para criar um arquivo **JSON** no final.

Bom, chegamos ao fim do nosso estudo sobre _Pods_. Será abordado em breve os outros objetos do **Kubernetes** que você deve conhecer e estudar sobre. Esse formato de artigo é pensado para passar de forma mais rápida e direta o que todo desenvolvedor precisa conhecer. Caso queira se especializar nos _Pods_ do **Kubernetes**, recomendo uma leitura mais minuciosa em toda a parte teórica presente na documentação do mesmo ao qual deixo o link abaixo:

[Documentação sobre os Pods do Kubernetes](https://kubernetes.io/docs/concepts/workloads/pods/)

Espero que tenha gostado e até a próxima!