Usar o Workload Identity com a AWS

Este tópico descreve como ativar o Workload Identity para as suas cargas de trabalho do GKE on AWS de modo a controlar o respetivo acesso aos recursos da AWS.

Para obter informações sobre a utilização da identidade de carga de trabalho com contas de gestão de identidade e de acesso (IAM) para controlar o acesso aos recursos do GCP, consulte o artigo Utilizar a identidade de carga de trabalho com Google Cloud. Google Cloud

Vista geral

O Workload Identity usa autorizações do AWS IAM para controlar o acesso aos recursos da nuvem. Com o Workload Identity, pode atribuir diferentes funções da IAM a cada carga de trabalho. Este controlo detalhado das autorizações permite-lhe seguir o princípio do privilégio mínimo. Sem a identidade da carga de trabalho, tem de atribuir funções do AWS IAM aos seus nós do GKE on AWS, concedendo a todas as cargas de trabalho no nó as mesmas autorizações que o próprio nó.

Para ativar a identidade de carga de trabalho para o seu cluster, conclua os seguintes passos, que estão agrupados pelas funções administrativas que os executam.

Administrador do cluster

  1. Crie um contentor do Cloud Storage para armazenar dados de descoberta OIDC.
  2. Crie uma função de gestão de identidade e de acesso para ler a partir desse contentor.
  3. Crie um cluster de utilizadores com a identidade de carga de trabalho ativada.
  4. Crie um webhook no seu cluster que aplica credenciais de identidade da carga de trabalho aos pods na criação. Se não quiser usar o webhook, pode definir manualmente as variáveis de ambiente nos seus pods.
  5. Configure o fornecedor OIDC da AWS.
  6. Crie funções e políticas de IAM do AWS.
Administrador ou programador do cluster
  1. Crie contas de serviço do Kubernetese associe-lhes políticas da AWS.
Programador
  1. Aplique credenciais aos seus Pods.

Pré-requisitos

Para concluir os passos neste documento, tem de ter a seguinte configuração:

  • Um serviço de gestão do GKE no AWS.
  • Clusters de utilizadores que estão a executar uma versão do Kubernetes superior a 1.17.9.

  • As seguintes autorizações e ferramentas.

Autorizações

Para criar um cluster com a identidade de workload ativada, precisa das seguintes autorizações:

Google Cloud

  • Crie um contentor do Cloud Storage legível publicamente com o acesso uniforme ao nível do contentor ativado.
  • Conceda management-sa@PROJECT_NAME.iam.gserviceaccount.com autorizações de leitura/escrita ao contentor.

AWS

  • Crie um fornecedor de OIDC da AWS
  • Crie funções de IAM do AWS

Ferramentas

Na sua máquina local, recomendamos que tenha a ferramenta jq instalada.

Criar o segmento de descoberta do OIDC

Esta secção destina-se a administradores de clusters.

O cluster de utilizadores tem de armazenar os dados de deteção do OIDC num contentor do Cloud Storage acessível publicamente. O contentor inclui a configuração de descoberta do OIDC e as chaves públicas. A AWS usa o conteúdo para autenticar pedidos dos seus clusters de utilizadores.

O seu contentor tem de ter os seguintes atributos:

Se não tiver um contentor com estes atributos, crie um através dos seguintes gcloud storagecomandos:

BUCKET=BUCKET_NAME
gcloud storage buckets create gs://${BUCKET} --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding gs://${BUCKET} \
    --member=allUsers --role=roles/storage.objectViewer

Substitua BUCKET_NAME pelo nome do novo contentor.

Conceda autorizações à conta de serviço de gestão

A conta de serviço de gestão de identidade e acesso para o serviço de gestão do GKE no AWS precisa de autorizações para ler e escrever objetos neste contentor.

  1. Conceda autorizações à sua conta de serviço de gestão através do seguinte comando.

    MANAGEMENT_SA=management-sa@PROJECT_NAME.iam.gserviceaccount.com
    gcloud storage buckets add-iam-policy-binding gs://${BUCKET} \
        --member=serviceAccount:${MANAGEMENT_SA} \
        --role=roles/storage.admin
    

    Substitua PROJECT_NAME pelo seu Google Cloud projeto.

  2. Crie uma nova função de IAM com autorizações para gerir este contentor. Para criar a função, primeiro guarde a definição da função num ficheiro e, em seguida, crie a função e associe-a à sua conta de serviço de gestão.

    Para concluir estes passos, execute os seguintes comandos:

    cat << EOF >  anthos-oidc-role.yaml
    title: anthosAwsOidcStorageAdmin
    description: permissions to manage the OIDC buckets
    stage: GA
    includedPermissions:
    - storage.buckets.get
    EOF
    
    gcloud iam roles create anthosAwsOidcStorageAdmin --project=PROJECT_NAME \
      --file=anthos-oidc-role.yaml
    
    gcloud projects add-iam-policy-binding \
      PROJECT_NAME \
      --member=serviceAccount:${MANAGEMENT_SA} \
      --role=projects/PROJECT_NAME/roles/anthosAwsOidcStorageAdmin
    

    Substitua PROJECT_NAME pelo seu Google Cloud projeto.

    A Google Cloud CLI confirma que a associação de políticas foi criada.

Criar um cluster de utilizadores

Esta secção destina-se a administradores de clusters.

Crie um cluster de utilizadores com a identidade de carga de trabalho ativada

Crie um cluster de utilizadores que contenha detalhes sobre o seu bucket de descoberta do OIDC. Pode definir estas informações no campo AWSCluster's spec.controlPlane.workloadIdentity.oidcDiscoveryGCSBucket.

Neste exemplo, cria um cluster manualmente a partir de CRDs AWSCluster e AWSNodePool.

  1. Altere para o diretório com a configuração do GKE na AWS. Criou este diretório quando Instalou o serviço de gestão.

    cd anthos-aws

  2. No diretório do anthos-aws, use anthos-gke para mudar o contexto para o seu serviço de gestão.

    cd anthos-aws
    anthos-gke aws management get-credentials

  3. Abra um editor de texto e copie a seguinte definição AWSCluster para um ficheiro com o nome custom-cluster.yaml.

    apiVersion: multicloud.cluster.gke.io/v1
    kind: AWSCluster
    metadata:
      name: CLUSTER_NAME
    spec:
      region: AWS_REGION
      networking:
        vpcID: VPC_ID
        podAddressCIDRBlocks: POD_ADDRESS_CIDR_BLOCKS
        serviceAddressCIDRBlocks: SERVICE_ADDRESS_CIDR_BLOCKS
        ServiceLoadBalancerSubnetIDs: SERVICE_LOAD_BALANCER_SUBNETS
      controlPlane:
        version:  CLUSTER_VERSION # Latest version is 1.25.5-gke.2100
        instanceType: AWS_INSTANCE_TYPE
        keyName: SSH_KEY_NAME
        subnetIDs:
        - CONTROL_PLANE_SUBNET_IDS
        securityGroupIDs:
        - CONTROL_PLANE_SECURITY_GROUPS
        iamInstanceProfile: CONTROL_PLANE_IAM_ROLE
        rootVolume:
          sizeGiB: ROOT_VOLUME_SIZE
          volumeType: ROOT_VOLUME_TYPE # Optional
          iops: ROOT_VOLUME_IOPS # Optional
          kmsKeyARN: ROOT_VOLUME_KEY # Optional
        etcd:
          mainVolume:
            sizeGiB: ETCD_VOLUME_SIZE
            volumeType: ETCD_VOLUME_TYPE # Optional
            iops: ETCD_VOLUME_IOPS # Optional
            kmsKeyARN: ETCD_VOLUME_KEY # Optional
        databaseEncryption:
          kmsKeyARN: ARN_OF_KMS_KEY
        hub: # Optional
          membershipName: ANTHOS_CONNECT_NAME
        cloudOperations: # Optional
          projectID: YOUR_PROJECT
          location: GCP_REGION
          enableLogging: ENABLE_LOGGING
          enableMonitoring: ENABLE_MONITORING
        workloadIdentity: # Optional
          oidcDiscoveryGCSBucket: WORKLOAD_IDENTITY_BUCKET
    

    Substitua o seguinte:

    • CLUSTER_NAME: o nome do cluster.
    • AWS_REGION: a região da AWS onde o cluster é executado.

    • VPC_ID: o ID da VPC onde o cluster é executado.

    • POD_ADDRESS_CIDR_BLOCKS: o intervalo de endereços IPv4 usados pelos pods do cluster. Atualmente, só é suportado um único intervalo. O intervalo não pode sobrepor-se a nenhuma sub-rede acessível a partir da sua rede. É seguro usar o mesmo intervalo em vários objetos AWSCluster diferentes. Por exemplo, 10.2.0.0/16.

    • SERVICE_ADDRESS_CIDR_BLOCKS: o intervalo de endereços IPv4 usados pelos serviços do cluster. Atualmente, só é suportado um único intervalo. O intervalo não pode sobrepor-se a nenhuma sub-rede acessível a partir da sua rede. É seguro usar o mesmo intervalo em vários objetos AWSCluster diferentes. Por exemplo, 10.1.0.0/16.

    • SERVICE_LOAD_BALANCER_SUBNETS: os IDs das sub-redes onde o GKE no AWS pode criar equilibradores de carga públicos ou privados.

    • CLUSTER_VERSION: a Versão do Kubernetes suportada pelo GKE no AWS. A versão mais recente é a 1.25.5-gke.2100.

    • AWS_INSTANCE_TYPE: um tipo de instância do EC2 suportado.

    • SSH_KEY_NAME: um par de chaves do AWS EC2.

    • CONTROL_PLANE_SUBNET_IDS: os IDs das sub-redes nas ZDs onde as instâncias do plano de controlo são executadas.

    • CONTROL_PLANE_SECURITY_GROUPS: um securityGroupID criado durante a instalação do serviço de gestão. Pode personalizar esta opção adicionando os securityGroupIDs necessários para estabelecer ligação ao plano de controlo.

    • CONTROL_PLANE_IAM_PROFILE: nome do perfil da instância do AWS EC2 atribuído a réplicas do plano de controlo.

    • ROOT_VOLUME_SIZE: o tamanho, em gibibytes (GiB), dos volumes raiz do plano de controlo.

    • ROOT_VOLUME_TYPE com o tipo de volume EBS. Por exemplo, gp3.

    • ROOT_VOLUME_IOPS com a quantidade de operações de E/S aprovisionadas por segundo (IOPS) para o volume. Só é válido quando volumeType é GP3. Para mais informações, consulte o artigo Volumes SSD de uso geral (gp3).

    • ROOT_VOLUME_KEY com o nome do recurso da Amazon da chave do AWS KMS que encripta os volumes raiz da instância do plano de controlo.

    • ETCD_VOLUME_SIZE: o tamanho dos volumes usados pelo etcd.

    • ETCD_VOLUME_TYPE com o tipo de volume EBS. Por exemplo, gp3.

    • ETCD_VOLUME_IOPS com a quantidade de operações de E/S aprovisionadas por segundo (IOPS) para o volume. Só é válido quando volumeType é gp3. Para mais informações, consulte o artigo Volumes SSD de uso geral (gp3).

    • ETCD_VOLUME_KEY com o nome de recurso da Amazon da chave do AWS KMS que encripta os volumes de dados etcd do plano de controlo.

    • ARN_OF_KMS_KEY: a chave do AWS KMS usada para encriptar os segredos do cluster.

    • ANTHOS_CONNECT_NAME: o nome do membro do Connect usado para registar o seu cluster. O nome da subscrição tem de ser exclusivo. Por exemplo, projects/YOUR_PROJECT/locations/global/memberships/CLUSTER_NAME, onde YOUR_PROJECT é o seu Google Cloud projeto e CLUSTER_NAME é um nome exclusivo no seu projeto. Este campo é opcional.

    • YOUR_PROJECT: o ID do seu projeto.

    • GCP_REGION: a Google Cloud região onde quer armazenar os registos. Escolha uma região próxima da região da AWS. Para mais informações, consulte Localizações globais – Regiões e zonas — por exemplo, us-central1.

    • ENABLE_LOGGING: true ou false, se o Cloud Logging estiver ativado nos nós do plano de controlo.

    • ENABLE_MONITORING: true ou false, se o Cloud Monitoring estiver ativado nos nós do plano de controlo.

    • WORKLOAD_IDENTITY_BUCKET: o nome do contentor do Cloud Storage que contém as informações de deteção da identidade da carga de trabalho. Este campo é opcional.

  4. Crie um ou mais AWSNodePools para o seu cluster. Abra um editor de texto e copie a seguinte definição de AWSCluster para um ficheiro com o nome custom-nodepools.yaml.

    apiVersion: multicloud.cluster.gke.io/v1
    kind: AWSNodePool
    metadata:
      name: NODE_POOL_NAME
    spec:
      clusterName: AWSCLUSTER_NAME
      version:  CLUSTER_VERSION # latest version is 1.25.5-gke.2100
      region: AWS_REGION
      subnetID: AWS_SUBNET_ID
      minNodeCount: MINIMUM_NODE_COUNT
      maxNodeCount: MAXIMUM_NODE_COUNT
      maxPodsPerNode: MAXIMUM_PODS_PER_NODE_COUNT
      instanceType: AWS_NODE_TYPE
      keyName: KMS_KEY_PAIR_NAME
      iamInstanceProfile: NODE_IAM_PROFILE
      proxySecretName: PROXY_SECRET_NAME
      rootVolume:
        sizeGiB: ROOT_VOLUME_SIZE
        volumeType: VOLUME_TYPE # Optional
        iops: IOPS # Optional
        kmsKeyARN: NODE_VOLUME_KEY # Optional 
    

    Substitua o seguinte:

    • NODE_POOL_NAME: um nome exclusivo para o seu AWSNodePool.
    • AWSCLUSTER_NAME: o nome do seu AWSCluster. Por exemplo, staging-cluster.
    • CLUSTER_VERSION: uma versão do Kubernetes do GKE on AWS suportada.
    • AWS_REGION: a mesma região da AWS que o seu AWSCluster.
    • AWS_SUBNET_ID: uma sub-rede da AWS na mesma região que o seu AWSCluster.
    • MINIMUM_NODE_COUNT: o número mínimo de nós no node pool. Consulte o artigo Dimensionar clusters de utilizadores para mais informações.
    • MAXIMUM_NODE_COUNT: o número máximo de nós no node pool.
    • MAXIMUM_PODS_PER_NODE_COUNT: o número máximo de pods que o GKE no AWS pode atribuir a um nó.
    • AWS_NODE_TYPE: um tipo de instância do AWS EC2.
    • KMS_KEY_PAIR_NAME: o par de chaves do AWS KMS atribuído a cada worker do conjunto de nós.
    • NODE_IAM_PROFILE: o nome do perfil da instância do AWS EC2 atribuído aos nós no conjunto.
    • ROOT_VOLUME_SIZE: o tamanho, em gibibytes (GiB), dos volumes raiz do plano de controlo.
    • VOLUME_TYPE: o tipo de volume do EBS da AWS do nó. Por exemplo, gp3.
    • IOPS: a quantidade de operações de E/S aprovisionadas por segundo (IOPS) para volumes. Só é válido quando volumeType é gp3.
    • NODE_VOLUME_KEY: o ARN da chave do AWS KMS usada para encriptar o volume. Para mais informações, consulte o artigo Usar uma CMK gerida pelo cliente para encriptar volumes.
  5. Aplique os manifestos ao seu serviço de gestão.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f custom-cluster.yaml
    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f custom-nodepools.yaml
    

Crie um kubeconfig

Enquanto o cluster de utilizadores é iniciado, pode criar um kubeconfig contexto para o seu novo cluster de utilizadores. Usa o contexto para autenticar um utilizador ou um cluster de gestão.

  1. Use anthos-gke aws clusters get-credentials para gerar um kubeconfig para o seu cluster de utilizadores no ~/.kube/config.

    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    

    Substitua CLUSTER_NAME pelo nome do cluster. Por exemplo, cluster-0.

  2. Use kubectl para se autenticar no novo cluster de utilizadores.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl cluster-info
    

    Se o cluster estiver pronto, o resultado inclui os URLs dos componentes do Kubernetes no cluster.

Ver o estado do cluster

O serviço de gestão aprovisiona recursos da AWS quando aplica um AWSCluster ou AWSNodePool.

  1. No diretório do anthos-aws, use anthos-gke para mudar o contexto para o seu serviço de gestão.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Para listar os seus clusters, use kubectl get AWSClusters.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get AWSClusters
    

    O resultado inclui o nome, o estado, a idade, a versão e o ponto final de cada cluster.

    Por exemplo, a saída seguinte inclui apenas um AWSCluster denominado cluster-0:

    NAME        STATE          AGE     VERSION         ENDPOINT
    cluster-0   Provisioning   2m41s   1.25.5-gke.2100   gke-xyz.elb.us-east-1.amazonaws.com
    

Veja os eventos do seu cluster

Para ver os eventos do Kubernetes recentes do cluster de utilizadores, use kubectl get events.

  1. No diretório do anthos-aws, use anthos-gke para mudar o contexto para o seu serviço de gestão.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Corrida kubectl get events.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get events
    

O resultado inclui informações, avisos e erros relacionados com o seu serviço de gestão.

Criar o webhook do Workload Identity

Esta secção destina-se a administradores de clusters.

Para fornecer credenciais de identidade de carga de trabalho às suas cargas de trabalho sem configuração adicional, pode, opcionalmente, criar um webhook nos seus clusters de utilizadores. Este webhook interceta pedidos de criação de agrupamentos e, em seguida, disponibiliza as seguintes informações do AWS IAM como variáveis de ambiente para o agrupamento:

  • AWS_ROLE_ARN: o nome de recurso da Amazon (ARN) da função de IAM
  • aws-iam-token: o token trocado por credenciais do AWS IAM
  • AWS_WEB_IDENTITY_TOKEN_FILE: o caminho onde o token está armazenado

Com estas variáveis, as suas cargas de trabalho podem chamar a ferramenta de linha de comandos da AWS ou o SDK pode aceder aos recursos concedidos à função da AWS.

A criação do webhook é opcional. Se decidir não criar o webhook, tem de definir as variáveis de ambiente indicadas anteriormente no Pod. Para obter informações sobre como não usar um webhook, consulte o artigo Aplicar credenciais sem o webhook.

Crie ficheiros YAML para o webhook

Para implementar o webhook, siga estes passos:

  1. No diretório do anthos-aws, use anthos-gke para mudar o contexto para o seu serviço de gestão.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Obtenha o nome do cluster de utilizadores com kubectl:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get awscluster
    

    kubectl apresenta todos os seus clusters de utilizadores. Escolha o cluster de utilizadores que criou com a identidade da carga de trabalho ativada.

  3. Defina o nome do cluster numa variável de ambiente.

    CLUSTER_NAME=CLUSTER_NAME
    

    Substitua CLUSTER_NAME pelo nome do seu cluster. Por exemplo, cluster-0.

  4. Defina as variáveis de ambiente para a imagem do pod e o espaço de nomes da identidade do fluxo de trabalho.

    IDENTITY_IMAGE=amazon/amazon-eks-pod-identity-webhook:ed8c41f
    
    WEBHOOK_NAMESPACE=workload-identity-webhook
    
  5. Gere o manifesto YAML do webhook num ficheiro denominado aws-webhook.yaml seguindo os passos abaixo:

    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials ${CLUSTER_NAME}
    
    CLUSTER_CA=$(env HTTPS_PROXY=http://localhost:8118 \
      kubectl config view --raw -o json  | jq -r '.clusters[] | select(.name == "'$(kubectl config current-context)'") | .cluster."certificate-authority-data"')
    
    cat << EOF > aws-webhook.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    rules:
      - apiGroups: ['']
        resources: ['secrets']
        verbs: ['create']
      - apiGroups: ['']
        resources: ['secrets']
        verbs: ['get', 'update', 'patch']
        resourceNames:
          - pod-identity-webhook
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: pod-identity-webhook
    subjects:
      - kind: ServiceAccount
        name: pod-identity-webhook
        namespace: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: pod-identity-webhook
    rules:
      - apiGroups: ['']
        resources: ['serviceaccounts']
        verbs: ['get', 'watch',  'list']
      - apiGroups:  ['certificates.k8s.io']
        resources: ['certificatesigningrequests']
        verbs:  ['create', 'get', 'list', 'watch']
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: pod-identity-webhook
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: pod-identity-webhook
    subjects:
      - kind: ServiceAccount
        name: pod-identity-webhook
        namespace: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: pod-identity-webhook
      template:
        metadata:
          labels:
            app: pod-identity-webhook
        spec:
          serviceAccountName: pod-identity-webhook
          containers:
            - name: pod-identity-webhook
              image: ${IDENTITY_IMAGE}
              imagePullPolicy: Always
              command:
                - /webhook
                - --in-cluster
                - --namespace=${WEBHOOK_NAMESPACE}
                - --service-name=pod-identity-webhook
                - --tls-secret=pod-identity-webhook
                - --annotation-prefix=eks.amazonaws.com
                - --token-audience=sts.amazonaws.com
                - --logtostderr
              volumeMounts:
                - name: webhook-certs
                  mountPath: /var/run/app/certs
                  readOnly: false
          volumes:
            - name: webhook-certs
              emptyDir: {}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
      annotations:
        prometheus.io/port: '443'
        prometheus.io/scheme: https
        prometheus.io/scrape: 'true'
    spec:
      ports:
        - port: 443
          targetPort: 443
      selector:
        app: pod-identity-webhook
    ---
    apiVersion: admissionregistration.k8s.io/v1
    kind: MutatingWebhookConfiguration
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    webhooks:
      - name: pod-identity-webhook.amazonaws.com
        failurePolicy: Ignore
        sideEffects: 'None'
        admissionReviewVersions: ['v1beta1']
        clientConfig:
          service:
            name: pod-identity-webhook
            namespace: ${WEBHOOK_NAMESPACE}
            path: /mutate
          caBundle: ${CLUSTER_CA}
        rules:
          - operations: ['CREATE']
            apiGroups: ['']
            apiVersions: ['v1']
            resources: ['pods']
    EOF
    

    O conteúdo de aws-webhook.yaml está pronto para ser aplicado ao seu cluster.

Aplique o webhook ao seu cluster de utilizadores

Para aplicar o webhook ao seu cluster de utilizadores, siga estes passos.

  1. Aplique o ficheiro aws-webhook.yaml ao seu cluster de utilizadores.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f aws-webhook.yaml
    
  2. Quando aplica o manifesto, o pod do webhook gera pedidos de assinatura de certificados (CSR) do Kubernetes. Aprovar todos os pedidos de system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook com kubectl certificate approve.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl certificate approve $(env HTTPS_PROXY=http://localhost:8118 \ &&\
      kubectl get csr -o \
        jsonpath="{.items[?(@.spec.username==\"system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook\")].metadata.name}")
    
  3. Certifique-se de que não existem CSRs não aprovados restantes.

    Use kubectl get csr para verificar se todos os CSRs do requerente system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook estão aprovados:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get csr
    

    Resposta:

    NAME        AGE   REQUESTOR                                            CONDITION
    csr-mxrt8   10s   system:serviceaccount:default:pod-identity-webhook   Approved,Issued
    

Configurar o fornecedor OIDC da AWS

Esta secção destina-se a administradores de clusters.

Para criar um fornecedor OIDC na AWS, a AWS requer uma autoridade de certificação (AC) intermédia ou uma impressão digital do certificado do servidor. As suas credenciais de descoberta do OIDC são armazenadas em storage.googleapis.com, com um certificado assinado por uma CA intermédia denominada GTS CA 1C3. O thumbprint SHA-1 da respetiva AC intermediária GTS CA 1C3 é 08745487E891C19E3078C1F2A07E452950EF36F6.

Para registar o seu contentor de descoberta OIDC como um fornecedor OIDC na AWS, siga os passos abaixo:

  1. No diretório do anthos-aws, use anthos-gke para mudar o contexto para o seu serviço de gestão.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Guarde o URL do emissor OIDC, o caminho do anfitrião do emissor e a impressão digital do Google Cloud Storage em variáveis de ambiente.

    ISSUER_URL=$(env HTTPS_PROXY=http://localhost:8118 \
      kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.workloadIdentityInfo.issuerURL}')
    ISSUER_HOSTPATH=${ISSUER_URL#"https://"}
    CA_THUMBPRINT=08745487E891C19E3078C1F2A07E452950EF36F6
    
  3. Use a ferramenta de linha de comandos aws para criar um fornecedor OIDC na AWS.

    aws iam create-open-id-connect-provider \
      --url ${ISSUER_URL} \
      --thumbprint-list ${CA_THUMBPRINT} \
      --client-id-list sts.amazonaws.com
    

Atualize a impressão digital

Se a Google rodar a AC para storage.googleapis.com, execute os seguintes comandos:

  1. Copie a impressão digital do certificado atualizada, 08745487E891C19E3078C1F2A07E452950EF36F6.

  2. Siga as instruções para o comando aws iam update-open-id-connect-provider-thumbprint. Use storage.googleapis.com como o nome de anfitrião de destino e 08745487E891C19E3078C1F2A07E452950EF36F6 como a impressão digital.

Criar funções e políticas de IAM do AWS

Esta secção destina-se a administradores de clusters.

Crie uma função de IAM do AWS para associar a uma conta de serviço do Kubernetes. A função de IAM tem autorizações para sts:AssumeRoleWithWebIdentity.

Para criar a função, siga estes passos:

  1. Encontre ou crie uma política de IAM da AWS que conceda as autorizações necessárias para as suas cargas de trabalho.

    Precisa do nome do recurso da Amazon (ARN) da política Política IAM da AWS. Por exemplo, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.

  2. Defina variáveis de ambiente com as suas informações de autenticação.

    KSA_NAME=KUBERNETES_SERVICE_ACCOUNT
    WORKLOAD_NAMESPACE=WORKLOAD_IDENTITY_NAMESPACE
    
    AWS_ROLE_NAME=AWS_ROLE_NAME
    AWS_POLICY=EXISTING_AWS_POLICY
    

    Substitua o seguinte:

    • KUBERNETES_SERVICE_ACCOUNT: o nome da nova conta de serviço do Kubernetes
    • WORKLOAD_IDENTITY_NAMESPACE: o nome do espaço de nomes onde as cargas de trabalho são executadas
    • AWS_ROLE_NAME: o nome de uma nova função da AWS para as suas cargas de trabalho
    • EXISTING_AWS_POLICY: o nome do recurso da Amazon (ARN) de uma política de IAM da AWS existente Por exemplo, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.
  3. No diretório do anthos-aws, use anthos-gke para mudar o contexto para o seu serviço de gestão.

    cd anthos-aws
    anthos-gke aws management get-credentials

  4. Crie uma política de IAM do AWS que permita ao cluster de utilizadores assumir credenciais de segurança temporárias com o AWS Security Token Service:

    CLUSTER_ID=$(env HTTPS_PROXY=http://localhost:8118 \
      kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.clusterID}')
    
    # Get the ID Provider ARN
    PROVIDER_ARN=$(aws iam list-open-id-connect-providers  \
    | jq '.OpenIDConnectProviderList' \
    | jq ".[] | select(.Arn |  contains(\"${CLUSTER_ID}\"))"   \
    | jq  '.Arn' | tr -d '"')
    
    # Create AWS role and policy
    cat > irp-trust-policy.json << EOF
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "${PROVIDER_ARN}"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "${ISSUER_HOSTPATH}:sub": "system:serviceaccount:${WORKLOAD_NAMESPACE}:${KSA_NAME}"
            }
          }
        }
      ]
    }
    EOF
    
  5. Para criar uma função de IAM do AWS com esta política e anexar a sua política existente à função, execute os seguintes comandos:

    aws iam create-role \
      --role-name ${AWS_ROLE_NAME} \
      --assume-role-policy-document file://irp-trust-policy.json
    aws iam update-assume-role-policy \
      --role-name ${AWS_ROLE_NAME} \
      --policy-document file://irp-trust-policy.json
    aws iam attach-role-policy \
      --role-name ${AWS_ROLE_NAME} \
      --policy-arn ${AWS_POLICY}
    

    A ferramenta de linha de comandos aws confirma que a política está anexada à sua função.

Criar contas de serviço do Kubernetes para cargas de trabalho

Esta secção destina-se a programadores ou administradores de clusters.

Para criar contas de serviço do Kubernetes associadas à função de IAM do AWS que foi especificada anteriormente, siga estes passos:

  1. No diretório do anthos-aws, use anthos-gke para mudar o contexto para o cluster de utilizadores.

    cd anthos-aws
    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    Substitua CLUSTER_NAME pelo nome do cluster de utilizadores.

  2. Crie a conta de serviço do Kubernetes executando os seguintes comandos:

    S3_ROLE_ARN=$(aws iam get-role \
      --role-name AWS_ROLE_NAME \
      --query Role.Arn --output text)
    
    cat << EOF  > k8s-service-account.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ${KSA_NAME}
      namespace: WORKLOAD_IDENTITY_NAMESPACE
    EOF
    
    env HTTPS_PROXY=http://localhost:8118 \
    kubectl apply -f k8s-service-account.yaml
    
    env HTTPS_PROXY=http://localhost:8118 \
    kubectl annotate sa --namespace ${WORKLOAD_NAMESPACE} ${KSA_NAME} eks.amazonaws.com/role-arn=${S3_ROLE_ARN}
    

    Substitua o seguinte:

    • AWS_ROLE_NAME: o nome da função do IAM da AWS a aplicar às suas cargas de trabalho
    • WORKLOAD_IDENTITY_NAMESPACE: o nome do espaço de nomes onde as cargas de trabalho são executadas

Aplicar credenciais aos seus pods

Esta secção destina-se a programadores.

Esta secção pressupõe que implementou o webhook do Workload Identity. Se não implementou o webhook, avance para a secção Aplicar credenciais sem o webhook.

Aplique credenciais com o webhook

Esta secção descreve como configurar os seus pods para ler as credenciais disponibilizadas pelo webhook.

Adicione a conta de serviço ao pod

Para usar a identidade da carga de trabalho com uma carga de trabalho, adicione a conta de serviço do Kubernetes aos seguintes campos:

  • Para uma implementação: spec.template.spec.serviceAccountName
  • Para um agrupamento: spec.serviceAccount

O manifesto do pod seguinte inicia uma imagem base do CentOS e contém o campo spec.serviceAccount.

apiVersion: v1
kind: Pod
metadata:
  name: sample-centos-pod
  namespace: WORKLOAD_IDENTITY_NAMESPACE
spec:
  containers:
  - command:
    - /bin/bash
    - -ec
    - while :; do echo '.'; sleep 500 ; done
    image: amazon/aws-cli
    name: centos
  serviceAccount: KUBERNETES_SERVICE_ACCOUNT

Substitua o seguinte:

  • WORKLOAD_IDENTITY_NAMESPACE: o nome do espaço de nomes onde as cargas de trabalho são executadas
  • KUBERNETES_SERVICE_ACCOUNT: o nome da conta de serviço do Kubernetes que criou anteriormente

Verifique se os pods têm as variáveis de ambiente definidas

Para verificar se os pods têm as variáveis de ambiente definidas, execute o seguinte comando para obter as informações do pod:

kubectl get pod --namespace WORKLOAD_IDENTITY_NAMESPACE POD_NAME -o yaml

Substitua o seguinte:

  • WORKLOAD_IDENTITY_NAMESPACE: o nome do espaço de nomes onde as cargas de trabalho são executadas
  • POD_NAME: o nome do agrupamento a verificar

A saída contém os valores das variáveis de ambiente em spec.containers.command.env e o ponto de montagem para o token do AWS IAM. Segue-se um exemplo de um manifesto de agrupamento.

apiVersion: v1
kind: Pod
metadata:
  ...
spec:
  containers:
  - command:
    - /bin/bash
    - -ec
    - while :; do echo '.'; sleep 500 ; done
    env:
    - name: AWS_ROLE_ARN
      value: arn:aws:iam::1234567890:role/my-example-workload-role-1
    - name: AWS_WEB_IDENTITY_TOKEN_FILE
      value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
    image: amazon/aws-cli
    imagePullPolicy: IfNotPresent
    name: centos
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: my-k8s-serviceaccount-token-d4nz4
      readOnly: true
    - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
      name: aws-iam-token
      readOnly: true
  serviceAccount: my-k8s-serviceaccount
  serviceAccountName: my-k8s-serviceaccount
  volumes:
  - name: aws-iam-token
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          audience: sts.amazonaws.com
          expirationSeconds: 86400
          path: token
  - name: my-k8s-serviceaccount-token-d4nz4
    secret:
      defaultMode: 420
      secretName: my-k8s-serviceaccount-token-d4nz4
   ...
status:
  ...

Aplique credenciais sem o webhook

Se não implementar o webhook do Workload Identity, tem de fazer o seguinte:

Crie um pod com credenciais para a identidade de carga de trabalho

Para criar um pod que inclua as credenciais necessárias para a identidade da carga de trabalho, siga estes passos:

  1. Copie o seguinte manifesto do pod para um ficheiro com o nome sample-pod-no-webhook.yaml. A configuração inicia uma imagem CentOS base com as credenciais necessárias.

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-centos-pod-no-webhook
      namespace: WORKLOAD_IDENTITY_NAMESPACE
    spec:
      containers:
      - command:
        - /bin/bash
        - -ec
        - while :; do echo '.'; sleep 500 ; done
        image: centos:7
        name: centos
        env:
        - name: AWS_ROLE_ARN
          value: IAM_ROLE_ARN
        - name: AWS_WEB_IDENTITY_TOKEN_FILE
          value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
        volumeMounts:
        - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
          name: aws-iam-token
          readOnly: true
      volumes:
      - name: aws-iam-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: sts.amazonaws.com
              expirationSeconds: 86400
              path: token
      serviceAccount: KUBERNETES_SERVICE_ACCOUNT
    

    Substitua o seguinte:

    • WORKLOAD_IDENTITY_NAMESPACE: o nome do espaço de nomes onde as cargas de trabalho são executadas.
    • IAM_ROLE_ARN: o ARN da função de IAM concedida ao pod. Por exemplo, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.
    • KUBERNETES_SERVICE_ACCOUNT: o nome da conta de serviço do Kubernetes que criou anteriormente.
  2. Aplique o manifesto do pod ao seu cluster através do comando kubectl:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f sample-pod-no-webhook.yaml
    

Verifique se os pods podem aceder a recursos da AWS

O procedimento seguinte descreve como verificar se o pod recebeu as credenciais necessárias para o funcionamento da identidade da carga de trabalho.

Para concluir os passos, precisa do seguinte:

  • bash acesso ao shell do contentor; a maioria das imagens de produção não tem um shell disponível. O exemplo seguinte mostra como usar o Pod especificado na secção anterior para aceder ao AWS S3.

  • O seu Pod tem de ter acesso de saída à Internet para transferir a interface de linha de comandos da AWS.

Para verificar se o pod consegue aceder a um contentor S3, siga estes passos:

  1. Use kubectl exec para iniciar um shell bash interativo no pod sample-centos-pod-no-webhook:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl exec -it --namespace ${WORKLOAD_NAMESPACE} sample-centos-pod-no-webhook -- bash
    

    O terminal abre a shell bash no pod.

  2. Verifique as autorizações e as credenciais do AWS IAM através da ferramenta aws:

    aws sts assume-role-with-web-identity \
     --role-arn ${AWS_ROLE_ARN} \
     --role-session-name mh9test \
     --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token \
     --duration-seconds 1000
    

    A ferramenta aws imprime informações de credenciais semelhantes às seguintes:

    {
        "AssumedRoleUser": {
            "AssumedRoleId": "AROAR2ZZZLEXVSDCDJ37N:mh9test",
            "Arn": "arn:aws:sts::126285863215:assumed-role/my-example-workload-role-1/mh9test"
        },
        "Audience": "sts.amazonaws.com",
        "Provider": "arn:aws:iam::126285863215:oidc-provider/storage.googleapis.com/gke-issuer-cec6c353",
        "SubjectFromWebIdentityToken": "system:serviceaccount:default:my-s3-reader-ksa",
        "Credentials": {
            "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
            "SessionToken": "MY_TOKEN",
            "Expiration": "2020-08-14T22:46:36Z",
            "AccessKeyId": "AKIAIOSFODNN7EXAMPLE"
        }
    }
    

    Se vir a seguinte mensagem, verifique se o contentor está acessível publicamente: An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Couldn't retrieve verification key from your identity provider, please reference AssumeRoleWithWebIdentity documentation for requirements

Atualizar o webhook

Se criou um cluster do Kubernetes 1.18 ou inferior com o Workload Identity ativado e a versão do webhook do Workload Identity release-0.2.2-gke.0, tem de atualizar o webhook antes de atualizar para o Kubernetes 1.19.

Para atualizar o webhook, siga estes passos:

  1. Confirme se o webhook está instalado executando os seguintes comandos:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get MutatingWebhookConfiguration
    

    Se o cluster tiver o webhook implementado, o resultado inclui o seguinte:

    NAME                   WEBHOOKS   AGE
    pod-identity-webhook   1          11m
    

    Se o webhook não estiver implementado no seu cluster, pode ignorar os passos seguintes.

  2. Se guardou o ficheiro aws-webhook.yaml, pode eliminar o manifesto. Se não tiver este ficheiro disponível, pode eliminar os componentes do webhook manualmente. Escolha entre o ficheiro ou os componentes abaixo.

    Ficheiro

    Se ainda tiver o ficheiro aws-webhook.yaml, execute o seguinte comando para eliminar o webhook:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl delete -f aws-webhook.yaml
    

    Componentes

    Para eliminar manualmente os componentes do webhook, execute os seguintes comandos:

    env HTTPS_PROXY=http://localhost:8118 \
       kubectl delete namespace WEBHOOK_NAMESPACE
    env HTTPS_PROXY=http://localhost:8118 \
       kubectl delete clusterrole pod-identity-webhook
    env HTTPS_PROXY=http://localhost:8118 \
       kubectl delete clusterrolebinding pod-identity-webhook
    env HTTPS_PROXY=http://localhost:8118 \
       kubectl delete mutatingwebhookconfiguration pod-identity-webhook
    

    Substitua WEBHOOK_NAMESPACE pelo espaço de nomes onde instalou o webhook de identidade da carga de trabalho. Por exemplo: workload-identity-webhook.

  3. Verifique se tem pedidos de assinatura de certificados (CSRs) restantes executando o seguinte comando:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get csr |grep pod-identity-webhook
    

    Se a saída estiver em branco, avance para o passo seguinte. Se existirem CSRs restantes, o comando kubectl apresenta uma lista das CSRs existentes. Para remover os CSRs, execute o seguinte comando:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl delete csr $(kubectl get csr -o \
      jsonpath="{.items[?(@.spec.username==\"system:serviceaccount:WEBHOOK_NAMESPACE:pod-identity-webhook\")].metadata.name}")
    

    Substitua WEBHOOK_NAMESPACE pelo espaço de nomes onde instalou o webhook de identidade da carga de trabalho. Por exemplo: workload-identity-webhook.

  4. Siga os passos em Crie o webhook para implementar a nova versão do webhook.

    Depois de implementar a nova versão do webhook, tem de reiniciar os pods que usam o webhook. Pode reiniciar os seus pods atualizando um cluster de utilizadores.

Limpar

Esta secção mostra como remover recursos que criou anteriormente neste documento.

Limpe a conta de serviço e a respetiva função IAM associada

Para eliminar a conta de serviço e a respetiva função do IAM, siga estes passos:

  1. Limpe a conta de serviço:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl delete sa KUBERNETES_SERVICE_ACCOUNT --namespace WORKLOAD_IDENTITY_NAMESPACE
    

    Substitua o seguinte:

    • KUBERNETES_SERVICE_ACCOUNT: o nome da nova conta de serviço do Kubernetes
    • WORKLOAD_IDENTITY_NAMESPACE: o nome do espaço de nomes onde as cargas de trabalho são executadas
  2. Limpe a função do AWS IAM. Escolha uma das seguintes opções:

    • Elimine a função do IAM do AWS com a consola do AWS.

    • Elimine a função com a ferramenta de linha de comandos da AWS através dos seguintes comandos:

      aws iam  detach-role-policy \
        --role-name=${AWS_ROLE_NAME} \
        --policy-arn=${AWS_POLICY}
      aws iam delete-role --role-name=${AWS_ROLE_NAME}
      

Elimine o seu cluster de utilizadores

Para eliminar o cluster de utilizadores, siga os passos descritos no artigo Desinstalar o GKE no AWS.

Limpe o fornecedor OIDC da AWS

Após a eliminação do cluster de utilizadores, anule o registo e elimine o fornecedor OIDC na AWS através do seguinte comando de shell bash ou da consola da AWS.

  1. No diretório do anthos-aws, use anthos-gke para mudar o contexto para o seu serviço de gestão.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Elimine a função com a ferramenta de linha de comandos da AWS com os seguintes comandos:

    CLUSTER_ID=$(env HTTPS_PROXY=http://localhost:8118 \
      kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.clusterID}')
    
    PROVIDER_ARN=$(aws iam list-open-id-connect-providers  \
    | jq '.OpenIDConnectProviderList' \
    | jq ".[] | select(.Arn |  contains(\"${CLUSTER_ID}\"))"   \
    | jq  '.Arn' | tr -d '"')
    
    aws iam delete-open-id-connect-provider \
      --open-id-connect-provider-arn=${PROVIDER_ARN}
    

    Recebe uma confirmação de que o fornecedor de OIDC da AWS foi eliminado.

O que se segue?