咱們知道 apiserver 有如下幾種認證方式:html
通常咱們使用二進制自建 k8s 集羣,或者使用 kubeadm 建立的集羣,集羣的管理者,也就是 k8s 中 user 這個對象,都是使用的 X509 證書進行驗證,若是屬於同一個 CA 簽發的,就承認這個用戶;node
企業爲了減小用戶管理的複雜程度,須要想辦法如何把 IAM 的用戶集成到 EKS 集羣中,這樣咱們就不須要耽誤爲 EKS 建立用戶,減小一套用戶的維護工做,那這是如何集成的呢,是經過了 k8s 的 Webhook Token Authentication,其認證過程架構圖以下:git
咱們能夠從圖中看到多了 Authentication 這一部分,經過 aws-iam-authenticator,咱們能夠知道,這是運行在 EKS Control Plane 中的一組 DaemonSet Pod,用來接收 apiserver 的認證請求。github
咱們使用 eksctl 這個命令建立 EKS 集羣,默認 eksctl 會調用 awscli 的 config,因此咱們須要先配置好 awscli,相關的用戶或者角色具備建立 eks 集羣的權限便可:web
eksctl create cluster --name eks --region us-east-1 \ --node-type=t2.small --nodes 1 --ssh-public-key .ssh/id_rsa.pub \ --managed --zones us-east-1f,us-east-1c --vpc-nat-mode Disable
集羣建立好以後,會自動幫咱們配置好 kubeclt 須要的配置文件,而且集羣的建立者會自動獲取集羣 cluster-admin 的角色,擁有最高權限。bootstrap
咱們首先能夠經過 CloudWatch Logs 去查看 kube-apiserver 的啓動參數,咱們能夠看到有這樣一組啓動參數:api
--authentication-token-webhook-config-file="/etc/kubernetes/authenticator/apiserver-webhook-kubeconfig.yaml"
說明咱們已經啓動了 webhook 方式的認證,那參數後面的 yaml 文件裏面是什麼呢,咱們能夠經過 aws-iam-authenticator 的 github 文檔能夠看到,咱們使用以下命令進行生成:安全
wangzan:~/k8s $ aws-iam-authenticator init -i `openssl rand 16 -hex` INFO[2020-01-07T07:50:54Z] generated a new private key and certificate certBytes=804 keyBytes=1192 INFO[2020-01-07T07:50:54Z] saving new key and certificate certPath=cert.pem keyPath=key.pem INFO[2020-01-07T07:50:54Z] loaded existing keypair certPath=cert.pem keyPath=key.pem INFO[2020-01-07T07:50:54Z] writing webhook kubeconfig file kubeconfigPath=aws-iam-authenticator.kubeconfig INFO[2020-01-07T07:50:54Z] copy cert.pem to /var/aws-iam-authenticator/cert.pem on kubernetes master node(s) INFO[2020-01-07T07:50:54Z] copy key.pem to /var/aws-iam-authenticator/key.pem on kubernetes master node(s) INFO[2020-01-07T07:50:54Z] copy aws-iam-authenticator.kubeconfig to /etc/kubernetes/aws-iam-authenticator/kubeconfig.yaml on kubernetes master node(s) INFO[2020-01-07T07:50:54Z] configure your apiserver with `--authentication-token-webhook-config-file=/etc/kubernetes/aws-iam-authenticator/kubeconfig.yaml` to enable authentication with aws-iam-authenticator
查看生成的配置文件aws-iam-authenticator.kubeconfig
服務器
wangzan:~/k8s $ cat aws-iam-authenticator.kubeconfig # clusters refers to the remote service. clusters: - name: aws-iam-authenticator cluster: certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJRENDQWdpZ0F3SUJBZ0lRVDRmUllwRy9uSlE0UURmSHUwb2M3ekFOQmdrcWhraUc5dzBCQVFzRkFEQWcKTVI0d0hBWURWUVFERXhWaGQzTXRhV0Z0TFdGMWRHaGxiblJwWTJGMGIzSXdJQmNOTWpBd01UQTNNRGMxTURVMApXaGdQTWpFeE9URXlNVFF3TnpVd05UUmFNQ0F4SGpBY0JnTlZCQU1URldGM2N5MXBZVzB0WVhWMGFHVnVkR2xqCllYUnZjakNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLRkhTU3ZjWGZFNVZrN3UKejBRNjFGVE1LQS9PeE5HaVlOa05iS0ZzSW9pdW5VejBLdUI4aFBReitEOGxpNnpYZUozWDdNNVNyaG1hYjRBMgowWXJNZEVlcSthYVR5aVhFV2QrREFlUU9HcFFRQm0ya2hvdEgzS2Vrd2dlTjlwbzFUUjBHQVgrbFBQWWloOHNBCml6ZWxBRENLZUMrUS8yWnVZYkttaUFiSm1MNDdqc09nd0pXYldQV0JOdm54VDkrL0wwTHphN1c3MVdieCszaWsKQUdUT2xDWm5tZjY0b0sxQWw4eDNxUktnSXp0bnFBMWRFeEMwS2ZzR1dRRy9Xb00rbnRXZW40QmJEOW1XakF4Zgo0Yk9CaXBOcDMrMlFJOU5LL1pUOTYyaDFZbE8yUWdiYVMrSTZtR2o5WXhwamFXdXgyWGNUd2N0MTFjODFMNWcxCmNaVjZJZ2tDQXdFQUFhTlVNRkl3RGdZRFZSMFBBUUgvQkFRREFnS2tNQk1HQTFVZEpRUU1NQW9HQ0NzR0FRVUYKQndNQk1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0dnWURWUjBSQkJNd0VZSUpiRzlqWVd4b2IzTjBod1IvQUFBQgpNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUIyaE1wYm5kTDhVa3VRNVVuZzNkWTh5Y0RQZ2JvbU9Mb0t5dUlzCnVoNkljMUtaMUFiNmVoVDg2bzN2bzJzbnVoNkhibU13NjhvNE9SSllLdTB4RXB3RDR0YUlSVEN1bk9KVHFUeHoKZDZsN2xqdGtBMWZnUktpUHF1SjlyUmxqYXVTMGMxU05lWTVmR2hhUEh3UFBBMHoxN3orMWdiVzNiUjFEckxHQwp6WHVCNStFM0xSVHJCck53aHlZOUtIcVB4Vy9PL1M2V2FZbUR4R3Y4bklNNUUrTzltRFBPWGZpWFJDRFFkb2R5ClRadnU1VDR5ZVhQaEQwRmJKdjg4OSsxZnR4TGlSaUdTQ29lRTNEMUdiYSswZXFMT0hidExUY29VZ25WTGVlMTAKclZDOWRiOU05ckxDZnU1aUEvcGdORm80VTF1ejAvbFUyV0RnYSthUWNNeC9iaHZJCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K server: https://localhost:21362/authenticate # users refers to the API Server's webhook configuration # (we don't need to authenticate the API server). users: - name: apiserver # kubeconfig files require a context. Provide one for the API Server. current-context: webhook contexts: - name: webhook context: cluster: aws-iam-authenticator user: apiserver
首先,咱們查看一下 kubectl 的配置文件信息:架構
apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED server: https://93BEE997ED0F1C1BA3BD6C8395BE0756.sk1.us-east-1.eks.amazonaws.com name: eks.us-east-1.eksctl.io contexts: - context: cluster: eks.us-east-1.eksctl.io user: wangzan@eks.us-east-1.eksctl.io name: wangzan@eks.us-east-1.eksctl.io current-context: wangzan@eks.us-east-1.eksctl.io kind: Config preferences: {} users: - name: wangzan@eks.us-east-1.eksctl.io user: exec: apiVersion: client.authentication.k8s.io/v1alpha1 args: - token - -i - eks command: aws-iam-authenticator env: null
咱們能夠看到 user 字段,這裏不是使用證書進行認證的,而是使用的 aws-iam-authenticator client,其命令以下:
wangzan:~ $ aws-iam-authenticator token -i eks {"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1alpha1","spec":{},"status":{"expirationTimestamp":"2020-01-07T08:23:23Z","token":"k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUE1TkFHSEY2TllYU01DTEhPJTJGMjAyMDAxMDclMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDEwN1QwODA5MjNaJlgtQW16LUV4cGlyZXM9MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPTU2MjA5OTZhY2MzZGE3OWI3OGI0NDVjOTVkMTMyNmU0NjZmNTUyZTMzNDdkN2Y5MmExNGUwMzcwOTJiMzdmMDY"}}
這裏實際上是向 sts 獲取一個臨時的 token,用做身份憑證,這個命令也等同於下面的命令:
wangzan:~ $ aws eks get-token --cluster-name eks {"status": {"expirationTimestamp": "2020-01-07T08:25:38Z", "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1FeHBpcmVzPTYwJlgtQW16LURhdGU9MjAyMDAxMDdUMDgxMTM4WiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2VjdXJpdHktVG9rZW49JlgtQW16LUNyZWRlbnRpYWw9QUtJQTVOQUdIRjZOWVhTTUNMSE8lMkYyMDIwMDEwNyUyRnVzLWVhc3QtMSUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1TaWduYXR1cmU9NDUyYzA5ZTIwMzg2YjFmODU0NTU4YjhjNzBkNDA2MzdkYzM2Y2ExNzA5YWIxODQzNzE3NDdhY2IwYTUyNGIzYw"}, "kind": "ExecCredential", "spec": {}, "apiVersion": "client.authentication.k8s.io/v1alpha1"}
咱們回到上面的架構圖,kubectl 會把這個獲取的 token,放到 http 的請求頭 Authorization 裏面,發送給 apiserver,apiserver 收到以後,回去請求已經配置好的 webhook 服務器,也就是咱們前面所說的 daemonset pod(aws-iam-authenticator server),這個 aws-iam-authenticator server 會拿着 token 去請求 sts 服務,sts 服務驗證其 token 的合法性,並返回 IAM 用戶的 ARN(IAM Identity);
當 aws-iam-authenticator server 獲得返回的 ARN 以後,回去和 k8s 中的一個 configmap aws-auth 去對比。
咱們查看一下剛建立好的機器,aws-auth 這個 configmap裏面有什麼信息:
wangzan:~ $ kubectl get cm aws-auth -nkube-system -oyaml apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::921283538843:role/eksctl-eks-nodegroup-ng-5a1b33b9-NodeInstanceRole-1B757SI5DCABJ username: system:node:{{EC2PrivateDNSName}} - groups: - system:bootstrappers - system:nodes - system:node-proxier rolearn: arn:aws:iam::921283538843:role/eksctl-eks-cluster-FargatePodExecutionRole-DEAGGBFGQ9YB username: system:node:{{SessionName}} kind: ConfigMap metadata: creationTimestamp: "2019-12-30T07:57:47Z" name: aws-auth namespace: kube-system resourceVersion: "529891" selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth uid: 117c0e14-2ada-11ea-8820-0a64f353aa45
這裏面定義了 IAM Identity 和 k8s 裏面的 user 或者 group 的映射關係,集羣建立的默認管理員並無放在這裏面,多是處於安全的考慮,由於這個文件是能夠進行編輯修改的。
經過上面一步咱們能夠知道,經過對比 aws-auth,apiserver 會獲得請求用戶的 username 或者 group,而後在經過其 authorization 受權方式對 IAM 賦予相應的權限,咱們集羣通常使用的是 RBAC。
關於更多的一些配置信息,能夠參照官方文檔:
https://github.com/kubernetes-sigs/aws-iam-authenticator
https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/add-user-role.html