Skip to content

Latest commit

 

History

History
82 lines (66 loc) · 6.47 KB

EKS 인증과정.md

File metadata and controls

82 lines (66 loc) · 6.47 KB

kubectl에서 EKS Cluster의 K8s API Server에 접근하거나, Worker Node에서 동작하는 kubelet에서 EKS Cluster의 K8s API Server 접근시에는 AWS IAM Authenticator가 이용된다.

image image

왼쪽은 kubelet의 kubeconfig이고, 오른쪽은 kubectl의 kubeconfig이다. 두 kubeconfig 모두 user 부분을 확인해보면 aws eks get-token 명령어를 수행하는 것을 확인할 수 있다. aws eks get-token 명령어는 해당 명령어를 수행하는 Identity가 누구인지 알려주는 AWS STS의 GetCallerIdentity API의 Presigned URL을 생성하고, 생성한 URL을 Encoding하여 Token을 생성한다. 여기서 Identity는 AWS IAM의 User/Role을 의미한다.

Presigned URL은 의미 그대로 미리 할당된 URL을 의미한다. AWS STS의 GetCallerIdentity API를 호출하기 위해서는 AccessKey/SecretAccessKey와 같은 Secret이 필요하지만, Presigned URL을 이용하여 GetCallerIdentity API를 호출하면 Secret없이 호출이 가능하다. Token을 통해서 전달되는 GetCallerIdentity API의 Presigned URL은 AWS IAM Authenticator에게 전달되어 aws eks get-token 명령어를 수행한 Identity이 누구인지 파악하는데 이용된다.

# "aws eks get-token" 명령어 출력 결과 예시
$ aws eks get-token --cluster-name test-eks-cluster
{
	"kind": "ExecCredential",
	"apiVersion": "client.authentication.k8s.io/v1alpha1",
	"spec": {},
	"status": {
		"expirationTimestamp": "2022-04-26T17:46:42Z",
		"token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTIuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFSNVFPRVpQVTRRWFg1SDRGJTJGMjAyMjA0MjYlMkZhcC1ub3J0aGVhc3QtMiUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjIwNDI2VDE3MzI0MlomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPTIxOGQ4MDQ5NTBlZGMxMWRlZmQ0OWMwYTFkNWZkYWNjMzI0Y2M4MzBmZDZmMDZkNTlhN2Q5NzUwMGZhM2U3Mzg"
	}
}

$ base64url decode aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTIuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFSNVFPRVpQVTRRWFg1SDRGJTJGMjAyMjA0MjYlMkZhcC1ub3J0aGVhc3QtMiUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjIwNDI2VDE3MzI0MlomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPTIxOGQ4MDQ5NTBlZGMxMWRlZmQ0OWMwYTFkNWZkYWNjMzI0Y2M4MzBmZDZmMDZkNTlhN2Q5NzUwMGZhM2U3Mzg
https://sts.ap-northeast-2.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAR5QOEZPU4QXX5H4F%2F20220426%2Fap-northeast-2%2Fsts%2Faws4_request&X-Amz-Date=20220426T173242Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=218d804950edc11defd49c0a1d5fdacc324cc830fd6f06d59a7d97500fa3e738

token의 "k8s-aws-v1" 뒷부분의 문자열을 base64url로 decoding을 수행하면 GetCallerIdentity API의 Presigned URL을 확인할 수 있다.

GetCallerIdentity API의 Presigned URL에 x-k8s-aws-id: Cluster 이름 Header와 함께 Get 요청을 수행하면 "aws eks get-token" 명령어를 수행한 Identity이 누구인지 알 수 있다. GetCallerIdentity API의 Presigned URL을 대상으로 Get 요청을 수행하면 "test" User가 "aws eks get-token" 명령어를 수행했다는 사실을 알 수 있다.

AWS IAM Authenticator는 EKS Cluster의 K8s API Server에 인증 Webhook Server로 등록되어 있다. 따라서 kubelet/kubectl이 "aws eks get-token" 명령어를 통해서 생성한 Token은 AWS IAM Authenticator에게 전달된다.

$ curl -H "x-k8s-aws-id: test-eks-cluster" "https://sts.ap-northeast-2.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAR5QOEZPU4QXX5H4F%2F20220426%2Fap-northeast-2%2Fsts%2Faws4_request&X-Amz-Date=20220426T173242Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=218d804950edc11defd49c0a1d5fdacc324cc830fd6f06d59a7d97500fa3e738"
<GetCallerIdentityResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
  <GetCallerIdentityResult>
    <Arn>arn:aws:iam::142021912854:user/test</Arn>
    <UserId>DCDAJXZHJQB4JQK2FDWQ</UserId>
    <Account>142021912854</Account>
  </GetCallerIdentityResult>
  <ResponseMetadata>
    <RequestId>9bdb9ca4-65c5-4659-8ca0-0e0625d14c5d</RequestId>
  </ResponseMetadata>
</GetCallerIdentityResponse>

"aws-auth" ConfigMap

AWS IAM Authenticator는 "aws eks get-token" 명령어를 수행한 Identity를 파악한 다음, 파악한 Identity가 EKS Cluster의 어떤 User/Group과 Mapping 되는지 확인한다. 이후 AWS IAM Authenticator는 Mapping 되는 EKS Cluster의 User/Group을 EKS Cluster의 K8s API Server에게 전달한다.

"aws eks get-token" 명령어을 수행한 Identity와 EKS Cluster의 User/Group과의 Mapping 정보는 kube-system Namespace에 존재하는 aws-auth ConfigMap에 저장되어 있다. mapUser 항목은 "aws eks get-token" 명령어을 수행한 AWS IAM User와 EKS Cluster의 User/Group을 Mapping을 하는데 이용되며, mapRoles 항목은 "aws eks get-token" 명령어를 수행한 AWS IAM Role과 EKS Cluster의 User/Group을 Mapping 하는데 이용한다.

에서 test AWS IAM User는 EKS Cluster의 admin User 또는 system:master Group에 Mapping되는걸 확인할 수 있다. EKS Cluster에서 Node Group 생성시 각 Node Group에서 이용하는 AWS IAM Role이 생성되는데, Node Group의 AWS IAM Role도 [파일 3]의 mapRoles 항목에서 확인할 수 있다.

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::132099418825:role/eksctl-test-eks-cluster-nodegrou-NodeInstanceRole-1CR0AFVMLFHSE
      username: system:node:
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::132099418825:role/eksctl-test-eks-cluster-nodegrou-NodeInstanceRole-1FLORRGQWIWD8
      username: system:node:
  mapUsers: |
    - userarn: arn:aws:iam::142627221238:user/test
      username: admin
      groups:
        - system:masters
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
...