Menggunakan workload identity dengan AWS

Topik ini menjelaskan cara mengaktifkan identitas workload untuk GKE di workload AWS guna mengontrol akses ke resource AWS.

Untuk mengetahui informasi tentang penggunaan workload identity dengan akun Google Cloud Identity and Access Management (IAM) untuk mengontrol akses ke resource GCP, lihat Menggunakan identitas workload dengan Google Cloud.

Ringkasan

Workload Identity menggunakan izin IAM AWS untuk mengontrol akses ke resource cloud. Dengan workload identity, Anda dapat menetapkan peran IAM yang berbeda untuk setiap workload. Dengan kontrol izin yang mendetail ini, Anda dapat mengikuti prinsip hak istimewa terendah. Tanpa identitas workload, Anda harus menetapkan peran IAM AWS ke GKE pada node AWS, sehingga semua beban kerja di node memiliki izin yang sama dengan node itu sendiri.

Guna mengaktifkan workload identity untuk cluster Anda, selesaikan langkah-langkah berikut, yang dikelompokkan berdasarkan peran administratif yang menjalankannya.

Administrator cluster

  1. Buat bucket Cloud Storage untuk menyimpan data penemuan OIDC.
  2. Membuat peran Identity and Access Management untuk membaca dari bucket tersebut.
  3. Buat cluster pengguna dengan identitas workload yang diaktifkan.
  4. Buat webhook pada cluster Anda yang menerapkan kredensial identitas workload ke Pod saat pembuatan. Jika tidak ingin menggunakan webhook, Anda dapat menetapkan variabel lingkungan secara manual di pod.
  5. Konfigurasikan penyedia AWS OIDC.
  6. Buat peran dan kebijakan IAM AWS.
Administrator atau developer cluster
  1. Buat akun layanan Kubernetes, dan ikat kebijakan AWS ke akun tersebut.
Developer
  1. Terapkan kredensial ke Pod Anda.

Prasyarat

Untuk menyelesaikan langkah-langkah dalam dokumen ini, Anda harus memiliki penyiapan berikut:

  • GKE di layanan pengelolaan AWS.
  • Cluster pengguna yang menjalankan versi Kubernetes di atas 1.17.9.

  • Berikut izin dan alat-alatnya.

Izin

Untuk membuat cluster dengan mengaktifkan identitas workload, Anda memerlukan izin berikut:

Google Cloud

  • Buat bucket Cloud Storage yang dapat dibaca publik dengan mengaktifkan akses level bucket seragam.
  • Beri management-sa@PROJECT_NAME.iam.gserviceaccount.com izin baca/tulis ke bucket.

AWS

  • Membuat penyedia AWS OIDC
  • Membuat peran IAM AWS

Alat

Di komputer lokal Anda, sebaiknya instal alat jq.

Membuat bucket penemuan OIDC

Bagian ini ditujukan bagi administrator cluster.

Cluster pengguna Anda perlu menyimpan data penemuan OIDC dalam bucket Cloud Storage yang dapat diakses secara publik. Bucket ini mencakup konfigurasi penemuan OIDC dan kunci publik. AWS menggunakan konten tersebut untuk mengautentikasi permintaan dari cluster pengguna Anda.

Bucket Anda harus memiliki atribut berikut:

Jika Anda tidak memiliki bucket dengan atribut ini, buat bucket dengan menggunakan perintah gsutil berikut:

BUCKET=BUCKET_NAME
gsutil mb -b on gs://${BUCKET}
gsutil iam ch allUsers:objectViewer gs://${BUCKET}

Ganti BUCKET_NAME dengan nama bucket baru Anda.

Memberikan izin akun layanan pengelolaan

Akun layanan Identity and Access Management untuk GKE di layanan pengelolaan AWS memerlukan izin untuk membaca dan menulis objek ke dalam bucket ini.

  1. Berikan izin untuk akun layanan pengelolaan Anda menggunakan perintah gsutil berikut.

    MANAGEMENT_SA=management-sa@PROJECT_NAME.iam.gserviceaccount.com
    gsutil iam ch serviceAccount:${MANAGEMENT_SA}:admin gs://${BUCKET}
    

    Ganti PROJECT_NAME dengan project Google Cloud Anda.

  2. Buat peran IAM baru dengan izin untuk mengelola bucket ini. Untuk membuat peran, pertama-tama simpan definisi peran ke file, lalu buat peran dan ikat peran tersebut ke akun layanan pengelolaan Anda.

    Untuk menyelesaikan langkah-langkah ini, jalankan perintah berikut:

    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
    

    Ganti PROJECT_NAME dengan project Google Cloud Anda.

    Google Cloud CLI mengonfirmasi bahwa binding kebijakan telah dibuat.

Membuat cluster pengguna

Bagian ini ditujukan bagi administrator cluster.

Membuat cluster pengguna dengan mengaktifkan workload identity

Buat cluster pengguna yang berisi detail tentang bucket penemuan OIDC Anda. Anda menetapkan informasi ini di kolom spec.controlPlane.workloadIdentity.oidcDiscoveryGCSBucket AWSCluster.

Dalam contoh ini, Anda membuat cluster secara manual dari CRD AWSCluster dan AWSNodePool.

  1. Beralihlah ke direktori yang memiliki konfigurasi GKE on AWS. Anda membuat direktori ini saat Menginstal layanan pengelolaan.

    cd anthos-aws

  2. Dari direktori anthos-aws, gunakan anthos-gke untuk mengalihkan konteks ke layanan pengelolaan Anda.

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

  3. Buka editor teks dan salin definisi AWSCluster berikut ke dalam file bernama 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
    

    Ganti kode berikut:

    • CLUSTER_NAME: nama cluster Anda.
    • AWS_REGION: region AWS tempat cluster Anda dijalankan.

    • VPC_ID: ID VPC tempat cluster Anda dijalankan.

    • POD_ADDRESS_CIDR_BLOCKS: rentang alamat IPv4 yang digunakan oleh pod cluster. Saat ini, hanya satu rentang yang didukung. Rentang tidak boleh tumpang tindih dengan subnet yang dapat dijangkau dari jaringan Anda. Anda dapat menggunakan rentang yang sama di beberapa objek AWSCluster yang berbeda. Contoh, 10.2.0.0/16.

    • SERVICE_ADDRESS_CIDR_BLOCKS: rentang alamat IPv4 yang digunakan oleh layanan cluster. Saat ini, hanya satu rentang yang didukung. Rentang tidak boleh tumpang tindih dengan subnet yang dapat dijangkau dari jaringan Anda. Rentang yang sama aman digunakan di beberapa objek AWSCluster yang berbeda. Contoh, 10.1.0.0/16.

    • SERVICE_LOAD_BALANCER_SUBNETS: ID subnet tempat GKE di AWS dapat membuat load balancer publik atau pribadi.

    • CLUSTER_VERSION: versi Kubernetes yang didukung oleh GKE di AWS. Versi terbaru adalah 1.25.5-gke.2100.

    • AWS_INSTANCE_TYPE: jenis instance EC2 yang didukung.

    • SSH_KEY_NAME: pasangan kunci AWS EC2.

    • CONTROL_PLANE_SUBNET_IDS: ID subnet di AZ tempat instance bidang kontrol Anda dijalankan.

    • CONTROL_PLANE_SECURITY_GROUPS: securityGroupID yang dibuat selama penginstalan layanan pengelolaan. Anda dapat menyesuaikannya dengan menambahkan securityGroupID yang diperlukan untuk terhubung ke bidang kontrol.

    • CONTROL_PLANE_IAM_PROFILE: nama profil instance AWS EC2 yang ditetapkan untuk replika bidang kontrol.

    • ROOT_VOLUME_SIZE: ukuran, dalam gibibyte (GiB), volume root bidang kontrol.

    • ROOT_VOLUME_TYPE dengan jenis volume EBS. Misalnya, gp3.

    • ROOT_VOLUME_IOPS dengan jumlah operasi IO per detik (IOPS) yang disediakan untuk volume. Hanya berlaku jika volumeType adalah GP3. Untuk informasi selengkapnya, lihat Volume SSD Tujuan Umum (gp3).

    • ROOT_VOLUME_KEY dengan Nama Resource Amazon dari kunci AWS KMS yang mengenkripsi volume root instance bidang kontrol Anda.

    • ETCD_VOLUME_SIZE: ukuran volume yang digunakan oleh etcd.

    • ETCD_VOLUME_TYPE dengan jenis volume EBS. Misalnya, gp3.

    • ETCD_VOLUME_IOPS dengan jumlah operasi IO per detik (IOPS) yang disediakan untuk volume. Hanya berlaku jika volumeType adalah gp3. Untuk informasi selengkapnya, lihat Volume SSD Tujuan Umum (gp3).

    • ETCD_VOLUME_KEY dengan Nama Resource Amazon dari kunci AWS KMS yang mengenkripsi volume data etcd bidang kontrol Anda.

    • ARN_OF_KMS_KEY: kunci AWS KMS yang digunakan untuk mengenkripsi Rahasia cluster.

    • ANTHOS_CONNECT_NAME: nama keanggotaan Connect yang digunakan untuk mendaftarkan cluster Anda. Nama keanggotaan harus unik. Misalnya, projects/YOUR_PROJECT/locations/global/memberships/CLUSTER_NAME, dengan YOUR_PROJECT sebagai project Google Cloud dan CLUSTER_NAME adalah nama unik dalam project Anda. Kolom ini bersifat opsional.

    • YOUR_PROJECT: project ID Anda.

    • GCP_REGION: region Google Cloud tempat Anda ingin menyimpan log. Pilih region yang dekat dengan region AWS. Untuk informasi selengkapnya, lihat Lokasi Global - Region & Zona — misalnya, us-central1.

    • ENABLE_LOGGING: true atau false, apakah Cloud Logging diaktifkan di node bidang kontrol.

    • ENABLE_MONITORING: true atau false, apakah Cloud Monitoring diaktifkan di node bidang kontrol.

    • WORKLOAD_IDENTITY_BUCKET: nama bucket Cloud Storage yang berisi informasi penemuan identitas workload Anda. Kolom ini bersifat opsional.

  4. Buat satu atau beberapa AWSNodePools untuk cluster Anda. Buka editor teks dan salin definisi AWSCluster berikut ke dalam file yang bernama 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 
    

    Ganti kode berikut:

    • NODE_POOL_NAME: nama unik untuk AWSNodePool Anda.
    • AWSCLUSTER_NAME: nama AWSCluster Anda. Misalnya, staging-cluster.
    • CLUSTER_VERSION: GKE yang didukung di versi AWS Kubernetes.
    • AWS_REGION: region AWS yang sama dengan AWSCluster Anda.
    • AWS_SUBNET_ID: subnet AWS di region yang sama dengan AWSCluster Anda.
    • MINIMUM_NODE_COUNT: jumlah minimum node dalam kumpulan node. Lihat Menskalakan cluster pengguna untuk mengetahui informasi selengkapnya.
    • MAXIMUM_NODE_COUNT: jumlah maksimum node dalam kumpulan node.
    • MAXIMUM_PODS_PER_NODE_COUNT: jumlah maksimum pod yang dapat dialokasikan GKE di AWS ke sebuah node.
    • AWS_NODE_TYPE: jenis instance AWS EC2.
    • KMS_KEY_PAIR_NAME: pasangan kunci AWS KMS yang ditetapkan ke setiap pekerja kumpulan node.
    • NODE_IAM_PROFILE: nama profil instance AWS EC2 yang ditetapkan ke node di kumpulan.
    • ROOT_VOLUME_SIZE: ukuran, dalam gibibyte (GiB), volume root bidang kontrol.
    • VOLUME_TYPE: jenis volume EBS AWS node. Misalnya, gp3.
    • IOPS: jumlah operasi IO per detik (IOPS) yang disediakan untuk volume. Hanya berlaku jika volumeType adalah gp3.
    • NODE_VOLUME_KEY: ARN kunci AWS KMS yang digunakan untuk mengenkripsi volume. Untuk informasi selengkapnya, lihat Menggunakan CMK yang dikelola pelanggan untuk mengenkripsi volume.
  5. Terapkan manifes ke layanan pengelolaan Anda.

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

Membuat kubeconfig

Saat cluster pengguna dimulai, Anda dapat membuat konteks kubeconfig untuk cluster pengguna baru. Anda menggunakan konteks untuk melakukan autentikasi ke cluster pengguna atau pengelolaan.

  1. Gunakan anthos-gke aws clusters get-credentials untuk membuat kubeconfig untuk cluster pengguna Anda di ~/.kube/config.

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

    Ganti CLUSTER_NAME dengan nama cluster Anda. Misalnya, cluster-0.

  2. Gunakan kubectl untuk melakukan autentikasi ke cluster pengguna baru.

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

    Jika cluster sudah siap, outputnya akan menyertakan URL untuk komponen Kubernetes dalam cluster Anda.

Melihat status cluster Anda

Layanan pengelolaan menyediakan resource AWS saat Anda menerapkan AWSCluster atau AWSNodePool.

  1. Dari direktori anthos-aws, gunakan anthos-gke untuk mengalihkan konteks ke layanan pengelolaan Anda.

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

  2. Untuk mencantumkan cluster, gunakan kubectl get AWSClusters.

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

    Outputnya mencakup nama, status, usia, versi, dan endpoint setiap cluster.

    Misalnya, output berikut hanya menyertakan satu AWSCluster yang bernama cluster-0:

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

Melihat peristiwa cluster Anda

Untuk melihat Peristiwa Kubernetes terbaru dari cluster pengguna, gunakan kubectl get events.

  1. Dari direktori anthos-aws, gunakan anthos-gke untuk mengalihkan konteks ke layanan pengelolaan Anda.

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

  2. Jalankan kubectl get events.

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

Output-nya mencakup informasi, peringatan, dan error yang terkait dari layanan pengelolaan Anda.

Membuat webhook workload identity

Bagian ini ditujukan bagi administrator cluster.

Untuk memberikan kredensial identitas workload ke beban kerja tanpa konfigurasi tambahan, Anda dapat membuat webhook di cluster pengguna secara opsional. Webhook ini mencegat permintaan pembuatan Pod, lalu menyediakan informasi IAM AWS berikut sebagai variabel lingkungan untuk Pod:

  • AWS_ROLE_ARN: Amazon Resource Name (ARN) dari peran IAM
  • aws-iam-token: token yang ditukar dengan kredensial IAM AWS
  • AWS_WEB_IDENTITY_TOKEN_FILE: jalur tempat token disimpan

Dengan variabel ini, beban kerja Anda dapat memanggil alat command line AWS atau SDK dapat mengakses resource yang diberikan ke peran AWS.

Membuat webhook bersifat opsional. Jika memutuskan untuk tidak membuat webhook, Anda harus menetapkan variabel lingkungan yang tercantum sebelumnya di Pod. Untuk mengetahui informasi tentang cara tidak menggunakan webhook, lihat Menerapkan kredensial tanpa webhook.

Membuat file YAML untuk webhook

Untuk men-deploy webhook, lakukan langkah-langkah berikut:

  1. Dari direktori anthos-aws, gunakan anthos-gke untuk mengalihkan konteks ke layanan pengelolaan Anda.

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

  2. Dapatkan nama cluster pengguna dengan kubectl:

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

    kubectl mencantumkan semua cluster pengguna Anda. Pilih cluster pengguna yang Anda buat dengan identitas workload diaktifkan.

  3. Tetapkan nama cluster di variabel lingkungan.

    CLUSTER_NAME=CLUSTER_NAME
    

    Ganti CLUSTER_NAME dengan nama cluster Anda. Misalnya, cluster-0.

  4. Menetapkan variabel lingkungan untuk image dan namespace Pod identitas workload.

    IDENTITY_IMAGE=amazon/amazon-eks-pod-identity-webhook:ed8c41f
    
    WEBHOOK_NAMESPACE=workload-identity-webhook
    
  5. Buat manifes YAML webhook dalam file bernama aws-webhook.yaml dengan melakukan langkah-langkah berikut:

    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
    

    Konten aws-webhook.yaml siap diterapkan ke cluster Anda.

Terapkan webhook ke cluster pengguna

Untuk menerapkan webhook ke cluster pengguna, lakukan langkah-langkah berikut.

  1. Terapkan file aws-webhook.yaml ke cluster pengguna Anda.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f aws-webhook.yaml
    
  2. Saat Anda menerapkan manifes, Pod webhook akan membuat permintaan penandatanganan sertifikat (CSR) Kubernetes. Setujui semua permintaan dari system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook dengan 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. Pastikan sudah tidak ada lagi CSR yang tidak disetujui.

    Gunakan kubectl get csr untuk memeriksa apakah semua CSR dari pemohon system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook telah disetujui:

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

    Respons:

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

Mengonfigurasi penyedia AWS OIDC

Bagian ini ditujukan bagi administrator cluster.

Untuk membuat penyedia OIDC di AWS, AWS memerlukan Certificate Authority (CA) perantara atau thumbprint sertifikat server. Kredensial penemuan OIDC Anda disimpan di storage.googleapis.com, dengan sertifikat yang ditandatangani oleh CA perantara bernama GTS CA 1C3. thumbprint SHA-1 dari GTS CA 1C3 CA perantaranya adalah 08745487E891C19E3078C1F2A07E452950EF36F6.

Untuk mendaftarkan bucket penemuan OIDC Anda sebagai penyedia OIDC dengan AWS, lakukan langkah-langkah berikut:

  1. Dari direktori anthos-aws, gunakan anthos-gke untuk mengalihkan konteks ke layanan pengelolaan Anda.

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

  2. Simpan URL penerbit OIDC, jalur host penerbit, dan thumbprint Cloud Storage di variabel lingkungan.

    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. Gunakan alat command line aws untuk membuat penyedia OIDC di AWS.

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

Memperbarui thumbprint

Jika Google merotasi CA untuk storage.googleapis.com, jalankan perintah berikut:

  1. Salin thumbprint sertifikat yang diperbarui, 08745487E891C19E3078C1F2A07E452950EF36F6.

  2. Ikuti petunjuk untuk perintah aws iam update-open-id-connect-provider-thumbprint. Gunakan storage.googleapis.com sebagai nama host target dan 08745487E891C19E3078C1F2A07E452950EF36F6 sebagai thumbprint.

Membuat peran dan kebijakan IAM AWS

Bagian ini ditujukan bagi administrator cluster.

Membuat peran IAM AWS untuk mengikat ke akun layanan Kubernetes. Peran IAM memiliki izin untuk sts:AssumeRoleWithWebIdentity.

Untuk membuat peran, lakukan langkah-langkah berikut:

  1. Temukan atau buat kebijakan IAM AWS yang memberikan izin yang diperlukan untuk workload Anda.

    Anda memerlukan kebijakan IAM nama resource Amazon (ARN) kebijakan. Contoh, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.

  2. Tetapkan variabel lingkungan dengan informasi autentikasi Anda.

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

    Ganti kode berikut:

    • KUBERNETES_SERVICE_ACCOUNT: nama akun layanan Kubernetes baru
    • WORKLOAD_IDENTITY_NAMESPACE: nama namespace tempat workload dijalankan
    • AWS_ROLE_NAME: nama peran AWS baru untuk workload Anda
    • EXISTING_AWS_POLICY: Nama resource Amazon (ARN) dari kebijakan IAM AWS yang ada Misalnya, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.
  3. Dari direktori anthos-aws, gunakan anthos-gke untuk mengalihkan konteks ke layanan pengelolaan Anda.

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

  4. Buat kebijakan IAM AWS yang memungkinkan cluster pengguna Anda mengasumsikan kredensial keamanan sementara dengan 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. Untuk membuat peran IAM AWS dengan kebijakan ini dan melampirkan kebijakan yang ada ke peran tersebut, lakukan perintah berikut:

    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}
    

    Alat command line aws mengonfirmasi bahwa kebijakan ini ditambahkan ke peran Anda.

Membuat akun layanan Kubernetes untuk beban kerja

Bagian ini ditujukan untuk developer atau administrator cluster.

Untuk membuat akun layanan Kubernetes yang terikat dengan peran IAM AWS yang telah ditentukan sebelumnya, lakukan langkah-langkah berikut:

  1. Dari direktori anthos-aws, gunakan anthos-gke untuk mengalihkan konteks ke cluster pengguna.

    cd anthos-aws
    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    Ganti CLUSTER_NAME dengan nama cluster pengguna Anda.

  2. Buat akun layanan Kubernetes dengan menjalankan perintah berikut:

    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}
    

    Ganti kode berikut:

    • AWS_ROLE_NAME: nama peran IAM AWS yang akan diterapkan ke workload Anda
    • WORKLOAD_IDENTITY_NAMESPACE: nama namespace tempat workload dijalankan

Menerapkan kredensial ke Pod Anda

Bagian ini ditujukan untuk developer.

Bagian ini mengasumsikan bahwa Anda telah men-deploy webhook workload identity. Jika Anda belum men-deploy webhook, lanjutkan ke bagian Menerapkan kredensial tanpa webhook.

Menerapkan kredensial dengan webhook

Bagian ini menjelaskan cara mengonfigurasi Pod Anda untuk membaca kredensial yang disediakan oleh webhook.

Menambahkan akun layanan ke Pod

Untuk menggunakan workload identity dengan beban kerja, tambahkan akun layanan Kubernetes ke kolom berikut:

  • Untuk Deployment: spec.template.spec.serviceAccountName
  • Untuk Pod: spec.serviceAccount

Manifes Pod berikut meluncurkan image CentOS dasar dan berisi kolom 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

Ganti kode berikut:

  • WORKLOAD_IDENTITY_NAMESPACE: nama namespace tempat workload dijalankan
  • KUBERNETES_SERVICE_ACCOUNT: nama akun layanan Kubernetes yang Anda buat sebelumnya

Memeriksa apakah variabel lingkungan Pod telah ditetapkan

Untuk memeriksa apakah variabel lingkungan Pod telah ditetapkan atau belum, jalankan perintah berikut untuk mendapatkan informasi Pod:

kubectl get pod --namespace WORKLOAD_IDENTITY_NAMESPACE POD_NAME -o yaml

Ganti kode berikut:

  • WORKLOAD_IDENTITY_NAMESPACE: nama namespace tempat workload dijalankan
  • POD_NAME: nama Pod yang akan diperiksa

Output-nya berisi nilai variabel lingkungan di spec.containers.command.env dan direktori pemasangan untuk token IAM AWS. Berikut contoh manifes 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:
  ...

Terapkan kredensial tanpa webhook

Jika tidak men-deploy webhook identitas workload, Anda harus melakukan hal berikut:

Membuat Pod dengan kredensial untuk workload identity

Untuk membuat Pod yang menyertakan kredensial yang diperlukan untuk workload identity, lakukan langkah-langkah berikut:

  1. Salin manifes Pod berikut ke dalam file bernama sample-pod-no-webhook.yaml. Konfigurasi ini meluncurkan image CentOS dasar dengan kredensial yang diperlukan.

    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
    

    Ganti kode berikut:

    • WORKLOAD_IDENTITY_NAMESPACE: nama namespace tempat workload dijalankan.
    • IAM_ROLE_ARN: ARN peran IAM yang diberikan ke Pod. Contoh, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.
    • KUBERNETES_SERVICE_ACCOUNT: nama akun layanan Kubernetes yang Anda buat sebelumnya.
  2. Terapkan manifes Pod ke cluster Anda menggunakan kubectl:

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

Memeriksa apakah Pod dapat mengakses resource AWS atau tidak

Prosedur berikut menjelaskan cara memeriksa apakah Pod telah menerima kredensial yang diperlukan agar identitas workload dapat berfungsi.

Untuk menyelesaikan langkah-langkah tersebut, Anda harus memiliki hal berikut:

  • Akses shell bash ke container; sebagian besar gambar produksi tidak memiliki shell yang tersedia. Contoh berikut menunjukkan cara menggunakan Pod yang ditentukan di bagian sebelumnya untuk mengakses AWS S3.

  • Pod Anda harus memiliki akses keluar ke internet untuk mendownload antarmuka command line AWS.

Untuk memeriksa apakah Pod dapat mengakses bucket S3, lakukan langkah-langkah berikut:

  1. Gunakan kubectl exec untuk meluncurkan bash shell interaktif di Pod sample-centos-pod-no-webhook:

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

    Terminal Anda akan membuka bash shell di Pod.

  2. Periksa izin dan kredensial IAM AWS menggunakan alat 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
    

    Alat aws mencetak informasi kredensial yang mirip dengan berikut ini:

    {
        "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"
        }
    }
    

    Jika Anda melihat pesan berikut, pastikan bucket dapat diakses secara publik: An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Couldn't retrieve verification key from your identity provider, please reference AssumeRoleWithWebIdentity documentation for requirements

Mengupgrade webhook

Jika membuat cluster Kubernetes 1.18 atau yang lebih rendah dengan workload identity aktif dan webhook identitas workload versi release-0.2.2-gke.0, Anda harus mengupgrade webhook sebelum mengupgrade ke Kubernetes 1.19.

Untuk mengupgrade webhook, lakukan langkah-langkah berikut:

  1. Pastikan webhook telah diinstal dengan menjalankan perintah berikut:

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

    Jika cluster Anda telah men-deploy webhook, outputnya akan menyertakan hal berikut:

    NAME                   WEBHOOKS   AGE
    pod-identity-webhook   1          11m
    

    Jika webhook tidak di-deploy di cluster, Anda dapat melewati langkah-langkah berikut.

  2. Jika menyimpan file aws-webhook.yaml, Anda dapat menghapus manifesnya. Jika tidak memiliki file ini, Anda dapat menghapus komponen webhook secara manual. Pilih dari file atau komponen di bawah ini.

    File

    Jika Anda masih memiliki file aws-webhook.yaml, jalankan perintah berikut untuk menghapus webhook:

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

    Komponen

    Untuk menghapus komponen webhook secara manual, jalankan perintah berikut:

    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
    

    Ganti WEBHOOK_NAMESPACE dengan namespace tempat Anda menginstal webhook identitas workload. Misalnya— workload-identity-webhook.

  3. Periksa apakah Anda memiliki permintaan penandatanganan sertifikat (CSR) yang tersisa dengan menjalankan perintah berikut:

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

    Jika output kosong, lanjutkan ke langkah berikutnya. Jika masih ada CSR yang tersisa, perintah kubectl akan mencantumkan CSR yang ada. Untuk menghapus CSR, jalankan perintah berikut:

    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}")
    

    Ganti WEBHOOK_NAMESPACE dengan namespace tempat Anda menginstal webhook identitas workload. Misalnya— workload-identity-webhook.

  4. Ikuti langkah-langkah di bagian Membuat webhook untuk men-deploy versi webhook baru.

    Setelah men-deploy versi webhook baru, Anda harus memulai ulang Pod yang menggunakan webhook. Anda dapat memulai ulang Pod dengan Mengupgrade cluster pengguna.

Pembersihan

Bagian ini menunjukkan cara menghapus resource yang telah Anda buat sebelumnya dalam dokumen ini.

Membersihkan akun layanan dan peran IAM terkaitnya

Untuk menghapus akun layanan dan peran IAM terkait, lakukan langkah-langkah berikut:

  1. Bersihkan akun layanan:

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

    Ganti kode berikut:

    • KUBERNETES_SERVICE_ACCOUNT: nama akun layanan Kubernetes baru
    • WORKLOAD_IDENTITY_NAMESPACE: nama namespace tempat workload dijalankan
  2. Membersihkan peran IAM AWS. Pilih dari salah satu opsi berikut:

    • Hapus peran IAM AWS dengan konsol AWS.

    • Hapus peran dengan alat command line AWS menggunakan perintah berikut:

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

Menghapus cluster pengguna

Untuk menghapus cluster pengguna, lakukan langkah-langkah di bagian Meng-uninstal GKE di AWS.

Membersihkan penyedia AWS OIDC

Setelah cluster pengguna dihapus, batalkan pendaftaran dan hapus penyedia OIDC di AWS menggunakan perintah shell bash berikut atau konsol AWS.

  1. Dari direktori anthos-aws, gunakan anthos-gke untuk mengalihkan konteks ke layanan pengelolaan Anda.

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

  2. Hapus peran dengan alat command line AWS dengan perintah berikut:

    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}
    

    Anda menerima konfirmasi bahwa penyedia AWS OIDC telah dihapus.

Langkah selanjutnya