Configure o Application Load Balancer clássico para o Cloud Service Mesh
Vista geral
Este documento destina-se a si se for um utilizador existente do Cloud Service Mesh que tenha o plano de controlo gerido do Istiod e quiser configurar o Application Load Balancer clássico como um gateway de entrada. O balanceador de carga de aplicações clássico também é conhecido como balanceador de carga de aplicações externo clássico.
Não use este documento se for um novo utilizador do Cloud Service Mesh. Os novos utilizadores são configurados automaticamente com o plano de controlo gerido do Cloud Service Mesh. Não pode usar a configuração descrita neste documento com o plano de controlo gerido do Cloud Service Mesh
O Cloud Load Balancing oferece muitas capacidades de limite geridas na nuvem, incluindo o balanceamento de carga global anycast, certificados geridos pela Google, gestão de identidade e acesso, firewall de nova geração do Google Cloud e sistema de deteção de intrusos do Google Cloud. A Cloud Service Mesh pode integrar perfeitamente estas capacidades de limite no seguinte modelo de entrada de malha. O gateway na nuvem da malha de serviços oferece uma forma unificada de configurar o gateway de entrada da malha de serviços na nuvem com o Cloud Load Balancing em simultâneo através da API Kubernetes Gateway.
Em comparação com o nosso guia do utilizador anterior, Do limite à malha: expor aplicações de malha de serviços através do GKE Ingress, com o gateway na nuvem de malha de serviços, este modelo pode agora ser implementado através de um recurso do gateway do Kubernetes, o que simplifica o processo de implementação do equilíbrio de carga alojado na nuvem e no cluster em conjunto.
Limitações da pré-visualização
Para a versão de pré-visualização desta funcionalidade, aplicam-se as seguintes limitações:
- Os gateways de vários clusters não são suportados.
- Os clusters do Autopilot não são suportados.
- Apenas é suportado o Application Load Balancer clássico. O balanceador de carga de aplicações externo global (por vezes, denominado balanceador de carga avançado) e o balanceador de carga de aplicações interno não são suportados.
- O tráfego entre o Application Load Balancer clássico e o gateway de entrada do Cloud Service Mesh é encriptado através do TLS. No entanto, o Application Load Balancer clássico não valida o certificado fornecido pela gateway de entrada do Cloud Service Mesh. Esta limitação aplica-se a todos os utilizadores do Google Cloud balanceador de carga de HTTP(S).
- Se o Cloud Service Mesh
GatewayClasses
for eliminado de um cluster, não é reinstalado automaticamente. No entanto, isto não afeta a usabilidade da funcionalidade. - A lógica de correspondência de rotas não segue as especificações da API Gateway e, em vez disso, corresponde pela ordem do
HTTPRoute
. Isto vai mudar em versões futuras para seguir as especificações da API Gateway.
Requisitos
- Managed Cloud Service Mesh instalado num cluster do Google Kubernetes Engine (GKE) com a versão 1.24 ou posterior. Outros clusters do GKE Enterprise não são suportados.
- Apenas a versão v1beta1 da API Kubernetes Gateway.
Pré-requisitos
Ative as seguintes APIs no seu projeto:
- compute.googleapis.com
- container.googleapis.com
- certificatemanager.googleapis.com
- serviceusage.googleapis.com
gcloud services enable \ compute.googleapis.com \ container.googleapis.com \ certificatemanager.googleapis.com \ serviceusage.googleapis.com
Implemente um gateway na nuvem de service mesh para uma malha de cluster único
Estas secções mostram como implementar um recurso do Kubernetes Gateway que implementa um Application Load Balancer clássico e um gateway de entrada do Cloud Service Mesh.
Ative a API Gateway com a malha de serviços na nuvem gerida
Ative a API Gateway no seu cluster. O cluster do GKE tem de ser a versão 1.24 ou posterior.
Instale o Cloud Service Mesh gerido com o
rapid
ou oregular
como canal de lançamento.
Implemente o recurso Gateway
Quando implementa o gateway de nuvem da service mesh, os recursos do gateway do Kubernetes são usados para implementar o Cloud Load Balancing e o gateway de entrada do Cloud Service Mesh num único passo. Tenha em atenção que os recursos do Kubernetes Gateway são diferentes dos recursos do Istio Gateway.
Para mais informações sobre as diferenças, consulte o artigo Kubernetes Gateways e Istio Gateways. Cada Kubernetes Gateway tem uma GatewayClass que indica o respetivo tipo e capacidades inerentes. O gateway de nuvem de malha de serviços tem uma GatewayClass com a capacidade de implementar o balanceamento de carga na nuvem e o gateway de entrada de malha de serviços na nuvem.
Guarde o seguinte manifesto GatewayClass num ficheiro com o nome
l7-gateway-class.yaml
:apiVersion: gateway.networking.k8s.io/v1beta1 kind: GatewayClass metadata: name: asm-l7-gxlb spec: controllerName: mesh.cloud.google.com/gateway
Implemente a GatewayClass no seu cluster:
kubectl apply -f l7-gateway-class.yaml
Verifique se a GatewayClass está presente após a instalação:
kubectl get gatewayclasses.gateway.networking.k8s.io
O resultado é semelhante ao seguinte:
NAME CONTROLLER asm-l7-gxlb mesh.cloud.google.com/gateway gke-l7-rilb networking.gke.io/gateway gke-l7-gxlb networking.gke.io/gateway
A implementação de todos os recursos pode demorar alguns minutos. Se não vir o resultado esperado, verifique se cumpriu corretamente os pré-requisitos.
Também vê a seguinte GatewayClass:
gke-l7-gxlb networking.gke.io/gateway
Isto é usado para implementar o balanceador de carga de aplicações clássico do Google Cloud subjacente.
Crie um namespace dedicado para o gateway na nuvem da malha de serviços:
kubectl create namespace istio-ingress
Guarde o seguinte manifesto do gateway num ficheiro com o nome
gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All
Implemente o Gateway no seu cluster no espaço de nomes istio-ingress:
kubectl apply -f gateway.yaml
Verifique se os objetos da API Kubernetes Gateway foram criados:
kubectl get gateways.gateway.networking.k8s.io -n istio-ingress
O resultado é semelhante ao seguinte:
NAME CLASS ADDRESS READY AGE asm-gw-gke-servicemesh-cloud-gw gke-l7-gxlb 34.111.114.64 True 9m40s asm-gw-istio-servicemesh-cloud-gw istio 9m44s servicemesh-cloud-gw asm-l7-gxlb 9m44s
Quando este objeto da API Kubernetes Gateway é implementado, acontece o seguinte:
- Um balanceador de carga HTTP(S) externo é implementado e configurado. Pode demorar alguns minutos até aparecer, mas, quando aparecer, o gateway indica o endereço IP e é anotado com os nomes dos recursos do balanceador de carga do Compute Engine que foram criados.
- É criada uma implementação do gateway de entrada do Cloud Service Mesh no namespace istio-ingress. Isto cria as instâncias de proxy do Envoy que vão receber tráfego do balanceador de carga.
- O balanceador de carga encripta e encaminha todo o tráfego para o gateway de entrada do Cloud Service Mesh.
Agora, tem a infraestrutura completa necessária para aceitar tráfego da Internet na sua malha. Tenha em atenção que esta é a implementação de gateway mais simples possível. Nas secções seguintes, adiciona políticas e capacidades adicionais que o tornam pronto para produção.
Implementação de apps e encaminhamento
Para demonstrar totalmente as capacidades, vai implementar uma aplicação no Cloud Service Mesh e receber tráfego da Internet através da sua gateway para fins de exemplo.
Etiquete o
default
Namespace para ativar a injeção de sidecar.kubectl label namespace default istio-injection=enabled istio.io/rev- --overwrite
Guarde o seguinte manifesto do gateway num ficheiro com o nome
whereami.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v1 spec: replicas: 2 selector: matchLabels: app: whereami-v1 template: metadata: labels: app: whereami-v1 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v1" --- apiVersion: v1 kind: Service metadata: name: whereami-v1 spec: selector: app: whereami-v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v2 spec: replicas: 2 selector: matchLabels: app: whereami-v2 template: metadata: labels: app: whereami-v2 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v2" --- apiVersion: v1 kind: Service metadata: name: whereami-v2 spec: selector: app: whereami-v2 ports: - port: 8080 targetPort: 8080
Este manifesto cria
Service/whereami-v1
,Service/whereami-v2
,Deployment/whereami-v1
eDeployment/whereami-v2
para whereami, uma aplicação simples que produz JSON para indicar a respetiva identidade e localização. Implementa duas versões diferentes.Crie os serviços e as implementações:
kubectl apply -f whereami.yaml
Assim que estiver em funcionamento, terá quatro pods whereami em execução no seu cluster.
Verifique se os quatro pods estão em execução:
kubectl get pods
O resultado é semelhante ao seguinte:
whereami-v1-7c76d89d55-qg6vs 2/2 Running 0 28s whereami-v1-7c76d89d55-vx9nm 2/2 Running 0 28s whereami-v2-67f6b9c987-p9kqm 2/2 Running 0 27s whereami-v2-67f6b9c987-qhj76 2/2 Running 0 27s
Guarde o manifesto HTTPRoute seguinte num ficheiro denominado
http-route.yaml
:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: where-route spec: parentRefs: - kind: Gateway name: servicemesh-cloud-gw namespace: istio-ingress hostnames: - "where.example.com" rules: - matches: - headers: - name: version value: v2 backendRefs: - name: whereami-v2 port: 8080 - backendRefs: - name: whereami-v1 port: 8080
Implemente o
http-route.yaml
no seu cluster:kubectl apply -f http-route.yaml
Esta HTTPRoute faz referência ao
servicemesh-cloud-gw
, o que significa que vai configurar o gateway na nuvem da malha de serviços para que configure o gateway de entrada da malha de serviços na nuvem subjacente com estas regras de encaminhamento. O HTTPRoute tem a mesma função que o Istio VirtualService, mas usa a API Kubernetes Gateway para o fazer. Uma vez que a API Gateway é uma especificação de OSS com muitas implementações subjacentes, é a melhor API adequada para definir o encaminhamento numa combinação de diferentes equilibradores de carga (como proxies e equilibradores de carga do Cloud Service Mesh).Obtenha o endereço IP do gateway para poder enviar tráfego para a sua aplicação:
VIP=$(kubectl get gateways.gateway.networking.k8s.io asm-gw-gke-servicemesh-cloud-gw -o=jsonpath="{.status.addresses[0].value}" -n istio-ingress)
O resultado é um endereço IP.
echo $VIP 34.111.61.135
Envie tráfego para o endereço IP do gateway para validar se esta configuração funciona corretamente. Envie um pedido com o cabeçalho
version: v2
e outro sem ele para determinar se o encaminhamento é feito corretamente nas duas versões da aplicação.curl ${VIP} -H "host: where.example.com" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v1", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v1-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" } curl ${VIP} -H "host: where.example.com" -H "version: v2" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v2", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v2-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" }
Implementação de gateway de produção
A secção anterior mostrou um exemplo muito simples de um gateway na nuvem de malha de serviços. Os passos seguintes baseiam-se no exemplo simples para mostrar uma configuração pronta para produção que demonstra as vantagens de delegar algumas das funcionalidades de encaminhamento de entrada no equilibrador de carga.
No exemplo seguinte, vai usar o servicemesh-cloud-gw
da secção anterior e adicionar as seguintes capacidades para criar um gateway mais seguro e gerível:
- Implemente o gateway com um endereço IP estático que é retido mesmo que a infraestrutura subjacente seja alterada.
- Converta o gateway para receber tráfego HTTPS com um certificado autoassinado.
Crie um endereço IP externo estático. Um IP estático é útil porque a infraestrutura subjacente pode mudar no futuro, mas o endereço IP pode ser mantido.
gcloud compute addresses create whereami-ip \ --global \ --project PROJECT_ID
Crie um certificado autoassinado para o domínio
where-example-com
:openssl genrsa -out key.pem 2048 cat <<EOF >ca.conf [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = where.example.com [sans_list] DNS.1 = where.example.com EOF
openssl req -new -key key.pem \ -out csr.pem \ -config ca.conf
openssl x509 -req \ -signkey key.pem \ -in csr.pem \ -out cert.pem \ -extfile ca.conf \ -extensions extension_requirements \ -days 365
gcloud compute ssl-certificates create where-example-com \ --certificate=cert.pem \ --private-key=key.pem \ --global \ --project PROJECT_ID
Existem várias formas de gerar certificados TLS. Podem ser gerados manualmente na linha de comandos, gerados através de certificados geridos pela Google ou gerados internamente pelo sistema de infraestrutura de chave pública (PKI) da sua empresa. Neste exemplo, gera manualmente um certificado autossinado. Embora os certificados autoassinados não sejam normalmente usados para serviços públicos, demonstram estes conceitos mais facilmente.
Para mais informações sobre como criar um certificado autoassinado através do segredo do Kubernetes, consulte o artigo Proteja um gateway.
Atualize o
gateway.yaml
com o seguinte manifesto:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 allowedRoutes: namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: where-example-com addresses: - type: NamedAddress value: whereami-ip
Volte a implementar o Gateway no cluster:
kubectl apply -f gateway.yaml
Obtenha o endereço IP do IP estático:
VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
Use
curl
para aceder ao domínio da Gateway. Uma vez que o DNS não está configurado para este domínio, use a opção --resolve para indicar ao curl que resolva o nome do domínio para o endereço IP do gateway:curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
Quando estiver concluído, o resultado é semelhante ao seguinte:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=where.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: where.example.com (matched) * issuer: O=example; CN=where.example.com * SSL certificate verify ok. ... { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "where-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "where-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
O resultado detalhado inclui uma negociação de TLS bem-sucedida seguida de uma resposta da aplicação, como o resultado seguinte. Isto prova que o TLS está a ser terminado no gateway corretamente e que a aplicação está a responder ao cliente de forma segura.
Implementou com êxito a seguinte arquitetura:
O servicemesh-cloud-gw
e a respetiva GatewayClass asm-l7-gxlb
abstraíram alguns componentes de infraestrutura internos para simplificar a experiência do utilizador.
O Cloud Load Balancing está a terminar o tráfego TLS com um certificado interno
e também está a verificar o funcionamento da camada de proxy do gateway de entrada do Cloud Service Mesh. O
whereami-route
implementado na
implementação de apps e encaminhamento configura os proxies do gateway de entrada do Cloud Service Mesh para encaminhar o tráfego para o
serviço alojado na malha correto.
No exemplo seguinte, vai usar o servicemesh-cloud-gw
da secção anterior e adicionar as seguintes capacidades para criar um gateway mais seguro e gerível:
- Implemente o gateway com um endereço IP estático que é retido mesmo que a infraestrutura subjacente seja alterada.
- Converta o gateway para receber tráfego HTTPS com um certificado autoassinado.
Crie um endereço IP externo estático. Um IP estático é útil porque a infraestrutura subjacente pode mudar no futuro, mas o endereço IP pode ser mantido.
gcloud compute addresses create whereami-ip \ --global \ --project PROJECT_ID
Crie um certificado autoassinado para o domínio
where-example-com
:openssl genrsa -out key.pem 2048 cat <<EOF >ca.conf [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = where.example.com [sans_list] DNS.1 = where.example.com EOF
openssl req -new -key key.pem \ -out csr.pem \ -config ca.conf
openssl x509 -req \ -signkey key.pem \ -in csr.pem \ -out cert.pem \ -extfile ca.conf \ -extensions extension_requirements \ -days 365
gcloud compute ssl-certificates create where-example-com \ --certificate=cert.pem \ --private-key=key.pem \ --global \ --project PROJECT_ID
Existem várias formas de gerar certificados TLS. Podem ser gerados manualmente na linha de comandos, gerados através de certificados geridos pela Google ou gerados internamente pelo sistema de infraestrutura de chave pública (PKI) da sua empresa. Neste exemplo, gera manualmente um certificado autossinado. Embora os certificados autoassinados não sejam normalmente usados para serviços públicos, demonstram estes conceitos mais facilmente.
Para mais informações sobre como criar um certificado autoassinado através do segredo do Kubernetes, consulte o artigo Proteja um gateway.
Atualize o
gateway.yaml
com o seguinte manifesto:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 allowedRoutes: namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: where-example-com addresses: - type: NamedAddress value: whereami-ip
Volte a implementar o Gateway no cluster:
kubectl apply -f gateway.yaml
Obtenha o endereço IP do IP estático:
VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
Use
curl
para aceder ao domínio da Gateway. Uma vez que o DNS não está configurado para este domínio, use a opção --resolve para indicar ao curl que resolva o nome do domínio para o endereço IP do gateway:curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
Quando estiver concluído, o resultado é semelhante ao seguinte:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=where.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: where.example.com (matched) * issuer: O=example; CN=where.example.com * SSL certificate verify ok. ... { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "where-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "where-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
O resultado detalhado inclui uma negociação de TLS bem-sucedida seguida de uma resposta da aplicação, como o resultado seguinte. Isto prova que o TLS está a ser terminado no gateway corretamente e que a aplicação está a responder ao cliente de forma segura.
Implementou com êxito a seguinte arquitetura:
O servicemesh-cloud-gw
e a respetiva GatewayClass asm-l7-gxlb
abstraíram alguns componentes de infraestrutura internos para simplificar a experiência do utilizador.
O Cloud Load Balancing está a terminar o tráfego TLS com um certificado interno
e também está a verificar o funcionamento da camada de proxy do gateway de entrada do Cloud Service Mesh. O
whereami-route
implementado na
implementação de apps e encaminhamento configura os proxies do gateway de entrada do Cloud Service Mesh para encaminhar o tráfego para o
serviço alojado na malha correto.
O que se segue?
- Saiba mais sobre a implementação do Google Kubernetes Engine (GKE) da API Kubernetes Gateway.
- Saiba como ativar funcionalidades opcionais do Cloud Service Mesh geridas.