O Kubernetes é uma poderosa plataforma de orquestração de contêineres, mas para aproveitar todo o seu potencial, é importante entender seus principais componentes, com pods e serviços desempenhando papéis fundamentais. Neste artigo, vamos explorar o que são e como trabalham juntos para expor e gerenciar o acesso a aplicativos em execução dentro de um cluster do Kubernetes.
O Que É um Pod?
Pods são as menores unidades de computação que você pode criar e gerenciar no Kubernetes.
Antes de criarmos um pod, vamos verificar os recursos da API disponíveis no seu cluster do Kubernetes; você pode usar o comando kubectl api-resources
. Esse comando lista os recursos da API suportados pelo servidor de API do Kubernetes, incluindo seus nomes abreviados, 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ásico para um pod executando um contêiner Nginx simples.
Crie um arquivo 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
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: rótulos: Pares de chave-valor que podem ser usados para organizar e selecionar o pod.
- spec:containers: Uma lista de contêineres que serão executados no pod.
- spec:containers:nome: O nome do contêiner.
- spec:containers:imagem: A imagem do contêiner a ser usada (neste caso, a última imagem do Nginx).
- spec:containers:portas: As portas a serem expostas pelo contêiner.
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 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 ser semelhante ao seguinte:
kubectl get pod
No resources found in default namespace.
O que é um Serviço?
A criação de 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 ainda não tiver, 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
Aplicar a configuração do Pod:
kubectl apply -f nginx-pod.yaml
Crie um arquivo YAML chamado nginx-service.yaml
para definir o Serviço:
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 Nginx.
- app: nginx: Isso deve corresponder ao rótulo no pod Nginx.
- type: ClusterIP: O tipo do Serviço. ClusterIP torna o Serviço acessível apenas dentro do cluster. Você também pode usar NodePort ou LoadBalancer para expor o Serviço externamente.
Aplicar a configuração do Serviço 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 Serviço é do tipo ClusterIP, ele só é acessível dentro do cluster. Para acessá-lo de fora do cluster, você pode alterar o tipo de Serviço para NodePort ou LoadBalancer.
Para expor o Serviço 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
Aplicar a configuração atualizada do Serviço:
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).
Pods de Múltiplos Contêineres
Usar um único contêiner por pod fornece a máxima granularidade e desacoplamento. No entanto, existem cenários nos quais 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 primário (conceito de sidecar), atuar como um proxy para sistemas externos (conceito de embaixador) ou modificar dados para se ajustar a um formato externo (conceito de adaptador). Esses contêineres secundários complementam o contêiner primário ao realizar tarefas que ele não lida.
Abaixo está um exemplo de uma configuração de Pod do Kubernetes que inclui um contêiner primário executando um servidor Nginx e um contêiner secundário atuando como um sidecar para lidar com o registro. O contêiner sidecar usa um contêiner de registro simples como o BusyBox para demonstrar como ele pode monitorar os logs 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 <nome-do-pod> -c log-sidecar
.
Seguindo estes 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 logging. Isso garantirá que a nova configuração esteja ativa e em execução em seu cluster Kubernetes.
Os pods de 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 de Vários Contêineres
Padrão Sidecar
Contêineres sidecar podem aprimorar o aplicativo principal fornecendo funções auxiliares como logging, gerenciamento de configuração ou proxy. Este padrão ajuda a estender a funcionalidade sem modificar o contêiner principal. Um contêiner sidecar pode lidar com logging coletando e encaminhando logs do contêiner do aplicativo principal.
Padrão Embaixador
Contêineres embaixadores atuam como um proxy, gerenciando a comunicação entre o aplicativo principal e os serviços externos. Isso pode simplificar a integração e configuração. Um contêiner embaixador pode lidar com a terminação SSL ou funções de gateway de API.
O padrão Embaixador envolve o uso de um contêiner sidecar para gerenciar a comunicação entre o aplicativo principal e os serviços externos. Este 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 requisições HTTP
- Contêiner Embaixador: Proxy Envoy configurado para gerenciar requisições à 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 as complexidades da comunicação e aprimora a modularidade e a manutenibilidade.
Padrão Adaptador
Contêineres Adaptadores podem modificar ou transformar dados entre a aplicação principal e 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 lateral para transformar dados entre o contêiner de aplicativo principal e sistemas externos. Isso pode ser útil quando a aplicação 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: Uma aplicação 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. Esse padrão ajuda a integrar aplicativos com serviços externos ao lidar 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 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