Usando identidade de carga de trabalho com AWS

Este tópico descreve como habilitar a identidade da carga de trabalho para suas cargas de trabalho do GKE na AWS para controlar seu acesso aos recursos da AWS.

Para obter informações sobre como usar a identidade da carga de trabalho com Google CloudContas de gerenciamento de identidade e acesso (IAM) para controlar o acesso aos recursos do GCP, consulte Usando a identidade da carga de trabalho com Google Cloud .

Visão geral

A identidade da carga de trabalho usa permissões do AWS IAM para controlar o acesso aos recursos da nuvem. Com a identidade da carga de trabalho, você pode atribuir diferentes funções do IAM a cada carga de trabalho. Esse controle detalhado de permissões permite seguir o princípio do privilégio mínimo . Sem a identidade da carga de trabalho, você deve 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 permissões que o próprio nó.

Para habilitar a identidade da carga de trabalho para seu cluster, conclua as etapas a seguir, que são agrupadas pelas funções administrativas que as executam.

Administrador de cluster

  1. Crie um bucket do Cloud Storage para armazenar dados de descoberta do OIDC .
  2. Crie uma função de Gerenciamento de Identidade e Acesso para ler desse bucket.
  3. Crie um cluster de usuários com identidade de carga de trabalho habilitada .
  4. Crie um webhook no seu cluster que aplique credenciais de identidade de carga de trabalho aos pods na criação. Se não quiser usar o webhook, você pode definir manualmente as variáveis ​​de ambiente nos seus pods.
  5. Configurar o provedor AWS OIDC .
  6. Crie funções e políticas do AWS IAM .
Administrador ou desenvolvedor de cluster
  1. Crie contas de serviço do Kubernetes e vincule políticas da AWS a elas.
Desenvolvedor
  1. Aplique credenciais aos seus Pods .

Pré-requisitos

Para concluir as etapas deste documento, você deve ter a seguinte configuração:

  • Um serviço de gerenciamento do GKE na AWS.
  • Clusters de usuários que executam uma versão do Kubernetes superior a 1.17.9.

  • As seguintes permissões e ferramentas.

Permissões

Para criar um cluster com identidade de carga de trabalho habilitada, você precisa das seguintes permissões:

Google Cloud

  • Crie um bucket do Cloud Storage legível publicamente com acesso uniforme em nível de bucket habilitado.
  • management-sa@ PROJECT_NAME .iam.gserviceaccount.com permissões de leitura/gravação no bucket.

AWS

  • Criar um provedor AWS OIDC
  • Criar funções do AWS IAM

Ferramentas

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

Criando o bucket de descoberta do OIDC

Esta seção é para administradores de cluster .

Seu cluster de usuários precisa armazenar os dados de descoberta do OIDC em um bucket do Cloud Storage de acesso público. O bucket inclui a configuração de descoberta do OIDC e chaves públicas. A AWS usa o conteúdo para autenticar solicitações dos seus clusters de usuários.

Seu bucket deve ter os seguintes atributos:

Se você não tiver um bucket com esses atributos, crie um usando os seguintes comandos gcloud storage :

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 seu novo bucket.

Conceder permissões à conta do serviço de gerenciamento

A conta de serviço de Gerenciamento de Identidade e Acesso para o serviço de gerenciamento do GKE na AWS precisa de permissões para ler e gravar objetos neste bucket.

  1. Conceda permissões à sua conta de serviço de gerenciamento usando o 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 do IAM com permissões para gerenciar este bucket. Para criar a função, primeiro salve a definição da função em um arquivo, depois crie a função e vincule-a à sua conta de serviço de gerenciamento.

    Para concluir essas etapas, 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.

    O Google Cloud CLI confirma que a vinculação de política foi criada.

Criando um cluster de usuários

Esta seção é para administradores de cluster .

Crie um cluster de usuários com identidade de carga de trabalho habilitada

Crie um cluster de usuários que contenha detalhes sobre o seu bucket de descoberta OIDC. Defina essas informações no campo spec.controlPlane.workloadIdentity.oidcDiscoveryGCSBucket do seu AWSCluster .

Neste exemplo, você cria um cluster manualmente a partir dos CRDs AWSCluster e AWSNodePool .

  1. Acesse o diretório com a configuração do GKE na AWS. Você criou este diretório ao instalar o serviço de gerenciamento .

    cd anthos-aws

  2. No seu diretório anthos-aws , use anthos-gke para alternar o contexto para seu serviço de gerenciamento.

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

  3. Abra um editor de texto e copie a seguinte definição AWSCluster em um arquivo chamado 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 seu cluster.
    • AWS_REGION : a região da AWS onde seu cluster é executado.

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

    • POD_ADDRESS_CIDR_BLOCKS : o intervalo de endereços IPv4 usado pelos pods do cluster. Atualmente, apenas um único intervalo é suportado. O intervalo não deve se sobrepor 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 usado pelos serviços do cluster. Atualmente, apenas um único intervalo é suportado. O intervalo não deve se sobrepor 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 de sub-rede onde o GKE na AWS pode criar balanceadores de carga públicos ou privados.

    • CLUSTER_VERSION : uma versão do Kubernetes compatível com o GKE na AWS. A versão mais recente é 1.25.5-gke.2100.

    • AWS_INSTANCE_TYPE : um tipo de instância EC2 compatível .

    • SSH_KEY_NAME : um par de chaves AWS EC2 .

    • CONTROL_PLANE_SUBNET_IDS : os IDs de sub-rede nas AZs onde suas instâncias do plano de controle são executadas.

    • CONTROL_PLANE_SECURITY_GROUPS : um securityGroupID criado durante a instalação do serviço de gerenciamento. Você pode personalizá-lo adicionando quaisquer securityGroupIDs necessários para se conectar ao plano de controle.

    • CONTROL_PLANE_IAM_PROFILE : nome do perfil de instância do AWS EC2 atribuído às réplicas do plano de controle.

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

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

    • ROOT_VOLUME_IOPS com a quantidade de operações de E/S provisionadas por segundo (IOPS) para o volume. Válido somente quando volumeType for GP3 . Para obter mais informações, consulte Volumes SSD de uso geral (gp3) .

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

    • ETCD_VOLUME_SIZE : o tamanho dos volumes usados ​​pelo etcd.

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

    • ETCD_VOLUME_IOPS com a quantidade de operações de E/S provisionadas por segundo (IOPS) para o volume. Válido somente quando volumeType for gp3 . Para obter mais informações, consulte Volumes SSD de uso geral (gp3) .

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

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

    • ANTHOS_CONNECT_NAME : o nome da associação Connect usado para registrar seu cluster. O nome da associação deve ser exclusivo. Por exemplo, projects/ YOUR_PROJECT /locations/global/memberships/ CLUSTER_NAME , onde YOUR_PROJECT é seu Google Cloud project e CLUSTER_NAME é um nome exclusivo no seu projeto. Este campo é opcional.

    • YOUR_PROJECT : seu ID de projeto.

    • GCP_REGION : a Google Cloud região onde você deseja armazenar logs. Escolha uma região próxima à região da AWS. Para obter mais informações, consulte Locais Globais - Regiões e Zonas — por exemplo, us-central1 .

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

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

    • WORKLOAD_IDENTITY_BUCKET : o nome do bucket do Cloud Storage que contém as informações de descoberta de identidade da sua 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 do AWSCluster para um arquivo chamado 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 seu AWSNodePool.
    • AWSCLUSTER_NAME : o nome do seu AWSCluster. Por exemplo, staging-cluster .
    • CLUSTER_VERSION : uma versão do GKE com suporte no AWS Kubernetes.
    • AWS_REGION : a mesma região da AWS que seu AWSCluster.
    • AWS_SUBNET_ID : uma sub-rede da AWS na mesma região que seu AWSCluster.
    • MINIMUM_NODE_COUNT : o número mínimo de nós no pool de nós. Consulte Dimensionamento de clusters de usuários para obter mais informações.
    • MAXIMUM_NODE_COUNT : o número máximo de nós no pool de nós.
    • MAXIMUM_PODS_PER_NODE_COUNT : o número máximo de pods que o GKE na AWS pode alocar para 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 trabalhador do pool de nós.
    • NODE_IAM_PROFILE : o nome do perfil da instância do AWS EC2 atribuído aos nós no pool.
    • ROOT_VOLUME_SIZE : o tamanho, em gibibytes (GiB), dos volumes raiz do seu plano de controle.
    • VOLUME_TYPE : o tipo de volume do AWS EBS do nó. Por exemplo, gp3 .
    • IOPS : a quantidade de operações de E/S provisionadas por segundo (IOPS) para volumes. Válido somente quando volumeType for gp3 .
    • NODE_VOLUME_KEY : o ARN da chave KMS da AWS usada para criptografar o volume. Para obter mais informações, consulte Usando uma CMK gerenciada pelo cliente para criptografar volumes .
  5. Aplique os manifestos ao seu serviço de gerenciamento.

    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 seu cluster de usuários é inicializado, você pode criar um contexto kubeconfig para o novo cluster. Use o contexto para autenticar em um cluster de usuários ou de gerenciamento.

  1. Use anthos-gke aws clusters get-credentials para gerar um kubeconfig para seu cluster de usuário em ~/.kube/config .

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

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

  2. Use kubectl para autenticar seu novo cluster de usuários.

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

    Se o seu cluster estiver pronto, a saída incluirá as URLs dos componentes do Kubernetes dentro do seu cluster.

Visualizando o status do seu cluster

O serviço de gerenciamento provisiona recursos da AWS quando você aplica um AWSCluster ou AWSNodePool .

  1. No seu diretório anthos-aws , use anthos-gke para alternar o contexto para seu serviço de gerenciamento.

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

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

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

    A saída inclui o nome, estado, idade, versão e ponto de extremidade de cada cluster.

    Por exemplo, a saída a seguir inclui apenas um AWSCluster chamado cluster-0 :

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

Visualize os eventos do seu cluster

Para ver eventos recentes do Kubernetes do seu cluster de usuários, use kubectl get events .

  1. No seu diretório anthos-aws , use anthos-gke para alternar o contexto para seu serviço de gerenciamento.

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

  2. Execute kubectl get events .

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

A saída inclui informações, avisos e erros relacionados ao seu serviço de gerenciamento.

Criando o webhook de identidade da carga de trabalho

Esta seção é para administradores de cluster .

Para fornecer credenciais de identidade de carga de trabalho às suas cargas de trabalho sem configuração adicional, você pode, opcionalmente, criar um webhook nos seus clusters de usuários. Este webhook intercepta as solicitações de criação de pod e, em seguida, disponibiliza as seguintes informações do AWS IAM como variáveis ​​de ambiente para o pod:

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

Com essas variáveis, suas cargas de trabalho podem chamar a ferramenta de linha de comando da AWS ou o SDK pode acessar os recursos concedidos à função da AWS.

A criação do webhook é opcional. Se você decidir não criá-lo, precisará definir as variáveis ​​de ambiente listadas anteriormente no Pod. Para obter informações sobre como não usar um webhook, consulte Aplicando credenciais sem o webhook .

Crie arquivos YAML para o webhook

Para implantar o webhook, execute as seguintes etapas:

  1. No seu diretório anthos-aws , use anthos-gke para alternar o contexto para seu serviço de gerenciamento.

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

  2. Obtenha o nome do cluster do usuário com kubectl :

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

    kubectl lista todos os seus clusters de usuários. Escolha o cluster de usuários que você criou com a identidade da carga de trabalho habilitada .

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

    CLUSTER_NAME=CLUSTER_NAME
    

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

  4. Defina variáveis ​​de ambiente para a identidade da carga de trabalho, imagem do pod e namespace.

    IDENTITY_IMAGE=amazon/amazon-eks-pod-identity-webhook:ed8c41f
    
    WEBHOOK_NAMESPACE=workload-identity-webhook
    
  5. Gere o manifesto YAML do webhook em um arquivo chamado aws-webhook.yaml executando as seguintes etapas:

    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 usuários

Para aplicar o webhook ao seu cluster de usuários, execute as seguintes etapas.

  1. Aplique o arquivo aws-webhook.yaml ao seu cluster de usuários.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f aws-webhook.yaml
    
  2. Ao aplicar o manifesto, o Pod do webhook gera solicitações de assinatura de certificado (CSR) do Kubernetes. Aprove todas as solicitações 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. Verifique se não há CSRs não aprovados restantes.

    Use kubectl get csr para verificar se todos os CSRs do system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook foram 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
    

Configurando o provedor AWS OIDC

Esta seção é para administradores de cluster .

Para criar um provedor OIDC na AWS , a AWS exige uma Autoridade Certificadora (CA) intermediária ou uma impressão digital do certificado do servidor. Suas credenciais de descoberta OIDC são armazenadas em storage.googleapis.com , com um certificado assinado por uma CA intermediária chamada GTS CA 1C3 . A impressão digital SHA-1 da CA intermediária GTS CA 1C3 é 08745487E891C19E3078C1F2A07E452950EF36F6 .

Para registrar seu bucket de descoberta OIDC como um provedor OIDC com a AWS, execute as seguintes etapas:

  1. No seu diretório anthos-aws , use anthos-gke para alternar o contexto para seu serviço de gerenciamento.

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

  2. Salve o URL do emissor do OIDC, o caminho do host do emissor e a impressão digital do 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 comando aws para criar um provedor OIDC na AWS.

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

Atualizar a impressão digital

Se o Google alternar a CA para storage.googleapis.com , execute os seguintes comandos:

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

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

Criação de funções e políticas do AWS IAM

Esta seção é para administradores de cluster .

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

Para criar a função, execute as seguintes etapas:

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

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

  2. Defina variáveis ​​de ambiente com 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 namespace onde as cargas de trabalho são executadas
    • AWS_ROLE_NAME : o nome de uma nova função da AWS para suas cargas de trabalho
    • EXISTING_AWS_POLICY : o nome do recurso da Amazon (ARN) de uma política do AWS IAM existente. Por exemplo, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess .
  3. No seu diretório anthos-aws , use anthos-gke para alternar o contexto para seu serviço de gerenciamento.

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

  4. Crie uma política do AWS IAM que permita que seu cluster de usuários assuma 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 do AWS IAM com esta política e anexar 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 comando aws confirma que a política está anexada à sua função.

Criação de contas de serviço do Kubernetes para cargas de trabalho

Esta seção é para desenvolvedores ou administradores de cluster .

Para criar contas de serviço do Kubernetes vinculadas à função do AWS IAM especificada anteriormente, execute as seguintes etapas:

  1. No seu diretório anthos-aws , use anthos-gke para alternar o contexto para seu cluster de usuários.

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

  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 AWS IAM a ser aplicada às suas cargas de trabalho
    • WORKLOAD_IDENTITY_NAMESPACE : o nome do namespace onde as cargas de trabalho são executadas

Aplicando credenciais aos seus Pods

Esta seção é para desenvolvedores .

Esta seção pressupõe que você tenha implantado o webhook de identidade da carga de trabalho. Se você não o tiver implantado, pule para Aplicando credenciais sem o webhook .

Aplicar credenciais com o webhook

Esta seção descreve como configurar seus Pods para ler 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 implantação: spec.template.spec.serviceAccountName
  • Para um Pod: spec.serviceAccount

O manifesto do Pod a seguir 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 namespace onde as cargas de trabalho são executadas
  • KUBERNETES_SERVICE_ACCOUNT : o nome da conta de serviço do Kubernetes que você 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 namespace onde as cargas de trabalho são executadas
  • POD_NAME : o nome do Pod a ser verificado

A saída contém os valores das variáveis ​​de ambiente em spec.containers.command.env e o ponto de montagem do token do AWS IAM. Veja a seguir um exemplo de manifesto do Pod.

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:
  ...

Aplicar credenciais sem o webhook

Se você não implantar o webhook de identidade da carga de trabalho, precisará fazer o seguinte:

Crie um Pod com credenciais para identidade de carga de trabalho

Para criar um Pod que inclua as credenciais necessárias para a identidade da carga de trabalho, execute as seguintes etapas:

  1. Copie o seguinte manifesto do Pod para um arquivo chamado sample-pod-no-webhook.yaml . A configuração inicia uma imagem base do CentOS 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 namespace onde as cargas de trabalho são executadas.
    • IAM_ROLE_ARN : o ARN da função 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 você criou anteriormente.
  2. Aplique o manifesto do Pod ao seu cluster usando kubectl :

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

Verifique se os Pods podem acessar os recursos da AWS

O procedimento a seguir descreve como verificar se o Pod recebeu as credenciais necessárias para que a identidade da carga de trabalho funcione.

Para concluir as etapas, você precisa ter o seguinte:

  • Acesso via shell bash ao contêiner; a maioria das imagens de produção não possui um shell disponível. O exemplo a seguir mostra como usar o Pod especificado na seção anterior para acessar o AWS S3.

  • Seu Pod precisa ter acesso de saída à Internet para baixar a interface de linha de comando da AWS.

Para verificar se o Pod pode acessar um bucket S3, execute as seguintes etapas:

  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
    

    Seu terminal abre o shell bash no Pod.

  2. Verifique as permissões e credenciais do AWS IAM usando a 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 você vir a seguinte mensagem, verifique se o bucket 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

Atualizando o webhook

Se você criou um cluster do Kubernetes 1.18 ou anterior com a identidade da carga de trabalho habilitada e a versão do webhook de identidade da carga de trabalho release-0.2.2-gke.0 , será necessário atualizar o webhook antes de atualizar para o Kubernetes 1.19.

Para atualizar o webhook, execute as seguintes etapas:

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

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

    Se o seu cluster tiver o webhook implantado, a saída incluirá o seguinte:

    NAME                   WEBHOOKS   AGE
    pod-identity-webhook   1          11m
    

    Se o webhook não estiver implantado no seu cluster, você pode pular as etapas a seguir.

  2. Se você salvou o arquivo aws-webhook.yaml , pode excluir o manifesto. Caso não tenha esse arquivo disponível, você pode excluir os componentes do webhook manualmente. Escolha entre os arquivos ou componentes abaixo.

    Arquivo

    Se você ainda tiver o arquivo aws-webhook.yaml , execute o seguinte comando para excluir o webhook:

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

    Componentes

    Para excluir os componentes do webhook manualmente, 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 namespace onde você instalou o webhook de identidade da carga de trabalho. Por exemplo workload-identity-webhook .

  3. Verifique se você tem alguma solicitação de assinatura de certificado (CSR) restante executando o seguinte comando:

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

    Se a saída estiver em branco, pule para a próxima etapa. Se houver CSRs restantes, o comando kubectl listará os 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 namespace onde você instalou o webhook de identidade da carga de trabalho. Por exemplo workload-identity-webhook .

  4. Siga as etapas em Criar o webhook para implantar a nova versão do webhook.

    Após implantar a nova versão do webhook, você precisa reiniciar os pods que o utilizam. Você pode reiniciar seus pods atualizando um cluster de usuários .

Limpeza

Esta seção mostra como remover recursos que você criou anteriormente neste documento.

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

Para excluir a conta de serviço e sua função do IAM associada, execute as seguintes etapas:

  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 namespace onde as cargas de trabalho são executadas
  2. Limpe a função do AWS IAM. Escolha uma das seguintes opções:

    • Exclua a função do AWS IAM com o console da AWS .

    • Exclua a função com a ferramenta de linha de comando da AWS usando os 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}
      

Excluir seu cluster de usuários

Para excluir seu cluster de usuários, siga as etapas em Desinstalar o GKE na AWS .

Limpar o provedor AWS OIDC

Após a exclusão do cluster de usuário, cancele o registro e exclua o provedor OIDC na AWS usando o seguinte comando bash shell ou o console da AWS.

  1. No seu diretório anthos-aws , use anthos-gke para alternar o contexto para seu serviço de gerenciamento.

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

  2. Exclua a função com a ferramenta de linha de comando 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}
    

    Você recebe a confirmação de que o provedor AWS OIDC foi excluído.

O que vem a seguir