Abordaremos a exposição de aplicações no Kubernetes usando o Ingress. O Ingress é uma ferramenta poderosa para roteamento de tráfego externo para serviços dentro do cluster, permitindo a exposição controlada de serviços de aplicativos para o mundo externo.
O que é o Ingress?
O Ingress é um recurso do Kubernetes que permite a configuração de regras de roteamento de tráfego HTTP e HTTPS para serviços dentro do cluster.
Ele é usado para controlar o acesso externo a serviços e aplicativos, fornecendo funcionalidades avançadas de roteamento, como hospedagem virtual, redirecionamento e regras de caminho.
Por que o Ingress é Importante?
O Ingress permite rotear o tráfego para serviços específicos com base em regras definidas, o que é essencial para aplicativos que têm várias partes expostas.
Ele fornece uma camada adicional de segurança, pois pode ser usado em conjunto com certificados SSL/TLS para criptografar o tráfego.
Simplifica o acesso a aplicativos e serviços por meio de URLs amigáveis e de fácil lembrança.
Componentes do Ingress
O Ingress no Kubernetes é composto por vários componentes, incluindo:
- Regras de Roteamento: Definem como o tráfego deve ser roteado com base em critérios como hosts e caminhos.
- Controladores de Ingress: Implementam as regras de roteamento e as aplicam aos serviços correspondentes. A
- Recursos TLS: Permitem a configuração de comunicações seguras usando certificados SSL/TLS.
Ingress Controller
Para que as regras de roteamento sejam aplicadas, é necessário configurar um controlador de Ingress no cluster Kubernetes. Os controladores mais populares incluem o Nginx Ingress Controller, o Traefik e o Istio.
O Ingress Controller é uma peça fundamental no Kubernetes quando se deseja expor serviços ao tráfego externo. Vamos descrever a teoria por trás disso:
Um Ingress Controller é responsável por ler as configurações de Ingress e provisionar os recursos necessários para atender a essas regras. Em termos simples, ele é um proxy reverso que roteia o tráfego externo para serviços específicos no cluster com base nas regras definidas em um recurso de Ingress.
Por que precisamos de um Ingress Controller
Enquanto os serviços Kubernetes do tipo LoadBalancer
e NodePort
oferecem maneiras de expor serviços ao tráfego externo, eles têm limitações:
LoadBalancer
: Cria um load balancer específico do provedor de nuvem para cada serviço, o que pode ser caro e ineficiente.NodePort
: Expõe o serviço em uma porta estática alta em todos os nós, o que não é prático para muitos domínios ou URLs de caminho específicos.
O Ingress Controller supera essas limitações, permitindo a definição de regras de roteamento flexíveis para tráfego externo, como roteamento baseado em nome de domínio (Virtual Hosting) ou caminhos de URL.
Como funciona um Ingress Controller?
Primeiro, você instala um Ingress Controller no seu cluster. Existem várias implementações populares, como Nginx, Traefik e o AWS Load Balancer Controller.
Uma vez instalado, o Ingress Controller começa a monitorar a API do Kubernetes para recursos de Ingress. Quando detecta uma nova regra ou uma alteração em uma regra existente, ele atualiza sua configuração para atender a essa regra.
Com as regras em vigor, o Ingress Controller roteia o tráfego recebido para os serviços apropriados no cluster, com base em informações como nome de domínio e caminho da URL.
Em muitos casos, o Ingress Controller também lida com a terminação SSL, o que significa que ele descriptografa o tráfego HTTPS e o envia para os serviços de back-end como tráfego HTTP. Assim, é crucial garantir que o Ingress Controller esteja seguro.
O Ingress Controller pode se tornar um ponto de estrangulamento se não estiver dimensionado corretamente, pois todo o tráfego externo passa por ele. É vital monitorá-lo e dimensioná-lo de acordo com as necessidades de tráfego.
Usar um Ingress Controller oferece flexibilidade na exposição de serviços. Por exemplo, você pode ter diferentes domínios e caminhos roteando para diferentes serviços, tudo através de um único ponto de entrada.
Recursos TLS no Ingress
Agurança às comunicações, você pode configurar recursos TLS no Ingress. Isso envolve a aquisição e configuração de certificados SSL/TLS para criptografar o tráfego entre os clientes e o cluster.
Instalação do Ingress Controller
Instalar o Ingress em um cluster Kubernetes rodando em EC2s na AWS é um processo bastante comum. Você precisará principalmente do “Ingress Controller” (por exemplo, Nginx Ingress Controller ou o AWS Load Balancer Controller) e depois criar recursos do tipo “Ingress” para rotear o tráfego.
Instale o Helm
Caso não esteja instalado: Helm é um gerenciador de pacotes para Kubernetes. É a maneira mais fácil de instalar o Nginx Ingress Controller:
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
Adicione o repositório do Nginx ao Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
Ingress Controller NodePort
O Ingress Controller diretamente, pode fazer o balancemaneto usando um serviço do tipo NodePort
ou ClusterIP
e, em seguida, configurar o acesso direto usando outras ferramentas ou métodos.
Instale o Nginx Ingress Controller com o tipo de serviço NodePort. Você precisará decidir se deseja usar NodePort
ou ClusterIP
.
NodePort
: Isso expõe o serviço em uma porta específica em todos os nós do cluster. Qualquer tráfego enviado a essa porta em qualquer nó será direcionado para o serviço.ClusterIP
: Isso expõe o serviço apenas internamente dentro do cluster. Para acessar o serviço de fora, você precisaria configurar algum tipo de encaminhamento de porta ou proxy.
Para este exemplo, vamos usar NodePort
:
helm install ingress-nginx ingress-nginx/ingress-nginx \
--set controller.service.type=NodePort
Passo 2. Descubra a porta NodePort atribuída
Depois de instalar o Ingress Controller, você pode descobrir em qual porta o serviço foi exposto com:
kubectl get svc ingress-nginx-controller
Isso listará os portas. Você verá algo como 80:31820/TCP,443:32122/TCP
, onde 31820
e 32122
são os portas NodePort para HTTP e HTTPS, respectivamente.
Lembre-se de que, usando o método NodePort
, você está contornando alguns dos recursos de alta disponibilidade e escalabilidade fornecidos pelo ELB. Além disso, gerenciar o tráfego diretamente pode exigir configurações adicionais e considerações de segurança.
Instalação Ingress Controller ELB
Se você estiver usando subnets privadas e desejar que o LoadBalancer seja interno (isto é, um ELB interno na AWS):
helm install ingress-nginx ingress-nginx/ingress-nginx \
--set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-internal"="0.0.0.0/0"
Isso criará um serviço de tipo LoadBalancer, que por sua vez provisionará um ELB na AWS.
Verifique se o Ingress Controller foi instalado corretamente
kubectl get svc -n default | grep ingress-nginx
Você deve ver o endereço IP do ELB provisionado na AWS.
Claro! Vamos falar sobre o recurso Ingress
no Kubernetes:
Ingress Resource
O recurso Ingress
é um objeto do Kubernetes que gerencia o acesso externo aos serviços em um cluster, normalmente HTTP. O Ingress permite roteamento de tráfego baseado em URLs e oferece funcionalidades como balanceamento de carga, terminação SSL e roteamento baseado em nomes de host ou caminhos de URL visto na seção anterior.
Por que precisamos do Ingress Resource?
Enquanto um Ingress Controller é o componente que efetivamente roteia o tráfego, o recurso Ingress
define como esse tráfego deve ser roteado. É a diferença entre a infraestrutura (o controller) e a configuração (o recurso Ingress
).
Como funciona um Ingress Resource?
Você cria um recurso Ingress especificando regras para roteamento de tráfego. Por exemplo, você pode definir que o tráfego destinado ao domínio example.com deve ser encaminhado para o serviço my-service.
Uma vez criado, o Ingress Controller monitora a API do Kubernetes em busca de recursos de Ingress. Quando detecta uma nova regra ou uma alteração em uma regra existente, ele atualiza sua configuração para atender a essa regra.
Com base nas regras definidas no recurso Ingress, o Ingress Controller roteia o tráfego recebido para os serviços correspondentes no cluster.
Definindo Regras de Roteamento
Paa configurar o Ingress, é preciso definir regras de roteamento que especificam como o tráfego deve ser tratado. Isso envolve:
Virtual Hosting
Roteamento com base em nomes de host, permitindo que vários aplicativos compartilhem o mesmo endereço IP.
No Kubernetes, quando você define um recurso Ingress
com diferentes regras baseadas em hostnames (nomes de domínio), você está essencialmente configurando “Name-based Virtual Hosting”. Isso permite que múltiplas aplicações/serviços sejam acessados através do mesmo IP, mas com diferentes nomes de domínio, cada um roteando para um destino diferente dentro do cluster.
A seção host
no recurso Ingress
especifica o hostname (domínio) para o qual essa regra se aplica. Por exemplo:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-based-virtual-hosting
spec:
rules:
- host: app1.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- host: app2.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
Neste exemplo, o tráfego direcionado para app1.example.com
é roteado para app1-service
, enquanto o tráfego para app2.example.com
é roteado para app2-service
, ambos utilizando o mesmo Ingress Controller e, potencialmente, o mesmo IP público.
Caminhos (Paths)
No contexto de Kubernetes e do recurso Ingress
, a seção que lida com “Caminhos” (ou “Paths” em inglês) define como o tráfego HTTP deve ser roteado com base no caminho da URL. Este conceito é frequentemente referido como “Path-based Routing”.
O roteamento baseado em caminho permite que você dirija o tráfego HTTP para diferentes serviços no seu cluster Kubernetes com base no caminho da URL. Isso é útil quando você deseja ter diferentes aplicações ou partes de uma aplicação servidas sob o mesmo domínio, mas com diferentes caminhos.
Por exemplo, você pode ter uma aplicação principal em example.com/
e um blog relacionado em example.com/blog/
. Usando o roteamento baseado em caminho, você pode direcionar o tráfego para dois serviços diferentes no seu cluster dependendo do caminho da URL acessada.
Veja um exemplo de recurso Ingress
que utiliza roteamento baseado em caminho:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-based-routing
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: main-app-service
port:
number: 80
- path: /blog/
pathType: Prefix
backend:
service:
name: blog-service
port:
number: 80
Neste exemplo:
- Solicitações para
example.com/
(comoexample.com/
,example.com/about
, etc., devido aopathType: Prefix
) serão roteadas para o serviçomain-app-service
. - Solicitações para
example.com/blog/
(e qualquer subcaminho, comoexample.com/blog/post1
, devido aopathType: Prefix
) serão roteadas para o serviçoblog-service
.
O pathType: Prefix
indica que qualquer URL que comece com o caminho especificado deve ser roteada para o serviço correspondente. Outro valor comum para pathType
é ImplementationSpecific
, que deixa a interpretação do caminho para o Ingress Controller específico (por exemplo, Nginx ou Traefik) e pode variar entre implementações.
A capacidade de rotear com base no caminho da URL permite uma flexibilidade significativa ao expor aplicações e serviços em um cluster Kubernetes.
Criação de um Recurso Ingress
O recurso Ingress
no Kubernetes fornece regras para rotear tráfego externo para serviços dentro do cluster. Ele permite que você exponha múltiplos serviços sob o mesmo IP com diferentes caminhos ou subdomínios.
O recurso Ingress
suporta roteamento baseado em host (domínio/subdomínio) e caminho. Por exemplo, você pode direcionar o tráfego de nginx.example.com/
para o serviço unginx-main .
Terminação SSL
O Ingress
também gerencia a terminação SSL, permitindo que você defina certificados SSL para domínios específicos.
Antes de criar um recurso Ingress
, você precisa ter os serviços para os quais deseja rotear o tráfego.
Exemplo 1. Caminho Raiz
Crie o Deployment e Service
Crie um arquivo de deployment e service chamado deploy-svc-main.yaml
, com o seguinte conteúdo:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-main
name: nginx-deploy-main
spec:
replicas: 1
selector:
matchLabels:
app: nginx-main
template:
metadata:
labels:
app: nginx-main
spec:
containers:
- image: nginx:1.25.2
name: nginx
---
apiVersion: v1
kind: Service
metadata:
name: nginx-main
spec:
selector:
app: nginx-main
ports:
- port: 80
targetPort: 80
Salve o arquivo como deploy-svc-main.yaml
e aplique com:
kubectl apply -f deploy-svc-main.yaml
Crie o recurso Ingress
Aqui está um exemplo básico de um arquivo chamado ingress-main.yaml
que contém um recurso Ingress
:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource-main
spec:
ingressClassName: nginx
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-main
port:
number: 80
Este recurso Ingress
direciona o tráfego que chega a nginx.example.com/
para o serviço nginx-main
.
Salve o arquivo como ingress-main.yaml
e aplique com:
kubectl apply -f ingress-main.yaml
Após a aplicação, você pode verificar o status do recurso Ingress
com:
kubectl describe ingress ingress-resource-main
Este comando mostrará detalhes sobre o recurso Ingress
, incluindo qualquer configuração de TLS, regras e backends.
Com o recurso Ingress
aplicado, você deve ser capaz de acessar seu serviço usando o caminho definidos (/
) através do IP/endereço fornecido pelo seu Ingress Controller.
Exemplo 2. Usando Multi Paths
Crie o Deployment e Service BLUE
Crie um arquivo de deployment e service chamado deploy-svc-blue.yaml
, com o seguinte conteúdo:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-blue
name: nginx-blue
spec:
replicas: 1
selector:
matchLabels:
app: nginx-blue
template:
metadata:
labels:
app: nginx-blue
spec:
volumes:
- name: webdata
emptyDir: {}
initContainers:
- name: web-content
image: busybox
volumeMounts:
- name: webdata
mountPath: "/webdata"
command: ["/bin/sh", "-c", 'echo "<h1>I am <font color=blue>BLUE</font></h1>" > /webdata/index.html']
containers:
- image: nginx:1.25.2
name: nginx
volumeMounts:
- name: webdata
mountPath: "/usr/share/nginx/html"
---
apiVersion: v1
kind: Service
metadata:
name: nginx-blue
spec:
selector:
app: nginx-blue
ports:
- port: 80
targetPort: 80
Salve o arquivo como deploy-svc-blue.yaml
e aplique com:
kubectl apply -f deploy-svc-blue.yaml
Crie o Deployment e Service GREEN
Crie um arquivo de deployment e service chamado deploy-svc-green.yaml
, com o seguinte conteúdo:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-green
name: nginx-green
spec:
replicas: 1
selector:
matchLabels:
app: nginx-green
template:
metadata:
labels:
app: nginx-green
spec:
volumes:
- name: webdata
emptyDir: {}
initContainers:
- name: web-content
image: busybox
volumeMounts:
- name: webdata
mountPath: "/webdata"
command: ["/bin/sh", "-c", 'echo "<h1>I am <font color=green>green</font></h1>" > /webdata/index.html']
containers:
- image: nginx:1.25.2
name: nginx
volumeMounts:
- name: webdata
mountPath: "/usr/share/nginx/html"
---
apiVersion: v1
kind: Service
metadata:
name: nginx-green
spec:
selector:
app: nginx-green
ports:
- port: 80
targetPort: 80
Salve o arquivo como deploy-svc-green.yaml
e aplique com:
kubectl apply -f deploy-svc-green.yaml
Antes de criar o recurso multi path, vamos remover o ingress resource criado para o caminho raiz. |
kubectl delete -f ingress-main.yaml
ou
kubectl delete ingress ingress-resource-main
Crie o recurso Ingress Multi Path
Aqui está um exemplo básico de um arquivo chamado ingress-multipath.yaml
que contém um recurso Ingress
:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: ingress-resource-2
spec:
ingressClassName: nginx
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-main
port:
number: 80
- path: /blue
pathType: Prefix
backend:
service:
name: nginx-blue
port:
number: 80
- path: /green
pathType: Prefix
backend:
service:
name: nginx-green
port:
number: 80
Salve o arquivo como ingress-multipath.yaml
e aplique com:
kubectl apply -f ingress-multipath.yaml
Com o recurso Ingress aplicado, você deve ser capaz de acessar seus serviços usando os caminhos definidos (‘/’,’/blue’ e ‘/green’ neste caso) através do IP/endereço fornecido pelo seu Ingress Controller.
Exemplo 3. Usando Virtual Hosting
Vamos utilizar os deployments que criamos anteriormente. Agora, focaremos na criação do recurso Ingress. Neste exemplo, utilizaremos os subdomínios ‘blue’ e ‘green’. Assim, o acesso à raiz será feito através de “nginx.example.com”. Para acessar o service nginx-blue, usaremos “blue.nginx.example.com”, e para o service nginx-green, “green.nginx.example.com”.
Crie o recurso Ingress Virtual Hosting
Aqui está um exemplo básico de um arquivo chamado ingress-virtualhosting.yaml
que contém um recurso Ingress
:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource-3
spec:
ingressClassName: nginx
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-main
port:
number: 80
- host: blue.nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-blue
port:
number: 80
- host: green.nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-green
port:
number: 80
Salve o arquivo como ingress-virtualhosting.yaml
e aplique com:
kubectl apply -f ingress-virtualhosting.yaml
Com o recurso Ingress aplicado, você deve ser capaz de acessar seus serviços usando os caminhos definidos (‘nginx.example.com’,’blue.nginx.example.com’ e ‘green.nginx.example.com’ neste caso) através do IP/endereço fornecido pelo seu Ingress Controller.