Multilocação entre projetos para o Knative serving

Este guia orienta você na configuração do Knative serving para permitir que um ou mais projetos do Google Cloud executem e gerenciem as cargas de trabalho em execução em um cluster do GKE em um projeto Google Cloud diferente.

Um modelo operacional comum com o Knative serving é para que uma equipe de desenvolvedores de aplicativos use o projeto do Google Cloud para implantar e gerenciar serviços executados em diferentes clusters do GKE em projetos doGoogle Cloud de outras equipes. Esse recurso, chamado multilocação, permite que você, como operador da plataforma, adapte o acesso das 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 Knative serving é compatível especificamente com a multilocação empresarial. Esse tipo de multilocação ativa um projeto Google Cloud de cluster para permitir o acesso a recursos específicos do cluster do GKE. O projeto Google Cloud que tem acesso ao projeto Google Cloud do cluster é o projeto Google Cloud do locatário. Os locatários do projeto de cluster Google Cloud podem usar o Knative serving 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 Knative serving:

  1. Configure o acesso do locatário ao projeto Google Cloud do cluster usando um Grupo do Google e o Identity and Access Management.
  2. Mapeie cada projeto Google Cloud de locatário para o projeto Google Cloud de cluster.
  3. Encaminhar os dados de registro do projeto de cluster Google Cloud para os projetos do locatário Google Cloud usando coletores e buckets de registro.
  4. Definir permissões de cluster para locatários usando o controle de acesso baseado em papéis.

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 Google Cloud e o projeto de locatário Google Cloud :

  1. Substitua YOUR_CLUSTER_PROJECT_ID pelo ID do projeto Google Cloud do cluster 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 Google 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 Google Cloud project is:" $CLUSTER_PROJECT_ID
    echo "tenant Google Cloud project is:" $TENANT_PROJECT_ID
    

Os IDs dos projetos do cluster Google Cloud e do locatário Google Cloud agora são 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 Google Cloud e nos projetos de locatário Google Cloud .

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

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 Google Cloud do cluster:

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

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

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 Google 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 Google Cloud do locatário. 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 do Monitoring

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 Google Cloud para o projeto de cluster Google Cloud

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

A configuração de recursos pode ser definida para cada projeto de locatário Google Cloud ou 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 UI do Knative serving, eles também vão encontrar os serviços no projeto de cluster Google Cloud . Isso não muda as permissões do IAM no projeto Google Cloud do cluster ou nos clusters do GKE. É apenas um mapeamento de um projeto (ou pasta) do locatário para um projeto Google Cloud do cluster.

  1. Ative a API resourcesettings no projeto Google Cloud do locatário.

    gcloud services enable resourcesettings.googleapis.com \
      --project=$TENANT_PROJECT_ID
    
  2. Execute o seguinte comando para adicionar os privilégios de administrador da organização (roles/resourcesettings.admin) ao seu ID de usuário:

    gcloud organizations add-iam-policy-binding YOUR_ORGANIZATION_ID \
      --member=YOUR_ADMIN_MEMBER_ID \
      --role='roles/resourcesettings.admin'
    

    Substitua YOUR_ORGANIZATION_ID pelo ID da organização e YOUR_ADMIN_MEMBER_ID pelo ID do usuário, por exemplo, user:my-email@my-domain.com.

  3. 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 Google Cloud se todos os projetos Google Cloud e pastas Google Cloud filhos usarem esse mesmo valor.

Projetos de locatário

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

  1. Consiga o name do projeto Google Cloud do locatário e defina-o como uma variável de ambiente local:
    export TENANT_PROJECT_NUMBER=$(gcloud 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 Google Cloud do locatário para o projeto Google Cloud do cluster. Vários IDs de projeto de cluster Google Cloud podem ser definidos nesse arquivo e adicionados a um único projeto de locatário Google 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 Google Cloud do locatário:
    gcloud 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 Google 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 Google Cloud . Vários IDs de projeto de cluster Google 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 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 registros, um coletor e as permissões para rotear os dados de registro do projeto Google Cloud do cluster para o projeto Google Cloud do locatário. Nas etapas a seguir, todos os registros do namespace no projeto de cluster Google 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 das variáveis de ambiente locais do projeto de cluster Google Cloud e do projeto de locatário Google 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 registros precisa ser o ID do projeto do cluster Google Cloud e não pode ser alterado ou modificado.

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

Execute o comando a seguir para criar o coletor do namespace especificado no projeto de cluster Google Cloud para o bucket do projeto de locatário Google Cloud . É possível restringir o escopo dos registros, por exemplo, para compartilhar apenas clusters individuais do GKE ou recursos específicos do Knative serving, definindo valores log-filter adicionais.

gcloud 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 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 Google 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 Google Cloud do cluster.

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/logging/sinks/create.

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

Esse papel permite que os locatários visualizem serviços do Knative serving. Isso é necessário para listar os serviços na interface do Knative serving.

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 permite um conjunto mais limitado apenas para criar serviços do Knative serving.

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

Capacidade de visualizar todos os namespaces

Para consultar o cluster do GKE, todos os locatários precisam da capacidade 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

Capacidade de listar os serviços do Knative serving

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

Capacidade 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=istio-system \
   --clusterrole=ingress-reader \
   --group=$TENANT_GROUP

Verificar

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

Acessar o Knative serving

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