O Kubernetes é uma plataforma poderosa de orquestração de contêineres, mas para aproveitar todo o seu potencial, é importante entender seus componentes principais, com pods e serviços desempenhando papéis fundamentais. Neste artigo, vamos mergulhar no que eles são e como trabalham juntos para expor e gerenciar o acesso a aplicativos em execução dentro de um cluster Kubernetes.
O que é um Pod?
Pods são as menores unidades implantáveis de computação que você pode criar e gerenciar no Kubernetes.
Antes de criarmos um pod, vamos verificar os recursos da API disponíveis em seu cluster Kubernetes; você pode usar o comando kubectl api-resources
. Esse comando lista os recursos da API que são suportados pelo servidor de API do Kubernetes, incluindo seus nomes curtos, grupos de API e se são ou não namespaced. Isso é útil para entender as capacidades do seu cluster, especialmente ao trabalhar com recursos personalizados ou explorar novos recursos do Kubernetes. O comando kubectl explain
complementa isso fornecendo informações detalhadas sobre recursos individuais.
Vamos criar um arquivo de configuração básica de pod para um pod em execução de um contêiner Nginx simples.
Crie um arquivo com o nome nginx-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Aqui está uma breve explicação dos termos utilizados:
- apiVersion: v1: Especifica a versão da API.
- kind: Pod: Indica que esta configuração é para um pod.
- metadata:name: O nome do pod.
- metadados: etiquetas: Pares de chave-valor que podem ser usados para organizar e selecionar o pod.
- especificação:containers: Uma lista de containers que serão executados no pod.
- especificação:containers:nome: O nome do container.
- especificação:containers:imagem: A imagem do container a ser usada (neste caso, a última imagem do Nginx).
- especificação:containers:portas: As portas a serem expostas pelo container.
Use kubectl
para aplicar o arquivo de configuração e criar o pod:
kubectl apply -f nginx-pod.yaml
Verifique o status do pod para garantir que ele tenha sido criado e esteja em execução:
kubectl get pods
Você deverá ver uma saída semelhante a esta:
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 10s
Em seguida, exclua o pod:
kubectl delete pod nginx-pod
A saída deve se parecer com o seguinte:
kubectl get pod
No resources found in default namespace.
O que é um Serviço?
Criar um serviço para um pod Nginx no Kubernetes permite expor a aplicação Nginx e torná-la acessível dentro ou fora do cluster. Aqui está um guia passo a passo para criar um Serviço para um pod Nginx.
Para garantir que você tenha um pod Nginx em execução, se você ainda não tiver um, crie um arquivo YAML chamado nginx-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Aplique a configuração do Pod:
Crie um arquivo YAML chamado nginx-service.yaml
para definir o Service:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
Aqui estão algumas coisas a serem observadas:
- selector: Um seletor de rótulo para corresponder ao pod do Nginx.
- app: nginx: Isso deve corresponder ao rótulo no pod do Nginx.
- type: ClusterIP: O tipo de Service. ClusterIP torna o Service acessível apenas dentro do cluster. Você também pode usar NodePort ou LoadBalancer para expor o Service externamente.
Aplique a configuração do Service usando kubectl
:
kubectl apply -f nginx-service.yaml
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.96.0.1 <none> 80/TCP 10s
Como o Service é do tipo ClusterIP, ele é acessível apenas dentro do cluster. Para acessá-lo de fora do cluster, você pode alterar o tipo de Service para NodePort ou LoadBalancer.
Para expor o Service externamente usando NodePort
, modifique o arquivo nginx-service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30007 # Specify a node port in the range 30000-32767 (optional)
type: NodePort
Aplique a configuração do Service atualizada:
kubectl apply -f nginx-service.yaml
Agora você pode acessar a aplicação Nginx usando o endereço IP do nó e a porta do nó (por exemplo, http://<node-ip>:30007).
Multi-Container Pods
O uso de um único contêiner por pod fornece a máxima granularidade e desacoplamento. No entanto, existem cenários em que implantar múltiplos contêineres, às vezes referidos como contêineres compostos, dentro de um único pod é benéfico. Esses contêineres secundários podem desempenhar várias funções: lidar com o registro ou aprimorar o contêiner principal (conceito de sidecar), atuar como um proxy para sistemas externos (conceito de embaixador) ou modificar dados para se adequarem a um formato externo (conceito de adaptador). Esses contêineres secundários complementam o contêiner principal ao realizar tarefas que ele não gerencia.
Abaixo está um exemplo de configuração de Pod do Kubernetes que inclui um contêiner principal executando um servidor Nginx e um contêiner secundário atuando como um sidecar para lidar com o registro. O contêiner sidecar utiliza um contêiner de registro simples como BusyBox para demonstrar como ele pode seguir os registros de acesso do Nginx.
apiVersion: v1
kind: Pod
metadata:
name: nginx-with-logging-sidecar
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
- name: log-sidecar
image: busybox:latest
command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
volumes:
- name: shared-logs
emptyDir: {}
Em seguida, você fará o seguinte:
- Salve a configuração YAML em um arquivo, por exemplo,
nginx-with-logging-sidecar.yaml
. - Aplique a configuração usando
kubectl:kubectl apply -f nginx-with-logging-sidecar.yaml
. - Verifique se o Pod está em execução:
kubectl get pods
. - Verifique os logs do contêiner sidecar para ver os logs de acesso do Nginx:
kubectl logs -f <pod-name> -c log-sidecar
.
Ao seguir esses passos, você excluirá o Pod existente e aplicará a nova configuração, configurando um Pod com um contêiner Nginx e um contêiner sidecar para registro. Isso garantirá que a nova configuração esteja ativa e em execução em seu cluster Kubernetes.
Pods com vários contêineres no Kubernetes oferecem várias vantagens, possibilitando implantação e gerenciamento de aplicativos mais flexíveis e eficientes.
Padrões de Pod com Múltiplos Contêineres
Padrão Sidecar
Os contêineres sidecar podem aprimorar o aplicativo principal, fornecendo funções auxiliares como registro, gerenciamento de configuração ou proxy. Esse padrão ajuda a estender a funcionalidade sem modificar o contêiner principal. Um contêiner sidecar pode lidar com o registro coletando e encaminhando logs do contêiner do aplicativo principal.
Padrão Ambassador
Os contêineres Ambassador atuam como um proxy, gerenciando a comunicação entre o aplicativo principal e os serviços externos. Isso pode simplificar a integração e a configuração. Um contêiner Ambassador pode lidar com a terminação SSL ou funções de gateway de API.
O padrão Ambassador envolve o uso de um contêiner sidecar para gerenciar a comunicação entre o aplicativo principal e os serviços externos. Esse padrão pode lidar com tarefas como proxy, balanceamento de carga ou gerenciamento de conexões seguras, abstraindo assim a complexidade do contêiner do aplicativo principal.
- Contêiner de Aplicativo Principal: Um servidor web simples que faz solicitações HTTP
- Contêiner Ambassador: Proxy Envoy configurado para gerenciar solicitações para a API externa
apiVersion: v1
kind: Pod
metadata:
name: app-with-ambassador
spec:
containers:
- name: web-app
image: python:3.8-slim
command: ["python", "-m", "http.server", "8000"]
volumeMounts:
- name: config-volume
mountPath: /etc/envoy
- name: envoy-proxy
image: envoyproxy/envoy:v1.18.3
args: ["-c", "/etc/envoy/envoy.yaml"]
ports:
- containerPort: 8080
volumeMounts:
- name: config-volume
mountPath: /etc/envoy
volumes:
- name: config-volume
configMap:
name: envoy-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: envoy-config
data:
envoy.yaml: |
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: external_service
http_filters:
- name: envoy.filters.http.router
clusters:
- name: external_service
connect_timeout: 0.25s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: external_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: api.example.com
port_value: 80
Este exemplo demonstra o padrão Ambassador no Kubernetes, onde um proxy Envoy atua como intermediário para gerenciar a comunicação externa para o contêiner de aplicativo principal. Este padrão ajuda a abstrair complexidades de comunicação e aprimora a modularidade e a manutenibilidade.
Padrão Adaptador
Contêineres Adaptadores podem modificar ou transformar dados entre o aplicativo principal e os sistemas externos, garantindo compatibilidade e integração. Por exemplo, um contêiner adaptador pode reformatar dados de log para atender aos requisitos de um serviço de log externo.
O padrão Adaptador no Kubernetes envolve o uso de um contêiner sidecar para transformar dados entre o contêiner de aplicativo principal e os sistemas externos. Isso pode ser útil quando o aplicativo principal requer dados em um formato específico que difere do formato fornecido ou exigido pelos sistemas externos.
Suponha que você tenha um contêiner de aplicativo principal que gera logs em um formato personalizado. Você precisa enviar esses logs para um serviço de log externo que requer logs em um formato padronizado específico. Um contêiner adaptador pode ser usado para transformar os dados de log no formato necessário antes de enviá-los para o serviço externo.
- Contêiner de Aplicativo Principal: Um aplicativo simples que escreve logs em um formato personalizado.
- Contêiner Adaptador: Um contêiner que lê os logs personalizados, os transforma em formato JSON e os envia para um serviço de log externo.
apiVersion: v1
kind: Pod
metadata:
name: app-with-adapter
spec:
containers:
- name: log-writer
image: busybox
command: ["sh", "-c", "while true; do echo \"$(date) - Custom log entry\" >> /var/log/custom/app.log; sleep 5; done"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/custom
- name: log-adapter
image: busybox
command: ["sh", "-c", "tail -f /var/log/custom/app.log | while read line; do echo \"$(echo $line | sed 's/ - / - {\"timestamp\": \"/;s/$/\"}/')\" >> /var/log/json/app.json; done"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/custom
- name: json-logs
mountPath: /var/log/json
- name: log-sender
image: busybox
command: ["sh", "-c", "while true; do cat /var/log/json/app.json | grep -v '^$' | while read line; do echo \"Sending log to external service: $line\"; done; sleep 10; done"]
volumeMounts:
- name: json-logs
mountPath: /var/log/json
volumes:
- name: shared-logs
emptyDir: {}
- name: json-logs
emptyDir: {}
Este exemplo demonstra o padrão Adapter no Kubernetes, onde um contêiner adaptador transforma dados do contêiner de aplicativo principal no formato necessário antes de enviá-lo para um sistema externo. Este padrão ajuda a integrar aplicativos com serviços externos, lidando com transformações de formato de dados dentro do contêiner sidecar.
Resumo
Em resumo, pods:
- São as menores unidades implantáveis no Kubernetes.
- Representam uma única instância de um processo em execução.
- Podem conter um ou mais contêineres.
Serviços:
- Fornece um endereço IP estável e um nome DNS para acessar pods.
- Permite o balanceamento de carga em um conjunto de pods.
- Facilita a descoberta de serviços dentro do cluster.
Source:
https://dzone.com/articles/the-ultimate-guide-to-kubernetes-pods-and-services