Envoy Gateway
O Envoy Gateway é um controlador Kubernetes Gateway API que usa o Envoy Proxy para lidar com o tráfego de entrada. Com ele, você pode publicar serviços HTTP, HTTPS, gRPC, TCP e UDP, configurar roteamento por domínio e caminho, gerenciar TLS e aplicar políticas de tráfego usando recursos padrão do Kubernetes.
O Gateway API é a evolução do Ingress. Em vez de um único recurso Ingress, as responsabilidades são divididas entre vários objetos dedicados:
GatewayClassdefine qual controlador vai gerenciar os gateways.Gatewaydescreve o ponto de entrada: portas, protocolos e configurações de TLS.HTTPRoutedefine as regras de roteamento do tráfego HTTP para os serviços de backend.GRPCRoute,TCPRoute,UDPRoute,TLSRoutetratam outros tipos de tráfego.
O Envoy Gateway monitora esses recursos e os utiliza para criar um Envoy Proxy que recebe o tráfego externo e o direciona para os serviços dentro do cluster.
Instalação Copiar link
Para instalar o Envoy Gateway:
- Acesse a seção Kubernetes e clique no cluster.
- Navegue até a aba Complementos e selecione Envoy Gateway.
- (Opcional) Ative a Instalação avançada para editar o
values.yaml. Na maioria dos casos, os valores padrão já são suficientes para começar. - Clique em Instalar.
- Aguarde a conclusão e verifique se os pods do Envoy Gateway estão em execução:
kubectl get pods -n envoy-gateway-systemTodos os pods devem exibir o status Running.
Você também pode confirmar que os recursos do Gateway API estão disponíveis no cluster:
kubectl api-resources | grep gateway.networking.k8s.ioExemplo prático Copiar link
Neste exemplo, vamos configurar o Envoy Gateway para receber tráfego HTTP em um único IP externo e roteá-lo para dois serviços diferentes:
http://app.example.com/service1 direciona para service1http://app.example.com/service2 direciona para service2
Comece criando um namespace dedicado:
kubectl create namespace envoy-exampleCriar um ConfigMap Copiar link
Crie um arquivo chamado configmap.yaml com as páginas HTML dos dois serviços:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-pages
namespace: envoy-example
data:
service1.html: |
<html>
<head><title>Service 1</title></head>
<body><h1>Service 1</h1></body>
</html>
service2.html: |
<html>
<head><title>Service 2</title></head>
<body><h1>Service 2</h1></body>
</html>Aplique o manifesto:
kubectl apply -f configmap.yamlCriar Deployments e Services Copiar link
Crie o arquivo service1.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: service1
namespace: envoy-example
spec:
replicas: 2
selector:
matchLabels:
app: service1
template:
metadata:
labels:
app: service1
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
configMap:
name: nginx-pages
items:
- key: service1.html
path: index.html
---
apiVersion: v1
kind: Service
metadata:
name: service1
namespace: envoy-example
spec:
selector:
app: service1
ports:
- name: http
port: 80
targetPort: 80
type: ClusterIPCrie o arquivo service2.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: service2
namespace: envoy-example
spec:
replicas: 2
selector:
matchLabels:
app: service2
template:
metadata:
labels:
app: service2
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
configMap:
name: nginx-pages
items:
- key: service2.html
path: index.html
---
apiVersion: v1
kind: Service
metadata:
name: service2
namespace: envoy-example
spec:
selector:
app: service2
ports:
- name: http
port: 80
targetPort: 80
type: ClusterIPAplique os dois manifestos:
kubectl apply -f service1.yaml
kubectl apply -f service2.yamlVerifique se os pods estão em execução:
kubectl get pods -n envoy-exampleCriar um GatewayClass Copiar link
O GatewayClass conecta o Gateway API ao controlador Envoy Gateway.
Crie o arquivo gatewayclass.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: envoy-gateway
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controllerAplique:
kubectl apply -f gatewayclass.yamlVerifique o status:
kubectl get gatewayclass envoy-gatewayA coluna ACCEPTED deve exibir True, indicando que o Envoy Gateway registrou o GatewayClass e vai gerenciar os recursos associados a ele.
Criar um Gateway Copiar link
O recurso Gateway define o ponto de entrada externo para a sua aplicação.
Crie o arquivo gateway.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: app-gateway
namespace: envoy-example
spec:
gatewayClassName: envoy-gateway
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: SameAplique:
kubectl apply -f gateway.yamlApós a criação do Gateway, o Envoy Gateway vai provisionar um Envoy Proxy e um load balancer. Você pode acompanhar a criação do load balancer no painel de controle ou verificar com o comando:
kubectl get gateway app-gateway -n envoy-exampleAguarde até que a coluna PROGRAMMED exiba True e a coluna ADDRESS mostre um IP externo.
Você também pode inspecionar o serviço criado:
kubectl get svc -n envoy-gateway-system \
-l gateway.envoyproxy.io/owning-gateway-namespace=envoy-example,gateway.envoyproxy.io/owning-gateway-name=app-gatewayCriar um HTTPRoute Copiar link
O HTTPRoute define as regras de roteamento. Crie o arquivo httproute.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
namespace: envoy-example
spec:
parentRefs:
- name: app-gateway
hostnames:
- app.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /service1
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: service1
port: 80
- matches:
- path:
type: PathPrefix
value: /service2
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: service2
port: 80Aplique:
kubectl apply -f httproute.yamlConfirme que a rota foi aceita:
kubectl get httproute app-route -n envoy-example -o yamlO status do recurso deve conter:
status: "True" type: AcceptedNeste manifesto, o HTTPRoute aceita requisições para app.example.com e as direciona para diferentes serviços com base no prefixo do caminho. O filtro URLRewrite substitui os prefixos /service1 e /service2 por /, para que o Nginx dentro de cada serviço sirva corretamente sua página principal.
Verificar o funcionamento Copiar link
Obtenha o IP externo do Gateway:
kubectl get gateway app-gateway -n envoy-exampleAdicione esse IP como um registro A para app.example.com nas configurações de DNS. Após a propagação, teste os dois endpoints:
curl http://app.example.com/service1
curl http://app.example.com/service2Se o DNS ainda não tiver propagado, você pode testar pelo IP usando o cabeçalho Host:
curl -H "Host: app.example.com" http://<EXTERNAL_IP>/service1
curl -H "Host: app.example.com" http://<EXTERNAL_IP>/service2Ambas as requisições devem retornar as páginas do Service 1 e do Service 2.
Limpar os recursos Copiar link
Para remover todos os recursos criados neste exemplo, execute:
kubectl delete namespace envoy-example
kubectl delete gatewayclass envoy-gatewayIsso não desinstala o add-on Envoy Gateway. Para removê-lo, acesse a aba Complementos no painel de controle do cluster.
Migrar do Nginx Ingress para o Envoy Gateway Copiar link
Você pode rodar o Envoy Gateway junto com o Nginx Ingress e migrar as rotas aos poucos. Essa abordagem permite testar os recursos do Gateway API em um IP externo separado antes de atualizar os registros DNS ou redirecionar o tráfego para o novo Gateway.
Para automatizar a conversão dos recursos Ingress existentes, use o utilitário ingress2gateway. Ele lê os recursos Ingress do seu cluster e gera os recursos equivalentes do Gateway API: Gateway, HTTPRoute e outros objetos relacionados.
Pré-requisitos Copiar link
Antes de migrar, certifique-se de que o cluster está preparado:
- O Envoy Gateway está instalado.
- Um
GatewayClasspara o Envoy Gateway foi criado. - Os recursos Ingress existentes estão funcionando corretamente pelo Nginx Ingress.
Verifique se as duas classes estão presentes:
kubectl get ingressclass
kubectl get gatewayclassO resultado deve incluir um IngressClass chamado nginx e um GatewayClass chamado envoy-gateway.
Instalar o ingress2gateway Copiar link
Se você tiver o Go instalado localmente, execute:
go install github.com/kubernetes-sigs/ingress2gateway@v1.0.0O binário será colocado em $(go env GOPATH)/bin. Certifique-se de que esse diretório está no seu PATH.
Outra opção é instalar via Homebrew:
brew install ingress2gatewayOu baixar um binário pré-compilado na página de releases do projeto.
Configuração de origem Copiar link
Neste exemplo, a migração é feita para uma aplicação já publicada pelo Nginx Ingress.
O cluster tem um namespace chamado ingress-migration-demo com:
- Um recurso Ingress chamado
migration-source - Os serviços
service1eservice2 - Duas regras de roteamento para o domínio
ingress-migration.example.com:/service1direciona paraservice1/service2direciona paraservice2
Verifique o Ingress de origem:
kubectl get ingress -n ingress-migration-demoA coluna CLASS deve exibir nginx.
Converter os recursos Ingress Copiar link
Para converter o Ingress em recursos do Gateway API, execute:
ingress2gateway print \
--providers=ingress-nginx \
--emitter=envoy-gateway \
--ingress-nginx-ingress-class=nginx \
--namespace=ingress-migration-demo > gateway-migration.yamlO que cada flag faz:
printexibe os recursos gerados no stdout; o redirecionamento>salva o resultado emgateway-migration.yaml.--providers=ingress-nginxespecifica o tipo de Ingress controller de origem.--emitter=envoy-gatewaydefine o Envoy Gateway como controlador de destino.--ingress-nginx-ingress-class=nginxfiltra apenas os recursos Ingress que usam a classenginx.--namespace=ingress-migration-demolimita a conversão ao namespace de origem.
Revisar e corrigir o arquivo gerado Copiar link
Abra o arquivo gateway-migration.yaml e revise os recursos antes de aplicá-los.
Preste atenção ao campo gatewayClassName no recurso Gateway. O utilitário pode gerar esse valor com base no nome do IngressClass de origem, resultando em algo como:
spec:
gatewayClassName: nginxO Envoy Gateway não vai processar um Gateway com esse nome de classe, a menos que exista um GatewayClass chamado nginx no cluster. Atualize o valor para corresponder ao GatewayClass que você criou:
spec:
gatewayClassName: envoy-gatewayAplicar os recursos do Gateway API Copiar link
Quando estiver satisfeito com o arquivo, aplique:
kubectl apply -f gateway-migration.yamlVerifique se o Gateway foi criado e recebeu um IP externo:
kubectl get gateway -AConfirme que o HTTPRoute foi aceito pelo controlador:
kubectl get httproute -A
kubectl describe httproute <nome-da-rota> -n <namespace>O status do HTTPRoute deve conter Accepted=True e ResolvedRefs=True.
Testar antes de mudar o tráfego Copiar link
Enquanto os registros DNS ainda apontam para o Nginx Ingress antigo, você pode verificar o novo Gateway enviando requisições diretamente para o IP externo com o cabeçalho Host:
curl -H "Host: app.example.com" http://<EXTERNAL_IP>/<path>Onde:
app.example.comé o domínio do seuHTTPRoute.<EXTERNAL_IP>é o IP do novoGateway.<path>é o caminho tratado pela rota.
Compare as respostas do Ingress antigo e do novo Gateway. Se tudo estiver correto, atualize os registros DNS para apontar para o IP do novo load balancer.