成都网站建设设计

将想法与焦点和您一起共享

EKSIRSA的工作机制

今天小编给大家分享的是EKS IRSA的工作机制,相信大部分人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,话不多说,一起往下看吧。

创新互联成立于2013年,是专业互联网技术服务公司,拥有项目网站制作、做网站网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元思礼做网站,已为上家服务,为思礼各地企业和个人服务,联系电话:028-86922220

一、aws-iam-token 的生成

1.1 token 生成

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

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

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

EKS IRSA的工作机制

在由 API Server 创建一个 pod 后,由 Self-hosted Kubernetes setup 所讲,通过 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"

--service-account-key-file 是用来 verify token的;
--service-account-issuer 对呀 JWT token 中的 iss claim。
service account token 是由 controller-manager 控制器签署的,相关的私钥在其启动参数中,所以我们查看其启动参数如下:

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

这里的 sa.keysa.pub 是一对秘钥对。

在 token 签署完成后,会触发 eks-pod-identity-webhook,这里的 pod-identity-webhook 是 k8s 的 mutating admission webhook,由 eks-pod-identity-webhook 协助将相关的 Token 信息写入到 etcd 中,然后以 Projected Volume 的形式把 token 挂载到 Pod 中,并把 iam service account 中的 role-arn 和刚刚生成的 token 注入到 Pod 的环境变量AWS_WEB_IDENTITY_TOKEN_FILE中。
我看可以通过命令查看到集群中的MutatingWebhookConfiguration

wangzan:~ $ kubectl get MutatingWebhookConfiguration pod-identity-webhook -o yaml
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"admissionregistration.k8s.io/v1beta1","kind":"MutatingWebhookConfiguration","metadata":{"annotations":{},"name":"pod-identity-webhook"},"webhooks":[{"clientConfig":{"caBundle":${CA_BUNDLE},"url":"https://127.0.0.1:23443/mutate"},"name":"iam-for-pods.amazonaws.com","rules":[{"apiGroups":[""],"apiVersions":["v1"],"operations":["CREATE"],"resources":["pods"]}]}]}
  creationTimestamp: "2019-12-30T07:53:28Z"
  generation: 1
  name: pod-identity-webhook
  resourceVersion: "170"
  selfLink: /apis/admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations/pod-identity-webhook
  uid: 7771f2b5-2ad9-11ea-8820-0a64f353aa45
webhooks:
- admissionReviewVersions:
  - v1beta1
  clientConfig:
    caBundle: ${CA_BUNDLE}
    url: https://127.0.0.1:23443/mutate
  failurePolicy: Ignore
  name: iam-for-pods.amazonaws.com
  namespaceSelector: {}
  rules:
  - apiGroups:
    - ""
    apiVersions:
    - v1
    operations:
    - CREATE
    resources:
    - pods
    scope: '*'
  sideEffects: Unknown
  timeoutSeconds: 30

the ${CA_BUNDLE}above refers to the actual CA bundle retrieved from the k8s API。
apiserver收到与rules匹配的请求时,apiserver根据clientConfig配置定向给webhook发送admissionReview请求。

我可以通过查看 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 创建,其属于 Kubernetes 默认创建的 Token 配置文件。
  • /var/run/secrets/eks.amazonaws.com/serviceaccount:由 eks-pod-identity-webhook 协助挂载,在挂载的过程中,向token注入了audience等参数,其中定义了 projected volume 的配置。

1.2、OIDC 相关信息

EKS 已经帮助我们创建好了 OIDC,通过自建 OIDC,我们可以了解到更多关于 OIDC 的信息,在这里我们是使用的最简陋的 oidc provider 服务,只是提供了一个验证的功能,可以比喻为我们证书的颁发机构 CA。

在 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"
        }]
    }

通过自建过程,我们可以得知 oidc 的公钥信息来自于上面的  sa.pub。

go run ./hack/self-hosted/main.go -key $PKCS_KEY  | jq '.keys += [.keys[0]] | .keys[1].kid = ""' > keys.json

二、Pod 访问 AWS 的资源

假如当这个 Pod 去访问 aws s3 资源的时候,我们发现可以直接使用命令aws s3 ls,由此可知,awscli 已经自动帮我们请求了 assume-role-with-web-identity,关于 awscli 为什么会自动请求这个接口,请参考awscli文档。后续的资源请求会调用获取的临时凭证,临时凭证的存储位置为 ~/.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/t4JaeVaN7F7qYFVMRjm2nltxc1UTsfOTlIigR6mdKqdHWX982bVlSzu95oocK4vOLcLOh5TCOTehFTnH8ghe0GMd4Pyydi5yjrSM08JRZ+ACw/7/NgZM+p8e1JWI2aLOWk66K3rTqWnKL0V2EM3d8MkVSpjRcv1Rk3j+DBnlnpD8AulTA8vxa3p2JM8jw+EHgsnFIpBoseWrOpVeY21XHkkxU8bSZCbuqWbVkrRPmNccr0Kc6MXb6jN4tXfB0/L0PjQiHqB1O74nx4f0mQGvrI8nJwAGHCRj++bOwuHG3j7CTZqrXXmzphECUKkGE0nr1zpT5CqjoZsM7e/LhDUxNznAwIpQ9AUAoi6ZMWP4wlpVOFWm/qNNZBFRX9hGb8DTLdFBgPhXB+scch62Kc/n+HYdW5sDj88eh6s9JjwR8Nst25gaVJKam++5hfIqz25PJXOXIQ51mDkY3SpvKVsa4ORXDVFJd6s+IXPpaSoqCkYfbsmXs6PVs1cnH1ZF89z2qmFalzed+QVRydQJv21j+C3wYB4foKZZpL5+qd9oXdtpBc5vHaqTbhEL9fhheCchOurTlgqLzY2PegVdzqzaCyZoL0jnEYSYXNWPGOJlIVz2cnYsW8xexh6rm1hGp7VckwsuS28AU63wF4DQFwtFbyU08QpLgBbVUpmmrG06A4Hb4ouLihGLm61LTX487gMADfoBpfMcOdLmOxKLKja1KAdtas4qHE0sovubGF5s/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 验证的机制。在前面使用 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,我们可以查看其 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
EKS IRSA的工作机制

OIDC

EKS IRSA的工作机制

看完上述内容,你们对EKS IRSA的工作机制有进一步的了解吗?如果还想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读。


网页题目:EKSIRSA的工作机制
标题网址:http://chengdu.cdxwcx.cn/article/phdogo.html