Esta página descreve como implementar recursos do Gateway do Kubernetes para o balanceamento de carga do tráfego de entrada em vários clusters do Google Kubernetes Engine (GKE) (ou frota). Antes de implementar gateways de vários clusters, consulte o artigo Ativar gateways de vários clusters para preparar o seu ambiente.
Para implementar gateways para equilibrar a carga do tráfego de entrada para apenas um cluster do GKE, consulte o artigo Implementar gateways.
Gateways em vários clusters
Um gateway de vários clusters é um recurso de gateway que equilibra a carga do tráfego em vários clusters do Kubernetes. No GKE, as gke-l7-global-external-managed-mc
, gke-l7-regional-external-managed-mc
, gke-l7-rilb-mc
e gke-l7-gxlb-mc
GatewayClasses implementam gateways de vários clusters que fornecem encaminhamento HTTP, divisão de tráfego, espelhamento de tráfego, comutação por falha baseada no estado e muito mais em diferentes clusters do GKE, namespaces do Kubernetes e em diferentes regiões.
Os gateways de vários clusters facilitam, tornam segura e escalável a gestão da rede de aplicações em vários clusters e equipas para os administradores de infraestrutura.
Esta página apresenta três exemplos para lhe ensinar a implementar gateways de vários clusters usando o controlador de gateway do GKE:
- Exemplo 1: um gateway externo de vários clusters que fornece balanceamento de carga em dois clusters do GKE para tráfego da Internet.
- Exemplo 2: um gateway privado de camada 7 entre regiões.
- Exemplo 3: divisão de tráfego azul/verde baseada no peso e espelhamento de tráfego em dois clusters do GKE para tráfego interno da VPC.
- Exemplo 4: um gateway baseado na capacidade para equilibrar a carga de pedidos para diferentes back-ends com base na respetiva capacidade máxima.
Cada um dos exemplos vai usar as mesmas aplicações store e site para modelar um cenário do mundo real em que um serviço de compras online e um serviço de Website são detidos e operados por equipas separadas e implementados numa frota de clusters do GKE partilhados. Cada um dos exemplos realça diferentes topologias e exemplos de utilização ativados por gateways de vários clusters.
Os gateways de vários clusters requerem alguma preparação ambiental antes de poderem ser implementados. Antes de continuar, siga os passos em Ativar gateways multicluster:
Implemente clusters do GKE.
Registe os seus clusters numa frota.
Ative os controladores de serviço em vários clusters e gateway em vários clusters.
Por último, reveja as limitações e os problemas conhecidos do controlador de gateway do GKE antes de o usar no seu ambiente.
Gateway externo multicluster e multirregional
Neste tutorial, vai criar um gateway externo de vários clusters que serve tráfego externo numa aplicação executada em dois clusters do GKE.
Nos passos seguintes:
- Implemente a aplicação
store
de exemplo nos clustersgke-west-1
egke-east-1
. - Configure os serviços em cada cluster a serem exportados para a sua frota (serviços em vários clusters).
- Implemente um gateway externo de vários clusters e um HTTPRoute
no cluster de configuração (
gke-west-1
).
Depois de os recursos da aplicação e do gateway serem implementados, pode controlar o tráfego nos dois clusters do GKE através do encaminhamento baseado em caminhos:
- Os pedidos para
/west
são encaminhados para os podsstore
no clustergke-west-1
. - Os pedidos para
/east
são encaminhados para os podsstore
no clustergke-east-1
. - Os pedidos para qualquer outro caminho são encaminhados para qualquer um dos clusters, de acordo com o respetivo estado, capacidade e proximidade do cliente que está a fazer o pedido.
Implementar a aplicação de demonstração
Crie a
store
implementação e o espaço de nomes nos três clusters que foram implementados em Ativar gateways de vários clusters:kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
Implementa os seguintes recursos em cada cluster:
namespace/store created deployment.apps/store created
Todos os exemplos nesta página usam a app implementada neste passo. Certifique-se de que a app está implementada nos três clusters antes de experimentar qualquer um dos passos restantes. Este exemplo usa apenas os clusters
gke-west-1
egke-east-1
, egke-west-2
é usado noutro exemplo.
Serviços em vários clusters
Os serviços são a forma como os pods são expostos aos clientes. Uma vez que o controlador de gateway do GKE usa o equilíbrio de carga nativo de contentores, não usa o ClusterIP nem o equilíbrio de carga do Kubernetes para alcançar os pods. O tráfego é enviado diretamente do equilibrador de carga para os endereços IP dos pods. No entanto, os serviços continuam a desempenhar um papel fundamental como identificador lógico para o agrupamento de pods.
Os serviços em vários clusters (MCS) são uma norma de API para serviços que abrangem clusters, e o respetivo controlador do GKE fornece a descoberta de serviços em clusters do GKE. O controlador do gateway de vários clusters usa recursos da API MCS para agrupar pods num serviço que é endereçável em vários clusters ou abrange vários clusters.
A API Services em vários clusters define os seguintes recursos personalizados:
- Os ServiceExports são mapeados para um serviço do Kubernetes, exportando os pontos finais desse serviço para todos os clusters registados na frota. Quando um serviço tem um ServiceExport correspondente, significa que o serviço pode ser abordado por um gateway de vários clusters.
- Os ServiceImports são gerados automaticamente pelo controlador de serviços de vários clusters. ServiceExport e ServiceImport são usados aos pares. Se existir um ServiceExport na frota, é criado um ServiceImport correspondente para permitir o acesso ao serviço mapeado para o ServiceExport a partir de todos os clusters.
Os serviços de exportação funcionam da seguinte forma. Existe um serviço de loja em gke-west-1
que seleciona um grupo de pods nesse cluster. É criado um ServiceExport no cluster que permite que os pods em gke-west-1
se tornem acessíveis a partir dos outros clusters na frota. O ServiceExport é mapeado e expõe os serviços que têm o mesmo nome e espaço de nomes que o recurso ServiceExport.
apiVersion: v1
kind: Service
metadata:
name: store
namespace: store
spec:
selector:
app: store
ports:
- port: 8080
targetPort: 8080
---
kind: ServiceExport
apiVersion: net.gke.io/v1
metadata:
name: store
namespace: store
O diagrama seguinte mostra o que acontece após a implementação de um ServiceExport. Se existir um par ServiceExport e Service, o controlador de serviços de vários clusters implementa um ServiceImport correspondente em todos os clusters do GKE na frota. O ServiceImport é a representação local do store
Service
em todos os clusters. Isto permite que o client
pod em gke-east-1
use ClusterIP ou serviços sem cabeçalho para alcançar os store
pods em gke-west-1
. Quando usados desta forma, os serviços de vários clusters oferecem balanceamento de carga leste-oeste entre clusters sem exigir um serviço LoadBalancer interno.
Para usar serviços em vários clusters para o equilíbrio de carga de cluster para cluster, consulte o artigo
Configurar serviços em vários clusters.
Os gateways de vários clusters também usam ServiceImports, mas não para o equilíbrio de carga de cluster para cluster. Em alternativa, os gateways usam ServiceImports como identificadores lógicos para um serviço que existe noutro cluster ou que se estende por vários clusters. O HTTPRoute seguinte faz referência a um ServiceImport em vez de um recurso de serviço. Ao fazer referência a um ServiceImport, isto indica que está a encaminhar tráfego para um grupo de pods de back-end que são executados em um ou mais clusters.
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-route
namespace: store
labels:
gateway: multi-cluster-gateway
spec:
parentRefs:
- kind: Gateway
namespace: store
name: external-http
hostnames:
- "store.example.com"
rules:
- backendRefs:
- group: net.gke.io
kind: ServiceImport
name: store
port: 8080
O diagrama seguinte mostra como o HTTPRoute encaminha o tráfego store.example.com
para os pods store
em gke-west-1
e gke-east-1
. O balanceador de carga trata-os como um único conjunto de back-ends. Se os pods de um dos clusters ficarem em mau estado,
inacessíveis ou não tiverem capacidade de tráfego, a carga de tráfego é equilibrada para os
pods restantes no outro cluster. É possível adicionar ou remover novos clusters com o serviço store
e o ServiceExport. Isto adiciona ou remove de forma transparente os pods de back-end sem alterações explícitas à configuração de encaminhamento.
Serviços de exportação
Neste momento, a aplicação está a ser executada em ambos os clusters. Em seguida, vai expor e exportar as aplicações implementando serviços e ServiceExports em cada cluster.
Aplique o seguinte manifesto ao cluster
gke-west-1
para criar os serviçosstore
estore-west-1
e as exportações de serviços:cat << EOF | kubectl apply --context gke-west-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-west-1 namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-west-1 namespace: store EOF
Aplique o seguinte manifesto ao cluster
gke-east-1
para criar os serviçosstore
estore-east-1
e as exportações de serviços:cat << EOF | kubectl apply --context gke-east-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-east-1 namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-east-1 namespace: store EOF
Verifique se foram criados os ServiceExports corretos nos clusters.
kubectl get serviceexports --context CLUSTER_NAME --namespace store
Substituir CLUSTER_NAME por
gke-west-1
egke-east-1
. O resultado deve ser semelhante ao seguinte:# gke-west-1 NAME AGE store 2m40s store-west-1 2m40s # gke-east-1 NAME AGE store 2m25s store-east-1 2m25s
Isto demonstra que o serviço
store
contémstore
pods em ambos os clusters, enquanto os serviçosstore-west-1
estore-east-1
contêm apenasstore
pods nos respetivos clusters. Estes serviços sobrepostos são usados para segmentar os agrupamentos em vários clusters ou um subconjunto de agrupamentos num único cluster.Após alguns minutos, verifique se os
ServiceImports
associados foram criados automaticamente pelo controlador de serviços de vários clusters em todos os clusters na frota.kubectl get serviceimports --context CLUSTER_NAME --namespace store
Substituir CLUSTER_NAME por
gke-west-1
egke-east-1
. O resultado deve ser semelhante ao seguinte:# gke-west-1 NAME TYPE IP AGE store ClusterSetIP ["10.112.31.15"] 6m54s store-east-1 ClusterSetIP ["10.112.26.235"] 5m49s store-west-1 ClusterSetIP ["10.112.16.112"] 6m54s # gke-east-1 NAME TYPE IP AGE store ClusterSetIP ["10.72.28.226"] 5d10h store-east-1 ClusterSetIP ["10.72.19.177"] 5d10h store-west-1 ClusterSetIP ["10.72.28.68"] 4h32m
Isto demonstra que os três serviços são acessíveis a partir de ambos os clusters na frota. No entanto, uma vez que existe apenas um cluster de configuração ativo por frota, só pode implementar gateways e HTTPRoutes que referenciem estas importações de serviços em
gke-west-1
. Quando um HTTPRoute no cluster de configuração faz referência a estes ServiceImports como backends, o Gateway pode encaminhar o tráfego para estes serviços, independentemente do cluster a partir do qual são exportados.
Implementar o Gateway e o HTTPRoute
Depois de as aplicações terem sido implementadas, pode configurar um gateway através da gke-l7-global-external-managed-mc
GatewayClass. Este gateway cria um Application Load Balancer externo configurado para distribuir o tráfego pelos seus clusters de destino.
Aplique o manifesto
Gateway
seguinte ao cluster de configuração,gke-west-1
neste exemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http namespace: store spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF
Esta configuração de gateway implementa recursos do equilibrador de carga da aplicação externo com a seguinte convenção de nomenclatura:
gkemcg1-NAMESPACE-GATEWAY_NAME-HASH
.Os recursos predefinidos criados com esta configuração são:
- 1 balanceador de carga:
gkemcg1-store-external-http-HASH
- 1 endereço IP público:
gkemcg1-store-external-http-HASH
- 1 regra de encaminhamento:
gkemcg1-store-external-http-HASH
- 2 serviços de back-end:
- Serviço de back-end 404 predefinido:
gkemcg1-store-gw-serve404-HASH
- Serviço de back-end predefinido 500:
gkemcg1-store-gw-serve500-HASH
- Serviço de back-end 404 predefinido:
- 1 verificação de funcionamento:
- Verificação do estado 404 predefinida:
gkemcg1-store-gw-serve404-HASH
- Verificação do estado 404 predefinida:
- 0 regras de encaminhamento (URLmap está vazio)
Nesta fase, qualquer pedido para GATEWAY_IP:80 vai resultar numa página predefinida que apresenta a seguinte mensagem:
fault filter abort
.- 1 balanceador de carga:
Aplique o manifesto
HTTPRoute
seguinte ao cluster de configuração,gke-west-1
neste exemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: public-store-route namespace: store labels: gateway: external-http spec: hostnames: - "store.example.com" parentRefs: - name: external-http rules: - matches: - path: type: PathPrefix value: /west backendRefs: - group: net.gke.io kind: ServiceImport name: store-west-1 port: 8080 - matches: - path: type: PathPrefix value: /east backendRefs: - group: net.gke.io kind: ServiceImport name: store-east-1 port: 8080 - backendRefs: - group: net.gke.io kind: ServiceImport name: store port: 8080 EOF
Nesta fase, qualquer pedido para GATEWAY_IP:80 vai resultar numa página predefinida que apresenta a seguinte mensagem:
fault filter abort
.Uma vez implementada, esta HTTPRoute vai configurar o seguinte comportamento de encaminhamento:
- Os pedidos para
/west
são encaminhados para os podsstore
no clustergke-west-1
, porque os pods selecionados pelo ServiceExportstore-west-1
só existem no clustergke-west-1
. - Os pedidos para
/east
são encaminhados para os podsstore
no clustergke-east-1
, porque os pods selecionados pelo ServiceExportstore-east-1
só existem no clustergke-east-1
. - Os pedidos para qualquer outro caminho são encaminhados para
store
pods em qualquer um dos clusters, de acordo com o respetivo estado, capacidade e proximidade do cliente solicitante. - Os pedidos para GATEWAY_IP:80 vão resultar numa página predefinida que apresenta a seguinte mensagem:
fault filter abort
.
Tenha em atenção que, se todos os pods num determinado cluster não estiverem em bom estado (ou não existirem), o tráfego para o serviço
store
só é enviado para clusters que tenham realmente podsstore
. A existência de um ServiceExport e um Service num determinado cluster não garante que o tráfego seja enviado para esse cluster. Os pods têm de existir e responder afirmativamente à verificação do estado do balanceador de carga. Caso contrário, o balanceador de carga envia apenas tráfego para podsstore
em bom estado noutros clusters.Os novos recursos são criados com esta configuração:
- 3 serviços de back-end:
- O
store
serviço de back-end:gkemcg1-store-store-8080-HASH
- O
store-east-1
serviço de back-end:gkemcg1-store-store-east-1-8080-HASH
- O
store-west-1
serviço de back-end:gkemcg1-store-store-west-1-8080-HASH
- O
- 3 verificações de funcionamento:
- A
store
verificação de funcionamentogkemcg1-store-store-8080-HASH
: - A
store-east-1
verificação de funcionamentogkemcg1-store-store-east-1-8080-HASH
: - A
store-west-1
verificação de funcionamentogkemcg1-store-store-west-1-8080-HASH
:
- A
- 1 regra de encaminhamento no URLmap:
- A regra de encaminhamento
store.example.com
: - 1 anfitrião:
store.example.com
- Vários
matchRules
para encaminhar para os novos serviços de back-end
- A regra de encaminhamento
- Os pedidos para
O diagrama seguinte mostra os recursos que implementou nos dois clusters.
Uma vez que gke-west-1
é o cluster de configuração do Gateway, é o cluster no qual o nosso Gateway, HTTPRoutes e ServiceImports são monitorizados pelo controlador do Gateway. Cada cluster tem um store
ServiceImport e outro
ServiceImport específico desse cluster. Ambos apontam para os mesmos pods. Isto permite que a HTTPRoute especifique exatamente para onde o tráfego deve ir: para os store
pods
num cluster específico ou para os store
pods em todos os clusters.
Tenha em atenção que este é um modelo de recurso lógico e não uma representação do fluxo de tráfego. O caminho do tráfego vai diretamente do equilibrador de carga para os pods de back-end e não tem relação direta com o cluster que é o cluster de configuração.
Validar a implementação
Agora, pode emitir pedidos para o nosso gateway de vários clusters e distribuir o tráfego pelos clusters do GKE.
Valide se o Gateway e o HTTPRoute foram implementados com êxito inspecionando o estado e os eventos do Gateway.
kubectl describe gateways.gateway.networking.k8s.io external-http --context gke-west-1 --namespace store
O resultado deve ser semelhante ao seguinte:
Name: external-http Namespace: store Labels: <none> Annotations: networking.gke.io/addresses: /projects/PROJECT_NUMBER/global/addresses/gkemcg1-store-external-http-laup24msshu4 networking.gke.io/backend-services: /projects/PROJECT_NUMBER/global/backendServices/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/backendServices/gke... networking.gke.io/firewalls: /projects/PROJECT_NUMBER/global/firewalls/gkemcg1-l7-default-global networking.gke.io/forwarding-rules: /projects/PROJECT_NUMBER/global/forwardingRules/gkemcg1-store-external-http-a5et3e3itxsv networking.gke.io/health-checks: /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-s... networking.gke.io/last-reconcile-time: 2023-10-12T17:54:24Z networking.gke.io/ssl-certificates: networking.gke.io/target-http-proxies: /projects/PROJECT_NUMBER/global/targetHttpProxies/gkemcg1-store-external-http-94oqhkftu5yz networking.gke.io/target-https-proxies: networking.gke.io/url-maps: /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-store-external-http-94oqhkftu5yz API Version: gateway.networking.k8s.io/v1beta1 Kind: Gateway Metadata: Creation Timestamp: 2023-10-12T06:59:32Z Finalizers: gateway.finalizer.networking.gke.io Generation: 1 Resource Version: 467057 UID: 1dcb188e-2917-404f-9945-5f3c2e907b4c Spec: Gateway Class Name: gke-l7-global-external-managed-mc Listeners: Allowed Routes: Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 34.36.127.249 Conditions: Last Transition Time: 2023-10-12T07:00:41Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2023-10-12T07:00:41Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-10-12T07:00:41Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T07:00:41Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2023-10-12T07:00:41Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T07:00:41Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal UPDATE 35m (x4 over 10h) mc-gateway-controller store/external-http Normal SYNC 4m22s (x216 over 10h) mc-gateway-controller SYNC on store/external-http was a success
Depois de a gateway ter sido implementada com êxito, obtenha o endereço IP externo a partir da
external-http
gateway.kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
Substitua
VIP
nos passos seguintes pelo endereço IP que recebe como resultado.Enviar tráfego para o caminho raiz do domínio. Este serviço equilibra o tráfego para o
store
ServiceImport que está no clustergke-west-1
egke-east-1
. O balanceador de carga envia o seu tráfego para a região mais próxima de si e pode não ver respostas da outra região.curl -H "host: store.example.com" http://VIP
O resultado confirma que o pedido foi processado pelo pod do cluster
gke-east-1
:{ "cluster_name": "gke-east-1", "zone": "us-east1-b", "host_header": "store.example.com", "node_name": "gke-gke-east-1-default-pool-7aa30992-t2lp.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-dg22z", "pod_name_emoji": "⏭", "project_id": "agmsb-k8s", "timestamp": "2021-06-01T17:32:51" }
Em seguida, envie tráfego para o caminho
/west
. Isto encaminha o tráfego para o ServiceImport que só tem pods em execução no clustergke-west-1
.store-west-1
Um ServiceImport específico do cluster, comostore-west-1
, permite que um proprietário da aplicação envie explicitamente tráfego para um cluster específico, em vez de deixar que o balanceador de carga tome a decisão.curl -H "host: store.example.com" http://VIP/west
O resultado confirma que o pedido foi processado pelo pod do cluster
gke-west-1
:{ "cluster_name": "gke-west-1", "zone": "us-west1-a", "host_header": "store.example.com", "node_name": "gke-gke-west-1-default-pool-65059399-2f41.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-d25m5", "pod_name_emoji": "🍾", "project_id": "agmsb-k8s", "timestamp": "2021-06-01T17:39:15", }
Por fim, envie tráfego para o caminho
/east
.curl -H "host: store.example.com" http://VIP/east
O resultado confirma que o pedido foi processado pelo pod do cluster
gke-east-1
:{ "cluster_name": "gke-east-1", "zone": "us-east1-b", "host_header": "store.example.com", "node_name": "gke-gke-east-1-default-pool-7aa30992-7j7z.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-hz6mw", "pod_name_emoji": "🧜🏾", "project_id": "agmsb-k8s", "timestamp": "2021-06-01T17:40:48" }
Implemente um gateway interno de vários clusters em várias regiões
Pode implementar gateways de vários clusters que fornecem o equilíbrio de carga da camada 7 interno em clusters do GKE em várias regiões. Estes gateways usam a gke-l7-cross-regional-internal-managed-mc
GatewayClass. Esta GatewayClass aprovisiona um Application Load Balancer interno entre regiões gerido pelo Google Cloud e que ativa VIPs internos aos quais os clientes na sua rede VPC podem aceder. Estas entradas podem ser expostas por front-ends nas regiões à sua escolha, bastando usar a entrada para pedir endereços nessas regiões. O VIP interno pode ser um único endereço IP ou endereços IP em várias regiões, com um endereço IP por região especificado no gateway. O tráfego é direcionado para o cluster GKE de back-end saudável mais próximo que pode publicar o pedido.
Antes de começar
Configure o projeto e a shell configurando o ambiente
gcloud
com o ID do projeto:export PROJECT_ID="YOUR_PROJECT_ID" gcloud config set project ${PROJECT_ID}
Crie clusters do GKE em diferentes regiões.
Este exemplo usa dois clusters,
gke-west-1
emus-west1
egke-east-1
emus-east1
. Certifique-se de que a API Gateway está ativada (--gateway-api=standard
) e que os clusters estão registados numa frota.gcloud container clusters create gke-west-1 \ --location=us-west1-a \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --project=${PROJECT_ID} \ --enable-fleet \ --gateway-api=standard gcloud container clusters create gke-east-1 \ --location=us-east1-c \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --project=${PROJECT_ID} \ --enable-fleet \ --gateway-api=standard
Mude o nome dos contextos para facilitar o acesso:
gcloud container clusters get-credentials gke-west-1 \ --location=us-west1-a \ --project=${PROJECT_ID} gcloud container clusters get-credentials gke-east-1 \ --location=us-east1-c \ --project=${PROJECT_ID} kubectl config rename-context gke_${PROJECT_ID}_us-west1-a_gke-west-1 gke-west1 kubectl config rename-context gke_${PROJECT_ID}_us-east1-c_gke-east-1 gke-east1
Ative os serviços em vários clusters (MCS) e a entrada em vários clusters (MCI/Gateway):
gcloud container fleet multi-cluster-services enable --project=${PROJECT_ID} # Set the config membership to one of your clusters (e.g., gke-west-1) # This cluster will be the source of truth for multi-cluster Gateway and Route resources. gcloud container fleet ingress enable \ --config-membership=projects/${PROJECT_ID}/locations/us-west1/memberships/gke-west-1 \ --project=${PROJECT_ID}
Configure sub-redes só de proxy. É necessária uma sub-rede só de proxy em cada região onde os seus clusters do GKE estão localizados e onde o balanceador de carga vai funcionar. Os Application Load Balancers internos entre regiões requerem que a finalidade desta sub-rede seja definida como
GLOBAL_MANAGED_PROXY
.# Proxy-only subnet for us-west1 gcloud compute networks subnets create us-west1-proxy-only-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=us-west1 \ --network=default \ --range=10.129.0.0/23 # Choose an appropriate unused CIDR range # Proxy-only subnet for us-east1 gcloud compute networks subnets create us-east1-proxy-only-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=us-east1 \ --network=default \ --range=10.130.0.0/23 # Choose an appropriate unused CIDR range
Se não estiver a usar a rede predefinida, substitua
default
pelo nome da sua rede VPC. Certifique-se de que os intervalos CIDR são únicos e não se sobrepõem.Implemente as suas aplicações de demonstração, como
store
, em ambos os clusters. O ficheiro de exemplostore.yaml
degke-networking-recipes
cria um espaço de nomesstore
e uma implementação.kubectl apply --context gke-west1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml kubectl apply --context gke-east1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
Exporte serviços de cada cluster criando recursos
Service
do Kubernetes e recursosServiceExport
em cada cluster, o que torna os serviços detetáveis em toda a frota. O exemplo seguinte exporta um serviçostore
genérico e serviços específicos da região (store-west-1
,store-east-1
) de cada cluster, tudo no espaço de nomesstore
.Aplicar a
gke-west1
:cat << EOF | kubectl apply --context gke-west1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-west-1 # Specific to this cluster namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-west-1 # Exporting the region-specific service namespace: store EOF
Aplicar a
gke-east1
:cat << EOF | kubectl apply --context gke-east1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-east-1 # Specific to this cluster namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-east-1 # Exporting the region-specific service namespace: store EOF
Verifique ServiceImports: Verifique se os recursos
ServiceImport
são criados em cada cluster no espaço de nomesstore
. A criação dos mesmos pode demorar alguns minutos.bash kubectl get serviceimports --context gke-west1 -n store kubectl get serviceimports --context gke-east1 -n store
Deve verstore
,store-west-1
estore-east-1
apresentados (ou entradas relevantes com base na propagação).
Configure um gateway interno de várias regiões
Defina um recurso Gateway
que faça referência à gke-l7-cross-regional-internal-managed-mc
GatewayClass. Aplica este manifesto ao cluster de configuração designado, como gke-west-1
.
O campo spec.addresses
permite-lhe pedir endereços IP efémeros em regiões específicas ou usar endereços IP estáticos pré-atribuídos.
Para usar endereços IP efémeros, guarde o seguinte manifesto
Gateway
comocross-regional-gateway.yaml
:# cross-regional-gateway.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-cross-region-gateway namespace: store # Namespace for the Gateway resource spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: # Addresses across regions. Address value is allowed to be empty or matching # the region name. - type: networking.gke.io/ephemeral-ipv4-address/us-west1 value: "us-west1" - type: networking.gke.io/ephemeral-ipv4-address/us-east1 value: "us-east1" listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute # Only allow HTTPRoute to attach
A lista seguinte define alguns dos campos no ficheiro YAML anterior:
metadata.namespace
: o espaço de nomes onde o recurso Gateway é criado, por exemplo,store
.spec.gatewayClassName
: o nome da GatewayClass. Tem de sergke-l7-cross-regional-internal-managed-mc
.spec.listeners.allowedRoutes.kinds
: os tipos de objetos Route que podem ser anexados, por exemplo,HTTPRoute
.spec.addresses
:type: networking.gke.io/ephemeral-ipv4-address/REGION
: pede um endereço IP efémero.value
: especifica a região do endereço, por exemplo,"us-west1"
ou"us-east1"
.
Aplique o manifesto ao cluster de configuração, por exemplo:
gke-west1
:kubectl apply --context gke-west1 -f cross-regional-gateway.yaml
Anexe HTTPRoutes ao Gateway
Defina recursos HTTPRoute
para gerir o encaminhamento de tráfego e aplique-os ao seu cluster de configuração.
Guarde o seguinte manifesto
HTTPRoute
comostore-route.yaml
:# store-route.yaml kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-route namespace: store labels: gateway: cross-regional-internal spec: parentRefs: - name: internal-cross-region-gateway namespace: store # Namespace where the Gateway is deployed hostnames: - "store.example.internal" # Hostname clients will use rules: - matches: # Rule for traffic to /west - path: type: PathPrefix value: /west backendRefs: - group: net.gke.io # Indicates a multi-cluster ServiceImport kind: ServiceImport name: store-west-1 # Targets the ServiceImport for the west cluster port: 8080 - matches: # Rule for traffic to /east - path: type: PathPrefix value: /east backendRefs: - group: net.gke.io kind: ServiceImport name: store-east-1 # Targets the ServiceImport for the east cluster port: 8080 - backendRefs: # Default rule for other paths (e.g., /) - group: net.gke.io kind: ServiceImport name: store # Targets the generic 'store' ServiceImport (any region) port: 8080
A lista seguinte define alguns dos campos no ficheiro YAML anterior:
spec.parentRefs
: anexa esta rota ainternal-cross-region-gateway
no espaço de nomesstore
.spec.hostnames
: representa o nome do anfitrião que os clientes usam para aceder ao serviço.spec.rules
: define a lógica de encaminhamento. Este exemplo usa o encaminhamento baseado no caminho:/west
do tráfego vai para o ServiceImportstore-west-1
./east
do tráfego vai para o ServiceImportstore-east-1
.- Todo o outro tráfego, como
/
, é encaminhado para o ServiceImport genéricostore
.
backendRefs
:group: net.gke.io
ekind: ServiceImport
segmentam serviços em vários clusters.
Aplique o manifesto
HTTPRoute
ao cluster de configuração:kubectl apply --context gke-west1 -f store-route.yaml
Valide o estado do gateway e da rota
Verifique o estado do gateway:
kubectl get gateway internal-cross-region-gateway -n store -o yaml --context gke-west1
Procure uma condição com o estado
type:
Programadoand
: "Verdadeiro". You should see IP addresses assigned in the
status.addressesfield, corresponding to the regions you specified (e.g., one for
us-west1and one for
us-east1`).Verifique o estado do HTTPRoute:
kubectl get httproute store-route -n store -o yaml --context gke-west1
Procure uma condição em
status.parents[].conditions
comtype: Accepted
(ouResolvedRefs
) estatus: "True"
.
Confirme o tráfego
Depois de atribuir os endereços IP ao gateway, pode testar o tráfego a partir de uma VM cliente que esteja na sua rede VPC e numa das regiões, ou numa região que possa estabelecer ligação ao endereço IP do gateway.
Recupere os endereços IP do gateway.
O comando seguinte tenta analisar a saída JSON. Pode ter de ajustar o
jsonpath
com base na estrutura exata.kubectl get gateway cross-region-gateway -n store --context gke-west1 -o=jsonpath="{.status.addresses[*].value}".
O resultado deste comando deve incluir os VIPs, como
VIP1_WEST
ouVIP2_EAST
.Envie pedidos de teste: A partir de uma VM cliente na sua VPC:
# Assuming VIP_WEST is an IP in us-west1 and VIP_EAST is an IP in us-east1 # Traffic to /west should ideally be served by gke-west-1 curl -H "host: store.example.internal" http://VIP_WEST/west curl -H "host: store.example.internal" http://VIP_EAST/west # Still targets store-west-1 due to path # Traffic to /east should ideally be served by gke-east-1 curl -H "host: store.example.internal" http://VIP_WEST/east # Still targets store-east-1 due to path curl -H "host: store.example.internal" http://VIP_EAST/east # Traffic to / (default) could be served by either cluster curl -H "host: store.example.internal" http://VIP_WEST/ curl -H "host: store.example.internal" http://VIP_EAST/
A resposta deve incluir detalhes da aplicação
store
que indiquem que pod de back-end publicou o pedido, comocluster_name
ouzone
.
Use endereços IP estáticos
Em vez de endereços IP efémeros, pode usar endereços IP internos estáticos pré-atribuídos.
Crie endereços IP estáticos nas regiões que quer usar:
gcloud compute addresses create cross-region-gw-ip-west --region us-west1 --subnet default --project=${PROJECT_ID} gcloud compute addresses create cross-region-gw-ip-east --region us-east1 --subnet default --project=${PROJECT_ID}
Se não estiver a usar a sub-rede predefinida, substitua
default
pelo nome da sub-rede que tem o endereço IP que quer atribuir. Estas sub-redes são sub-redes normais e não as sub-redes apenas de proxy.Atualize o manifesto do gateway modificando a secção
spec.addresses
no ficheirocross-regional-gateway.yaml
:# cross-regional-gateway-static-ip.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-cross-region-gateway # Or a new name if deploying alongside namespace: store spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: - type: networking.gke.io/named-address-with-region # Use for named static IP value: "regions/us-west1/addresses/cross-region-gw-ip-west" - type: networking.gke.io/named-address-with-region value: "regions/us-east1/addresses/cross-region-gw-ip-east" listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute
Aplique o manifesto do gateway atualizado.
kubectl apply --context gke-west1 -f cross-regional-gateway.yaml
Considerações especiais para sub-redes não predefinidas
Tenha em atenção as seguintes considerações quando usa sub-redes não predefinidas:
Mesma rede de VPC: todos os recursos criados pelo utilizador, como endereços IP estáticos, sub-redes apenas de proxy e clusters do GKE, têm de residir na mesma rede de VPC.
Sub-rede de endereços: quando cria endereços IP estáticos para o gateway, estes são atribuídos a partir de sub-redes normais nas regiões especificadas.
Nomenclatura da sub-rede do cluster: cada região tem de ter uma sub-rede com o mesmo nome da sub-rede em que o cluster de configuração do MCG reside.
- Por exemplo, se o cluster de configuração
gke-west-1
estiver emprojects/YOUR_PROJECT/regions/us-west1/subnetworks/my-custom-subnet
, as regiões para as quais está a pedir endereços também têm de ter a sub-redemy-custom-subnet
. Se pedir endereços nas regiõesus-east1
eus-centra1
, também tem de existir uma sub-rede denominadamy-custom-subnet
nessas regiões.
- Por exemplo, se o cluster de configuração
Encaminhamento azul-verde de vários clusters com gateway
As GatewayClasses gke-l7-global-external-managed-*
, gke-l7-regional-external-managed-*
e gke-l7-rilb-*
têm muitas capacidades avançadas de encaminhamento de tráfego, incluindo divisão de tráfego, correspondência de cabeçalhos, manipulação de cabeçalhos, replicação de tráfego e muito mais. Neste exemplo, vai demonstrar como usar a divisão de tráfego baseada em ponderação para controlar explicitamente a proporção de tráfego em dois clusters do GKE.
Este exemplo aborda alguns passos realistas que um proprietário de um serviço daria para mover ou expandir a respetiva aplicação para um novo cluster do GKE. O objetivo das implementações azul-verde é reduzir o risco através de vários passos de validação que confirmam que o novo cluster está a funcionar corretamente. Este exemplo explica quatro fases de implementação:
- 100%-Canário baseado em cabeçalhos: Use o encaminhamento de cabeçalhos HTTP para enviar apenas tráfego de teste ou sintético para o novo cluster.
- 100% – tráfego espelhado: espelhe o tráfego de utilizadores para o cluster de teste. Este teste testa a capacidade do cluster de teste preliminar copiando 100% do tráfego de utilizadores para este cluster.
- 90%-10%: Teste canário de uma divisão de tráfego de 10% para expor lentamente o novo cluster ao tráfego em direto.
- 0%-100%: Transição total para o novo cluster com a opção de voltar atrás se forem observados erros.
Este exemplo é semelhante ao anterior, exceto que implementa um gateway interno de vários clusters. Isto implementa um Application Load Balancer interno que só é acessível de forma privada a partir da VPC. Vai usar os clusters e a mesma aplicação que implementou nos passos anteriores, exceto que vai implementá-los através de um gateway diferente.
Pré-requisitos
O exemplo seguinte baseia-se em alguns dos passos da Implementação de um gateway externo de vários clusters. Certifique-se de que concluiu os seguintes passos antes de avançar com este exemplo:
Implementar uma aplicação de demonstração
Este exemplo usa os clusters
gke-west-1
egke-west-2
que já configurou. Estes clusters estão na mesma região porque agke-l7-rilb-mc
GatewayClass é regional e só suporta back-ends de cluster na mesma região.Implemente o serviço e os ServiceExports necessários em cada cluster. Se implementou Services e ServiceExports do exemplo anterior, já implementou alguns destes.
kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-1-service.yaml kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-2-service.yaml
Implementa um conjunto semelhante de recursos em cada cluster:
service/store created serviceexport.net.gke.io/store created service/store-west-2 created serviceexport.net.gke.io/store-west-2 created
Configurar uma sub-rede só de proxy
Se ainda não o fez, configure uma sub-rede
apenas de proxy para
cada região na qual está a implementar gateways internos. Esta sub-rede é usada para fornecer endereços IP internos aos proxies do equilibrador de carga e tem de ser configurada com um --purpose
definido apenas como REGIONAL_MANAGED_PROXY
.
Tem de criar uma sub-rede apenas de proxy antes de criar gateways que gerem equilibradores de carga de aplicações internos. Cada região de uma rede de nuvem virtual privada (VPC) na qual usa equilibradores de carga de aplicações internos tem de ter uma sub-rede apenas de proxy.
O comando gcloud compute networks subnets create
cria uma sub-rede só de proxy.
gcloud compute networks subnets create SUBNET_NAME \
--purpose=REGIONAL_MANAGED_PROXY \
--role=ACTIVE \
--region=REGION \
--network=VPC_NETWORK_NAME \
--range=CIDR_RANGE
Substitua o seguinte:
SUBNET_NAME
: o nome da sub-rede só de proxy.REGION
: a região da sub-rede só de proxy.VPC_NETWORK_NAME
: o nome da rede VPC que contém a sub-rede.CIDR_RANGE
: o intervalo de endereços IP principal da sub-rede. Tem de usar uma máscara de sub-rede não superior a/26
para que estejam disponíveis, pelo menos, 64 endereços IP para proxies na região. A máscara de sub-rede recomendada é/23
.
Implementar o gateway
O Gateway seguinte é criado a partir da gke-l7-rilb-mc
GatewayClass, que é um Gateway interno regional que só pode segmentar clusters do GKE na mesma região.
Aplique o manifesto
Gateway
seguinte ao cluster de configuração,gke-west-1
neste exemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-http namespace: store spec: gatewayClassName: gke-l7-rilb-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF
Valide se o gateway foi iniciado com êxito. Pode filtrar apenas os eventos desta entrada com o seguinte comando:
kubectl get events --field-selector involvedObject.kind=Gateway,involvedObject.name=internal-http --context=gke-west-1 --namespace store
A implementação do gateway foi bem-sucedida se o resultado for semelhante ao seguinte:
LAST SEEN TYPE REASON OBJECT MESSAGE 5m18s Normal ADD gateway/internal-http store/internal-http 3m44s Normal UPDATE gateway/internal-http store/internal-http 3m9s Normal SYNC gateway/internal-http SYNC on store/internal-http was a success
Teste com base no cabeçalho
O teste canário baseado em cabeçalhos permite ao proprietário do serviço fazer corresponder o tráfego de teste sintético que não é proveniente de utilizadores reais. Esta é uma forma fácil de validar se o funcionamento em rede básico da aplicação está a funcionar sem expor os utilizadores diretamente.
Aplique o manifesto
HTTPRoute
seguinte ao cluster de configuração,gke-west-1
neste exemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-store-route namespace: store labels: gateway: internal-http spec: parentRefs: - kind: Gateway namespace: store name: internal-http hostnames: - "store.example.internal" rules: # Matches for env=canary and sends it to store-west-2 ServiceImport - matches: - headers: - name: env value: canary backendRefs: - group: net.gke.io kind: ServiceImport name: store-west-2 port: 8080 # All other traffic goes to store-west-1 ServiceImport - backendRefs: - group: net.gke.io kind: ServiceImport name: store-west-1 port: 8080 EOF
Uma vez implementado, este HTTPRoute configura o seguinte comportamento de encaminhamento:
- Os pedidos internos para
store.example.internal
sem o cabeçalho HTTPenv: canary
são encaminhados para os podsstore
no clustergke-west-1
- Os pedidos internos para
store.example.internal
com o cabeçalho HTTPenv: canary
são encaminhados para os podsstore
no clustergke-west-2
Valide se o HTTPRoute está a funcionar corretamente enviando tráfego para o endereço IP do gateway.
- Os pedidos internos para
Recupere o endereço IP interno de
internal-http
.kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
Substitua VIP nos passos seguintes pelo endereço IP que recebe como resultado.
Envie um pedido ao gateway através do cabeçalho HTTP
env: canary
. Esta ação confirma que o tráfego está a ser encaminhado paragke-west-2
. Use um cliente privado na mesma VPC que os clusters do GKE para confirmar que os pedidos estão a ser encaminhados corretamente. O seguinte comando tem de ser executado numa máquina que tenha acesso privado ao endereço IP do gateway. Caso contrário, não funciona.curl -H "host: store.example.internal" -H "env: canary" http://VIP
O resultado confirma que o pedido foi publicado por um pod do cluster
gke-west-2
:{ "cluster_name": "gke-west-2", "host_header": "store.example.internal", "node_name": "gke-gke-west-2-default-pool-4cde1f72-m82p.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-9kdb5", "pod_name_emoji": "😂", "project_id": "agmsb-k8s", "timestamp": "2021-05-31T01:21:55", "zone": "us-west1-a" }
Espelho de trânsito
Esta fase envia tráfego para o cluster pretendido, mas também reflete esse tráfego no cluster de teste.
A utilização da replicação é útil para determinar como a carga de tráfego vai afetar o desempenho da aplicação sem afetar as respostas aos seus clientes de forma alguma. Pode não ser necessário para todos os tipos de implementações, mas pode ser útil quando implementa alterações grandes que podem afetar o desempenho ou o carregamento.
Aplique o manifesto
HTTPRoute
seguinte ao cluster de configuração,gke-west-1
neste exemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-store-route namespace: store labels: gateway: internal-http spec: parentRefs: - kind: Gateway namespace: store name: internal-http hostnames: - "store.example.internal" rules: # Sends all traffic to store-west-1 ServiceImport - backendRefs: - name: store-west-1 group: net.gke.io kind: ServiceImport port: 8080 # Also mirrors all traffic to store-west-2 ServiceImport filters: - type: RequestMirror requestMirror: backendRef: group: net.gke.io kind: ServiceImport name: store-west-2 port: 8080 EOF
Usando o seu cliente privado, envie um pedido para o
internal-http
gateway. Use o caminho/mirror
para poder identificar exclusivamente este pedido nos registos da aplicação num passo posterior.curl -H "host: store.example.internal" http://VIP/mirror
O resultado confirma que o cliente recebeu uma resposta de um pod no cluster
gke-west-1
:{ "cluster_name": "gke-west-1", "host_header": "store.example.internal", "node_name": "gke-gke-west-1-default-pool-65059399-ssfq.c.agmsb-k8s.internal", "pod_name": "store-5f5b954888-brg5w", "pod_name_emoji": "🎖", "project_id": "agmsb-k8s", "timestamp": "2021-05-31T01:24:51", "zone": "us-west1-a" }
Isto confirma que o cluster principal está a responder ao tráfego. Ainda tem de confirmar que o cluster para o qual está a migrar está a receber tráfego espelhado.
Verifique os registos da aplicação de um
store
pod no clustergke-west-2
. Os registos devem confirmar que o pod recebeu tráfego espelhado do equilibrador de carga.kubectl logs deployment/store --context gke-west-2 -n store | grep /mirror
Este resultado confirma que os pods no cluster
gke-west-2
também estão a receber os mesmos pedidos. No entanto, as respetivas respostas a estes pedidos não são enviadas de volta ao cliente. Os endereços IP apresentados nos registos são os endereços IP internos do balanceador de carga que estão a comunicar com os seus pods.Found 2 pods, using pod/store-5c65bdf74f-vpqbs [2023-10-12 21:05:20,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:20] "GET /mirror HTTP/1.1" 200 - [2023-10-12 21:05:27,158] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 - [2023-10-12 21:05:27,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
Divisão de tráfego
A divisão do tráfego é um dos métodos mais comuns de implementação de novo código ou implementação em novos ambientes de forma segura. O proprietário do serviço define uma percentagem explícita do tráfego que é enviado para os back-ends de teste beta, que é normalmente uma quantidade muito pequena do tráfego geral, para que o sucesso da implementação possa ser determinado com uma quantidade aceitável de risco para os pedidos de utilizadores reais.
A divisão do tráfego com uma minoria do tráfego permite ao proprietário do serviço inspecionar o estado de funcionamento da aplicação e as respostas. Se todos os sinais parecerem em bom estado, podem avançar para a mudança completa.
Aplique o manifesto
HTTPRoute
seguinte ao cluster de configuração,gke-west-1
neste exemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-store-route namespace: store labels: gateway: internal-http spec: parentRefs: - kind: Gateway namespace: store name: internal-http hostnames: - "store.example.internal" rules: - backendRefs: # 90% of traffic to store-west-1 ServiceImport - name: store-west-1 group: net.gke.io kind: ServiceImport port: 8080 weight: 90 # 10% of traffic to store-west-2 ServiceImport - name: store-west-2 group: net.gke.io kind: ServiceImport port: 8080 weight: 10 EOF
Usando o seu cliente privado, envie um pedido curl contínuo para o gateway
internal- http
.while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
O resultado será semelhante a este, indicando que está a ocorrer uma divisão de tráfego de 90/10.
"cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", "cluster_name": "gke-west-2", "cluster_name": "gke-west-1", "cluster_name": "gke-west-1", ...
Transferência de tráfego
A última fase da migração azul-verde consiste em mudar totalmente para o novo cluster e remover o cluster antigo. Se o proprietário do serviço estivesse a integrar
um segundo cluster num cluster existente, este último passo seria diferente,
uma vez que o passo final teria tráfego a aceder a ambos os clusters. Nesse cenário, recomenda-se uma única store
ServiceImportgke-west-1
que tenha pods dos clusters gke-west-1
e gke-west-2
. Isto permite que o balanceador de carga tome a decisão de para onde o tráfego deve ir para uma aplicação ativa-ativa, com base na proximidade, no estado e na capacidade.
Aplique o manifesto
HTTPRoute
seguinte ao cluster de configuração,gke-west-1
neste exemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-store-route namespace: store labels: gateway: internal-http spec: parentRefs: - kind: Gateway namespace: store name: internal-http hostnames: - "store.example.internal" rules: - backendRefs: # No traffic to the store-west-1 ServiceImport - name: store-west-1 group: net.gke.io kind: ServiceImport port: 8080 weight: 0 # All traffic to the store-west-2 ServiceImport - name: store-west-2 group: net.gke.io kind: ServiceImport port: 8080 weight: 100 EOF
Usando o seu cliente privado, envie um pedido curl contínuo para o gateway
internal- http
.while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
O resultado é semelhante a este, o que indica que todo o tráfego está agora a ser encaminhado para
gke-west-2
."cluster_name": "gke-west-2", "cluster_name": "gke-west-2", "cluster_name": "gke-west-2", "cluster_name": "gke-west-2", ...
Este passo final conclui uma migração de aplicações azul-verde completa de um cluster do GKE para outro cluster do GKE.
Implemente o balanceamento de carga baseado na capacidade
O exercício nesta secção demonstra os conceitos de equilíbrio de carga global e capacidade de serviço através da implementação de uma aplicação em dois clusters do GKE em diferentes regiões. O tráfego gerado é enviado a vários níveis de pedidos por segundo (RPS) para mostrar como o tráfego é equilibrado em termos de carga em clusters e regiões.
O diagrama seguinte mostra a topologia que vai implementar e como o tráfego transborda entre clusters e regiões quando o tráfego excede a capacidade do serviço:
Para saber mais sobre a gestão de tráfego, consulte o artigo Gestão de tráfego do GKE.
Prepare o seu ambiente
Siga os passos em Ativar gateways de vários clusters para preparar o seu ambiente.
Confirme se os recursos GatewayClass estão instalados no cluster de configuração:
kubectl get gatewayclasses --context=gke-west-1
O resultado é semelhante ao seguinte:
NAME CONTROLLER ACCEPTED AGE gke-l7-global-external-managed networking.gke.io/gateway True 16h gke-l7-global-external-managed-mc networking.gke.io/gateway True 14h gke-l7-gxlb networking.gke.io/gateway True 16h gke-l7-gxlb-mc networking.gke.io/gateway True 14h gke-l7-regional-external-managed networking.gke.io/gateway True 16h gke-l7-regional-external-managed-mc networking.gke.io/gateway True 14h gke-l7-rilb networking.gke.io/gateway True 16h gke-l7-rilb-mc networking.gke.io/gateway True 14h
Implemente uma aplicação
Implemente o servidor de aplicações Web de exemplo em ambos os clusters:
kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
O resultado é semelhante ao seguinte:
namespace/store created
deployment.apps/store created
Implemente um serviço, um gateway e uma HTTPRoute
Aplique o seguinte manifesto
Service
aos clustersgke-west-1
egke-east-1
:cat << EOF | kubectl apply --context gke-west-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOF
cat << EOF | kubectl apply --context gke-east-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOF
O serviço está anotado com
max-rate-per-endpoint
definido como 10 pedidos por segundo. Com 2 réplicas por cluster, cada serviço tem 20 RPS de capacidade por cluster.Para mais informações sobre como escolher um nível de capacidade do serviço para o seu serviço, consulte o artigo Determine a capacidade do seu serviço.
Aplique o manifesto
Gateway
seguinte ao cluster de configuração,gke-west-1
neste exemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store namespace: traffic-test spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOF
O manifesto descreve um Gateway externo, global e com vários clusters que implementa um balanceador de carga de aplicações externo com um endereço IP acessível publicamente.
Aplique o manifesto
HTTPRoute
seguinte ao cluster de configuração,gke-west-1
neste exemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store namespace: traffic-test labels: gateway: store spec: parentRefs: - kind: Gateway namespace: traffic-test name: store rules: - backendRefs: - name: store group: net.gke.io kind: ServiceImport port: 8080 EOF
O manifesto descreve um HTTPRoute que configura o Gateway com uma regra de encaminhamento que direciona todo o tráfego para o ServiceImport da loja. O
store
ServiceImport agrupa osstore
Service Pods em ambos os clusters e permite que sejam resolvidos pelo balanceador de carga como um único serviço.Pode verificar os eventos da gateway após alguns minutos para ver se a implementação foi concluída:
kubectl describe gateway store -n traffic-test --context gke-west-1
O resultado é semelhante ao seguinte:
... Status: Addresses: Type: IPAddress Value: 34.102.159.147 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 12m mc-gateway-controller traffic-test/store Normal SYNC 6m43s mc-gateway-controller traffic-test/store Normal UPDATE 5m40s (x4 over 12m) mc-gateway-controller traffic-test/store Normal SYNC 118s (x6 over 10m) mc-gateway-controller SYNC on traffic-test/store was a success
Este resultado mostra que o gateway foi implementado com êxito. Ainda pode demorar alguns minutos até que o tráfego comece a passar depois de a gateway ter sido implementada. Tome nota do endereço IP neste resultado, uma vez que é usado num passo seguinte.
Confirme o tráfego
Confirme se o tráfego está a ser transmitido para a aplicação testando o endereço IP do gateway com um comando curl:
curl GATEWAY_IP_ADDRESS
O resultado é semelhante ao seguinte:
{
"cluster_name": "gke-west-1",
"host_header": "34.117.182.69",
"pod_name": "store-54785664b5-mxstv",
"pod_name_emoji": "👳🏿",
"project_id": "project",
"timestamp": "2021-11-01T14:06:38",
"zone": "us-west1-a"
}
Este resultado mostra os metadados do pod, que indicam a região a partir da qual o pedido foi publicado.
Valide o tráfego através de testes de carga
Para verificar se o equilibrador de carga está a funcionar, pode implementar um gerador de tráfego no seu cluster gke-west-1
. O gerador de tráfego gera tráfego a diferentes níveis de carga para demonstrar a capacidade e as capacidades de overflow do equilibrador de carga. Os passos seguintes demonstram três níveis de carga:
- 10 RPS, que está abaixo da capacidade do serviço de loja em
gke-west-1
. - 30 RPS, que está acima da capacidade do serviço da loja
gke-west-1
e provoca um excesso de tráfego paragke-east-1
. - 60 RPS, que excede a capacidade dos serviços em ambos os clusters.
Configure o painel de controlo
Obtenha o nome do URLmap subjacente para o seu gateway:
kubectl get gateway store -n traffic-test --context=gke-west-1 -o=jsonpath="{.metadata.annotations.networking\.gke\.io/url-maps}"
O resultado é semelhante ao seguinte:
/projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1t
Na Google Cloud consola, aceda à página Explorador de métricas.
Em Selecione uma métrica, clique em CÓDIGO: MQL.
Introduza a seguinte consulta para observar as métricas de tráfego para o serviço de loja em ambos os clusters:
fetch https_lb_rule | metric 'loadbalancing.googleapis.com/https/backend_request_count' | filter (resource.url_map_name == 'GATEWAY_URL_MAP') | align rate(1m) | every 1m | group_by [resource.backend_scope], [value_backend_request_count_aggregate: aggregate(value.backend_request_count)]
Substitua
GATEWAY_URL_MAP
pelo nome do URLmap do passo anterior.Clique em Executar consulta. Aguarde, pelo menos, 5 minutos após implementar o gerador de carga na secção seguinte para que as métricas sejam apresentadas no gráfico.
Teste com 10 RPS
Implemente um Pod no seu cluster
gke-west-1
:kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 10'
Substitua
GATEWAY_IP_ADDRESS
pelo endereço IP do gateway do passo anterior.O resultado é semelhante ao seguinte, o que indica que o gerador de tráfego está a enviar tráfego:
If you don't see a command prompt, try pressing enter.
O gerador de carga envia continuamente 10 RPS para o gateway. Embora o tráfego seja proveniente de uma região, o balanceador de carga trata-o como tráfego de cliente proveniente da Costa Oeste dos EUA. Google Cloud Para simular uma diversidade de clientes realista, o gerador de carga envia cada pedido HTTP como uma nova ligação TCP, o que significa que o tráfego é distribuído pelos pods de back-end de forma mais uniforme.
O gerador demora até 5 minutos a gerar tráfego para o painel de controlo.
Veja o painel de controlo do explorador de métricas. São apresentadas duas linhas que indicam a quantidade de tráfego com equilíbrio de carga para cada um dos clusters:
Deve ver que
us-west1-a
está a receber aproximadamente 10 RPS de tráfego, enquantous-east1-b
não está a receber tráfego. Uma vez que o gerador de tráfego está a ser executado emus-west1
, todo o tráfego é enviado para o serviço no clustergke-west-1
.Pare o gerador de carga com Ctrl+C e, em seguida, elimine o pod:
kubectl delete pod loadgen --context gke-west-1
Teste com 30 RPS
Implemente novamente o gerador de carga, mas configurado para enviar 30 RPS:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 30'
O gerador demora até 5 minutos a gerar tráfego para o painel de controlo.
Veja o seu painel de controlo do Cloud Ops.
Deve ver que estão a ser enviados aproximadamente 20 RPS para
us-west1-a
e 10 RPS paraus-east1-b
. Isto indica que o serviço emgke-west-1
está totalmente utilizado e está a transbordar 10 RPS de tráfego para o serviço emgke-east-1
.Pare o gerador de carga com Ctrl+C e, em seguida, elimine o pod:
kubectl delete pod loadgen --context gke-west-1
Teste com 60 RPS
Implemente o gerador de carga configurado para enviar 60 RPS:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 60'
Aguarde 5 minutos e consulte o painel de controlo do Cloud Ops. Agora, deve mostrar que ambos os clusters estão a receber aproximadamente 30 RPS. Uma vez que todos os serviços estão sobreutilizados a nível global, não existe transbordo de tráfego e os serviços absorvem todo o tráfego que conseguem.
Pare o gerador de carga com Ctrl+C e, em seguida, elimine o pod:
kubectl delete pod loadgen --context gke-west-1
Limpar
Depois de concluir os exercícios nesta página, siga estes passos para remover recursos e evitar encargos indesejados na sua conta:
Anule o registo dos clusters da frota se não precisarem de ser registados para outro fim.
Desative a funcionalidade
multiclusterservicediscovery
:gcloud container fleet multi-cluster-services disable
Desative a entrada em vários clusters:
gcloud container fleet ingress disable
Desative as APIs:
gcloud services disable \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com \ trafficdirector.googleapis.com \ --project=PROJECT_ID
Use o gateway de vários clusters com a VPC partilhada
Também é possível implementar um gateway de vários clusters num ambiente de VPC partilhada, com diferentes topologias, consoante o exemplo de utilização.
A tabela seguinte descreve as topologias de gateway com vários clusters suportadas num ambiente de VPC partilhada:
Cenário | Projeto anfitrião da frota | Configurar cluster | Clusters de cargas de trabalho |
---|---|---|---|
1 | Projeto anfitrião da VPC partilhada | Projeto anfitrião da VPC partilhada | Projeto anfitrião da VPC partilhada |
2 | Projeto de serviço da VPC partilhada | Projeto de serviço da VPC partilhada (igual ao projeto de serviço da frota) |
Projeto de serviço da VPC partilhada (igual ao projeto de serviço da frota) |
Para criar gateways de vários clusters num ambiente de VPC partilhada, use os seguintes passos:
Siga os passos para configurar os serviços de vários clusters com a VPC partilhada
Crie os seus serviços e exporte-os para o cluster de configuração
Se planeia usar um gateway interno com vários clusters, crie uma sub-rede apenas de proxy
Crie o seu Gateway externo ou interno multicluster e HTTPRoutes
Depois de concluir estes passos, pode validar a implementação, consoante a sua topologia.
Resolução de problemas
A sub-rede só de proxy para o gateway interno não existe
Se o seguinte evento for apresentado no seu gateway interno, significa que não existe uma sub-rede apenas de proxy para essa região. Para resolver este problema, implemente uma sub-rede apenas de proxy.
generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/us-west1/targetHttpProxies/gkegw-x5vt-default-internal-http-2jzr7e3xclhj'. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.
Não existe nenhuma origem em bom estado
Sintoma:
O seguinte problema pode ocorrer quando cria um gateway, mas não consegue aceder aos serviços de back-end (código de resposta 503):
no healthy upstream
Motivo:
Esta mensagem de erro indica que o verificador de estado de funcionamento não consegue encontrar serviços de back-end em bom estado. É possível que os seus serviços de back-end estejam em bom estado, mas pode ter de personalizar as verificações de funcionamento.
Solução alternativa:
Para resolver este problema, personalize a verificação de estado com base nos requisitos da sua aplicação (por exemplo, /health
) através de um HealthCheckPolicy
.
O que se segue?
- Saiba mais sobre o controlador de gateway.