AWS EC2에 AWS EKS 쿠버네티스 클러스터 엑세스 권한 제공
이번 글에서는 프라이빗 서브넷으로 구축된 AWS EKS 클러스터에 접근할 수 있는 권한을 제공하는 방법에 대해 알아볼 것이다.
EC2 인스턴스에 AWS EKS 클러스터 엑세스 권한을 제공한 이유는, AWS EKS 쿠버네티스 클러스터를 프라이빗 서브넷으로 구축했을 때, 쿠버네티스 관리를 위한 EC2 인스턴스가 추가적으로 필요했다. 하지만 EC2 인스턴스는 쿠버네티스 클러스터 워커 노드가 아니기 때문에 클러스터 접근 및 관리가 불가능했다. 그래서 해당 EC2 인스턴스에 쿠버네티스 클러스터에 엑세스 할 수 있게 권한을 부여하게 되었다.
실습 순서는 다음과 같다.
1. AWS EKS 구축
2. EC2 인스턴스 생성 & IAM 계정 생성
3. AWS EKS 쿠버네티스 클러스터 접근권한 제공
1. AWS EKS 구축
AWS EKS를 활용한 쿠버네티스 클러스터 구축 글을 참고하길 바란다.
2. EC2 인스턴스 생성 & IAM 계정 생성
다음으로 쿠버네티스 클러스터에 엑세스 할 EC2 인스턴스 1개를 생성한다. 쿠버네티스 클러스터는 프라이빗 서브넷에 구축되었으니, 쿠버네티스 클러스터에 접근할 EC2 인스턴스는 쿠버네티스와 동일한 VPC에 있는 퍼블릭 서브넷에 생성해주자. IAM 역할도 지정해주지 말고 넘어가자(해당 인스턴스에 aws configure 를 통해 계정을 연결시켜주면 된다).
보안그룹은 AWS EKS에 접근 가능한 보안그룹 1개(eks-cluster-sg...)와 ssh로 외부에서 접근 가능한 보안그룹(eks-remoteAccess...) 두개를 선택한다.
EC2 생성이 완료되었으면, 쿠버네티스 클러스터 접근 용 IAM 계정을 생성해보자(계정명 : test-eks-cluster). IAM 계정에는 아무런 정책도 연결시키지 않는다.
IAM 계정 생성까지 완료하였으면, 조금 전 생성한 EC2 인스턴스에 kubectl을 설치해주자.
최신버전 설치 :
$ curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
바이너리를 실행 가능하게 변경 :
$ chmod +x ./kubectl
바이너리를 PATH가 지정된 곳으로 옮김 :
$ sudo mv ./kubectl /usr/local/bin/kubectl
다음으로 해당 EC2 인스턴스에 조금 전 생성했던 IAM 계정을 연결시켜주자.
$ aws configure
AWS Access Key ID [None]: AKIAQBXXFVLM2MTW6TXX
AWS Secret Access Key [None]: a3U/Sj5ifdUXXyx0Brdo7efruY9G6exxxxxxx
Default region name [None]: ap-northeast-2
Default output format [None]:
IAM 계정 연결이 완료되었으면 update-kubeconfig 명령어를 통해 쿠버네티스 클러스터 컨피그 파일을 생성하자.
$ aws eks --region [클러스터 리전] update-kubeconfig --name [클러스터 이름]
예 : aws eks --region ap-northeast-2 update-kubeconfig --name cloud-l3-eks
그러면 다음과 같이 에러 메시지가 발생하는 것을 확인할 수 있다.
An error occurred (AccessDeniedException) when calling the DescribeCluster operation: User: arn:aws:iam::003144002265:user/test-eks-cluster is not authorized to perform: eks:DescribeCluster on resource: arn:aws:eks:ap-northeast-2:003144002265:cluster/cloud-l3-eks
에러메시지를 확인해보면, EC2 인스턴스에 셋팅한 IAM 계정(test-eks-cluster)이 쿠버네티스 클러스터(cloud-l3-eks)에 eks:DescribeCluster를 수행할 권한이 없는 것으로 보인다.
3. IAM 계정에 eks:DescribeCluster 수행 권한 부여
IAM 계정(test-eks-cluster)에 eks:DescribeCluster 를 수행할 수 있는 권한을 부여해보자.
정책을 부여하는 방법에는 인라인 정책으로 JSON 파일을 수정하거나, eks:DescribeCluster 를 수행할 수 있는 권한을 포함하고 있는 정책을 주는 방식이 있는데 필자는 후자로 진행하도록 하겠다.
기존에 AWS EKS 워커 노드의 IAM 역할에 연결된 정책을 확인해보면 아래와 같다.
이 중 AmazonEKSWorkerNodePolicy 안에 eks:DescribeCluster 를 수행할 수 있는 권한이 포함되어 있다.
하지만 필자는 그냥 AWS EKS 워커 노드의 IAM 역할에 연결된 정책과 동일한 정책으로 설정하였다.
정책 연결이 완료되었으면 다시 쿠버네티스 클러스터 컨피그 파일을 생성해보자.
$ aws eks --region ap-northeast-2 update-kubeconfig --name cloud-l3-eks
Added new context arn:aws:eks:ap-northeast-2:003144002265:cluster/cloud-l3-eks to /home/ec2-user/.kube/config
정상적으로 컨피그 파일이 생성되었다.
그럼 이제 쿠버네티스 클러스터에 접근해보자.
$ kubectl get pod --all-namespaces
error: You must be logged in to the server (Unauthorized)
그래도 접근이 안되지 않는다.
error: You must be logged in to the server (Unauthorized) 라는 에러메시지가 나오게 되는데, 접근을 시도하는 EC2 인스턴스에 설정된 계정에는 쿠버네티스 클러스터에 접근할 수 있는 권한이 없기 때문에 나오는 에러메시지이다. 접근 권한 제공은 아래 4번에서 진행해보자.
4. AWS EKS 쿠버네티스 클러스터 접근권한 제공
EC2 인스턴스에게 쿠버네티스 클러스터 접근 권한을 주기 위해서는 쿠버네티스 클러스터의 configmap을 수정해줘야 한다.
하지만 configmap을 수정하기 위해서는 쿠버네티스 클러스터에 접근해야 하는데, 필자는 aws configure를 활용하여 로컬PC에 IAM 마스터 계정(AWS 로그인 계정)을 설정해놓고, 로컬PC에서 쿠버네티스 클러스터에 접근할 것이다.
우선 로컬PC에도 kubectl과 aws-cli가 설치되어 있다는 가정하에 실습을 진행하겠다.
4.1. 로컬PC에 AWS 로그인 계정 설정(aws configure)
로컬PC에서 aws configure 명령어를 통해서 IAM 계정을 설정해주는데, 이 글에서는 AWS 로그인 계정으로 설정해 줄 것이다.
AWS 로그인 계정은 우측 상단의 내 계정 선택 후 [내 보안 자격증명] -> [액세스 키]에서 생성 가능하다.
생성을 완료하였으면 로컬PC에서 해당 계정 설정을 진행해보자(필자는 로컬PC의 git-bash를 통해서 진행하였다)
$ aws configure
AWS Access Key ID [None]: AKIAIEX7B4SHBX3SFTEA
AWS Secret Access Key [None]: ABCefgFGXXX12UXXyx0Brdo7efruY9G6exxxxxxx
Default region name [None]: ap-northeast-2
Default output format [None]:
4.2. 로컬PC에 쿠버네티스 컨피그파일 생성
설정이 완료되었으면 쿠버네티스 컨피그 파일을 생성해보자.
로컬 PC는 AWS 로그인 계정으로 설정해 놓았기 때문에 AccessDeniedException 에러나 Unauthorized 에러 없이 쿠버네티스 클러스터에 접근하여 컨피그 파일 생성이 가능하다.
$ aws eks --region [클러스터 리전] update-kubeconfig --name [클러스터 이름]
예 : aws eks --region ap-northeast-2 update-kubeconfig --name cloud-l3-eks
4.3. EC2 인스턴스에 쿠버네티스 클러스터 접근권한 부여
컨피그 파일 생성이 완료되었으면 EC2 인스턴스에 쿠버네티스 클러스터에 접근권한을 부여해보자. 접근권한을 부여하기 위해서는 쿠버네티스 configmap을 수정해야 한다.
우선 현재 쿠버네티스 configmap 중 한개인 aws-auth라는 configmap을 aws-auth.yaml이라는 파일로 저장해보자.
$ kubectl get configmaps aws-auth -n kube-system -o yaml > aws-auth.yaml
그리고 저장한 aws-auth.yaml파일을 열어보면 아래와 같이 저장된 것을 확인할 수 있다.
apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::002144002222:role/cloud-l3-worker-node-role
username: system:node:{{EC2PrivateDNSName}}
kind: ConfigMap
metadata:
creationTimestamp: "2020-10-02T14:01:33Z"
name: aws-auth
namespace: kube-system
resourceVersion: "13807"
selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth
uid: 4214694c-f087-47fa-b850-2005c3a27777
위 내용에서 data 아래 부분에 mapUsers 항목을 새로 만든 후 접근을 시도하는 EC2 인스턴스에 설정된 user 정보를 셋팅해주면 된다.
EC2 인스턴스의 user 정보는 aws sts get-caller-identity 명령어를 통해 확인할 수 있다.
$ aws sts get-caller-identity
{
"Account": "003144002265",
"UserId": "AIDAQBO3FVLMU6KSPN3FC",
"Arn": "arn:aws:iam::002144002222:user/test-eks-cluster"
}
명령어를 통해 추출한 user 정보를 aws-auth.yaml 파일에 넣어보자.
apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::002144002222:role/cloud-l3-worker-node-role
username: system:node:{{EC2PrivateDNSName}}
mapUsers: |
- groups:
- system:masters
userarn: arn:aws:iam::002144002222:user/test-eks-cluster
username: test-eks-cluster
kind: ConfigMap
metadata:
creationTimestamp: "2020-10-02T14:01:33Z"
name: aws-auth
namespace: kube-system
resourceVersion: "13807"
selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth
uid: 4214694c-f087-47fa-b850-2005c3a27777
aws-auth.yaml 수정이 완료되었으면 변경사항을 적용시키자.
$ kubectl apply -f aws-auth.yaml --force
4.4. EC2 인스턴스에서 쿠버네티스 클러스터로 접근
설정이 완료되었으면 이제 EC2 인스턴스에서 쿠버네티스 클러스터로 접근해보자.
접근이 잘 되는 것을 확인할 수 있다.
$ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-node-n5vkl 1/1 Running 0 112m
kube-system aws-node-xzvtv 1/1 Running 0 111m
kube-system coredns-7dd7f84d9-b86hz 1/1 Running 0 3h11m
kube-system coredns-7dd7f84d9-mr8fd 1/1 Running 0 3h11m
kube-system kube-proxy-lnvtc 1/1 Running 0 112m
kube-system kube-proxy-x4sdr 1/1 Running 0 111m
$ kubectl get configmaps --all-namespaces
NAMESPACE NAME DATA AGE
kube-system aws-auth 2 23s
kube-system coredns 1 3h11m
kube-system cp-vpc-resource-controller 0 3h10m
kube-system eks-certificates-controller 0 3h11m
kube-system extension-apiserver-authentication 6 3h11m
kube-system kube-proxy 1 3h11m
kube-system kube-proxy-config 1 3h11m
※추가
필자가 실습을 진행하면서 잘 안되었던 부분은 aws-auth.yaml 파일에 접근 권한 추가가 완료된 상황에서도 계속해서 error: You must be logged in to the server (Unauthorized) 에러가 발생했던 점이었다.
에러가 발생한 사유는 aws-auth.yaml파일이 정상적으로 수정이 되지 않은 상황에서 발생한 에러였다.
mapRoles의 구문을 그대로 가져와서 mapUsers를 만들다보니 mapUsers에 rolearn을 설정하여 문제가 발생한 것이었다. 이 부분은 userarn으로 변경하여 문제를 해결하였다.
참고
aws.amazon.com/ko/premiumsupport/knowledge-center/amazon-eks-cluster-access/