Kubernetes – Conceitos básicos

Pods Kubernetes

Com o Kubernetes, nosso objetivo final é implantar nossa aplicação na forma de contêineres em um conjunto de máquinas configuradas como works nodes em um cluster. No entanto, o Kubernetes não distribui os containers diretamente nos works nodes. Os containers são encapsulados em um objeto do Kubernetes conhecido como pods. Um pod é a menor unidade que pode ser criada no Kubernetes.

Aqui vemos os casos mais simples em que você tem um único nó Kubernetes cluster com uma única instância de sua aplicação rodando em um único container Docker encapsulado em um pod.

Aplicação em um Pod

E se o número de usuários que acessam sua aplicação aumentar e você precisar escalar sua aplicação? Você precisa adicionar instâncias adicionais de sua aplicação web para compartilhar a carga. Agora, onde você adicionaria instâncias adicionais? Criaríamos um novo pod com uma nova instância da mesma aplicação.

Como você pode ver, agora temos duas instâncias de nossa aplicação web rodando em dois pods separados no mesmo sistema ou nó Kubernetes. E se a base de usuários aumentar ainda mais e seu nó atual não tiver capacidade suficiente?

Bem, então você sempre pode implantar pods adicionais em um novo nó no cluster. Você terá um novo nó adicionado ao cluster para expandir a capacidade física do cluster. Portanto, o que estou tentando ilustrar é que os pods geralmente têm uma relação de um para um com os containers que executam sua aplicação. Para aumentar, você cria novos pods, e para diminuir, você remove o pod existente. Você não adiciona containers extras a um pod existente para dimensionar sua aplicação.

Além disso, se você estiver se perguntando como implementamos tudo isso e como alcançamos o equilíbrio de carga entre os containers, etc., abordaremos esses tópicos em uma aula posterior.

Por enquanto, estamos apenas tentando entender os conceitos básicos. Acabamos de dizer que os pods geralmente têm uma relação de um para um com os containers, mas será que estamos restritos a ter um único container em um único pod? Não, um único pod pode ter vários containers, exceto pelo fato de que geralmente eles não são múltiplas instâncias do mesmo tipo de container. Como discutido anteriormente, se nossa intenção fosse escalar nossa aplicação, então precisaríamos criar pods adicionais, mas às vezes podemos ter um cenário em que temos um container auxiliar que pode estar desempenhando algum tipo de tarefa de suporte para nossa aplicação web, como processar um usuário e seus dados, processar um arquivo carregado pelo usuário, etc. e queremos que esses containers auxiliares coexistam com nosso container de aplicação.

Multiplos Container em um Pod

Nesse caso, podemos ter ambos os containers fazendo parte do mesmo pod para que, quando um novo container de aplicação for criado, o auxiliar também seja criado, e quando ele for encerrado, o auxiliar também seja encerrado, já que fazem parte do mesmo pod.

Os dois containers também podem se comunicar diretamente, referindo-se um ao outro como localhost, já que compartilham o mesmo espaço de rede e podem compartilhar facilmente o mesmo espaço de armazenamento. Se você ainda tiver dúvidas sobre esse tópico, eu entenderia, pois eu também tive quando aprendi esses conceitos pela primeira vez. Vamos tentar entender os pods a partir de um ângulo diferente.

Comunicação entre container no mesmo Pod

Vamos supor que estamos desenvolvendo um processo ou um roteiro para implantar nossa aplicação em um host Docker. Em seguida, simplesmente implantamos nossa aplicação usando um comando simples de execução do Docker para aplicação Python e a aplicação roda bem, e nossos usuários são capazes de acessá-la.

Quando a carga aumenta, empregamos mais instâncias de nossa aplicação, executando os comandos de execução do Docker várias vezes. Isso funciona bem, e todos estamos felizes. Agora, em algum momento no futuro, nossa aplicação é mais desenvolvida, passa por mudanças arquitetônicas e cresce e se torna complexa. Agora temos um novo container auxiliar que ajuda nossa aplicação web, processando ou buscando dados de outros lugares. Esses containers auxiliares têm uma relação de um para um com nosso container de aplicação e, portanto, precisam se comunicar diretamente com os containers de aplicação e acessar os dados desses containers.

Para isso, precisamos manter um mapa que mostra a conexão entre os containers de aplicação e os containers auxiliares.

Precisamos estabelecer a conectividade de rede entre esses contêineres usando links e redes personalizadas. Precisamos criar volumes compartilhados e compartilhá-los entre os contêineres. Precisamos manter um mapa disso também e, o mais importante, precisamos monitorar o estado do container de aplicação e, quando ele morrer, precisamos matar manualmente o container auxiliar, pois ele não será mais necessário.

Quando um novo contêiner é implantado, também precisamos implantar o novo container auxiliar. Com os pods, o Kubernetes faz tudo isso automaticamente para nós. Só precisamos definir quais containers compõem um pod, e os containers de um pod, por padrão, terão acesso ao mesmo armazenamento, ao mesmo espaço de rede e serão criados e encerrados juntos. Mesmo que nossa aplicação não seja tão complexa e possamos viver com um único container, o Kubernetes ainda exige que você crie pods, o que é bom a longo prazo, pois sua aplicação estará pronta para mudanças arquitetônicas e escala no futuro. No entanto, observe também que os múltiplos containers são um caso de uso raro, e vamos nos ater a containers únicos por pod neste curso. Vamos agora ver como implantar os pods.

Anteriormente, aprendemos sobre o comando kubectl. O que esse comando realmente faz é implantar um container Docker criando um pod. Primeiro, ele cria automaticamente um pod e implanta uma instância da imagem Docker do NGINX. Mas de onde ele obtém a imagem da aplicação? Para isso, você precisa especificar o nome da imagem usando o parâmetro image. A imagem da aplicação, neste caso, a imagem do NGINX, é baixada do repositório público Docker Hub. Você pode configurar o Kubernetes para extrair a imagem do Docker Hub público ou de um repositório privado dentro da organização.

kubectl run nginx --image nginx --port 80

Agora que temos um pod criado, como podemos ver a lista de pods disponíveis? O comando kubectl get pods nos ajuda a visualizar a lista de pods em nosso cluster.

Neste caso, vemos que o pod está em um estado de criação de containers e em breve mudará para um estado de execução quando estiver realmente em funcionamento.

Além disso, lembre-se de que ainda não discutimos os conceitos de como um usuário pode acessar o servidor web NGINX. Portanto, no estado atual, o servidor web ainda não está acessível para usuários externos. No entanto, você pode acessá-lo internamente a partir do nó. Por enquanto, vamos apenas aprender como implantar um pod e, em uma aula futura, quando aprendermos sobre redes e serviços, saberemos como tornar este serviço acessível aos usuários finais.

Criação de um Pod

Podemos criar um pod usando um arquivo de configuração baseado em uma demonstração da aula anterior e agora vamos aprender como desenvolver arquivos YAML especificamente para o Kubernetes.

Kubernetes usa arquivos YAML como entradas para a criação de objetos, como serviços, Deployments e etc. Todos eles seguem uma estrutura semelhante.

vim pod-definition.yaml
apiVersion: v1
kind: Pod
metadata:



spec:

O arquivo de definição do Kubernetes sempre contém quatro campos de nível superior: versão da API, tipo do objeto, metadados e especificações. Essas são as propriedades de nível superior ou raiz e também são campos obrigatórios, portanto, devem ser incluídos no arquivo de configuração.

apiVersion

O primeiro campo é apiVersion. Essa é a versão da API que estamos usando para criar o objeto, dependendo do tipo de objeto que estamos tentando criar. No nosso caso, como estamos trabalhando com Pods, definiremos a versão da API como v1. Outros valores possíveis para esse campo são apps/v1beta1.extensions/v1, etc. Veremos para que servem essas diferentes versões mais adiante no curso.

kind

O campo kind se refere ao tipo de objeto que estamos tentando criar. Neste caso, estamos criando um Pod, portanto, definiremos esse valor como Pod. Pode ser um conjunto de réplicas (ReplicaSet), uma implantação (Deployment) ou um serviço (Service).

metadata

Os metadados são dados sobre o objeto, como seu nome e labels. Diferentemente dos campos anteriores, onde especificamos valores de string, neste caso, os metadados são especificados na forma de um dicionário. Portanto, todos os campos dentro de metadata devem ter um nível de indentação a mais em relação ao campo pai. Essa indentação é de dois espaços.

No caso dos metadados, temos dois campos: name (nome) e labels (rótulos). O nome é um valor de sequência, no qual você pode nomear sua parte (pod). No campo labels, temos um dicionário no qual você pode adicionar pares de chave e valor para identificar e agrupar objetos posteriormente. Por exemplo, se você tiver centenas de pods executando um aplicativo front-end e centenas de pods executando um aplicativo back-end ou um banco de dados, pode ser difícil agrupar essas pods depois que elas forem implantadas. No entanto, se você as rotular agora como “back-end” ou “front-end”, poderá filtrar as partes com base nesses rótulos posteriormente.

spec

O último campo no arquivo de configuração é a seção de especificação (spec). Aqui, forneceremos informações adicionais relacionadas a esse objeto, que serão diferentes para objetos diferentes. No nosso caso, como estamos criando apenas um Pod com um único contêiner, podemos adicionar uma propriedade chamada containers, que é uma lista (ou array). Essa propriedade é uma lista porque os Pods podem ter vários contêineres dentro deles. No entanto, no nosso caso, adicionaremos apenas um único item à lista, pois planejamos ter apenas um contêiner no Pod.

Dentro do campo containers, temos um dicionário para especificar as propriedades name (nome) e image (imagem) do contêiner. O valor da imagem será o nome da imagem do Docker no repositório do Docker. Após criar o arquivo de configuração YAML, você pode usar o comando kubectl create -f <nome_do_arquivo> para criar o Pod.

apiVersion: v1
kind: Pod
metadata:
  name: mypod-app
  labels:
    app: mypod
spec:
  containers:
  - name: nginx 
    image: nginx 

Aplicando o manifesto yaml para criar o POD

kubectl create -f pod-definition.yaml

Verificando os Pods

Após criar o Pod, você pode usar o comando kubectl get pods para ver uma lista dos Pods disponíveis. Para obter informações detalhadas sobre um Pod específico, execute o comando kubectl describe pod <nome_do_pod>.

kubectl get pods

Isso fornecerá informações sobre o Pod, como sua criação, os rótulos atribuídos a ele, os contêineres que fazem parte dele e os eventos associados a esse Pod.

Sunset

Detalhes do pod

Pratica dos Conceitos básicos

Atividade 1: Criar um Pod

Passo 1.1. Crie um arquivo YAML chamado pod.yaml com as seguintes especificações:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - image: nginx
    name: nginx

Passo 1.2. Use o comando kubectl create para criar o Pod usando o arquivo YAML:

kubectl create -f pod.yaml

Passo 1.3. Verifique se o Pod foi criado corretamente usando o comando kubectl get:

kubectl get pods

Atividade 2: Obter detalhes de um Pod

Passo 2.1. Use o comando kubectl describe para obter detalhes sobre o Pod criado anteriormente:

kubectl describe pod nginx

Atividade 3: Editar um Pod

Passo 3.1. Use o comando kubectl edit para editar o Pod e adicionar uma nova anotação:

kubectl edit pod nginx

Passo 3.2. Adicione a seguinte linha abaixo de metadata::

apiVersion: v1
kind: Pod
metadata:
  annotations:
    example.com/annotation: example
  creationTimestamp: "2023-07-04T13:22:34Z"
  labels:
    app: nginx
  name: nginx
  namespace: default
  resourceVersion: "12532"
  uid: d486200c-c120-4202-9327-3046daed8301
spec:
  containers:
  - image: nginx
[.... Omitido .....]

Passo 3.3. Salve saindo do editor. Verifique se as alterações foram aplicadas usando o comando kubectl describe:

kubectl describe pod nginx

Atividade 4: Criar um Deployment

Passo 4.1. Crie um arquivo YAML chamado deployment.yaml com as seguintes especificações:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: meu-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: meu-app
  template:
    metadata:
      labels:
        app: meu-app
    spec:
      containers:
        - name: meu-container
          image: nginx

Passo 4.2. Use o comando kubectl create para criar o Deployment usando o arquivo YAML:

kubectl create -f deployment.yaml

Passo 4.3. Verifique se o Deployment foi criado corretamente usando o comando kubectl get:

kubectl get deployments

Atividade 5: Obter detalhes de um Deployment

Passo 5.1. Use o comando kubectl describe para obter detalhes sobre o Deployment criado anteriormente:

kubectl describe deployment meu-deployment
Essas atividades fornecem uma introdução prática ao uso dos comandos kubectl createkubectl getkubectl describe e kubectl edit. Explore mais opções e recursos desses comandos para aprimorar seu conhecimento.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *