현재 EKS로 마이그레이션을 진행하면서, 노드 클러스터를 프라이빗 서브넷에 엔드포인트를 두었다.
만약 노드 클러스터의 엔드포인트가 '퍼블릭'이었다면 맥 터미널 등 외부 CLI 환경을 통해 접근할 수 있었겠지만
나는 보안성을 높이고자 엔드포인트를 '프라이빗'으로 두었기 때문에 동일 VPC 내의 인스턴스로 접근해야 했었다.
EKS 클러스터에 접근하기 위한 인스턴스로 기존에 사용하던 EC2 인스턴스를 그대로 사용하였다.
(각종 패키지 설치하고 설정하는게 귀찮아서...)
EKS Cluster를 만들때는 AWS root 계정으로 로그인하여 생성했는데,
이 때문에 현재 EC2인스턴스에 연결된 IAM 사용자로는 권한 문제로 계속 kubectl get nodes가 안되고 오류가 발생했었다.
다음과 같은 순서로 문제를 해결하였다.
(1) EKS관리 Role 만들기
→ (2) sqs-user가 그 Role을 Assume 할 수 있게 허용(trust policy)
→ (3) Role에 권한(권한부여/attach)
→ (4) aws-auth에 Role 매핑(mapRoles)
→ (5) kubeconfig를 Role로 업데이트
1. 준비
a. 클러스터를 만들 때 사용한 계정(root)으로 로그인하여 AWS CLI 환경을 만들고,
b. 현재 권한을 부여하고자하는 IAM사용자(MyUser)가 로그인된 EC2에 ssh 접속하여 쉘을 띄운다.
arn:aws:iam::[AWS ID]:user/MyUser
총 2개의 쉘이 띄워진다.
aws sts get-caller-identity
각각의 환경에서 해당 명령어를 통해, 로그인한 사용자가 맞는지 확인한다.
2. Trust policy 작성
a쉘(root)에서 /tmp/trust-policy.json을 만든다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::[AWS ID]:user/MyUser" },
"Action": "sts:AssumeRole"
}
]
}
이 파일은 EKSAdminRole을 sqs-user가 AssumeRole 할 수 있게 허용하는 신뢰 정책(trust policy)이다.
3. IAM Role 생성
a쉘에서 다음 명령어를 통해 IAM Role을 생성한다.
aws iam create-role \
--role-name EKSAdminRole \
--assume-role-policy-document file:///tmp/trust-policy.json
확인:
aws iam get-role --role-name EKSAdminRole
4. Role에 관리자 권한 붙이기
a쉘에서 진행한다.
aws iam attach-role-policy \
--role-name EKSAdminRole \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
5. sqs-user에 AssumeRole 호출 권한 명시적으로 추가
일반적으로 trust policy만 있어도 가능하지만, 어떤 환경에선 호출자 정책에서 sts:AssumeRole이 필요할 수 있다.
a쉘에서 파일 /tmp/allow-assume-policy.json 생성한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::[AWS ID]:role/EKSAdminRole"
}
]
}
적용:
aws iam put-user-policy \
--user-name MyUser \
--policy-name AllowAssumeEKSAdminRole \
--policy-document file:///tmp/allow-assume-policy.json
6. aws-auth ConfigMap에 Role 매핑
aws-auth에 Role을 추가해서 EKS가 그 Role을 Kubernetes system:masters로 매핑하도록 해야한다.
6-1. 기존 ConfigMap 받아오기
kubectl get configmap aws-auth -n kube-system -o yaml > /tmp/aws-auth.yaml
6-2. /tmp/aws-auth.yaml 편집 -> data.mapRoles에 아래 블록을 기존 노드 role 뒤에 추가
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: arn:aws:iam::[AWS ID]:role/ec2-role-for-eks-node
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
- rolearn: arn:aws:iam::[AWS ID]:role/EKSAdminRole
username: eks-admin
groups:
- system:masters
이건 전체 예시인데, mapRoles의 맨아래의 "- rolearn: arn:aws:iam::[AWS ID]:role/EKSAdminRole"에서부터 4줄을 추가해주면 된다.
이때, groups: 아래의 들여쓰기를 꼭 2칸 띄워서 문법 규칙을 잘 지켜줘야한다!!!
6-3. 기존 메타데이터(resourceVersion, uid, creationTimestamp 등)는 파일에 남겨두지 않고, 지워준다.
6-4. 적용
kubectl apply -f /tmp/aws-auth.yaml -n kube-system
# 또는 충돌 시
kubectl replace -f /tmp/aws-auth.yaml -n kube-system
6-5. 확인
kubectl describe configmap aws-auth -n kube-system
# data.mapRoles 가 갱신되었는지 확인
7. kubeconfig를 Role 사용으로 업데이트
MyUser가 Role을 assume 하여 kube 토큰을 얻는다.
b쉘(MyUser쉘)에서 다음 명령어를 실행한다.
aws eks update-kubeconfig \
--region ap-northeast-2 \
--name [Cluster Name] \
--role-arn arn:aws:iam::[AWS ID]:role/EKSAdminRole
이 명령은 kubeconfig의 users.exec.args에 --role-arn <EKSAdminRole ARN>을 추가해서 AWS CLI가 EKS 토큰을 얻을 때 AssumeRole 하도록 설정한다.
8. 테스트
먼저 직접 STS로 assume 해본다.
aws sts assume-role \
--role-arn arn:aws:iam::[AWS ID]:role/EKSAdminRole \
--role-session-name test-session
성공하면 Credentials(AccessKeyId/Secret/SessionToken)이 리턴됨 → MyUser가 Role을 정상적으로 assume 가능.
그 다음 kubectl로 확인
kubectl get nodes
kubectl create namespace production