Multilocação entre projetos do Cloud Run para Anthos no Google Cloud

Neste guia, você aprende a configurar o Cloud Run para Anthos no Google Cloud para permitir que um ou mais projetos do Google Cloud executem e gerenciem as cargas de trabalho em execução em um cluster do Google Kubernetes Engine em um projeto diferente do Cloud.

Um modelo operacional comum com o Cloud Run para Anthos no Google Cloud é para que uma equipe de desenvolvedores de aplicativos use o projeto do Cloud para implantar e gerenciar serviços que estão sendo executados em diferentes clusters do Google Kubernetes Engine em projetos do Google Cloud de outras equipes. Esse recurso, chamado multilocação, permite que você, como operador da plataforma, adapte suas equipes de desenvolvimento somente aos serviços em execução nos diversos ambientes da sua organização (por exemplo, produção e preparação).

O Cloud Run para Anthos no Google Cloud é compatível especificamente com a multilocação empresarial. Esse tipo de multilocação ativa um projeto de cluster do Cloud para permitir o acesso a recursos específicos do cluster do Google Kubernetes Engine. O projeto do Cloud que tem acesso ao respectivo projeto de cluster é o projeto de locatário do Cloud. Os locatários do projeto de cluster do Cloud podem usar o Cloud Run para Anthos no Google Cloud para acessar, operar e ser proprietários desses serviços e recursos a que eles têm acesso.

Conceitualmente, há quatro etapas para configurar a multilocação empresarial com o Cloud Run para Anthos no Google Cloud:

  1. Configurar o acesso do locatário ao projeto de cluster do Cloud usando um Grupo do Google e o gerenciamento de identidade e acesso.
  2. Mapear cada projeto de locatário do Cloud para o respectivo projeto de cluster.
  3. Encaminhar os dados de registro do projeto de cluster do Cloud para os projetos do Cloud do locatário usando coletores e buckets de registro.
  4. Definir as permissões de cluster para locatários usando o controle de acesso baseado em papéis no GKE.

Antes de começar

O operador da plataforma responsável pela configuração da multilocação precisa entender e atender aos requisitos a seguir:

Defina as variáveis de ambiente locais

Para simplificar os comandos usados neste processo, defina variáveis de ambiente locais para o projeto de cluster do Cloud e o projeto de locatário do Cloud:

  1. Substitua YOUR_CLUSTER_PROJECT_ID pelo ID do projeto de cluster do Cloud e execute o comando a seguir:

    export CLUSTER_PROJECT_ID=YOUR_CLUSTER_PROJECT_ID
    
  2. Substitua YOUR_TENANT_PROJECT_ID pelo ID do projeto de locatário do Cloud e execute o comando a seguir:

    export TENANT_PROJECT_ID=$YOUR_TENANT_PROJECT_ID
    
  3. Verifique as variáveis de ambiente locais executando os comandos a seguir:

    echo "cluster Cloud project is:" $CLUSTER_PROJECT_ID
    echo "tenant Cloud project is:" $TENANT_PROJECT_ID
    

Os IDs dos projetos do Cloud do cluster e do locatário agora podem ser usados em todos os comandos a seguir, em que $CLUSTER_PROJECT_ID e $TENANT_PROJECT_ID são especificados.

Verificação das permissões do IAM

Execute os comandos testIamPermissions a seguir para confirmar que você tem as permissões necessárias do IAM para acessar os recursos no projeto de cluster do Cloud e nos projetos do Cloud do locatário.

Execute o comando a seguir para validar suas permissões no projeto de cluster do Cloud:

curl -X POST \
  -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
  --header "Content-Type: application/json" \
  --data '{"permissions":["logging.sinks.create", "logging.sinks.get", "resourcemanager.projects.setIamPolicy"]}' \
  https://cloudresourcemanager.googleapis.com/v1/projects/$CLUSTER_PROJECT_ID:testIamPermissions

Resultados esperados para o projeto de cluster do Cloud:

{
  "permissions": [
    "logging.sinks.create",
    "logging.sinks.get",
    "resourcemanager.projects.setIamPolicy"
  ]
}

Execute o comando a seguir para validar suas permissões em cada projeto de locatário do Cloud:

curl -X POST \
  -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
  --header "Content-Type: application/json" \
  --data '{"permissions":["logging.buckets.create", "logging.buckets.get", "resourcemanager.projects.setIamPolicy", "resourcesettings.settingvalues.create", "serviceusage.services.enable"]}' \
  https://cloudresourcemanager.googleapis.com/v1/projects/$TENANT_PROJECT_ID:testIamPermissions

Resultados esperados para cada projeto de locatário do Cloud:

{
  "permissions": [
    "logging.buckets.create",
    "logging.buckets.get",
    "resourcemanager.projects.setIamPolicy",
    "resourcesettings.settingvalues.create",
    "serviceusage.services.enable",
  ]
}

Usar um Grupo do Google e o gerenciamento de identidade e acesso para configurar o acesso do locatário

Usar um Grupo do Google para permitir que os locatários acessem o cluster do GKE. Com as permissões do IAM, os locatários podem acessar as credenciais, mas não podem fazer nada no cluster até que o controle de acesso baseado em papéis do Kubernetes seja configurado em uma etapa posterior.

Você precisa criar um Grupo do Google com todos os usuários do projeto de locatário do Cloud. Para mais informações sobre como usar um grupo de segurança, consulte Como usar Grupos do Google para o GKE.

Crie a seguinte variável de ambiente local para seu Grupo do Google:

export SECURITY_GROUP=gke-security-groups@company.com

Leitor de cluster do Kubernetes

Execute os comandos a seguir para permitir que os locatários consigam credenciais no cluster. Isso não permite que eles leiam ou manipulem recursos no cluster do GKE.

Referência do IAM

gcloud projects add-iam-policy-binding $CLUSTER_PROJECT_ID \
   --member=group:$SECURITY_GROUP \
   --role='roles/container.clusterViewer' \
   --condition=None

Para restringir o acesso a um cluster específico, use uma condição do IAM.

gcloud projects add-iam-policy-binding $CLUSTER_PROJECT_ID \
   --member=group:$SECURITY_GROUP \
   --role='roles/container.clusterViewer' \
   --condition="expression=resource.name == 'cluster-name',title=Restrict cluster access"

Leitor do Monitoring

Execute o comando a seguir para permitir que os locatários leiam as métricas de monitoramento.

Referência dos papéis de monitoramento

gcloud projects add-iam-policy-binding $CLUSTER_PROJECT_ID \
   --member=group:$SECURITY_GROUP \
   --role='roles/monitoring.viewer' \
   --condition=None

Como mapear cada projeto de locatário do Cloud para o respectivo projeto de cluster

Use valores de configuração de recursos para mapear projetos do Cloud do locatário para um projeto de cluster do Cloud.

A configuração de recursos pode ser definida para cada projeto de locatário do Cloud ou pode ser definida em qualquer nível da hierarquia de pastas. É mais fácil definir isso no nível da pasta do locatário individual, mas é mais flexível definir isso no nível do projeto de cada locatário. Após a configuração, sempre que os locatários navegarem pela IU do Cloud Run, eles também verão os serviços no projeto de cluster do Cloud. Isso não altera as permissões do IAM no projeto de cluster do Cloud ou nos clusters do GKE. É apenas um mapeamento de um projeto (ou pasta) do locatário para um projeto de cluster do Cloud.

  1. Ative a API resourcesettings no projeto de cluster do Cloud.

    gcloud services enable resourcesettings.googleapis.com \
      --project=$TENANT_PROJECT_ID
    
  2. Escolha um dos métodos a seguir para definir o mapeamento.

    É possível definir o valor da configuração do recurso em uma pasta pai do Google Cloud se todos os projetos filhos do Cloud e as pastas do Google Cloud usarem esse mesmo valor.

Projetos de locatário

Defina o valor da configuração de recursos para cada projeto de locatário do Cloud:

  1. Consiga o name do projeto de locatário do Cloud e defina-o como uma variável de ambiente local:
    export TENANT_PROJECT_NUMBER=$(gcloud alpha projects
     describe $TENANT_PROJECT_ID
     --format="value(projectNumber)")
    
  2. Crie um arquivo de valor de configuração de recursos para definir o mapeamento do projeto de locatário do Cloud para o projeto de cluster do Cloud. Vários IDs de projeto de cluster do Cloud podem ser definidos nesse arquivo e adicionados a um único projeto de locatário do Cloud.
    cat > value-file.json << EOF
    {
    "name": "projects/$TENANT_PROJECT_NUMBER/settings/cloudrun-multiTenancy/value",
    "value": {
      "stringSetValue": {
        "values": [ "projects/$CLUSTER_PROJECT_ID" ]
      }
    }
    }
    EOF
    
  3. Implante as configurações de recursos no projeto de locatário do Cloud:
    gcloud alpha resource-settings set-value
     cloudrun-multiTenancy
     --value-file value-file.json
     --project $TENANT_PROJECT_ID
    

Pastas de locatário

Defina o valor da configuração de recursos em uma pasta de locatário pai para definir esse valor para todas as pastas e projetos filhos de locatário do Cloud:

  1. Consiga o number da pasta de locatário e defina-o como uma variável de ambiente local:
    export TENANT_FOLDER_NUMBER=$TENANT_FOLDER_NUMBER
    
  2. Crie um arquivo de valor de configuração de recursos para definir o mapeamento da pasta de locatário para o projeto de cluster do Cloud. Vários IDs de projeto de cluster do Cloud podem ser definidos nesse arquivo e adicionados a uma única pasta de locatário.
    cat > value-file.json << EOF
    {
    "name": "folders/$TENANT_FOLDER_NUMBER/settings/cloudrun-multiTenancy/value",
    "value": {
      "stringSetValue": {
        "values": [ "projects/$CLUSTER_PROJECT_ID" ]
      }
    }
    }
    EOF
    
  3. Implante as configurações de recursos na pasta de locatário:
    gcloud alpha resource-settings set-value cloudrun-multiTenancy
     --value-file value-file.json
     --folder $TENANT_FOLDER_NUMBER
    

Como configurar coletores e buckets de registros para rotear dados de registro

Para cada locatário, você cria um bucket de registro, um coletor e as permissões para rotear os dados de registro do projeto de cluster do Cloud para o projeto de locatário do Cloud. Nas etapas a seguir, todos os registros do namespace no projeto de cluster do Cloud serão roteados para o bucket. Consulte o conjunto abaixo para ver detalhes sobre como limitar quais registros são compartilhados.

Crie as seguintes variáveis de ambiente locais:

  • Especifique o namespace do cluster do GKE que os locatários acessam.
  • O nome do coletor. Para simplificar essa etapa, o nome é uma combinação do projeto de cluster do Cloud com as variáveis de ambiente locais do projeto de locatário do Cloud criadas anteriormente. É possível modificar esse valor.
export NAMESPACE=$NAMESPACE
export SINK_NAME=$CLUSTER_PROJECT_ID-$TENANT_PROJECT_ID

Execute o comando a seguir para criar o bucket de registros no projeto de locatário. Observe que o nome do bucket de registro precisa ser o ID do projeto de cluster do Cloud e não pode ser alterado ou modificado.

gcloud alpha logging buckets \
   create $CLUSTER_PROJECT_ID \
   --location=global \
   --project=$TENANT_PROJECT_ID

Execute o comando a seguir para criar o coletor a partir do namespace especificado no projeto de cluster do Cloud para o bucket do projeto de locatário do Cloud. É possível restringir o escopo dos registros. Por exemplo, é possível compartilhar somente clusters individuais do GKE ou recursos específicos do Cloud Run para Anthos no Google Cloud, definindo outros valores log-filter.

gcloud alpha logging sinks \
   create $SINK_NAME \
   logging.googleapis.com/projects/$TENANT_PROJECT_ID/locations/global/buckets/$CLUSTER_PROJECT_ID \
   --log-filter=resource.labels.namespace_name=$NAMESPACE \
   --project $CLUSTER_PROJECT_ID

Execute os comandos a seguir para adicionar a permissão da conta de serviço do coletor de registros ao bucket criado.

export SINK_SERVICE_ACCOUNT=$(gcloud alpha logging sinks \
   describe $SINK_NAME \
   --project $CLUSTER_PROJECT_ID \
   --format="value(writerIdentity)")
gcloud projects add-iam-policy-binding $TENANT_PROJECT_ID \
   --member=$SINK_SERVICE_ACCOUNT \
   --role='roles/logging.bucketWriter' \
   --condition="expression=resource.name.endsWith\
   (\"locations/global/buckets/$CLUSTER_PROJECT_ID\"),\
   title=Log bucket writer from $CLUSTER_PROJECT_ID"

Configuração de permissões de locatário com controle de acesso baseado em papéis (RBAC)

Você usou anteriormente Grupos do Google e o IAM para configurar permissões e permitir que os locatários acessem o projeto do Cloud do cluster do GKE. Para permitir que os locatários acessem os recursos no cluster do GKE, você precisa definir permissões com o RBAC do Kubernetes.

Criar papéis de cluster

Depois de definir e criar os papéis de cluster a seguir, é possível continuar a usá-los no futuro para adicionar todos os locatários subsequentes do projeto de cluster do Cloud.

Papéis de IU

Com esse papel, os locatários podem consultar todos os namespaces. Isso é necessário para descobrir quais namespaces os usuários têm acesso para criar serviços /sdk/gcloud/reference/alpha/logging/sinks/create.

kubectl create clusterrole \
   namespace-lister \
   --verb=list \
   --resource=namespaces

Esse papel permite que os locatários visualizem serviços do Cloud Run para Anthos no Google Cloud. Isso é necessário para listar os serviços na IU do Cloud Run para Anthos no Google Cloud.

kubectl create clusterrole \
   ksvc-lister \
   --verb=list \
   --resource=services.serving.knative.dev

Criar papéis de cluster

Apenas uma dessas permissões é necessária. A primeira permissão admite que os locatários manipulem qualquer recurso no seu namespace. A segunda permissão admite um conjunto mais limitado para a criação de serviços do Cloud Run para Anthos no Google Cloud.

kubectl create clusterrole \
   kubernetes-developer \
   --verb="*" \
   --resource="*.*"

Se a permissão kubernetes-developer for muito permissiva, o código a seguir admitirá que os locatários criem serviços do Knative nos seus namespaces e vejam os outros recursos do Knative.

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: knative-developer
rules:
- apiGroups: ["serving.knative.dev"]
  resources: ["services"]
  verbs: ["*"]
- apiGroups: ["serving.knative.dev"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]
EOF

Crie namespace de locatário e atribua permissões.

Isso pressupõe que você configurou usando o Grupos do Google para o GKE. Isso é necessário para cada locatário.

export TENANT_GROUP=tenant-a@company.com

TENANT_GROUP precisa parte de SECURITY_GROUP

Possibilidade de visualizar todos os namespaces

Para consultar o cluster do GKE, todos os locatários precisam ter a possibilidade de listar namespaces. Atualmente, não há um auth can-i que retorna namespaces para os quais uma ação é possível. A única solução é listar os namespaces e, em seguida, consultar cada namespace individualmente.

kubectl create clusterrolebinding \
   all-namespace-listers \
   --clusterrole=namespace-lister \
   --group=$TENANT_GROUP

Possibilidade de listar serviços do Cloud Run para Anthos no Google Cloud

kubectl create clusterrolebinding \
   all-ksvc-listers \
   --clusterrole=ksvc-lister \
   --group=$TENANT_GROUP

Possibilidade de manipular recursos no namespace

Primeiro, crie o namespace:

kubectl create namespace $NAMESPACE

Se estiver usando o papel kubernetes-developer:

kubectl create rolebinding \
   kubernetes-developer \
   --namespace=$NAMESPACE \
   --clusterrole=kubernetes-developer \
   --group=$TENANT_GROUP

Se estiver usando o papel knative-developer:

kubectl create rolebinding \
   kubernetes-developer \
   --namespace=$NAMESPACE \
   --clusterrole=knative-developer \
   --group=$TENANT_GROUP

Adicione a possibilidade de o locatário acessar o endereço IP externo

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ingress-reader
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get"]
EOF
kubectl create rolebinding \
   ingress-reader-$TENANT_GROUP \
   --namespace=gke-system \
   --clusterrole=ingress-reader \
   --group=$TENANT_GROUP

Verificar

Para verificar se você configurou corretamente a multilocação empresarial, abra o projeto de locatário do Cloud no Cloud Run para Anthos no Google Cloud e implante um serviço em um cluster do projeto de cluster do Cloud.

Acessar o Cloud Run

Parabéns, agora seu locatário pode interagir com os serviços e recursos dentro do namespace do cluster do GKE a que ele recebeu acesso.

Referência de multilocação