Integrar a IAP com o Cloud Service Mesh
Este guia descreve como integrar o Identity-Aware Proxy (IAP) com a Cloud Service Mesh. A integração do IAP com a Cloud Service Mesh permite-lhe aceder em segurança aos serviços com base nos princípios do BeyondCorp da Google. O IAP valida a identidade do utilizador e o contexto do pedido para determinar se um utilizador deve ter permissão para aceder a uma aplicação ou a um recurso. A integração do IAP com a Cloud Service Mesh oferece-lhe as seguintes vantagens:
Controlo de acesso sensível ao contexto completo aos cargas de trabalho em execução no Cloud Service Mesh. Pode definir políticas de acesso detalhadas com base nos atributos do pedido de origem, como a identidade do utilizador, o endereço IP e o tipo de dispositivo. Pode combinar as suas políticas de acesso com restrições baseadas no nome do anfitrião e no caminho de um URL de pedido.
Ativar o suporte para reivindicações sensíveis ao contexto na autorização da malha de serviços na nuvem.
Acesso escalável, seguro e de alta disponibilidade à sua aplicação através de um balanceador de carga do Google Cloud. O balanceamento de carga de alto desempenho oferece proteção integrada contra ataques de negação de serviço distribuída (DDoS) e suporte para endereçamento IP anycast global.
Pré-requisitos
Siga os passos em Instale ferramentas dependentes e valide o cluster para:- Instale as ferramentas necessárias
- Transferir
asmcli
- Conceda autorizações de administrador do cluster
- Valide o seu projeto e cluster
Além disso, este guia pressupõe que tem:
Configurar um cluster com o Anthos Service Mesh
Esta secção explica como fazer a configuração para a integração da IAP para novas instalações da Cloud Service Mesh e atualizações.
Novas instalações
Ative
iap.googleapis.com
. No comando seguinte, substituaPROJECT_ID
pelo projeto no qual vai instalar o Cloud Service Mesh:gcloud services enable \ --project=PROJECT_ID \ iap.googleapis.com
O cluster que está a atualizar tem de ter a opção
--addons=HttpLoadBalancing
definida. O suplementoHttpLoadBalancing
ativa um controlador de balanceamento de carga HTTP (L7) para o cluster. Execute o seguinte comando para atualizar o cluster com as opções necessárias para a Cloud Service Mesh. A menos que tenha definido uma zona ou uma região predefinida, tem de fornecer a região (--region=REGION) ou a zona (--zone=ZONE) no comando.gcloud container clusters update CLUSTER_NAME \ --project=PROJECT_ID \ --update-addons=HttpLoadBalancing=ENABLED
Por predefinição, o ficheiro
iap-operator.yaml
tem a porta 31223 definida como a porta de estado e a porta 31224 definida como a porta http. Se a porta 31223 já estiver a ser usada no cluster, execute o seguinte para definir outra porta de estado:kpt cfg set asm gcloud.container.cluster.ingress.statusPort STATUS_PORT
Se a porta 31224 já estiver a ser usada no seu cluster, execute o seguinte para definir outra porta http:
kpt cfg set asm gcloud.container.cluster.ingress.httpPort HTTP_PORT
Siga os passos em Instale as funcionalidades predefinidas e a AC de malha para usar um script fornecido pela Google para instalar o Cloud Service Mesh. Quando executar o script, inclua a seguinte opção:
--option iap-operator
Por exemplo:
./asmcli install \ --project_id "PROJECT_ID" \ --cluster_name "CLUSTER_NAME" \ --cluster_location "CLUSTER_LOCATION" \ --fleet_id FLEET_PROJECT_ID \ --output_dir DIR_PATH \ --enable_all \ --option iap-operator
Quando instala o Cloud Service Mesh, o ficheiro
iap-operator.yaml
define o campotype
no serviçoistio-ingressgateway
comoNodePort
, o que configura o gateway para abrir uma porta específica na malha de serviços. Isto permite-lhe configurar um equilibrador de carga que encaminha o tráfego enviado para o nome do seu domínio para esta porta.Se estiver a instalar o Cloud Service Mesh gerido, conclua também os seguintes passos:
Adicione a etiqueta de revisão ao espaço de nomes
istio-system
.Transfira a especificação do serviço de gateway de entrada do Istio para o IAP e atribua-lhe o nome
iap_operator.yaml
.Instale o ingresso como um serviço NodePort. Para mais informações, consulte o artigo Migrar do IstioOperator.
asmcli experimental mcp-migrate-check -f iap_operator.yaml istioctl install -f /asm-generated-configs/gateways-istiooperator/"GATEWAY_NAME".yaml
Após instalar o Cloud Service Mesh, regresse a este guia e continue com a secção seguinte para configurar a integração com o IAP.
Atualizações
Esta secção aborda os seguintes exemplos de utilização de atualizações:
Já configurou a integração do IAP e está a atualizar o Cloud Service Mesh. Neste caso, já ativou o
iap.googleapis.com
no seu projeto e o suplementoHttpLoadBalancing
no seu cluster. Avance para o passo 3 para transferir o pacoteasm
e atualizar o Cloud Service Mesh.Está a atualizar o Cloud Service Mesh e quer configurar a integração com o IAP pela primeira vez. Neste caso, tem de concluir todos os seguintes passos, atualizar o Cloud Service Mesh e voltar a este guia após a atualização para concluir a integração.
Ative
iap.googleapis.com
. No comando seguinte, substituaPROJECT_ID
pelo projeto no qual vai instalar o Cloud Service Mesh.gcloud services enable \ --project=PROJECT_ID \ iap.googleapis.com
O cluster que está a atualizar tem de ter a opção
--addons=HttpLoadBalancing
definida. O suplementoHttpLoadBalancing
ativa um controlador de balanceamento de carga HTTP (L7) para o cluster. Execute o seguinte comando para atualizar o cluster com as opções necessárias para a Cloud Service Mesh. A menos que tenha definido uma zona ou uma região predefinida, tem de fornecer a região (--region=REGION) ou a zona (--zone=ZONE) no comando.gcloud container clusters update CLUSTER_NAME \ --project=PROJECT_ID --update-addons=HttpLoadBalancing=ENABLED
Se estiver a atualizar um HTTP Cloud Load Balancer existente e em funcionamento, execute o seguinte comando para preservar as portas http e de estado existentes:
kpt cfg set asm gcloud.container.cluster.ingress.httpPort $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
kpt cfg set asm gcloud.container.cluster.ingress.statusPort $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')
Siga os passos em Atualizar o Cloud Service Mesh para usar um script fornecido pela Google para atualizar o Cloud Service Mesh.
Quando atualiza o Cloud Service Mesh, o ficheiro
iap-operator.yaml
define o campotype
no serviçoistio-ingressgateway
comoNodePort
, o que configura o gateway para abrir uma porta específica na malha de serviços. Isto permite-lhe configurar um balanceador de carga, que encaminha o tráfego enviado para o seu nome de domínio para esta porta.Por predefinição, o ficheiro
iap-operator.yaml
tem a porta 31223 definida como a porta de estado e a porta 31224 definida como a porta http.Quando executar o script, inclua a seguinte opção:
--option iap-operator
Por exemplo:
./asmcli install \ --project_id "PROJECT_ID" \ --cluster_name "CLUSTER_NAME" \ --cluster_location "CLUSTER_LOCATION" \ --fleet_id FLEET_PROJECT_ID \ --output_dir DIR_PATH \ --enable_all \ --option iap-operator
Conclua a atualização acionando a injeção automática de proxy sidecar nas suas cargas de trabalho. Para ver detalhes, consulte o artigo Implementar e reimplementar cargas de trabalho.
Após concluir a atualização, regresse a este guia e continue com a secção seguinte para configurar a integração com as CAs.
Reservar um endereço IP estático e configurar o DNS
Para integrar o Identity-Aware Proxy com a Cloud Service Mesh, tem de configurar um Google Cloud equilibrador de carga HTTP(S), que requer um nome de domínio que aponte para um endereço IP estático. Pode reservar um endereço IP externo estático, que atribui o endereço ao seu projeto indefinidamente até o libertar explicitamente.
Reserve um endereço IP externo estático:
gcloud compute addresses create example-static-ip --global
Obtenha o endereço IP estático:
gcloud compute addresses describe example-static-ip --global
Na entidade de registo do nome do domínio, configure um nome do domínio totalmente qualificado (FQDN) com o endereço IP estático. Normalmente, adiciona um registo
A
às definições de DNS. Os passos de configuração e a terminologia para adicionar um registoA
para um FQDN variam consoante a sua entidade de registo de nome de domínio.A propagação da definição de DNS pode demorar entre 24 e 48 horas. Pode continuar a configurar tudo neste guia, mas não vai poder testar a configuração até que as definições de DNS sejam propagadas.
Implementar uma aplicação de exemplo
Antes de ativar as CAs, precisa de uma aplicação em execução no seu cluster do GKE para poder validar se todos os pedidos têm uma identidade. Este guia usa o exemplo Bookinfo para demonstrar como configurar o balanceador de carga HTTP(S) e ativar a IAP.
Siga os passos para implementar o Bookinfo. Até implementar o balanceador de carga, a aplicação Bookinfo não está acessível fora do cluster do GKE (por exemplo, a partir de um navegador).
Pedidos externos
O recurso Gateway do Bookinfo (definido em
samples/bookinfo/networking/bookinfo-gateway.yaml
) usa o
istio-ingressgateway
pré-configurado.
Recorde que, quando implementou o Cloud Service Mesh, especificou NodePort
para o
istio-ingressgateway
, que abre uma porta específica na service mesh.
Embora os nós no seu cluster tenham endereços IP externos, os pedidos provenientes
de fora do cluster são bloqueados por Google Cloud regras de firewall. Com a IAP, a forma correta de expor aplicações à Internet pública é através de um equilibrador de carga. Não exponha os endereços dos nós através de regras de firewall, o que contornaria o IAP.
Para encaminhar pedidos para o Bookinfo, configure um balanceador de carga HTTP(S) no seu Google Cloud projeto. Uma vez que o balanceador de carga está no seu projeto, está dentro da firewall e pode aceder aos nós no seu cluster. Depois de configurar o equilibrador de carga com o endereço IP estático e o nome do domínio, pode enviar pedidos para o nome do domínio, e o equilibrador de carga encaminha os pedidos para os nós no cluster.
Ativar CNA
Os passos seguintes descrevem como ativar as CNA.
Use o ID de cliente (
CLIENT_ID
no passo acima) eCLIENT_SECRET
para ativar o Cloud Service Mesh. Crie um segredo do Kubernetes com os materiais do seu cliente OAuth:kubectl create secret generic -n istio-system my-secret --from-literal=client_id=CLIENT_ID \ --from-literal=client_secret=CLIENT_SECRET
Implementar o balanceador de carga
Pode usar um recurso Ingress para criar um balanceador de carga de HTTP(S) com certificados SSL configurados automaticamente. Os certificados SSL geridos são aprovisionados, renovados e geridos para o seu domínio.
Crie um recurso ManagedCertificate. Este recurso especifica o domínio do certificado SSL. A lista
spec.domains
tem de conter apenas um domínio. Os domínios com carateres universais não são suportados. No YAML seguinte, substituaDOMAIN_NAME
pelo nome do domínio que configurou para o endereço IP estático externo.cat <<EOF | kubectl apply -f - apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: example-certificate namespace: istio-system spec: domains: - DOMAIN_NAME EOF
Crie um recurso BackendConfig. Este recurso indica ao GCLB como realizar verificações de estado no gateway de entrada, bem como configurar o proxy com reconhecimento de identidade. Primeiro, recolha alguns valores do gateway de entrada sobre as verificações de estado:
Porta de entrada da verificação de funcionamento: esta é a porta de verificação de funcionamento do istio-ingress.
export HC_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')
Caminho de entrada da verificação de funcionamento: este é o caminho de verificação de funcionamento do istio-ingress.
export HC_INGRESS_PATH=$(kubectl get pods -n istio-system -l app=istio-ingressgateway -o jsonpath='{.items[0].spec.containers[?(@.name=="istio-proxy")].readinessProbe.httpGet.path}')
cat <<EOF | kubectl apply -n istio-system -f - apiVersion: cloud.google.com/v1 kind: BackendConfig metadata: name: http-hc-config spec: healthCheck: checkIntervalSec: 2 timeoutSec: 1 healthyThreshold: 1 unhealthyThreshold: 10 port: ${HC_INGRESS_PORT} type: HTTP requestPath: ${HC_INGRESS_PATH} iap: enabled: true oauthclientCredentials: secretName: my-secret EOF
Anote o serviço de entrada com o seu BackendConfig.
kubectl annotate -n istio-system service/istio-ingressgateway --overwrite \ cloud.google.com/backend-config='{"default": "http-hc-config"}' \ cloud.google.com/neg='{"ingress":false}'
Crie o balanceador de carga definindo o recurso Ingress.
Defina a anotação
networking.gke.io/managed-certificates
para o nome do certificado que criou no passo anterior,example-certificate
.Defina a anotação
kubernetes.io/ingress.global-static-ip-name
para o nome do endereço IP estático que reservou,example-static-ip
.Defina o
serviceName
comoistio-ingressgateway
, que é usado no recurso Gateway para o exemplo Bookinfo.
cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: istio-system annotations: kubernetes.io/ingress.global-static-ip-name: example-static-ip networking.gke.io/managed-certificates: example-certificate spec: defaultBackend: service: name: istio-ingressgateway port: number: 80 EOF
Na Google Cloud consola, aceda à página Kubernetes Engine > Serviços & Ingress.
Aceda à página Serviços e entrada
Deve ver a mensagem "A criar entrada" na coluna Estado. Aguarde que o GKE aprovisione totalmente o Ingress antes de continuar. Atualize a página a cada poucos minutos para obter o estado mais atualizado do Ingress. Depois do aprovisionamento do Ingress, pode ver o estado "OK" ou o erro "Todos os serviços de back-end estão no estado UNHEALTHY". Um dos recursos que o GKE aprovisiona é uma verificação de estado predefinida. Se vir a mensagem de erro, significa que o Ingress foi aprovisionado e que a verificação de estado predefinida foi executada. Quando vir o estado "OK" ou o erro, continue com a secção seguinte para configurar as verificações de estado do equilibrador de carga.
Configure a lista de acesso da IAP
Adicione um utilizador à política de acesso para o IAP:
gcloud beta iap web add-iam-policy-binding \ --member=user:EMAIL_ADDRESS \ --role=roles/iap.httpsResourceAccessor
onde EMAIL_ADDRESS
é o endereço de email completo do utilizador, como alice@example.com
.
Teste o balanceador de carga. Direcione o navegador para:
http://DOMAIN_NAME/productpage
onde
DOMAIN_NAME
é o nome do domínio que configurou com o endereço IP estático externo.Deve ver o
productpage
da aplicação Bookinfo. Se atualizar a página várias vezes, deve ver diferentes versões das críticas apresentadas de forma rotativa: estrelas vermelhas, estrelas pretas e sem estrelas.Também deve testar o acesso
https
ao Bookinfo.
Ative a compatibilidade com RCToken na malha de serviços
Por predefinição, o IAP gera um símbolo da Web JSON (JWT) com âmbito para o cliente OAuth. Para a Cloud Service Mesh, pode configurar o IAP para gerar um RequestContextToken (RCToken), que é um JWT, mas com um público-alvo configurável. O RCToken permite-lhe configurar o público-alvo do JWT para uma string arbitrária, que pode ser usada nas políticas da Cloud Service Mesh para autorização detalhada.
Para configurar o RCToken:
Crie uma variável de ambiente para o público-alvo do RCToken. Pode ser qualquer string que quiser.
export RCTOKEN_AUD="your-rctoken-aud"
Opcional: o passo seguinte requer o
BACKEND_SERVICE_ID
. Se precisar de saber oBACKEND_SERVICE_ID
, execute o seguinte comando:kubectl -n istio-system get Ingress example-ingress -o json | jq \ '.metadata.annotations."ingress.kubernetes.io/backends"'
O resultado esperado é semelhante a
"{\"BACKEND_SERVICE_ID\":\"HEALTHY\"}"
. Por exemplo,"ingress.kubernetes.io/backends": "{\"k8s-be-31224--51f3b55cd1457fb6\":\"HEALTHY\"}"
. OBACKEND_SERVICE_ID
neste exemplo ék8s-be-31224--51f3b55cd1457fb6
.Obter as definições de CNA existentes.
gcloud iap settings get --format json \ --project=${PROJECT_ID} --resource-type=compute --service=BACKEND_SERVICE_ID > iapSettings.json
Atualize
IapSettings
com o público-alvo do RCToken.cat iapSettings.json | jq --arg RCTOKEN_AUD_STR $RCTOKEN_AUD \ '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \ > updatedIapSettings.json
gcloud iap settings set updatedIapSettings.json --format json \ --project=${PROJECT_ID} --resource-type=compute --service=BACKEND_SERVICE_ID
Ative a autenticação RCToken no gateway de entrada do Istio.
cat <<EOF | kubectl apply -f - apiVersion: "security.istio.io/v1beta1" kind: "RequestAuthentication" metadata: name: "ingressgateway-jwt-policy" namespace: "istio-system" spec: selector: matchLabels: app: istio-ingressgateway jwtRules: - issuer: "https://cloud.google.com/iap" jwksUri: "https://www.gstatic.com/iap/verify/public_key-jwk" audiences: - $RCTOKEN_AUD fromHeaders: - name: ingress-authorization prefix: "Istio " outputPayloadToHeader: "verified-jwt" forwardOriginalToken: true EOF
Opcional: certifique-se de que os pedidos que não têm JWTs válidos são rejeitados:
cat <<EOF | kubectl apply -f - apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: iap-gateway-require-jwt namespace: istio-system spec: selector: matchLabels: app: istio-iap-ingressgateway action: DENY rules: - from: - source: notRequestPrincipals: ["*"] EOF
Certifique-se de que os pedidos ao Bookinfo
productpage
continuam a ser bem-sucedidos:http://DOMAIN_NAME/productpage
Para testar a política:
Crie um objeto de pedido
IapSettings
, mas defina orctokenAud
como uma string diferente:cat iapSettings.json | jq --arg RCTOKEN_AUD_STR wrong-rctoken-aud \ '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \ > wrongIapSettings.json
Chame a API
IapSettings
para definir o público-alvo do RCtoken.gcloud beta iap settings set wrongIapSettings.json --project=PROJECT_ID --resource-type=compute --service=BACKEND_SERVICE
Faça um pedido ao Bookinfo
productpage
e este deve falhar:http://DOMAIN_NAME/productpage
Limpar
Após concluir este tutorial, remova os seguintes recursos para evitar a incorrência de cobranças indesejadas na sua conta:
Elimine o certificado gerido:
kubectl delete managedcertificates example-certificate
Elimine a entrada, que anula a atribuição dos recursos de balanceamento de carga:
kubectl -n istio-system delete ingress example-ingress
Elimine o endereço IP estático:
gcloud compute addresses delete example-static-ip --global
Se o fizer, certifique-se de que elimina o endereço IP da sua entidade de registo de domínios.
Elimine o cluster, o que elimina os recursos que compõem o cluster, como as instâncias de computação, os discos e os recursos de rede:
gcloud container clusters delete CLUSTER_NAME