zoukankan      html  css  js  c++  java
  • 如何深入理解 EKS IRSA 的实现机制

    一、aws-iam-token 的生成

    1.1 token 生成

    我们这里使用的 AWS 完全管理的 K8s 集群 EKS,并且通过如下命令创建了 iamserviceaccount [1]

    eksctl create iamserviceaccount --name alice --namespace default 
    --cluster eks --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess 
    --approve  --override-existing-serviceaccounts
    

    关于 IRSA 的一个架构图大致如下:

    在由 API Server 创建一个 pod 后,由 Self-hosted Kubernetes setup [2] 所说,由于 IRSA 是基于 Service Account 的方式进行验证,其中,产生 Token 的行为由 API Server 在启动阶段的以下相关参数决定,以下参数通过 CloudWatch 获取到 API Server 的相关启动参数:

    --service-account-key-file="[/etc/kubernetes/pki/sa.pub]"
    --service-account-signing-key-file=“”
    --service-account-issuer="https://oidc.eks.us-east-1.amazonaws.com/id/900B62D5EA15DC82EC523AD824232853"
    

    因为 token 其实是由 controller manager 签署, sa 的私钥在其启动参数中,所以我们查看其启动参数如下:

    --service-account-private-key-file="/etc/kubernetes/pki/sa.key"
    

    在 token 签署完成后,会触发 eks-pod-identity-webhook,由 eks-pod-identity-webhook 协助将相关的 Token 信息以 Projected Volume [3] 的形式挂在到 Pod 中,并把 iam service account 中的 role-arn 和刚刚生成的 token 注入到 Pod 的环境变量中。

    我可以通过查看 Pod 的 yaml 文件查看其相关信息:

    spec:
      containers:
      - command:
        - sh
        - -c
        - echo Hello Kubernetes! && sleep 360000
        env:
        - name: AWS_ROLE_ARN
          value: arn:aws:iam::921283538843:role/eksctl-eks-addon-iamserviceaccount-default-a-Role1-SSGCB7DDESI5
        - name: AWS_WEB_IDENTITY_TOKEN_FILE
          value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
        image: amazonlinux:latest
        imagePullPolicy: Always
        name: myapp
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          name: alice-token-qlsjp
          readOnly: true
        - 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
      - name: alice-token-qlsjp
        secret:
          defaultMode: 420
          secretName: alice-token-qlsjp
    

    可以看到系统里面挂载了两个 token,

    • /var/run/secrets/kubernetes.io/serviceaccount:由 Service Account Admission Controller [4] 创建,其属于 Kubernetes 默认创建的 Token 配置文件。
    • /var/run/secrets/eks.amazonaws.com/serviceaccount:由 eks-pod-identity-webhook 协助挂载,其中定义了 projected volume 的配置 [5]

    1.2、OIDC 相关信息

    EKS 已经帮助我们创建好了 OIDC,通过自建 OIDC [6],我们可以了解到更多关于 OIDC 的信息。

    在 EKS OIDC discovery 文件中,其最终将其放置于 /.well-known/openid-configuration 配置文件定义下列规范:

    	{
    		"issuer": "https://oidc.eks.us-east-1.amazonaws.com/id/93BEE997ED0F1C1BA3BD6C8395BE0756",
    		"jwks_uri": "https://oidc.eks.us-east-1.amazonaws.com/id/93BEE997ED0F1C1BA3BD6C8395BE0756/keys",
    		"authorization_endpoint": "urn:kubernetes:programmatic_authorization",
    		"response_types_supported": ["id_token"],
    		"subject_types_supported": ["public"],
    		"claims_supported": ["sub", "iss"],
    		"id_token_signing_alg_values_supported": ["RS256"]
    	}
    

    以及 jwks_uri 描述 signing key 的信息,用于进行查询验证:

     {
    		"keys": [{
    			"kty": "RSA",
    			"e": "AQAB",
    			"use": "sig",
    			"kid": "22b7abf04dc344c44fb83499508a158d789d82d5",
    			"alg": "RS256",
    			"n": "qJj1vYyzD0CpEaU93PlPdroS_Xir23X6GdLptyCMFb5zVNoSvegTo8Bb0_zb-8-z_VYoUj-L-3q8sP6R3Hp03ozkBCKa-cQ3gtITFUuQ6UQr0oIQjeZ3etJCOt1GktXLjeYssGiW58ToiTFzqjoeqGzz2-75WS6nsFnxCyCLg-2xFq4ALFrI4fAnwKwaQKowJQDKuUA50Tqv9P9ctEclHDlVi7K3_3giyiToZtmNUn-4KpQNx-a-4I7avn8d67UybOFOdYFeDnyOe9E8Ajuis22v2CvRr7rHEFjyxVCPoT0NFqiXkQMApd-7A6Rs33kIt7STwVBWhjFT5F--BzgJfQ"
    		}]
    	}
    

    二、Pod 访问 AWS 的资源

    假如当这个 Pod 去访问 aws s3 资源的时候,我们发现可以直接使用命令aws s3 ls,由此可知,awscli 已经自动帮我们请求了 assume-role-with-web-identity,关于 awscli 为什么会自动请求这个接口,请参考文档 [7]。后续的资源请求会调用获取的临时凭证,临时凭证的存储位置为 ~/.aws/cli/cache

    我们也可也手动去 sts 服务获取临时凭证,命令如下:

    aws sts assume-role-with-web-identity --role-arn $AWS_ROLE_ARN --role-session-name alice --web-identity-token file://$AWS_WEB_IDENTITY_TOKEN_FILE
    

    获取的内容大致如下:

    {
        "Credentials": {
            "AccessKeyId": "ASIA5NAGHF6NZIPEBVGZ",
            "SecretAccessKey": "U5GXw/lcz0PTbHUPO+A7Rk4RbMAK9ISzdrYW9BeK",
            "SessionToken": "IQoJb3JpZ2luX2VjELL//////////wEaCXVzLWVhc3QtMSJIMEYCIQC7Myfzl1QvG87aAF8ZdrFACbiQbNrtzzuQfLf+QX6j4AIhAJtehbkrVMLuO7HWjzetrwkHBCGxttoGFCn8stAxfs/rKpsECCoQABoMOTIxMjgzNTM4ODQzIgxy22hqmCjadsTNf/0q+AN4hIfLXLrUtwVuysbDCuGKZByp/Ow2N/t4JaeVaN7F7qYFVMRjm2nltxc1UTsfOTlIigR6mdKqdHWX982bVlSzu95oocK4vOLcLOh4TCOTehFTnH8ghe0GMd4Pyydi5yjrSM08JRZ+ACw/7/NgZM+p8e1JWI2aLOWk66K3rTqWnKL0V2EM3d8MkVSpjRcv1Rk3j+DBnlnpD8AulTA8vxa3p2JM8jw+EHgsnFIpBoseWrOpVeY21XHkkxU8bSZCbuqWbVkrRPmNccr0Kc6MXb6jN4tXfB0/L0PjQiHqB1O74nx4f0mQGvrI8nJwAGHCRj++bOwuHG3j7CTZqrXXmzphECUKkGE0nr1zpT5CqjoZsM7e/LhDUxNznAwIpQ9AUAoi6ZMWP4wlpVOFWm/qNNZBFRX9hGb8DTLdFBgPhXB+scch52Kc/n+HYdW5sDj88eh5s9JjwR8Nst25gaVJKam++5hfIqz25PJXOXIQ51mDkY3SpvKVsa4ORXDVFJd6s+IXPpaSoqCkYfbsmXs6PVs1cnH1ZF89z2qmFalzed+QVRydQJv21j+C3wYB4foKZZpL5+qd9oXdtpBc5vHaqTbhEL9fhheCchOurTlgqLzY2PegVdzqzaCyZoL0jnEYSYXNWPGOJlIVz2cnYsW8xexh5rm1hGp7VckwsuS28AU63wF4DQFwtFbyU08QpLgBbVUpmmrG06A4Hb4ouLihGLm61LTX487gMADfoBpfMcOdLmOxKLKja1KAdtas4qHE0sovubGF5s/1ntVA44GPMIAWZlnAEf4N03YG6AbJzWxBdLZ4FZBCluLzQtm0Y2r61o92KdId5hDFF1wm/9NfH3xpi3TNW9IZbIWAan2ccoPorgZOZjqfMGqj9PDnGkVqeWX9jo6RoqFPTNigngf7FAx/kk1Q7l+eoD94P2VIKrfAAhTfGm1WPsA+1mOgzkRPGgKhbw+I+mmbloegJRY9Om8S",
            "Expiration": "2020-01-02T10:04:50Z"
        },
        "SubjectFromWebIdentityToken": "system:serviceaccount:default:alice",
        "AssumedRoleUser": {
            "AssumedRoleId": "AROA5NAGHF6NZWI5VRGOR:alice",
            "Arn": "arn:aws:sts::921283538843:assumed-role/eksctl-eks-addon-iamserviceaccount-default-a-Role1-SSGCB7DDESI5/alice"
        },
        "Provider": "arn:aws:iam::921283538843:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/93BEE997ED0F1C1BA3BD6C8395BE0756",
        "Audience": "sts.amazonaws.com"
    }
    

    那么 STS 如何与 OIDC Provider 进行验证并且最终发布 Secret Key 及 Access Key。

    由于 IAM Role 的设计也包含其他 Federation 验证的机制 [8]。在前面使用 eksctl 创建的iamserviceaccount 的时候,创建了一个 role arn:aws:iam::921283538843:role/eksctl-eks-addon-iamserviceaccount-default-a-Role1-SSGCB7DDESI5 的资源项目,例如:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::921283538843:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/93BEE997ED0F1C1BA3BD6C8395BE0756"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "oidc.eks.us-east-1.amazonaws.com/id/93BEE997ED0F1C1BA3BD6C8395BE0756:aud": "sts.amazonaws.com",
              "oidc.eks.us-east-1.amazonaws.com/id/93BEE997ED0F1C1BA3BD6C8395BE0756:sub": "system:serviceaccount:default:alice"
            }
          }
        }
      ]
    }
    

    他信任这个 Federation 来源的用户,只要是 token 可也通过 OIDC 的验证,并且满足 Condition 即可,因为我们知道,token 是由 controller manager 通过 --service-account-private-key-file="/etc/kubernetes/pki/sa.key 签署完成,而 OIDC 的 jwks_uri 里面的验证证书为 sa.pub,这是一对秘钥对,因此可也可以信任 token,这是一个 json web token [9],我们可以查看其 Payload 结构信息如下:

    {
      "aud": [
        "sts.amazonaws.com"
      ],
      "exp": 1578041687,
      "iat": 1577955287,
      "iss": "https://oidc.eks.us-east-1.amazonaws.com/id/93BEE997ED0F1C1BA3BD6C8395BE0756",
      "kubernetes.io": {
        "namespace": "default",
        "pod": {
          "name": "myapp",
          "uid": "873e92b0-2d3d-11ea-8820-0a64f353aa45"
        },
        "serviceaccount": {
          "name": "alice",
          "uid": "7a58554d-2bb1-11ea-8820-0a64f353aa45"
        }
      },
      "nbf": 1577955287,
      "sub": "system:serviceaccount:default:alice"
    }
    

    一旦 Pod 与 STS 服务器节点发起 AssumeRoleWithWebIdentity 动作时,用户端会带入 WebIdentityToken 信息,其中 STS 会将该 Token 经由您配置的 OIDC Provider 上提供的凭证信息进行比对验证 (keys.json),确认其您用户端使用 Service Account Token 发起来源为您的 OIDC Provider 所签署识别其来源,并且,认证您在 Trust Relationship 的政策,以允许您的用户端操作 AssumeRoleWithWebIdentity 动作而可以获取您对应 IAM Role 的临时存取信息,最终返回对应的 AccessKeyID 及 SecretAccessKey 资讯,使您的用户端能够再度使用该临时金钥访问其他 AWS 资源 (例如:S3 Bucket)

    参考、OAuth 2.0 VS OIDC

    OAuth 2.0

    OIDC

    参考文档:
    https://medium.com/getamis/aws-irsa-for-self-hosted-kubernetes-e045564494af
    https://www.simpleorientedarchitecture.com/openid-connect-in-a-nutshell/
    https://tools.ietf.org/html/rfc6749
    https://openid.net/specs/openid-connect-core-1_0.html

  • 相关阅读:
    1.27
    1.25
    Representation Learning with Contrastive Predictive Coding
    Learning a Similarity Metric Discriminatively, with Application to Face Verification
    噪声对比估计(负样本采样)
    Certified Adversarial Robustness via Randomized Smoothing
    Certified Robustness to Adversarial Examples with Differential Privacy
    Dynamic Routing Between Capsules
    Defending Adversarial Attacks by Correcting logits
    Visualizing Data using t-SNE
  • 原文地址:https://www.cnblogs.com/wzlinux/p/12134193.html
Copyright © 2011-2022 走看看