您好,登錄后才能下訂單哦!
今天小編給大家分享的是EKS IRSA的工作機制,相信大部分人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,話不多說,一起往下看吧。
我們這里使用的 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 的一個架構圖大致如下:
在由 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.key
和sa.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 的配置。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 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
OIDC
看完上述內容,你們對EKS IRSA的工作機制有進一步的了解嗎?如果還想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。