Configurar a segurança do serviço com gRPC sem proxy
Neste guia, você verá como configurar um serviço de segurança para a malha de serviço gRPC sem proxy.
Requisitos
Antes de configurar a segurança do serviço para a malha de serviço gRPC sem proxy, verifique se você atende aos requisitos a seguir.
- Sua implantação atende aos requisitos em Preparar-se para configurar APIs de roteamento de serviço com cargas de trabalho sem proxy e Envoy.
- É necessário que você use a xDS v3.
- Você terá acesso à versão do xDS necessária e à funcionalidade do provedor
de certificado com uma das seguintes linguagens:
- gRPC em Java
- gRPC em C++
- gRPC em Python
- gRPC em Go Encontre as versões de linguagem necessárias no github
- Você tem acesso ao gerador de inicialização versão 0.16.0. A imagem do gerador de inicialização está localizada no repositório de contêiner do Google Cloud.
- Você atende a todos os pré-requisitos do balanceamento de carga da malha de serviço do gRPC sem proxy.
- Você tem permissões suficientes para criar ou atualizar os recursos de malha de serviço do Google Cloud e do Cloud Service Mesh para usar a segurança do PSM. Para informações completas sobre as permissões necessárias, consulte Preparar para configurar o Cloud Service Mesh com serviços gRPC sem proxy.
- Você tem as permissões necessárias para usar o Certificate Authority Service, que está descrito em Criar autoridades certificadoras para emitir certificados.
Configurar o gerenciamento de identidade e acesso
Você precisa ter as permissões necessárias para usar o Google Kubernetes Engine. Você precisa ter pelo menos os seguintes papéis:
- Papel GKE
roles/container.clusterAdmin
- Papel Compute Engine
roles/compute.instanceAdmin
- Papel
roles/iam.serviceAccountUser
Para criar os recursos necessários à configuração, você precisa ter o
papel compute.NetworkAdmin
. Esse papel contém todas as permissões necessárias para
criar, atualizar, excluir, listar e usar (ou seja, mencionar isso em outros
recursos) os recursos necessários. Se você for o editor-proprietário do projeto,
terá esse papel automaticamente.
networksecurity.googleapis.com.clientTlsPolicies.use
e
networksecurity.googleapis.com.serverTlsPolicies.use
não são aplicados quando você
faz referência a esses recursos no recurso de serviço de back-end.
Se isso for aplicado no futuro e você estiver usando o papel compute.NetworkAdmin
, não haverá problemas quando essa verificação for aplicada.
Se você estiver usando papéis personalizados e essa verificação for aplicada no futuro, certifique-se
de incluir a respectiva permissão .use
. Caso contrário, no futuro,
você verá que o papel personalizado não tem as permissões necessárias
para se referir a clientTlsPolicy
ou serverTlsPolicy
pelo serviço de back-end.
Preparar para a configuração
A segurança da malha de serviço sem proxy (PSM, na sigla em inglês) adiciona segurança a uma malha de serviço
configurada para balanceamento de carga de acordo com a documentação dos serviços gRPC
sem proxy. Em uma malha
de serviço sem proxy, um cliente gRPC usa o esquema xds:
no URI para acessar o
serviço, o que permite os recursos de balanceamento de carga PSM e descoberta de endpoints.
Atualizar clientes e servidores gRPC para a versão correta
Crie ou recrie seus aplicativos usando a versão mínima do gRPC compatível com sua linguagem.
Atualizar o arquivo de inicialização
Os aplicativos gRPC usam um único arquivo de inicialização, que precisa ter todos os campos exigidos pelo código do cliente e do servidor gRPC. Um gerador de inicialização gera automaticamente o arquivo de inicialização para incluir sinalizações e valores necessários para a segurança do PSM. Para mais informações, consulte a seção Arquivo de inicialização, que inclui um arquivo de inicialização de amostra.
Visão geral da configuração
Esse processo de configuração é uma extensão da configuração da malha de serviços da Cloud com o GKE e os serviços gRPC sem proxy. As etapas não modificadas dessa configuração são referenciadas sempre que se aplicarem.
As principais melhorias na configuração do Cloud Service Mesh com o GKE são:
- Configurar o serviço de CA, em que você cria pools de CAs particulares e as autoridades certificadoras necessárias.
- Criar um cluster do GKE com a federação de identidade da carga de trabalho do GKE para recursos de certificados de malha e integração do serviço de CA.
- Configuração da emissão de certificados de malha no cluster.
- Criação das contas de serviço do cliente e do servidor.
- Configuração do servidor de exemplo que usa APIs xDS e credenciais do servidor xDS para adquirir a configuração de segurança do Cloud Service Mesh.
- Configuração do cliente de exemplo que usa credenciais do xDS.
- Atualização da configuração do Cloud Service Mesh para incluir a configuração de segurança.
Você pode ver exemplos de código para usar credenciais xDS nos seguintes locais:
Atualizar a CLI do Google Cloud
Para atualizar a CLI do Google Cloud, execute o comando a seguir:
gcloud components update
Configurar variáveis de ambiente
Neste guia, você usa comandos do Cloud Shell, e a repetição de informações nos comandos é representada por várias variáveis de ambiente. Defina os valores específicos para as seguintes variáveis de ambiente no ambiente shell antes de executar os comandos. Cada linha de comentário indica o significado da variável de ambiente associada.
# Your project ID PROJECT_ID=PROJECT_ID # GKE cluster name and zone for this example. CLUSTER_NAME=CLUSTER_NAME ZONE=ZONE gcloud config set compute/zone $ZONE # GKE cluster URL derived from the above GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/${PROJECT_ID}/locations/${ZONE}/clusters/${CLUSTER_NAME}" # Workload pool to be used with the GKE cluster WORKLOAD_POOL="${PROJECT_ID}.svc.id.goog" # Kubernetes namespace to run client and server demo. K8S_NAMESPACE='default' DEMO_BACKEND_SERVICE_NAME='grpc-gke-helloworld-service' # Compute other values # Project number for your project PROJNUM=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") # VERSION is the GKE cluster version. Install and use the most recent version # from the rapid release channel and substitute its version for # CLUSTER_VERSION, for example: # VERSION=latest available version # Note that the minimum required cluster version is 1.21.4-gke.1801. VERSION="CLUSTER_VERSION" SA_GKE=service-${PROJNUM}@container-engine-robot.iam.gserviceaccount.com
Ativar o acesso às APIs necessárias
Esta seção mostra como ativar o acesso às APIs necessárias.
Execute o comando a seguir para ativar o Cloud Service Mesh e outras APIs necessárias para a segurança da malha de serviço gRPC sem proxy.
gcloud services enable \ container.googleapis.com \ cloudresourcemanager.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ networksecurity.googleapis.com \ privateca.googleapis.com \ gkehub.googleapis.com
Execute o comando a seguir para permitir que a conta de serviço padrão acesse a API de segurança do Cloud Service Mesh.
GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \ --filter='displayName:Compute Engine default service account') gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member serviceAccount:${GSA_EMAIL} \ --role roles/trafficdirector.client
Criar ou atualizar um cluster do GKE
A segurança do serviço do Cloud Service Mesh depende da integração do serviço de CA com o GKE. O cluster do GKE precisa atender aos seguintes requisitos, além dos requisitos de configuração:
- Use uma versão de cluster mínima de 1.21.4-gke.1801. Se você precisar de recursos que estejam em uma versão posterior, poderá encontrá-la no canal de lançamento rápido.
- O cluster do GKE precisa ser ativado e configurado com certificados de malha, conforme descrito em Como criar autoridades certificadoras para emitir certificados.
Crie um cluster que use a federação de identidade da carga de trabalho para o GKE. Se você estiver atualizando um cluster existente, pule para a próxima etapa. O valor fornecido para
--tags
precisa corresponder ao nome transmitido à sinalização--target-tags
para o comandofirewall-rules create
na seção Como configurar o Cloud Service Mesh com componentes do Cloud Load Balancing.# Create a GKE cluster with GKE managed mesh certificates. gcloud container clusters create CLUSTER_NAME \ --release-channel=rapid \ --scopes=cloud-platform \ --image-type=cos_containerd \ --machine-type=e2-standard-2 \ --zone=ZONE \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-mesh-certificates \ --cluster-version=CLUSTER_VERSION \ --enable-ip-alias \ --tags=allow-health-checks \ --workload-metadata=GKE_METADATA
A criação do cluster pode levar vários minutos para ser concluída.
Se você estiver usando um cluster atual, ative a Federação de Identidade da Carga de Trabalho para GKE e os certificados de malha do GKE. Verifique se o cluster foi criado com a sinalização
--enable-ip-alias
, que não pode ser usada com o comandoupdate
.gcloud container clusters update CLUSTER_NAME \ --enable-mesh-certificates
Execute o comando a seguir para alternar para o novo cluster como o cluster padrão para os comandos
kubectl
:gcloud container clusters get-credentials CLUSTER_NAME \ --zone ZONE
Registrar clusters com uma frota
Registre o cluster que você criou ou atualizou em Como criar um cluster do GKE com uma frota. Registrar o cluster facilita a configuração de clusters em vários projetos.
Essas etapas podem levar até dez minutos para serem concluídas.
Registre seu cluster na frota:
gcloud container fleet memberships register CLUSTER_NAME \ --gke-cluster=ZONE/CLUSTER_NAME \ --enable-workload-identity --install-connect-agent \ --manifest-output-file=MANIFEST-FILE_NAME
Substitua as variáveis da seguinte maneira:
- CLUSTER_NAME: o nome do cluster.
- ZONE: a zona do cluster.
- MANIFEST-FILE_NAME: o caminho em que esses comandos geram o manifesto para registro.
Quando o processo de registro for bem-sucedido, você verá uma mensagem como a seguinte:
Finished registering the cluster CLUSTER_NAME with the fleet.
Aplique o arquivo de manifesto gerado ao cluster:
kubectl apply -f MANIFEST-FILE_NAME
Quando o processo do aplicativo for bem-sucedido, você verá mensagens como estas:
namespace/gke-connect created serviceaccount/connect-agent-sa created podsecuritypolicy.policy/gkeconnect-psp created role.rbac.authorization.k8s.io/gkeconnect-psp:role created rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created role.rbac.authorization.k8s.io/agent-updater created rolebinding.rbac.authorization.k8s.io/agent-updater created role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created role.rbac.authorization.k8s.io/gke-connect-namespace-getter created rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created secret/http-proxy created deployment.apps/gke-connect-agent-20210416-01-00 created service/gke-connect-monitoring created secret/creds-gcp create
Consiga o recurso de assinatura do cluster:
kubectl get memberships membership -o yaml
A saída precisa incluir o pool de identidade do Workoad atribuído pela frota, em que PROJECT_ID é o ID do projeto:
workload_identity_pool: PROJECT_ID.svc.id.goog
Isso significa que o cluster foi registrado com sucesso.
Criar autoridades certificadoras para emitir certificados
Para emitir certificados para os pods, crie um pool de serviço de CA e as seguintes autoridades certificadoras (CAs):
- CA raiz. Essa é a raiz da confiança de todos os certificados de malha emitidos. Use uma CA raiz atual, se tiver uma. Crie a CA raiz no
nível
enterprise
, que é destinado à emissão de certificados de longa duração e de baixo volume. - CA subordinada. Essa CA emite certificados para cargas de trabalho. Crie a
CA subordinada na região em que o cluster está implantado. Crie a
CA subordinada no nível
devops
, que se destina à emissão de certificados de curta duração e de grande volume.
Criar uma CA subordinada é opcional, mas é altamente recomendável criá-la em vez de usar a CA raiz para emitir certificados de malha do GKE. Se você decidir usar a CA raiz para emitir certificados de malha, verifique se o modo de emissão baseado em configuração padrão permanece permitido.
A CA subordinada pode estar em uma região diferente do cluster, mas é altamente recomendável criá-la na mesma região do cluster para otimizar o desempenho. No entanto, é possível criar as CAs raiz e subordinadas em diferentes regiões sem qualquer impacto no desempenho ou na disponibilidade.
Estas regiões são compatíveis com o serviço de CA:
Nome da região | Descrição da região |
---|---|
asia-east1 |
Taiwan |
asia-east2 |
Hong Kong |
asia-northeast1 |
Tóquio |
asia-northeast2 |
Osaka |
asia-northeast3 |
Seul |
asia-south1 |
Mumbai |
asia-south2 |
Délhi |
asia-southeast1 |
Singapura |
asia-southeast2 |
Jacarta |
australia-southeast1 |
Sydney |
australia-southeast2 |
Melbourne |
europe-central2 |
Varsóvia |
europe-north1 |
Finlândia |
europe-southwest1 |
Madri |
europe-west1 |
Bélgica |
europe-west2 |
Londres |
europe-west3 |
Frankfurt |
europe-west4 |
Países Baixos |
europe-west6 |
Zurique |
europe-west8 |
Milão |
europe-west9 |
Paris |
europe-west10 |
Berlim |
europe-west12 |
Turim |
me-central1 |
Doha |
me-central2 |
Damã |
me-west1 |
Tel Aviv |
northamerica-northeast1 |
Montreal |
northamerica-northeast2 |
Toronto |
southamerica-east1 |
São Paulo |
southamerica-west1 |
Santiago |
us-central1 |
Iowa |
us-east1 |
Carolina do Sul |
us-east4 |
Norte da Virgínia |
us-east5 |
Columbus |
us-south1 |
Dallas |
us-west1 |
Oregon |
us-west2 |
Los Angeles |
us-west3 |
Salt Lake City |
us-west4 |
Las Vegas |
A lista de locais compatíveis também pode ser verificada executando o seguinte comando:
gcloud privateca locations list
Conceda o
roles/privateca.caManager
do IAM a indivíduos que criam um pool de CAs e uma CA. Para MEMBER, o formato correto éuser:userid@example.com
. Se essa pessoa for o usuário atual, é possível conseguir o ID do usuário atual com o comando shell$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
.gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.caManager
Conceda o papel
role/privateca.admin
para o serviço de CA a indivíduos que precisam modificar as políticas do IAM, em queMEMBER
é um indivíduo que precisa desse acesso, especificamente, qualquer pessoa que execute as etapas abaixo. que concedem os papéisprivateca.auditor
eprivateca.certificateManager
:gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.admin
Crie o pool de serviço de CA raiz.
gcloud privateca pools create ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --tier enterprise
Crie uma CA raiz.
gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \ --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \ --key-algorithm="ec-p256-sha256" \ --max-chain-length=1 \ --location ROOT_CA_POOL_LOCATION
Para essa configuração de demonstração, use os seguintes valores para as variáveis:
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_NAME=pkcs2-ca
- ROOT_CA_POOL_LOCATION=us-east1
- ROOT_CA_ORGANIZATION="TestCorpLLC"
Crie o pool subordinado e a CA subordinada. Verifique se o modo de emissão baseado em configuração padrão permanece permitido.
gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --tier devops
gcloud privateca subordinates create SUBORDINATE_CA_NAME \ --pool SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --issuer-pool ROOT_CA_POOL_NAME \ --issuer-location ROOT_CA_POOL_LOCATION \ --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \ --key-algorithm "ec-p256-sha256" \ --use-preset-profile subordinate_mtls_pathlen_0
Para essa configuração de demonstração, use os seguintes valores para as variáveis:
- SUBORDINATE_CA_POOL_NAME="td-ca-pool"
- SUBORDINATE_CA_POOL_LOCATION=us-east1
- SUBORDINATE_CA_NAME="td-ca"
- SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_POOL_LOCATION=us-east1
Conceda o papel
privateca.auditor
do IAM para a CA raiz para permitir o acesso da conta de serviço do GKE:gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --role roles/privateca.auditor \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
Conceda o papel
privateca.certificateManager
do IAM para o pool da CA subordinado para permitir o acesso pela conta de serviço do GKE:gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --role roles/privateca.certificateManager \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
Salve a seguinte configuração YAML
WorkloadCertificateConfig
para informar ao cluster como emitir certificados de malha:apiVersion: security.cloud.google.com/v1 kind: WorkloadCertificateConfig metadata: name: default spec: # Required. The CA service that issues your certificates. certificateAuthorityConfig: certificateAuthorityServiceConfig: endpointURI: ISSUING_CA_POOL_URI # Required. The key algorithm to use. Choice of RSA or ECDSA. # # To maximize compatibility with various TLS stacks, your workloads # should use keys of the same family as your root and subordinate CAs. # # To use RSA, specify configuration such as: # keyAlgorithm: # rsa: # modulusSize: 4096 # # Currently, the only supported ECDSA curves are "P256" and "P384", and the only # supported RSA modulus sizes are 2048, 3072 and 4096. keyAlgorithm: rsa: modulusSize: 4096 # Optional. Validity duration of issued certificates, in seconds. # # Defaults to 86400 (1 day) if not specified. validityDurationSeconds: 86400 # Optional. Try to start rotating the certificate once this # percentage of validityDurationSeconds is remaining. # # Defaults to 50 if not specified. rotationWindowPercentage: 50
Substitua:
- O ID do projeto em que o cluster é executado:
PROJECT_ID
- O URI totalmente qualificado da CA que emite os certificados de malha (ISSUING_CA_POOL_URI).
Pode ser a CA subordinada (recomendado) ou a CA raiz. O formato é:
//privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
- O ID do projeto em que o cluster é executado:
Salve a seguinte configuração YAML
TrustConfig
para informar ao cluster como confiar nos certificados emitidos:apiVersion: security.cloud.google.com/v1 kind: TrustConfig metadata: name: default spec: # You must include a trustStores entry for the trust domain that # your cluster is enrolled in. trustStores: - trustDomain: PROJECT_ID.svc.id.goog # Trust identities in this trustDomain if they appear in a certificate # that chains up to this root CA. trustAnchors: - certificateAuthorityServiceURI: ROOT_CA_POOL_URI
Substitua:
- O ID do projeto em que o cluster é executado:
PROJECT_ID
- O URI totalmente qualificado do pool de CA raiz (ROOT_CA_POOL_URI).
O formato é:
//privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
- O ID do projeto em que o cluster é executado:
Aplique as configurações ao cluster:
kubectl apply -f WorkloadCertificateConfig.yaml kubectl apply -f TrustConfig.yaml
Criar um serviço gRPC sem proxy com NEGs
Para a segurança do PSM, você precisa de um servidor gRPC sem proxy capaz de usar xDS para
adquirir a configuração de segurança da Cloud Service Mesh. Esta etapa é
semelhante a Como configurar serviços do GKE com NEGs no guia de configuração
do balanceamento de carga do PSM, com a diferença de que você usa o servidor helloworld
com xDS ativado no
exemplo do xDS no repositório
grpc-java
em vez da imagem java-example-hostname
.
Crie e execute esse servidor em um contêiner criado a partir de uma imagem openjdk:8-jdk
.
Use também o recurso NEG nomeado, que permite especificar um nome para o NEG. Isso
simplificará etapas posteriores porque a implantação sabe o nome do NEG sem
precisar procurá-lo.
Veja a seguir um exemplo completo da especificação Kubernetes do servidor gRPC. Observe o seguinte:
- A especificação cria uma conta de serviço do Kubernetes
example-grpc-server
que é usada pelo pod de servidor gRPC. - A especificação usa o campo
name
na anotaçãocloud.google.com/neg
do serviço para especificar o nome do NEGexample-grpc-server
. - A variável
${PROJNUM}
representa o número do seu projeto. - A especificação usa a seção
initContainers
para executar um gerador de inicialização para preencher o arquivo de inicialização de que a biblioteca gRPC sem proxy precisa. Esse arquivo de inicialização reside em/tmp/grpc-xds/td-grpc-bootstrap.json
no contêiner do servidor gRPC chamadoexample-grpc-server
.
Adicione a seguinte anotação à especificação do pod:
annotations: security.cloud.google.com/use-workload-certificates: ""
Você pode ver a posição correta na especificação completa a seguir.
Na criação, cada pod recebe um volume em /var/run/secrets/workload-spiffe-credentials
.
Este volume contém o seguinte:
private_key.pem
, uma chave privada gerada automaticamente.certificates.pem
, um pacote de certificados formatados em PEM que pode ser apresentado a outro pod como a cadeia de certificados do cliente ou usado como uma cadeia de certificados de servidor.ca_certificates.pem
, um pacote de certificados formatados em PEM para usar como âncoras de confiança ao validar a cadeia de certificados do cliente apresentado por outro pod ou a cadeia de certificados de servidor recebida ao se conectar a outro pod.
Observe que ca_certificates.pem
contém certificados para o domínio de confiança local
das cargas de trabalho, que é o pool de cargas de trabalho do cluster.
O certificado de folha em certificates.pem
contém a seguinte declaração de identidade SPIFFE
de texto simples:
spiffe://WORKLOAD_POOL/ns/NAMESPACE/sa/KUBERNETES_SERVICE_ACCOUNT
Nesta declaração:
- WORKLOAD_POOL é o nome do pool de carga de trabalho do cluster.
- NAMESPACE é o namespace da conta de serviço do Kubernetes.
- KUBERNETES_SERVICE_ACCOUNT é o nome da conta de serviço do Kubernetes.
As instruções a seguir para sua linguagem criam a especificação a ser usada neste exemplo.
Java
Execute o seguinte comando para garantir que o número do projeto esteja definido corretamente:
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Crie a especificação:
cat << EOF > example-grpc-server.yaml apiVersion: v1 kind: ServiceAccount metadata: name: example-grpc-server namespace: default annotations: iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com --- apiVersion: v1 kind: Service metadata: name: example-grpc-server namespace: default labels: k8s-app: example-grpc-server annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}' spec: ports: - name: helloworld port: 8080 protocol: TCP targetPort: 50051 selector: k8s-app: example-grpc-server type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: example-grpc-server namespace: default labels: k8s-app: example-grpc-server spec: replicas: 1 selector: matchLabels: k8s-app: example-grpc-server strategy: {} template: metadata: annotations: security.cloud.google.com/use-workload-certificates: "" labels: k8s-app: example-grpc-server spec: containers: - image: openjdk:8-jdk imagePullPolicy: IfNotPresent name: example-grpc-server command: - /bin/sleep - inf env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" ports: - protocol: TCP containerPort: 50051 resources: limits: cpu: 800m memory: 512Mi requests: cpu: 100m memory: 512Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - name: grpc-td-init image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: Always args: - --config-mesh-experimental - "grpc-mesh" - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" - --node-metadata=app=helloworld resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ serviceAccountName: example-grpc-server volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
C++
Execute o seguinte comando para garantir que o número do projeto esteja definido corretamente:
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Crie a especificação:
cat << EOF > example-grpc-server.yaml apiVersion: v1 kind: ServiceAccount metadata: name: example-grpc-server namespace: default annotations: iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com --- apiVersion: v1 kind: Service metadata: name: example-grpc-server namespace: default labels: k8s-app: example-grpc-server annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}' spec: ports: - name: helloworld port: 8080 protocol: TCP targetPort: 50051 selector: k8s-app: example-grpc-server type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: example-grpc-server namespace: default labels: k8s-app: example-grpc-server spec: replicas: 1 selector: matchLabels: k8s-app: example-grpc-server strategy: {} template: metadata: annotations: security.cloud.google.com/use-workload-certificates: "" labels: k8s-app: example-grpc-server spec: containers: - image: phusion/baseimage:18.04-1.0.0 imagePullPolicy: IfNotPresent name: example-grpc-server command: - /bin/sleep - inf env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" ports: - protocol: TCP containerPort: 50051 resources: limits: cpu: 8 memory: 8Gi requests: cpu: 300m memory: 512Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - name: grpc-td-init image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: Always args: - --config-mesh-experimental - "grpc-mesh" - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" - --node-metadata=app=helloworld resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ serviceAccountName: example-grpc-server volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
Python
Execute o seguinte comando para garantir que o número do projeto esteja definido corretamente:
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Crie a especificação:
cat << EOF > example-grpc-server.yaml apiVersion: v1 kind: ServiceAccount metadata: name: example-grpc-server namespace: default annotations: iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com --- apiVersion: v1 kind: Service metadata: name: example-grpc-server namespace: default labels: k8s-app: example-grpc-server annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}' spec: ports: - name: helloworld port: 8080 protocol: TCP targetPort: 50051 selector: k8s-app: example-grpc-server type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: example-grpc-server namespace: default labels: k8s-app: example-grpc-server spec: replicas: 1 selector: matchLabels: k8s-app: example-grpc-server strategy: {} template: metadata: annotations: security.cloud.google.com/use-workload-certificates: "" labels: k8s-app: example-grpc-server spec: containers: - image: phusion/baseimage:18.04-1.0.0 imagePullPolicy: IfNotPresent name: example-grpc-server command: - /bin/sleep - inf env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" ports: - protocol: TCP containerPort: 50051 resources: limits: cpu: 8 memory: 8Gi requests: cpu: 300m memory: 512Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - name: grpc-td-init image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: Always args: - --config-mesh-experimental - "grpc-mesh" - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" - --node-metadata=app=helloworld resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ serviceAccountName: example-grpc-server volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
Go
Execute o seguinte comando para garantir que o número do projeto esteja definido corretamente:
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Crie a especificação:
cat << EOF > example-grpc-server.yaml apiVersion: v1 kind: ServiceAccount metadata: name: example-grpc-server namespace: default annotations: iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com --- apiVersion: v1 kind: Service metadata: name: example-grpc-server namespace: default labels: k8s-app: example-grpc-server annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}' spec: ports: - name: helloworld port: 8080 protocol: TCP targetPort: 50051 selector: k8s-app: example-grpc-server type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: example-grpc-server namespace: default labels: k8s-app: example-grpc-server spec: replicas: 1 selector: matchLabels: k8s-app: example-grpc-server strategy: {} template: metadata: annotations: security.cloud.google.com/use-workload-certificates: "" labels: k8s-app: example-grpc-server spec: containers: - image: golang:1.16-alpine imagePullPolicy: IfNotPresent name: example-grpc-server command: - /bin/sleep - inf env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" ports: - protocol: TCP containerPort: 50051 resources: limits: cpu: 8 memory: 8Gi requests: cpu: 300m memory: 512Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - name: grpc-td-init image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: Always args: - --config-mesh-experimental - "grpc-mesh" - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" - --node-metadata=app=helloworld resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ serviceAccountName: example-grpc-server volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
Conclua o processo da maneira a seguir.
Aplique a especificação:
kubectl apply -f example-grpc-server.yaml
Conceda os papéis necessários à conta de serviço:
gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/example-grpc-server]" \ ${PROJNUM}-compute@developer.gserviceaccount.com gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/example-grpc-server]" \ --role roles/trafficdirector.client
Execute estes comandos para verificar se o serviço e o pod foram criados corretamente:
kubectl get deploy/example-grpc-server kubectl get svc/example-grpc-server
Verifique se o nome do NEG está correto:
gcloud compute network-endpoint-groups list \ --filter "name=example-grpc-server" --format "value(name)"
O comando precisa retornar o nome NEG
example-grpc-server
.
Configurar o Cloud Service Mesh com componentes de balanceamento de carga do Google Cloud
As etapas desta seção são semelhantes às de Como configurar o Cloud Service Mesh com componentes de balanceamento de carga, mas com algumas alterações, conforme descrito nas seções a seguir.
Criar a verificação de integridade, a regra de firewall e o serviço de back-end
Quando o servidor gRPC é configurado para usar mTLS, as verificações de integridade do gRPC não funcionam porque o cliente de verificação de integridade não pode apresentar um certificado do cliente válido para os servidores. Você pode resolver isso de duas maneiras:
Na primeira abordagem, o servidor cria uma porta de exibição adicional designada como a porta de verificação de integridade. Ela está anexada a um serviço de verificação de integridade especial, como texto simples ou TLS para essa porta.
O servidor de exemplo helloworld
do xDS
usa PORT_NUMBER
+ 1 como a porta de verificação de integridade de texto simples. O exemplo usa
50052 como a porta de verificação de integridade porque 50051 é a porta do servidor de aplicativos
gRPC.
Na segunda abordagem, você configura a verificação de integridade para verificar apenas a conectividade TCP com a porta de exibição do aplicativo. Isso verifica apenas a conectividade e também gera tráfego desnecessário para o servidor quando não há handshakes TLS mal-sucedidos. Por esse motivo, recomendamos que você use a primeira abordagem.
Crie a verificação de integridade. A verificação de integridade não é iniciada até que você crie e inicie o servidor.
Se você estiver criando uma porta de exibição designada para verificação de integridade, que é a abordagem recomendada, use este comando:
gcloud compute health-checks create grpc grpc-gke-helloworld-hc \ --enable-logging --port 50052
Se você estiver criando uma verificação de integridade TCP, que não recomendamos, use este comando:
gcloud compute health-checks create tcp grpc-gke-helloworld-hc \ --use-serving-port
Criar o firewall. Verifique se o valor de
--target-tags
corresponde ao valor que você forneceu para--tags
na seção Criar ou atualizar um cluster do GKE.gcloud compute firewall-rules create grpc-gke-allow-health-checks \ --network default --action allow --direction INGRESS \ --source-ranges 35.191.0.0/16,130.211.0.0/22 \ --target-tags allow-health-checks \ --rules tcp:50051-50052
Crie o serviço de back-end:
gcloud compute backend-services create grpc-gke-helloworld-service \ --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --protocol=GRPC \ --health-checks grpc-gke-helloworld-hc
Anexe o NEG ao serviço de back-end:
gcloud compute backend-services add-backend grpc-gke-helloworld-service \ --global \ --network-endpoint-group example-grpc-server \ --network-endpoint-group-zone ${ZONE} \ --balancing-mode RATE \ --max-rate-per-endpoint 5
Criar os recursos Mesh
e GRPCRoute
Isso é semelhante à maneira como você configura os recursos Mesh
e GRPCRoute
em
Configurar serviços gRPC sem proxy.
Crie a especificação
Mesh
e salve-a em um arquivo chamadomesh.yaml
.name: grpc-mesh
Importe o recurso
Mesh
da especificação.gcloud network-services meshes import grpc-mesh \ --source=mesh.yaml \ --location=global
Crie a especificação
GRPCRoute
e salve-a em um arquivo chamadogrpc_route.yaml
.name: helloworld-grpc-route hostnames: - helloworld-gke:8000 meshes: - projects/PROJECT_NUMBER/locations/global/meshes/grpc-mesh rules: - action: destinations: - serviceName: projects/PROJECT_NUMBER/locations/global/backendServices/grpc-gke-helloworld-service
Importe o recurso
GRPCRoute
da especificaçãogrpc_route.yaml
.gcloud network-services grpc-routes import helloworld-grpc-route \ --source=grpc_route.yaml \ --location=global
Configurar o Cloud Service Mesh com a segurança gRPC sem proxy
Este exemplo demonstra como configurar o mTLS no lado do cliente e do servidor.
Formato para referências de políticas
Observe o seguinte formato obrigatório para se referir às políticas de TLS do servidor e TLS do cliente:
projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies]/[server-tls-policy|client-mtls-policy]
Exemplo:
projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
Configurar o mTLS no lado do servidor
Primeiro, crie uma política de TLS para o servidor. A política solicita que o servidor do gRPC
use a configuração do plug-in certificateProvicerInstance
identificada pelo nome
google_cloud_private_spiffe
do certificado de identidade, que faz parte do
serverCertificate
. A seção mtlsPolicy
indica a segurança mTLS e usa
o mesmo google_cloud_private_spiffe
que a configuração do plug-in para
clientValidationCa
, que é a especificação de certificado raiz (validação).
Em seguida, crie uma política de endpoint. Isso especifica que um back-end, por exemplo,
um servidor gRPC usando a porta 50051
com algum ou nenhum rótulo de metadados, receberá a
política de TLS do servidor anexada chamada server-mtls-policy
. Use MATCH_ALL
ou um valor compatível para especificar rótulos de metadados. Os rótulos de metadados compatíveis podem ser encontrados no campo endpointMatcher.metadataLabelMatcher.metadataLabelMatchCriteria
no documento NetworkServicesEndpointPolicy. Crie a política de endpoint com um arquivo temporário
ep-mtls-psms.yaml
que contém os valores do recurso de política de endpoint
usando a política já definida.
Crie um arquivo temporário
server-mtls-policy.yaml
no diretório atual com os valores do recurso de política de TLS do servidor:name: "projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe mtlsPolicy: clientValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
Crie um recurso de política de TLS do servidor chamado
server-mtls-policy
importando o arquivo temporárioserver-mtls-policy.yaml
:gcloud network-security server-tls-policies import server-mtls-policy \ --source=server-mtls-policy.yaml --location=global
Crie a política de endpoint criando o arquivo temporário
ep-mtls-psms.yaml
:name: "ep-mtls-psms" type: "GRPC_SERVER" serverTlsPolicy: "projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy" trafficPortSelector: ports: - "50051" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: "MATCH_ALL" metadataLabels: - labelName: app labelValue: helloworld
Crie o recurso de política de endpoint importando o arquivo
ep-mtls-psms.yaml
:gcloud beta network-services endpoint-policies import ep-mtls-psms \ --source=ep-mtls-psms.yaml --location=global
Configurar o mTLS no lado do cliente
A política de segurança do lado do cliente está anexada ao serviço de back-end. Quando um cliente acessa um back-end (o servidor gRPC) pelo serviço de back-end, a política de segurança do lado do cliente anexada é enviada ao cliente.
Crie o conteúdo do recurso de política de TLS do cliente em um arquivo temporário chamado
client-mtls-policy.yaml
no diretório atual:name: "client-mtls-policy" clientCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
Crie o recurso de política de TLS do cliente chamado
client-mtls-policy
importando o arquivo temporárioclient-mtls-policy.yaml
:gcloud network-security client-tls-policies import client-mtls-policy \ --source=client-mtls-policy.yaml --location=global
Crie um snippet em um arquivo temporário para referenciar essa política e adicione detalhes para
subjectAltNames
na mensagemSecuritySettings
, como no exemplo a seguir. Substitua${PROJECT_ID}
pelo valor do ID do projeto, que é o valor da variável de ambiente${PROJECT_ID}
descrita anteriormente. Observe queexample-grpc-server
emsubjectAltNames
é o nome da conta de serviço do Kubernetes usado para o pod do servidor gRPC na especificação de implantação.if [ -z "$PROJECT_ID" ] ; then echo Please make sure PROJECT_ID is set. ; fi cat << EOF > client-security-settings.yaml securitySettings: clientTlsPolicy: projects/${PROJECT_ID}/locations/global/clientTlsPolicies/client-mtls-policy subjectAltNames: - "spiffe://${PROJECT_ID}.svc.id.goog/ns/default/sa/example-grpc-server" EOF
Adicione a mensagem
securitySettings
ao serviço de back-end que você já criou. Estas tapas exportam o conteúdo do serviço de back-end atual, adicionam a mensagemsecuritySetting
do cliente e reimportam o novo conteúdo para atualizar o serviço de back-end.gcloud compute backend-services export grpc-gke-helloworld-service --global \ --destination=/tmp/grpc-gke-helloworld-service.yaml cat /tmp/grpc-gke-helloworld-service.yaml client-security-settings.yaml \ >/tmp/grpc-gke-helloworld-service1.yaml gcloud compute backend-services import grpc-gke-helloworld-service --global \ --source=/tmp/grpc-gke-helloworld-service1.yaml -q
Verificar a configuração
A configuração do Cloud Service Mesh agora está concluída, incluindo a segurança do lado do servidor e do cliente. Em seguida, você irá preparar e executar as cargas de trabalho do servidor e do cliente. Isso conclui o exemplo.
Criar um cliente gRPC sem proxy
Esta etapa é semelhante à anterior, Como criar um serviço gRPC sem proxy.
Você usa o cliente helloworld
ativado por xDS no diretório de exemplo
xDS no repositório grpc-java
. Crie e execute o cliente em um contêiner
criado a partir de uma imagem openjdk:8-jdk
. A especificação do Kubernetes do cliente gRPC faz o
seguinte.
- Ele cria uma conta de serviço
example-grpc-client
do Kubernetes que é usada pelo pod do cliente gRPC. ${PROJNUM}
representa o número do seu projeto e precisa ser substituído pelo número real.
Adicione a seguinte anotação à especificação do pod:
annotations: security.cloud.google.com/use-workload-certificates: ""
Na criação, cada pod recebe um volume em /var/run/secrets/workload-spiffe-credentials
.
Este volume contém o seguinte:
private_key.pem
, uma chave privada gerada automaticamente.certificates.pem
, um pacote de certificados formatados em PEM que pode ser apresentado a outro pod como a cadeia de certificados do cliente ou usado como uma cadeia de certificados de servidor.ca_certificates.pem
, um pacote de certificados formatados em PEM para usar como âncoras de confiança ao validar a cadeia de certificados do cliente apresentado por outro pod ou a cadeia de certificados de servidor recebida ao se conectar a outro pod.
ca_certificates.pem
contém os certificados raiz do domínio
de confiança local para as cargas de trabalho, que é o pool de carga de trabalho do cluster.
O certificado de folha em certificates.pem
contém a seguinte declaração de identidade SPIFFE
de texto simples:
spiffe://WORKLOAD_POOL/ns/NAMESPACE/sa/KUBERNETES_SERVICE_ACCOUNT
Nesta declaração:
- WORKLOAD_POOL é o nome do pool de carga de trabalho do cluster.
- NAMESPACE é o nome da conta de serviço do Kubernetes.
- KUBERNETES_SERVICE_ACCOUNT é o namespace da conta de serviço do Kubernetes.
As instruções a seguir para sua linguagem criam a especificação a ser usada neste exemplo.
Java
Execute o seguinte comando para garantir que o número do projeto esteja definido corretamente:
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Crie a seguinte especificação:
cat << EOF > example-grpc-client.yaml apiVersion: v1 kind: ServiceAccount metadata: name: example-grpc-client namespace: default annotations: iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com --- apiVersion: apps/v1 kind: Deployment metadata: name: example-grpc-client namespace: default labels: k8s-app: example-grpc-client spec: replicas: 1 selector: matchLabels: k8s-app: example-grpc-client strategy: {} template: metadata: annotations: security.cloud.google.com/use-workload-certificates: "" labels: k8s-app: example-grpc-client spec: containers: - image: openjdk:8-jdk imagePullPolicy: IfNotPresent name: example-grpc-client command: - /bin/sleep - inf env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" resources: limits: cpu: 800m memory: 512Mi requests: cpu: 100m memory: 512Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - name: grpc-td-init image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: Always args: - --config-mesh-experimental - "grpc-mesh" - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ serviceAccountName: example-grpc-client volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
C++
Execute o seguinte comando para garantir que o número do projeto esteja definido corretamente:
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Crie a seguinte especificação:
cat << EOF > example-grpc-client.yaml apiVersion: v1 kind: ServiceAccount metadata: name: example-grpc-client namespace: default annotations: iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com --- apiVersion: apps/v1 kind: Deployment metadata: name: example-grpc-client namespace: default labels: k8s-app: example-grpc-client spec: replicas: 1 selector: matchLabels: k8s-app: example-grpc-client strategy: {} template: metadata: annotations: security.cloud.google.com/use-workload-certificates: "" labels: k8s-app: example-grpc-client spec: containers: - image: phusion/baseimage:18.04-1.0.0 imagePullPolicy: IfNotPresent name: example-grpc-client command: - /bin/sleep - inf env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" resources: limits: cpu: 8 memory: 8Gi requests: cpu: 300m memory: 512Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - name: grpc-td-init image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: Always args: - --config-mesh-experimental - "grpc-mesh" - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ serviceAccountName: example-grpc-client volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
Python
Execute o seguinte comando para garantir que o número do projeto esteja definido corretamente:
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Crie a seguinte especificação:
cat << EOF > example-grpc-client.yaml apiVersion: v1 kind: ServiceAccount metadata: name: example-grpc-client namespace: default annotations: iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com --- apiVersion: apps/v1 kind: Deployment metadata: name: example-grpc-client namespace: default labels: k8s-app: example-grpc-client spec: replicas: 1 selector: matchLabels: k8s-app: example-grpc-client strategy: {} template: metadata: annotations: security.cloud.google.com/use-workload-certificates: "" labels: k8s-app: example-grpc-client spec: containers: - image: phusion/baseimage:18.04-1.0.0 imagePullPolicy: IfNotPresent name: example-grpc-client command: - /bin/sleep - inf env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" resources: limits: cpu: 8 memory: 8Gi requests: cpu: 300m memory: 512Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - name: grpc-td-init image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: Always args: - --config-mesh-experimental - "grpc-mesh" - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ serviceAccountName: example-grpc-client volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
Go
Execute o seguinte comando para garantir que o número do projeto esteja definido corretamente:
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Crie a seguinte especificação:
cat << EOF > example-grpc-client.yaml apiVersion: v1 kind: ServiceAccount metadata: name: example-grpc-client namespace: default annotations: iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com --- apiVersion: apps/v1 kind: Deployment metadata: name: example-grpc-client namespace: default labels: k8s-app: example-grpc-client spec: replicas: 1 selector: matchLabels: k8s-app: example-grpc-client strategy: {} template: metadata: annotations: security.cloud.google.com/use-workload-certificates: "" labels: k8s-app: example-grpc-client spec: containers: - image: golang:1.16-alpine imagePullPolicy: IfNotPresent name: example-grpc-client command: - /bin/sleep - inf env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" resources: limits: cpu: 8 memory: 8Gi requests: cpu: 300m memory: 512Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - name: grpc-td-init image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: Always args: - --config-mesh-experimental - "grpc-mesh" - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ serviceAccountName: example-grpc-client volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
Conclua o processo da maneira a seguir.
Aplique a especificação:
kubectl apply -f example-grpc-client.yaml
Conceda os papéis necessários à conta de serviço:
gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/example-grpc-client]" \ ${PROJNUM}-compute@developer.gserviceaccount.com gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/example-grpc-client]" \ --role roles/trafficdirector.client
Verifique se o pod do cliente está em execução:
kubectl get pods
O comando retorna informações semelhantes às seguintes:
NAMESPACE NAME READY STATUS RESTARTS AGE default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 104s [..skip..]
Executar o servidor
Crie e execute o servidor helloworld
ativado por xDS no pod de servidor que você criou
anteriormente.
Java
Consiga o nome do pod criado para o serviço
example-grpc-server
:kubectl get pods | grep example-grpc-server
Você verá comentários como estes:
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
Abra um shell para o pod do servidor:
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
No shell, verifique se o arquivo de inicialização em
/tmp/grpc-xds/td-grpc-bootstrap.json
corresponde ao esquema descrito na seção Arquivo de inicialização.Faça o download do gRPC em Java versão 1.42.1 e crie o aplicativo do servidor
xds-hello-world
.curl -L https://github.com/grpc/grpc-java/archive/v1.42.1.tar.gz | tar -xz cd grpc-java-1.42.1/examples/example-xds ../gradlew --no-daemon installDist
Execute o servidor com a sinalização
--xds-creds
para indicar a segurança ativada por xDS, usando50051
como a porta de detecção exds-server
como o nome de identificação do servidor:./build/install/example-xds/bin/xds-hello-world-server --xds-creds 50051 xds-server
Depois que o servidor receber a configuração necessária do Cloud Service Mesh, você verá a seguinte saída:
Listening on port 50051 plain text health service listening on port 50052
C++
Consiga o nome do pod criado para o serviço
example-grpc-server
:kubectl get pods | grep example-grpc-server
Você verá comentários como estes:
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
Abra um shell para o pod do servidor:
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
No shell, verifique se o arquivo de inicialização em
/tmp/grpc-xds/td-grpc-bootstrap.json
corresponde ao esquema descrito na seção Arquivo de inicialização.Faça o download do gRPC em C++ e crie o aplicativo servidor
xds-hello-world
.apt-get update -y && \ apt-get install -y \ build-essential \ clang \ python3 \ python3-dev curl -L https://github.com/grpc/grpc/archive/master.tar.gz | tar -xz cd grpc-master tools/bazel build examples/cpp/helloworld:xds_greeter_server
Execute o servidor usando
50051
como a porta de detecção exds_greeter_server
como o nome de identificação do servidor:bazel-bin/examples/cpp/helloworld/xds_greeter_server --port=50051 --maintenance_port=50052 --secure
Para executar o servidor sem credenciais, especifique o seguinte:
bazel-bin/examples/cpp/helloworld/xds_greeter_server --nosecure
Depois que o servidor receber a configuração necessária do Cloud Service Mesh, você verá a seguinte saída:
Listening on port 50051 plain text health service listening on port 50052
Python
Consiga o nome do pod criado para o serviço
example-grpc-server
:kubectl get pods | grep example-grpc-server
Você verá comentários como estes:
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
Abra um shell para o pod do servidor:
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
No shell, verifique se o arquivo de inicialização em
/tmp/grpc-xds/td-grpc-bootstrap.json
corresponde ao esquema descrito na seção Arquivo de inicialização.Faça o download do gRPC em Python 1.41.0 e crie o aplicativo de exemplo.
apt-get update -y
apt-get install -y python3 python3-pip
curl -L https://github.com/grpc/grpc/archive/v1.41.x.tar.gz | tar -xz
cd grpc-1.41.x/examples/python/xds/
python3 -m virtualenv venv
source venv/bin/activate
python3 -m pip install -r requirements.txt
Execute o servidor com a sinalização
--xds-creds
para indicar a segurança ativada por xDS, usando50051
como porta de detecção.python3 server.py 50051 --xds-creds
Depois que o servidor receber a configuração necessária do Cloud Service Mesh, você verá a seguinte saída:
2021-05-06 16:10:34,042: INFO Running with xDS Server credentials 2021-05-06 16:10:34,043: INFO Greeter server listening on port 50051 2021-05-06 16:10:34,046: INFO Maintenance server listening on port 50052
Go
Consiga o nome do pod criado para o serviço
example-grpc-server
:kubectl get pods | grep example-grpc-server
Você verá comentários como estes:
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
Abra um shell para o pod do servidor:
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/sh
No shell, verifique se o arquivo de inicialização em
/tmp/grpc-xds/td-grpc-bootstrap.json
corresponde ao esquema descrito na seção Arquivo de inicialização.Faça o download do gRPC Go versão 1.41.0 e navegue até o diretório que contém o aplicativo do servidor
xds-hello-world
.apk add curl curl -L https://github.com/grpc/grpc-go/archive/v1.42.0.tar.gz | tar -xz cd grpc-go-1.42.0/examples/features/xds/server
Crie e execute o servidor com a sinalização
--xds_creds
para indicar a segurança ativada para xDS, usando50051
como a porta de detecção:GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY_LEVEL="info" \ go run main.go \ -xds_creds \ -port 50051
Depois que o servidor receber a configuração necessária do Cloud Service Mesh, você verá a seguinte saída:
Using xDS credentials... Serving GreeterService on 0.0.0.0:50051 and HealthService on 0.0.0.0:50052
O processo de verificação de integridade leva de três a cinco minutos para mostrar que o serviço está íntegro depois que o servidor é iniciado.
Execute o cliente e verifique a configuração
Crie e execute o cliente helloworld
ativado para xDS no pod cliente criado
anteriormente.
Java
Encontre o nome do pod do cliente:
kubectl get pods | grep example-grpc-client
Você verá comentários como este:
default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 105s
Abra um shell para o pod do cliente:
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
No shell de comando, faça o download do gRPC em Java versão 1.42.0 e crie o aplicativo cliente
xds-hello-world
.curl -L https://github.com/grpc/grpc-java/archive/v1.42.1.tar.gz | tar -xz cd grpc-java-1.42.1/examples/example-xds ../gradlew --no-daemon installDist
Execute o cliente com a sinalização
--xds-creds
para indicar a segurança ativada por xDS, o nome do cliente e a string de conexão de destino:./build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \ xds:///helloworld-gke:8000
A resposta será parecida com esta:
Greeting: Hello xds-client, from xds-server
C++
Encontre o nome do pod do cliente:
kubectl get pods | grep example-grpc-client
Você verá comentários como este:
default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 105s
Abra um shell para o pod do cliente:
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
Dentro do shell, faça o download do gRPC em C++ e crie o aplicativo cliente
xds-hello-world
.apt-get update -y && \ apt-get install -y \ build-essential \ clang \ python3 \ python3-dev
curl -L https://github.com/grpc/grpc/archive/master.tar.gz | tar -xz
cd grpc-master
tools/bazel build examples/cpp/helloworld:xds_greeter_client
Execute o cliente com a sinalização
--xds-creds
para indicar a segurança ativada por xDS, o nome do cliente e a string de conexão de destino:bazel-bin/examples/cpp/helloworld/xds_greeter_client --target=xds:///helloworld-gke:8000
Para executar o cliente sem credenciais, use o seguinte:
bazel-bin/examples/cpp/helloworld/xds_greeter_client --target=xds:///helloworld-gke:8000 --nosecure
A resposta será parecida com esta:
Greeter received: Hello world
Python
Encontre o nome do pod do cliente:
kubectl get pods | grep example-grpc-client
Você verá comentários como este:
default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 105s
Abra um shell para o pod do cliente:
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
Dentro do shell, faça o download do gRPC em Python versão 1.41.0 e crie o aplicativo cliente de exemplo.
apt-get update -y apt-get install -y python3 python3-pip python3 -m pip install virtualenv curl -L https://github.com/grpc/grpc/archive/v1.41.x.tar.gz | tar -xz cd grpc-1.41.x/examples/python/xds/ python3 -m virtualenv venv source venv/bin/activate python3 -m pip install -r requirements.txt
Execute o cliente com a sinalização
--xds-creds
para indicar a segurança ativada por xDS, o nome do cliente e a string de conexão de destino:python3 client.py xds:///helloworld-gke:8000 --xds-creds
A resposta será parecida com esta:
Greeter client received: Hello you from example-host!
Go
Encontre o nome do pod do cliente:
kubectl get pods | grep example-grpc-client
Você verá comentários como este:
default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 105s
Abra um shell para o pod do cliente:
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/sh
Depois de entrar no shell, faça o download do gRPC em Go versão 1.42.0 e navegue até o diretório que contém o aplicativo cliente
xds-hello-world
.apk add curl curl -L https://github.com/grpc/grpc-go/archive/v1.42.0.tar.gz | tar -xz cd grpc-go-1.42.0/examples/features/xds/client
Crie e execute o cliente com a flag
--xds_creds
para indicar a segurança ativada pelo xDS, o nome do cliente e a string de conexão de destino:GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY_LEVEL="info" \ go run main.go \ -xds_creds \ -name xds-client \ -target xds:///helloworld-gke:8000
A resposta será parecida com esta:
Greeting: Hello xds-client, from example-grpc-server-77548868d-l9hmf
Configurar o acesso no nível do serviço com uma política de autorização
O suporte para gRFC A41 é necessário para o suporte à política de autorização. Você pode encontrar as versões de linguagem necessárias no github (em inglês)
Use estas instruções para configurar o acesso no nível do serviço com políticas de autorização. Antes de criar políticas de autorização, leia com cuidado em Restringir o acesso usando autorização.
Para facilitar a verificação da configuração, crie outro nome de host
que o cliente possa usar para se referir ao serviço helloworld-gke
.
Atualize a especificação
GRPCRoute
armazenada anteriormente emgrpc_route.yaml
name: helloworld-grpc-route hostnames: - helloworld-gke:8000 - helloworld-gke-noaccess:8000 meshes: - projects/PROJECT_NUMBER/locations/global/meshes/grpc-mesh rules: - action: destinations: - serviceName: projects/PROJECT_NUMBER/locations/global/backendServices/grpc-gke-helloworld-service
Importe o recurso
GRPCRoute
novamente da especificaçãogrpc_route.yaml
.gcloud network-services grpc-routes import helloworld-grpc-route \ --source=grpc_route.yaml \ --location=global
Nas instruções a seguir, criamos uma política de autorização que permite solicitações
enviadas pela conta example-grpc-client
em que o nome do host é
helloworld-gke:8000
e a porta é 50051
.
gcloud
Crie uma política de autorização criando um arquivo chamado
helloworld-gke-authz-policy.yaml
.action: ALLOW name: helloworld-gke-authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/default/sa/example-grpc-client destinations: - hosts: - helloworld-gke:8000 ports: - 50051
Importe a política.
gcloud network-security authorization-policies import \ helloworld-gke-authz-policy \ --source=helloworld-gke-authz-policy.yaml \ --location=global
Atualize a política do endpoint para fazer referência à nova política de autorização anexando o seguinte ao arquivo
ep-mtls-psms.yaml
.authorizationPolicy: projects/${PROJECT_ID}/locations/global/authorizationPolicies/helloworld-gke-authz-policy
A política de endpoints agora especifica que o mTLS e a política de autorização precisam ser aplicados às solicitações de entrada para pods com arquivos de inicialização gRPC que contenham o rótulo
app:helloworld
.Importe a política:
gcloud network-services endpoint-policies import ep-mtls-psms \ --source=ep-mtls-psms.yaml --location=global
Validar a política de autorização
Use estas instruções para confirmar se a política de autorização está funcionando corretamente.
Java
Abra um shell para o pod do cliente usado anteriormente.
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
No shell de comando, execute os seguintes comandos para validar a configuração.
cd grpc-java-1.42.1/examples/example-xds ./build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \ xds:///helloworld-gke:8000
A resposta será parecida com esta:
Greeting: Hello xds-client, from xds-server
Execute o cliente novamente com o nome do servidor alternativo. Este é um caso de falha. A solicitação é inválida porque a política de autorização permite apenas acesso ao nome do host
helloworld-gke:8000
../build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \ xds:///helloworld-gke-noaccess:8000
A resposta será parecida com esta:
WARNING: RPC failed: Status{code=PERMISSION_DENIED}
Se essa saída não aparecer, talvez a política de autorização ainda não esteja em uso. Aguarde alguns minutos e tente todo o processo de verificação novamente.
Go
Abra um shell para o pod do cliente usado anteriormente.
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
No shell de comando, execute os seguintes comandos para validar a configuração.
cd grpc-go-1.42.0/examples/features/xds/client GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY_LEVEL="info" \ go run main.go \ -xds_creds \ -name xds-client \ -target xds:///helloworld-gke:8000
A resposta será parecida com esta:
Greeting: Hello xds-client, from example-grpc-server-77548868d-l9hmf
Execute o cliente novamente com o nome do servidor alternativo. Este é um caso de falha. A solicitação é inválida porque a política de autorização permite apenas acesso ao nome do host
helloworld-gke:8000
.GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY_LEVEL="info" \ go run main.go \ -xds_creds \ -name xds-client \ -target xds:///helloworld-gke-noaccess:8000
A resposta será parecida com esta:
could not greet: rpc error: code = PermissionDenied desc = Incoming RPC is not allowed: rpc error: code = PermissionDenied desc = incoming RPC did not match an allow policy exit status 1
Se essa saída não aparecer, talvez a política de autorização ainda não esteja em uso. Aguarde alguns minutos e tente todo o processo de verificação novamente.
Usar TLS em vez de mTLS
O uso de TLS neste exemplo requer apenas uma pequena mudança.
Na
ServerTlsPolicy
, descarte amtlsPolicy
:cat << EOF > server-tls-policy.yaml name: "server-tls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe EOF
Na
EndpointPolicy
, use esta política:cat << EOF > ep-tls-psms.yaml name: "ep-mtls-psms" type: "GRPC_SERVER" serverTlsPolicy: "projects/${PROJECT_ID}/locations/global/serverTlsPolicies/server-tls-policy" trafficPortSelector: ports: - "50051" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: "MATCH_ALL" metadataLabels: [] EOF
A
ClientTlsPolicy
para mTLS também funciona no caso TLS, mas a seçãoclientCertificate
da política pode ser descartada porque não é necessária para TLS:cat << EOF > client-tls-policy.yaml name: "client-tls-policy" serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe EOF
Usar a segurança do serviço com o exemplo da Google Wallet
Esta seção fornece uma visão geral de alto nível sobre como ativar o exemplo da Wallet com segurança de serviço para Java, C++ e Go.
Java
Você encontra o exemplo de código-fonte para Java no github (link em inglês).
O código já usa as credenciais XdsChannel
e XdsServer
quando você
configura a segurança sem proxy.
Estas instruções descrevem a configuração do exemplo da Wallet com o Go. O processo é semelhante para Java. Nas instruções, são usadas uma imagem Docker existente do repositório de contêineres do Google Cloud.
Para criar o exemplo, siga estas instruções:
- Clone o repositório e receba os arquivos no diretório Exemplos de gRPC.
- Edite o arquivo
00-common-env.sh
. Comente a linha atual que define o valor deWALLET_DOCKER_IMAGE
para a imagem do Go Docker e remova a marca de comentário da linha que define o valor deWALLET_DOCKER_IMAGE
como a imagem Java Docker. - Crie e configure instâncias do Cloud Router com as instruções
nesta página
ou usando a função
create_cloud_router_instances
no script10.apis.sh
. - Crie um cluster usando as instruções para o exemplo
hello world
ou a funçãocreate_cluster
no script20-cluster.sh
. - Crie autoridades certificadoras particulares usando as instruções para o
serviço de CA
ou usando o script
30-private-ca-setup.sh
. - Crie recursos do Kubernetes, incluindo contas de serviço, namespaces,
serviços do Kubernetes, NEGs e implantação do lado do servidor para todos os serviços:
account
,stats
,stats_premium
,wallet_v1
:wallet_v2
, usando o script40-k8s-resources.sh
. - Para cada serviço criado, crie uma verificação de integridade e um serviço de back-end
usando
create_health_check
ecreate_backend_service
no script50-td-components.sh
. - Crie os componentes de roteamento do Cloud Service Mesh usando
create_routing_components
no script60-routing-components.sh
. - Crie os componentes de segurança do Cloud Service Mesh para cada serviço de back-end
usando
create_security_components
no script70-security-components.sh
. - Crie a implantação do cliente da Google Wallet usando
create_client_deployment
no script75-client-deployment.sh
. - Verifique a configuração iniciando seu cliente conforme descrito em Verificar com clientes grpc-wallet.
C++
Você encontra o exemplo de código-fonte para C++ no github (link em inglês). O código já usa as credenciais
XdsChannel
e XdsServer
ao configurar a segurança sem proxy.
Estas instruções descrevem a configuração do exemplo da Wallet com o Go. O processo é semelhante para C++. Nas instruções, são usadas uma imagem Docker existente do repositório de contêineres do Google Cloud.
Para criar o exemplo, siga estas instruções:
- Clone o repositório e receba os arquivos no diretório Exemplos de gRPC.
- Edite o arquivo
00-common-env.sh
. Transforme em comentário a linha atual que define o valor deWALLET_DOCKER_IMAGE
como a imagem do Go Docker e remova a marca de comentário da linha que define o valor deWALLET_DOCKER_IMAGE
como a imagem do Docker C++. - Crie e configure instâncias do Cloud Router com as instruções
nesta página
ou usando a função
create_cloud_router_instances
no script10.apis.sh
. - Crie um cluster usando as instruções para o exemplo
hello world
ou a funçãocreate_cluster
no script20-cluster.sh
. - Crie autoridades certificadoras particulares usando as instruções para o serviço de AC
ou o script
30-private-ca-setup.sh
. - Crie recursos do Kubernetes, incluindo contas de serviço, namespaces,
serviços do Kubernetes, NEGs e implantação do lado do servidor para todos os serviços:
account
,stats
,stats_premium
,wallet_v1
:wallet_v2
, usando o script40-k8s-resources.sh
. - Para cada serviço criado, crie uma verificação de integridade e um serviço de back-end
usando
create_health_check
ecreate_backend_service
no script50-td-components.sh
. - Crie os componentes de roteamento do Cloud Service Mesh usando
create_routing_components
no script60-routing-components.sh
. - Crie os componentes de segurança do Cloud Service Mesh para cada serviço de back-end
usando
create_security_components
no script70-security-components.sh
. - Crie a implantação do cliente da Google Wallet usando
create_client_deployment
no script75-client-deployment.sh
. - Verifique a configuração iniciando seu cliente conforme descrito em Verificar com clientes grpc-wallet.
Go
Você pode encontrar um código-fonte de exemplo para Go no github. O código já usa as credenciais
XdsChannel
e XdsServer
ao configurar a segurança sem proxy.
Nas instruções, são usadas uma imagem Docker existente do repositório de contêineres do Google Cloud.
Para criar o exemplo, siga estas instruções:
- Clone o repositório e receba os arquivos no diretório Exemplos de gRPC.
- Edite o arquivo
00-common-env.sh
para definir os valores corretos para as variáveis de ambiente. - Crie e configure instâncias do Cloud Router com as instruções
nesta página
ou usando a função
create_cloud_router_instances
no script10.apis.sh
. - Crie um cluster usando as instruções para o exemplo
hello world
ou a funçãocreate_cluster
no script20-cluster.sh
. - Crie autoridades certificadoras particulares usando as instruções para o
serviço de CA
ou usando o script
30-private-ca-setup.sh
. - Crie recursos do Kubernetes, incluindo contas de serviço, namespaces,
serviços do Kubernetes, NEGs e implantação do lado do servidor para todos os serviços:
account
,stats
,stats_premium
,wallet_v1
:wallet_v2
, usando o script40-k8s-resources.sh
. - Para cada serviço criado, crie uma verificação de integridade e um serviço de back-end
usando
create_health_check
ecreate_backend_service
no script50-td-components.sh
. - Crie os componentes de roteamento do Cloud Service Mesh usando
create_routing_components
no script60-routing-components.sh
. - Crie os componentes de segurança do Cloud Service Mesh para cada serviço de back-end
usando
create_security_components
no script70-security-components.sh
. - Crie a implantação do cliente da Google Wallet usando
create_client_deployment
no script75-client-deployment.sh
. - Verifique a configuração iniciando seu cliente conforme descrito em Verificar com clientes grpc-wallet.
Arquivo de inicialização
O processo de configuração neste guia usa um gerador de inicialização para criar o arquivo de inicialização necessário. Nesta seção, fornecemos informações de referência sobre o próprio arquivo de inicialização.
O arquivo de inicialização contém informações de configuração exigidas pelo código gRPC sem proxy, incluindo informações de conexão do servidor xDS. O arquivo de inicialização contém a configuração de segurança exigida pelo recurso de segurança gRPC sem proxy. O servidor gRPC requer um campo adicional. Esta é uma amostra de arquivo de inicialização:
{ "xds_servers": [ { "server_uri": "trafficdirector.googleapis.com:443", "channel_creds": [ { "type": "google_default" } ], "server_features": [ "xds_v3" ] } ], "authorities": { "traffic-director-c2p.xds.googleapis.com": { "xds_servers": [ { "server_uri": "dns:///directpath-pa.googleapis.com", "channel_creds": [ { "type": "google_default" } ], "server_features": [ "xds_v3", "ignore_resource_deletion" ] } ], "client_listener_resource_name_template": "xdstp://traffic-director-c2p.xds.googleapis.com/envoy.config.listener.v3.Listener/%s" } }, "node": { "id": "projects/9876012345/networks/mesh:grpc-mesh/nodes/b59f49cc-d95a-4462-9126-112f794d5dd3", "cluster": "cluster", "metadata": { "INSTANCE_IP": "10.28.2.8", "TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE": true, "TRAFFICDIRECTOR_GCP_PROJECT_NUMBER": "223606568246", "TRAFFICDIRECTOR_NETWORK_NAME": "default", "app": "helloworld" }, "locality": { "zone": "us-central1-c" } }, "certificate_providers": { "google_cloud_private_spiffe": { "plugin_name": "file_watcher", "config": { "certificate_file": "/var/run/secrets/workload-spiffe-credentials/certificates.pem", "private_key_file": "/var/run/secrets/workload-spiffe-credentials/private_key.pem", "ca_certificate_file": "/var/run/secrets/workload-spiffe-credentials/ca_certificates.pem", "refresh_interval": "600s" } } }, "server_listener_resource_name_template": "grpc/server?xds.resource.listening_address=%s" }
Atualizações no arquivo de inicialização do serviço de segurança
Os campos a seguir refletem as modificações relacionadas à segurança e ao uso do xDS v3:
O campo id
dentro do node
fornece uma identidade exclusiva do cliente gRPC para
o Cloud Service Mesh. É necessário fornecer o número do projeto do Google Cloud e
o nome da rede usando o ID do nó neste formato:
projects/{project number}/networks/{network name}/nodes/[UNIQUE_ID]
Este é um exemplo do projeto número 1234 e da rede padrão:
projects/1234/networks/default/nodes/client1
O campo INSTANCE_IP
é o endereço IP do pod ou 0.0.0.0
para indicar
INADDR_ANY
. Esse campo é usado pelo servidor gRPC para buscar o recurso
Listener do Cloud Service Mesh para segurança no lado do servidor.
Campos de configuração de segurança no arquivo de inicialização
Chave JSON | Tipo | Valor | Observações |
---|---|---|---|
server_listener_resource_name_template |
String | grpc/server?xds.resource.listening_address=%s |
Obrigatório para servidores gRPC. O gRPC usa esse valor para compor o nome do recurso para buscar o recurso "Listener" do Cloud Service Mesh para segurança do servidor e outras configurações. O gRPC o usa para formar a string do nome do recurso |
certificate_providers |
Estrutura JSON | google_cloud_private_spiffe |
Obrigatório. O valor é uma estrutura JSON que representa um mapa de nomes para instâncias de provedor de certificado. Uma instância de provedor de certificado é usada para buscar certificados raiz e identidade. O exemplo do arquivo de inicialização contém um nome: google_cloud_private_spiffe com a estrutura JSON da instância do provedor de certificados como o valor. Cada estrutura JSON de instância do provedor de certificado tem dois campos:
|
O conteúdo da estrutura JSON config
para o plug-in file_watcher
é:
certificate_file
: string obrigatória. Esse valor é o local do certificado de identidade.private_key_file
: string obrigatória. O valor é o local do arquivo de chave privada, que deve corresponder ao certificado de identidade.ca_certificate_file
: string obrigatória. O valor é o local do certificado raiz, também conhecido como o pacote de confiança.refresh_interval
: string opcional. O valor indica o intervalo de atualização, especificado usando a representação de string do mapeamento JSON de uma duração. O valor padrão é "600s", uma duração de 10 minutos.
Gerador de inicialização
A imagem de contêiner do gerador de inicialização está disponível em
gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
. O código-fonte está
disponível em https://github.com/GoogleCloudPlatform/traffic-director-grpc-bootstrap
.
As opções de linha de comando mais usadas são estas:
--output
: use esta opção para especificar o local de gravação do arquivo de inicialização de saída. Por exemplo, o comando--output /tmp/bootstrap/td-grpc-bootstrap.json
gera o arquivo de inicialização para/tmp/bootstrap/td-grpc-bootstrap.json
no sistema de arquivo do pod.--config-mesh-experimental
: use essa opção para especificar o nome da malha correspondente ao recursoMesh
.--node-metadata
: use esta sinalização para preencher os metadados do nó no arquivo de inicialização. Isso é necessário quando você usa correspondentes de rótulo de metadados noEndpointPolicy
, em que o Cloud Service Mesh usa os dados de rótulo fornecidos na seção de metadados do nó do arquivo de inicialização. O argumento é fornecido no formato key=value, por exemplo:--node-metadata version=prod --node-metadata type=grpc
As informações anteriores adicionam o seguinte à seção de metadados do nó do arquivo de inicialização:
{ "node": { ... "metadata": { "version": "prod", "type": "grpc", ... }, ... }, ... }
Excluir a implantação
Como opção, é possível executar esses comandos para excluir a implantação criada usando este guia.
Para excluir o cluster, execute este comando:
gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet
Para excluir os recursos criados, execute estes comandos:
gcloud compute backend-services delete grpc-gke-helloworld-service --global --quiet gcloud compute network-endpoint-groups delete example-grpc-server --zone ZONE --quiet gcloud compute firewall-rules delete grpc-gke-allow-health-checks --quiet gcloud compute health-checks delete grpc-gke-helloworld-hc --quiet gcloud network-services endpoint-policies delete ep-mtls-psms \ --location=global --quiet gcloud network-security authorization-policies delete helloworld-gke-authz-policy \ --location=global --quiet gcloud network-security client-tls-policies delete client-mtls-policy \ --location=global --quiet gcloud network-security server-tls-policies delete server-tls-policy \ --location=global --quiet gcloud network-security server-tls-policies delete server-mtls-policy \ --location=global --quiet
Solução de problemas
Use estas instruções para ajudar você a resolver problemas com a implantação da segurança.
Não é possível configurar as cargas de trabalho no Cloud Service Mesh
Se você vir um erro semelhante a este:
PERMISSION_DENIED: Request had insufficient authentication scopes.
Certifique-se disto:
- Ter criado o cluster do GKE com o argumento
--scopes=cloud-platform
. - Ter atribuído
roles/trafficdirector.client
às contas de serviço do Kubernetes. - Você atribuiu o
roles/trafficdirector.client
à sua conta de serviço padrão do Google Cloud (${GSA_EMAIL} acima). - Ter ativado o serviço
trafficdirector.googleapis.com
(API).
Seu servidor gRPC não usa TLS/mTLS mesmo com a configuração correta do Cloud Service Mesh
Especifique GRPC_SERVER
na configuração das políticas de endpoint. Se
você especificou SIDECAR_PROXY
, o gRPC ignorará a configuração.
Não é possível criar o cluster do GKE com a versão solicitada
O comando de criação do cluster do GKE pode falhar e apresentar um erro como este:
Node version "1.20.5-gke.2000" is unsupported.
Verifique se você está usando o argumento --release-channel rapid
no
comando de criação do cluster. Você precisa usar o canal de lançamento rápido para conseguir
a versão correta para este lançamento.
Você verá um erro No usable endpoint
Se um cliente não conseguir se comunicar com o servidor devido a um erro
No usable endpoint
, talvez o verificador de integridade tenha marcado os back-ends do servidor como não íntegros.
Para verificar a integridade dos back-ends, execute este comando gcloud
:
gcloud compute backend-services get-health grpc-gke-helloworld-service --global
Se o comando retornar o status de back-end não íntegro, pode ser por um destes motivos:
- O firewall não foi criado ou não contém o intervalo de IP de origem correto.
- As tags de destino no firewall não correspondem às tags no cluster que você criou.
As cargas de trabalho não conseguem se comunicar na configuração de segurança
Se as cargas de trabalho não conseguirem se comunicar depois que você configurar a segurança da malha de serviço sem proxy, siga estas instruções para determinar a causa.
- Desative a segurança sem proxy e elimine problemas nos casos de uso do balanceamento de carga
da malha de serviço sem proxy. Para desativar a segurança na malha, siga um
destes procedimentos:
- Use credenciais de texto simples no lado do cliente e do servidor OU
- não configure a segurança do serviço de back-end e da política de endpoint na configuração do Cloud Service Mesh.
Siga as etapas em Como solucionar problemas de implantações sem proxy do Cloud Service Mesh, porque não há configuração de segurança na sua implantação.
Modifique suas cargas de trabalho para usar credenciais xDS com texto simples ou credenciais não seguras como as credenciais de fallback. Mantenha a configuração do Cloud Service Mesh com a segurança desativada, conforme discutido anteriormente. Nesse caso, embora o gRPC permita que o Cloud Service Mesh configure a segurança, o Cloud Service Mesh não envia informações de segurança. Nesse caso, o gRPC precisa retornar a credenciais de texto simples (ou não seguras) que funcionarão como no primeiro caso acima. Se isso não funcionar, faça o seguinte:
- Aumente o nível de geração de registros no cliente e no servidor para ver as mensagens xDS trocadas entre o gRPC e o Cloud Service Mesh.
- Verifique se o Cloud Service Mesh não tem a segurança ativada nas respostas de CDS e LDS enviadas para as cargas de trabalho.
- Verifique se as cargas de trabalho não estão usando os modos TLS ou mTLS nos canais. Se você notar mensagens de registro relacionadas a handshakes de TLS, verifique o código-fonte do aplicativo e confirme se você está usando texto simples ou não seguro como credenciais de fallback. Se o código-fonte do aplicativo estiver correto, talvez seja um bug na biblioteca do gRPC
Verifique se a integração do serviço de CA com o GKE está funcionando corretamente para o cluster do GKE seguindo as etapas de solução de problemas desse guia do usuário. Verifique se os certificados e chaves fornecidos por esse recurso estão disponíveis no diretório especificado,
/var/run/secrets/workload-spiffe-credentials/
.Ative o TLS (em vez do mTLS) na malha, conforme descrito anteriormente, e reinicie as cargas de trabalho de cliente e do servidor.
- Aumente o nível de geração de registros no cliente e no servidor para ver as mensagens xDS trocadas entre o gRPC e o Cloud Service Mesh.
- Verifique se o Cloud Service Mesh está com a segurança ativada nas respostas de CDS e LDS enviadas para as cargas de trabalho.
O cliente falha com uma CertificateException
e uma mensagem Peer certificate SAN check failed
Isso indica um problema com os valores subjectAltNames
na
mensagem SecuritySettings
. Observe que esses valores são baseados nos serviços
do Kubernetes criados para seu serviço de back-end. Para cada serviço do Kubernetes
criado por você, há um ID de SPIFFE associado neste formato:
spiffe://${WORKLOAD_POOL}/ns/${K8S_NAMESPACE}/sa/${SERVICE_ACCOUNT}
Esses valores são:
WORKLOAD_POOL
: o pool da carga de trabalho do cluster, que é${PROJECT_ID}.svc.id.goog
K8S_NAMESPACE
: o namespace do Kubernetes usado na implantação do serviçoSERVICE_ACCOUNT
: a conta de serviço do Kubernetes usada na implantação do serviço
Verifique se você calculou corretamente o ID do SPIFFE e o adicionou
ao campo subjectAltNames
na mensagem SecuritySettings
para todos os serviços do Kubernetes anexados ao serviço de back-end como um grupo de endpoints
de rede.
Os aplicativos não podem usar os certificados mTLS com a biblioteca gRPC
Se os aplicativos não puderem usar os certificados mTLS com a biblioteca do gRPC, faça o seguinte:
Verifique se a especificação do pod contém a anotação
security.cloud.google.com/use-workload-certificates
descrita em Como criar um serviço gRPC sem proxy com NEGs.Verifique se os arquivos que contêm a cadeia de certificados e o certificado de folha, a chave privada e os certificados de CA confiáveis são acessíveis nos seguintes caminhos de dentro pod:
- Cadeia de certificados e certificado de folha: "/var/run/secrets/workload-spiffe-credentials/certificates.pem"
- Chave privada: "/var/run/secrets/workload-spiffe-credentials/private_key.pem"
- Pacote de CA: "/var/run/secrets/workload-spiffe-credentials/ca_certificates.pem"
Se os certificados da etapa anterior não estiverem disponíveis, faça o seguinte:
gcloud privateca subordinates describe SUBORDINATE_CA_POOL_NAME
--location=LOCATIONVerifique se o plano de controle do GKE tem a vinculação correta de papel do IAM, concedendo acesso ao CA.
# Get the IAM policy for the CA gcloud privateca roots get-iam-policy ROOT_CA_POOL_NAME # Verify that there is an IAM binding granting access in the following format - members: - serviceAccount:service-projnumber@container-engine-robot.iam.gserviceaccount.com role: roles/privateca.certificateManager # Where projnumber is the project number (e.g. 2915810291) for the GKE cluster.
Verifique se o certificado não expirou. Esta é a cadeia de certificados e o certificado de folha em
/var/run/secrets/workload-spiffe-credentials/certificates.pem
. Para verificar, execute este comando:cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
Execute este comando para verificar se o tipo de chave é compatível com o aplicativo:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
Verifique se o aplicativo gRPC em Java tem o seguinte
keyAlgorithm
no arquivo YAMLWorkloadCertificateConfig
:
keyAlgorithm: rsa: modulusSize: 4096
Verifique se a CA usa a mesma família de chaves que a chave de certificado.
O certificado de um aplicativo é rejeitado pelo cliente, servidor ou peering
- Verifique se o aplicativo de peering usa o mesmo pacote de confiança para verificar o certificado.
- Verifique se o certificado sendo usado não expirou (cadeia de certificados com o certificado de folha: "/var/run/secrets/workload-spiffe-credentials/certificates.pem").
Os pods permanecem em um estado pendente
Se os pods permanecerem em estado pendente durante o processo de configuração, aumente os recursos de CPU e memória para os pods na especificação de implantação.
Não foi possível criar um cluster com a sinalização --enable-mesh-certificates
Verifique se você está executando a versão mais recente da CLI gcloud:
gcloud components update
A sinalização --enable-mesh-certificates
funciona apenas com gcloud beta
.
Os pods não são iniciados
Os pods que usam certificados de malha do GKE poderão falhar ao iniciar se o provisionamento de certificados estiver falhando. Isso pode acontecer quando:
- A
WorkloadCertificateConfig
ouTrustConfig
estiver configurada incorretamente ou ausente. - As CSRs não forem aprovadas.
Verifique se o provisionamento de certificados está falhando verificando os eventos do pod.
Verifique o status do pod:
kubectl get pod -n POD_NAMESPACE POD_NAME
Substitua:
POD_NAMESPACE
: o namespace do pod.POD_NAME
: o nome do pod.
Verifique os eventos recentes do pod:
kubectl describe pod -n POD_NAMESPACE POD_NAME
Se o provisionamento de certificados estiver falhando, você verá um evento com
Type=Warning
,Reason=FailedMount
,From=kubelet
e um campoMessage
que começa comMountVolume.SetUp failed for volume "gke-workload-certificates"
. O campoMessage
contém informações de solução de problemas.Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedMount 13s (x7 over 46s) kubelet MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)
Veja as etapas de solução de problemas a seguir se o pod não iniciar por causa de objetos configurados incorretamente ou devido a CSRs recusadas.
WorkloadCertificateConfig
ou TrustConfig
está configurada incorretamente
Verifique se você criou os objetos WorkloadCertificateConfig
e TrustConfig
corretamente. É possível diagnosticar configurações incorretas em um desses
objetos usando kubectl
.
Recupere o status atual.
Para obter
WorkloadCertificateConfig
:kubectl get WorkloadCertificateConfig default -o yaml
Para obter
TrustConfig
:kubectl get TrustConfig default -o yaml
Inspecione a saída do status. Um objeto válido terá uma condição com
type: Ready
estatus: "True"
.status: conditions: - lastTransitionTime: "2021-03-04T22:24:11Z" message: WorkloadCertificateConfig is ready observedGeneration: 1 reason: ConfigReady status: "True" type: Ready
Para objetos inválidos,
status: "False"
será exibido. Os camposreason
emessage
apresentam mais detalhes sobre a solução de problemas.
As CSRs não foram aprovadas
Se algo der errado durante o processo de aprovação da CSR, verifique os detalhes
do erro nas condições type: Approved
e type: Issued
da CSR.
Liste CSRs relevantes usando
kubectl
:kubectl get csr \ --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
Escolha uma CSR que seja
Approved
e nãoIssued
ou que não sejaApproved
.Veja detalhes sobre a CSR selecionada usando o kubectl:
kubectl get csr CSR_NAME -o yaml
Substitua
CSR_NAME
pelo nome da CSR escolhida.
Uma CSR válida tem uma condição com type: Approved
e status: "True"
e um
certificado válido no campo status.certificate
:
status:
certificate: <base64-encoded data>
conditions:
- lastTransitionTime: "2021-03-04T21:58:46Z"
lastUpdateTime: "2021-03-04T21:58:46Z"
message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
reason: AutoApproved
status: "True"
type: Approved
As informações sobre solução de problemas para CSRs inválidos aparecem nos campos message
e
reason
.
Os pods estão sem certificado
Veja a especificação do pod:
kubectl get pod -n POD_NAMESPACE POD_NAME -o yaml
Substitua:
POD_NAMESPACE
: o namespace do pod.POD_NAME
: o nome do pod.
Verifique se a especificação do pod contém a anotação
security.cloud.google.com/use-workload-certificates
descrita em Configurar pods para receber credenciais mTLS.Verifique se o controlador de admissão de certificados de malha do GKE injetou com sucesso um volume de driver CSI do tipo
workloadcertificates.security.cloud.google.com
na especificação do pod:volumes: ... -csi: driver: workloadcertificates.security.cloud.google.com name: gke-workload-certificates ...
Verifique se todos os contêineres apresentam uma ativação de volume.
containers: - name: ... ... volumeMounts: - mountPath: /var/run/secrets/workload-spiffe-credentials name: gke-workload-certificates readOnly: true ...
Verifique se os seguintes pacotes de certificados e a chave privada estão disponíveis nos seguintes locais no pod:
- Pacote da cadeia de certificados:
/var/run/secrets/workload-spiffe-credentials/certificates.pem
- Chave privada:
/var/run/secrets/workload-spiffe-credentials/private_key.pem
- Pacote de âncoras de confiança da CA:
/var/run/secrets/workload-spiffe-credentials/ca_certificates.pem
- Pacote da cadeia de certificados:
Se os arquivos não estiverem disponíveis, siga estas etapas:
Recupere a instância do serviço da CA (Visualização) para o cluster:
kubectl get workloadcertificateconfigs default -o jsonpath '{.spec.certificateAuthorityConfig.certificateAuthorityServiceConfig.endpointURI}'
Recupere o status da instância do serviço da CA (Visualização):
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATION
Substitua:
ISSUING_CA_TYPE
: o tipo de CA emissora, que precisa sersubordinates
ouroots
.ISSUING_CA_NAME
: o nome da CA emissora.ISSUING_CA_LOCATION
: a região da CA emissora.
Consiga a política do IAM para a CA raiz:
gcloud privateca roots get-iam-policy ROOT_CA_NAME
Substitua
ROOT_CA_NAME
pelo nome da CA raiz.Na política do IAM, verifique se a vinculação de política
privateca.auditor
existe:... - members: - serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com role: roles/privateca.auditor ...
Neste exemplo,
PROJECT_NUMBER
é o número do projeto do cluster.Consiga a política do IAM para a CA subordinada:
gcloud privateca subordinates get-iam-policy SUBORDINATE_CA_NAME
Substitua
SUBORDINATE_CA_NAME
pelo nome da CA subordinada.Na política do IAM, verifique se a vinculação de política
privateca.certificateManager
existe:... - members: - serviceAccount: service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com role: roles/privateca.certificateManager ...
Neste exemplo,
PROJECT_NUMBER
é o número do projeto do cluster.
Os aplicativos não podem usar as credenciais mTLS emitidas
Verifique se o certificado expirou:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
Verifique se o tipo de chave que você usou é compatível com o aplicativo.
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
Verifique se a CA emissora usa a mesma família de chaves que a chave de certificado.
Veja o status da instância do serviço de CA (Visualização):
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATION
Substitua:
ISSUING_CA_TYPE
: o tipo de CA emissora, que precisa sersubordinates
ouroots
.ISSUING_CA_NAME
: o nome da CA emissora.ISSUING_CA_LOCATION
: a região da CA emissora.
Verifique se o
keySpec.algorithm
na saída é o mesmo algoritmo de chave definido no manifesto YAMLWorkloadCertificateConfig
. A saída é assim:config: ... subjectConfig: commonName: td-sub-ca subject: organization: TestOrgLLC subjectAltName: {} createTime: '2021-05-04T05:37:58.329293525Z' issuingOptions: includeCaCertUrl: true keySpec: algorithm: RSA_PKCS1_2048_SHA256 ...
Os certificados são recusados
- Verifique se o aplicativo de peering usa o mesmo pacote de confiança para verificar o certificado.
Verifique se o certificado expirou:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
Verifique se o código do cliente, se não estiver usando a API Reload Credentials do gRPC Go, atualiza periodicamente as credenciais do sistema de arquivos.
Verifique se as cargas de trabalho estão no mesmo domínio de confiança que a CA. Os certificados de malha do GKE suportam a comunicação entre as cargas de trabalho em um único domínio de confiança.
Limitações
A segurança do serviço do Cloud Service Mesh é compatível apenas com o GKE. Não é possível implantar a segurança do serviço com o Compute Engine.
O Cloud Service Mesh não é compatível com cenários em que há dois ou mais recursos de política de endpoints que correspondem igualmente a um endpoint, por exemplo, duas políticas com os mesmos rótulos e portas ou duas ou mais políticas com rótulos diferentes que correspondem igualmente aos rótulos de um endpoint. Para mais informações sobre como as políticas de endpoint são correspondidas aos rótulos de um endpoint, consulte as APIs para EndpointPolicy.EndpointMatcher.MetadataLabelMatcher. Nessas situações, o Cloud Service Mesh não gera configurações de segurança de nenhuma das políticas conflitantes.