A Gateway API é a próxima geração de API de roteamento e balanceamento de carga para Kubernetes. Este tópico descreve como configure rotas HTTP, modifique cabeçalhos de requisição e distribuir requisições por peso em um cluster ACK Edge usando o componente Gateway with Inference Extension.
Como funciona
O componente Gateway with Inference Extension baseia-se no projeto Envoy Gateway e oferece suporte a todos os recursos básicos do Gateway API e aos recursos de extensão do Envoy Gateway.
A arquitetura do Envoy Gateway inclui:
Control plane: o control plane é composto pelo componente Envoy Gateway, que escuta as regras de tráfego dentro do cluster, cria e gerencia dinamicamente instâncias de proxy Envoy e atualiza as regras de encaminhamento em tempo real. O control plane não encaminha diretamente o tráfego de service.
Data plane: o data plane é composto pelas instâncias de proxy Envoy, que processam e encaminham o tráfego de service.
Em um cluster ACK Edge, o método de implantação do Envoy Gateway difere daquele em um cluster ACK padrão:
|
Diferenças |
ACK padrão |
ACK Edge |
|
Método de exposição do service |
LoadBalancer |
NodePort |
|
Implantação do control plane |
Nível de cluster |
Um conjunto implantado por node pool |
|
Implantação do data plane |
Nível de cluster |
Implantado por node pool |
|
Múltiplos node pools |
Compartilham um gateway |
Crie um gateway separado para cada node pool |
|
Topologia de service |
Não requer configuração |
Requer a anotação |
A implantação atual está configure com uma política de distribuição por node pool. Ajuste o número de réplicas no gerenciamento de componentes para garantir que ao menos uma réplica do control plane seja executada em cada node pool.

Escopo
Você criou um cluster na versão 1.30 ou posterior.
O componente Gateway with Inference Extension está instale.
Preparativos
Etapa 1: crie um aplicativo de teste
Salve o exemplo a seguir como backend.yaml e execute o comando kubectl apply -f backend.yaml para crie os aplicativos de teste: backend e backend-2.
Em cenários ACK Edge, é necessário configure a topologia de service. Adicione a anotação openyurt.io/topologyKeys: openyurt.io/nodepool ao Service para garantir que o tráfego seja encaminhado somente para pods dentro do mesmo node pool. Para mais informações, consulte Topologia de service para node pools .
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend
---
apiVersion: v1
kind: Service
metadata:
name: backend
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool # Configure the node pool topology
labels:
app: backend
service: backend
spec:
ports:
- name: http
port: 3000
targetPort: 3000
selector:
app: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 1
selector:
matchLabels:
app: backend
version: v1
template:
metadata:
labels:
app: backend
version: v1
spec:
serviceAccountName: backend
containers:
- image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/envoygateway-echo-basic:v20231214-v1.0.0-140-gf544a46e
imagePullPolicy: IfNotPresent
name: backend
ports:
- containerPort: 3000
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend-2
---
apiVersion: v1
kind: Service
metadata:
name: backend-2
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool # Configure the node pool topology
labels:
app: backend-2
service: backend-2
spec:
ports:
- name: http
port: 3000
targetPort: 3000
selector:
app: backend-2
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-2
spec:
replicas: 1
selector:
matchLabels:
app: backend-2
version: v1
template:
metadata:
labels:
app: backend-2
version: v1
spec:
serviceAccountName: backend-2
containers:
- image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/envoygateway-echo-basic:v20231214-v1.0.0-140-gf544a46e
imagePullPolicy: IfNotPresent
name: backend-2
ports:
- containerPort: 3000
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
Etapa 2: confirme o GatewayClass
Após instale o componente Gateway with Inference Extension, um GatewayClass é criado por padrão. Execute o comando a seguir para confirme:
kubectl get gatewayclass
Saída esperada:
NAME CONTROLLER ACCEPTED AGE
ack-gateway gateway.envoyproxy.io/gatewayclass-controller True 2m31s
Se o recurso GatewayClass não for encontrado, crie-o manualmente. Salve o exemplo a seguir como gatewayclass.yaml e execute o comando kubectl apply -f gatewayclass.yaml para criá-lo.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: ack-gateway
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
Etapa 3: crie uma configuração personalizada de EnvoyProxy
Em um cluster ACK Edge, crie uma configuração personalizada de EnvoyProxy para cada node pool a fim de especifique o node pool de agendamento dos pods do data plane e o método de exposição do service.
Substitua NPXXX no exemplo a seguir pelo ID real do seu node pool. Em seguida, salve a configuração como gateway-config.yaml e execute o comando kubectl apply -f gateway-config.yaml.
Você encontra o ID do node pool na página no ACK console.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
spec:
provider:
type: Kubernetes
kubernetes:
envoyDeployment:
pod:
nodeSelector:
alibabacloud.com/nodepool-id: NPXXX # Replace with your actual node pool ID
envoyService:
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool # Configure the service topology
type: NodePort # ACK Edge uses NodePort to expose services
Esta configuração inclui três definições importantes para cenários ACK Edge:
|
Item de configuração |
Descrição |
|
|
Agenda os pods do data plane do gateway para o node pool especificado |
|
Anotação |
Configure a topologia de service para manter o tráfego dentro do node pool |
|
|
Utiliza NodePort para expor o service. LoadBalancer não é usado em cenários de edge. |
Etapa 4: crie o recurso Gateway
Salve o exemplo a seguir como gateway.yaml e execute o comando kubectl apply -f gateway.yaml.
O control plane do componente cria automaticamente um deployment de EnvoyProxy e um service NodePort com base no recurso Gateway. Também inicia um listener na porta especificada do nó.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: ack-gateway
spec:
gatewayClassName: ack-gateway
listeners:
- name: http
protocol: HTTP
port: 80
infrastructure:
parametersRef:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config # Associate with the custom configuration created in Step 3
Etapa 5: obtenha o endpoint do gateway
O service do gateway é exposto como NodePort. O endpoint de service correspondente é o endereço IP de qualquer nó no node pool e sua porta de service.
-
Consulte a porta do service.
kubectl get service -n kube-system -l gateway.envoyproxy.io/owning-gateway-name=ack-gatewaySaída esperada:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE envoy-default-ack-gateway-7452df7d NodePort 192.168.86.174 <none> 80:30364/TCP 19m Defina a variável de ambiente do host do gateway. Substitua
NODEIPpelo endereço IP de qualquer nó no node pool eNODEPORTpelo número da porta obtido na etapa anterior.export GATEWAY_HOST=NODEIP:NODEPORT
Configure roteamento HTTP com base na correspondência de prefixo de caminho
O arquivo YAML de exemplo a seguir cria um HTTPRoute que corresponde ao prefixo /get.
-
Crie um HTTPRoute. Salve o conteúdo YAML a seguir como
httproute.yaml. Em seguida, execute o comandokubectl apply -f httproute.yamlpara aplicá-lo.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: ack-gateway hostnames: - "www.example.com" rules: - backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 1 matches: - path: type: PathPrefix value: /get -
Acesse o aplicativo.
curl -H "Host: www.example.com" http://$GATEWAY_HOST/getSaída esperada:
{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "953b2f8f-26d3-4ba9-93ba-a482b197b1ff" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }
Adicionar um cabeçalho de requisição
Atualize o HTTPRoute adicionando um cabeçalho à requisição.
-
Atualize o recurso
HTTPRoute. Salve o conteúdo YAML a seguir comohttproute.yaml. Em seguida, execute o comandokubectl apply -f httproute.yamlpara aplicá-lo.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: ack-gateway hostnames: - "www.example.com" rules: - matches: - path: type: PathPrefix value: /get backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 1 filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: "added-header" value: "foo" -
Acesse o aplicativo.
curl -H "Host: www.example.com" http://$GATEWAY_HOST/getSaída esperada:
{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "Added-Header": [ "foo" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "d37f19e5-25c1-45cf-90e5-51453e7ae3ed" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }%Como o aplicativo de exemplo ecoa as informações da requisição em sua resposta, você deve visualizar o
added-headerna saída. Isso confirme que a operação foi bem-sucedida.
Configure divisão proporcional de tráfego
Atualize o HTTPRoute com base no modelo YAML a seguir, que acrescenta regras de roteamento para o Service backend-2 e especifique os pesos de tráfego para os Services backend e backend-2.
A soma dos pesos especificados no parâmetro backendRefs não precisa ser 100. A proporção de tráfego roteado para um Service =
-
Atualize o HTTPRoute. Salve o conteúdo YAML a seguir como
httproute.yaml. Em seguida, execute o comandokubectl apply -f httproute.yamlpara aplicá-lo.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: ack-gateway hostnames: - "www.example.com" rules: - matches: - path: type: PathPrefix value: /get backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 8 - group: "" kind: Service name: backend-2 port: 3000 weight: 2 -
Acesse o aplicativo 20 vezes e verifique a proporção real de tráfego entre os dois Services.
O comando a seguir envia 20 requisições e processa a saída para mostrar somente o Service backend (
backendoubackend-2) que atendeu cada requisição.for i in $(seq 1 20); do curl -sS -H "Host: www.example.com" http://$GATEWAY_HOST/get |grep backend; done | \ sed -E 's/".*"(backend(-2)?)-[0-9a-zA-Z]*-.*/\1/'Saída esperada:
backend-2 backend backend backend backend backend backend backend backend backend backend backend-2 backend-2 backend backend backend-2 backend backend backend backendA saída mostra que cerca de 80% das requisições são encaminhadas ao Service
backende os 20% restantes ao Servicebackend-2.