본문 바로가기

AWS EKS 실습/EKS Beginner

Kubernetes access 관리를 위한 IAM Groups 사용

ㅁ Create IAM Roles

 

3개의 Role을 만든다.

 

ㅇ k8sAdmin (EKS Cluster를 위한 admin 권한)

ㅇ k8sDev (EKS Cluster의  developers namespace에 액세스 권한 할당)

ㅇ k8sInteg (EKS Cluster의 Integration namespace에 액세스 권한 할당)

 

POLICY=$(echo -n '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::'; echo -n "$ACCOUNT_ID"; echo -n ':root"},"Action":"sts:AssumeRole","Condition":{}}]}')

echo ACCOUNT_ID=$ACCOUNT_ID
echo POLICY=$POLICY

aws iam create-role \
  --role-name k8sAdmin \
  --description "Kubernetes administrator role (for AWS IAM Authenticator for Kubernetes)." \
  --assume-role-policy-document "$POLICY" \
  --output text \
  --query 'Role.Arn'

aws iam create-role \
  --role-name k8sDev \
  --description "Kubernetes developer role (for AWS IAM Authenticator for Kubernetes)." \
  --assume-role-policy-document "$POLICY" \
  --output text \
  --query 'Role.Arn'
  
aws iam create-role \
  --role-name k8sInteg \
  --description "Kubernetes role for integration namespace in quick cluster." \
  --assume-role-policy-document "$POLICY" \
  --output text \
  --query 'Role.Arn'

ㅁ Create IAM Groups

 

kubernetes 클러스터에서 다른 권한을 갖기 위해 특정 IAM 그룹에 추가 될 다른 IAM  사용자를 갖기 위해 3개의 그룹을 정의한다.

 

ㅇ k8sAdmin - 이 그룹의 사용자는 kubernetes 클러스터에 대한 Admin 권한을 갖는다.

ㅇ k8sDev - 이 그룹의 사용자는 클러스터의 Development namespace에서만 Full Access 권한을 갖는다. 

ㅇ k8nteg - 이 그룹의 사용자는 Integration namespace에서 Access 권한을 갖는다.

 

[Create K8sAdmin Group]

 

The k8sAdmin group 은 k8sAdmin IAM Role을 할당하려고 한다.

먼저 k8sAdmin 그룹을 생성

aws iam create-group --group-name k8sAdmin

k8sAdmin 그룹에 k8sAdmin ROLE을 할당한다.

ADMIN_GROUP_POLICY=$(echo -n '{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowAssumeOrganizationAccountRole",
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::'; echo -n "$ACCOUNT_ID"; echo -n ':role/k8sAdmin"
    }
  ]
}')
echo ADMIN_GROUP_POLICY=$ADMIN_GROUP_POLICY

aws iam put-group-policy \
--group-name k8sAdmin \
--policy-name k8sAdmin-policy \
--policy-document "$ADMIN_GROUP_POLICY"

[Create k8sDev Group]

aws iam create-group --group-name k8sDev

k8sDev Role을 k8sDev Group에 할당한다.

DEV_GROUP_POLICY=$(echo -n '{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowAssumeOrganizationAccountRole",
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::'; echo -n "$ACCOUNT_ID"; echo -n ':role/k8sDev"
    }
  ]
}')
echo DEV_GROUP_POLICY=$DEV_GROUP_POLICY

aws iam put-group-policy \
--group-name k8sDev \
--policy-name k8sDev-policy \
--policy-document "$DEV_GROUP_POLICY"

[Create k8sInteg IAM Group]

aws iam create-group --group-name k8sInteg
INTEG_GROUP_POLICY=$(echo -n '{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowAssumeOrganizationAccountRole",
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::'; echo -n "$ACCOUNT_ID"; echo -n ':role/k8sInteg"
    }
  ]
}')
echo INTEG_GROUP_POLICY=$INTEG_GROUP_POLICY

aws iam put-group-policy \
--group-name k8sInteg \
--policy-name k8sInteg-policy \
--policy-document "$INTEG_GROUP_POLICY"

최종적으로 만들어진 3개의 그룹을 확인한다.

aws iam list-groups

ㅁ Create IAM Users

 

 테스트 시나리오를 위해 3개의 유저를 생성하고 각 그룹에 할당한다.

aws iam create-user --user-name PaulAdmin
aws iam create-user --user-name JeanDev
aws iam create-user --user-name PierreInteg

aws iam add-user-to-group --group-name k8sAdmin --user-name PaulAdmin
aws iam add-user-to-group --group-name k8sDev --user-name JeanDev
aws iam add-user-to-group --group-name k8sInteg --user-name PierrInteg

 

정확하게 할당되었는지 확인

aws iam get-group --group-name k8sAdmin
aws iam get-group --group-name k8sDev
aws iam get-group --group-name k8sInteg

각 유저별로 Access Keys를 검색해 본다.

aws iam create-access-key --user-name PaulAdmin | tee /tmp/PaulAdmin.json
aws iam create-access-key --user-name JeanDev | tee /tmp/JeanDev.json
aws iam create-access-key --user-name PierreInteg | tee /tmp/PierreInteg.json

ㅁ Configure Kubernetes RBAC

 

우선 kubernetes namespace를 생성한다.

 

- k8sDev group에 IAM user를 위한 development namespace

- k8sInteg Group에 IAM user를 위한 integration namespace

 

를 생성한다.

 

kubectl create namespace integration
kubectl create namespace development

ㅇ Configuring access to development namespace

 

kubernetes user dev-user에게 full access 권한을 부여하는 development namespace에서 kubernetes role과 role binding을 생성한다.

cat << EOF | kubectl apply -f - -n development
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: dev-role
rules:
  - apiGroups:
      - ""
      - "apps"
      - "batch"
      - "extensions"
    resources:
      - "configmaps"
      - "cronjobs"
      - "deployments"
      - "events"
      - "ingresses"
      - "jobs"
      - "pods"
      - "pods/attach"
      - "pods/exec"
      - "pods/log"
      - "pods/portforward"
      - "secrets"
      - "services"
    verbs:
      - "create"
      - "delete"
      - "describe"
      - "get"
      - "list"
      - "patch"
      - "update"
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: dev-role-binding
subjects:
- kind: User
  name: dev-user
roleRef:
  kind: Role
  name: dev-role
  apiGroup: rbac.authorization.k8s.io
EOF

kubernetes user integ-user에게 full access 권한을 부여하는 integration namespace에서 kubernetes role과 role binding을 생성한다.

cat << EOF | kubectl apply -f - -n integration
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: integ-role
rules:
  - apiGroups:
      - ""
      - "apps"
      - "batch"
      - "extensions"
    resources:
      - "configmaps"
      - "cronjobs"
      - "deployments"
      - "events"
      - "ingresses"
      - "jobs"
      - "pods"
      - "pods/attach"
      - "pods/exec"
      - "pods/log"
      - "pods/portforward"
      - "secrets"
      - "services"
    verbs:
      - "create"
      - "delete"
      - "describe"
      - "get"
      - "list"
      - "patch"
      - "update"
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: integ-role-binding
subjects:
- kind: User
  name: integ-user
roleRef:
  kind: Role
  name: integ-role
  apiGroup: rbac.authorization.k8s.io
EOF

여기서 정의한 role은 해당 namespace의 모든 것에 대한 전체 Access 권한일 뿐이다. ClusterRole이 아니라 Role 이므로 그것은 integration namespace/development namespace에서만 각각 적용된다.,

 

ㅁ Configure Kubernetes Role Access

 

위에서 정의한 IAM 역할에 대한 엑세스 권한을 EKS Cluster에 부여하려면 특정 mapRoles을 aws-auth ConfigMap에 추가해야 한다.

 

IAM User를 직접 지정하는것 대신 클러스터에 Access 할때 Role을 사용하는 장점은 관리가 보다 쉽다는 것이다. User를 추가하거나 삭제할 때 Configmap을 일일히 업데이트 할필요가 없이 IAM Group에 추가하거나 삭제하면 된다. 그리고 이를 위해 IAM Group과 연결된 IAM Role만 허용하도록 ConfigMap을 구성하면 된다..

 

ㅇ Update the aws-auth ConfigMap to allow our IAM roles

 

arn 그룹을 허용하거나 삭제하려면 kube-system 네임 스페이스  aws-auth ConfigMap을 편집해야합니다.

이 파일은 IAM 역할과 k8S RBAC 권한을 매핑합니다. 수동으로 편집 할 수 있습니다.

 

eksctl create iamidentitymapping \
  --cluster eks-newelite-eksctl \
  --arn arn:aws:iam::${ACCOUNT_ID}:role/k8sDev \
  --username dev-user

eksctl create iamidentitymapping \
  --cluster eks-newelite-eksctl \
  --arn arn:aws:iam::${ACCOUNT_ID}:role/k8sInteg \
  --username integ-user

eksctl create iamidentitymapping \
  --cluster eks-newelite-eksctl \
  --arn arn:aws:iam::${ACCOUNT_ID}:role/k8sAdmin \
  --username admin \
  --group system:masters

 

만약 ConfigMap에서 해당 mapping을 삭제하려면

eksctl delete iamidentitymapping --cluster eks-newelite-eksctlv --arn arn:aws:iam::xxxxxxxxxx:role/k8sDev --username dev-user

를 수행하면 된다.

 

ConfigMap을 확인하려면

kubectl get cm -n kube-system aws-auth -o yaml

을 수행한다.

 

아래와 같은 결과가 나온다.

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::221745184950:role/eksctl-eks-newelite-eksctl-nodegr-NodeInstanceRole-WUWRBSPL4T26
      username: system:node:{{EC2PrivateDNSName}}
    - rolearn: arn:aws:iam::221745184950:role/k8sDev
      username: dev-user
    - rolearn: arn:aws:iam::221745184950:role/k8sInteg
      username: integ-user
    - groups:
      - system:masters
      rolearn: arn:aws:iam::221745184950:role/k8sAdmin
      username: admin
  mapUsers: |
    - userarn: arn:aws:iam::221745184950:user/rbac-user
      username: rbac-user
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"mapUsers":"- userarn: arn:aws:iam::221745184950:user/rbac-user\n  username: rbac-user\n"},"kind":"ConfigMap","metadata":{"annotations":{},"creationTimestamp":"2021-02-17T09:09:18Z","name":"aws-auth","namespace":"kube-system","resourceVersion":"913","selfLink":"/api/v1/namespaces/kube-system/configmaps/aws-auth","uid":"79240ae3-acfb-4505-a5b8-f321e6e37dc2"}}
  creationTimestamp: "2021-02-17T09:09:18Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "1810162"
  selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth
  uid: 79240ae3-acfb-4505-a5b8-f321e6e37dc2

클러스터에 관리되는 모든 identity의 리스트를 확인하려면

eksctl get iamidentitymapping --cluster eksworkshop-eksctl

을 수행하면 아래와 같은 결과가 나온다.

ARN                                                                                             USERNAME                               GROUPS
arn:aws:iam::221745184950:role/eksctl-eks-newelite-eksctl-nodegr-NodeInstanceRole-WUWRBSPL4T26  system:node:{{EC2PrivateDNSName}}      system:bootstrappers,system:nodes
arn:aws:iam::221745184950:role/k8sAdmin                                                         admin                                  system:masters
arn:aws:iam::221745184950:role/k8sDev                                                           dev-user
arn:aws:iam::221745184950:role/k8sInteg                                                         integ-user
arn:aws:iam::221745184950:user/rbac-user    

ㅁ AWS CLI로 Role Assume 자동화

 

파일 ~/.aws/config 및 ~/.aws/credentials 에서 AWS CLI를 구성하여 위임된 역할에 대한 임시 자격 증명 검색을 자동화 할 수 있다.

 

~/.aws/config: 에서 추가

if [ ! -d ~/.aws ]; then
  mkdir ~/.aws
fi

cat << EoF >> ~/.aws/config
[profile admin]
role_arn=arn:aws:iam::${ACCOUNT_ID}:role/k8sAdmin
source_profile=eksAdmin

[profile dev]
role_arn=arn:aws:iam::${ACCOUNT_ID}:role/k8sDev
source_profile=eksDev

[profile integ]
role_arn=arn:aws:iam::${ACCOUNT_ID}:role/k8sInteg
source_profile=eksInteg

EoF

~/.aws/credentials: 에 추가

cat << EoF >> ~/.aws/credentials

[eksAdmin]
aws_access_key_id=$(jq -r .AccessKey.AccessKeyId /tmp/PaulAdmin.json)
aws_secret_access_key=$(jq -r .AccessKey.SecretAccessKey /tmp/PaulAdmin.json)

[eksDev]
aws_access_key_id=$(jq -r .AccessKey.AccessKeyId /tmp/JeanDev.json)
aws_secret_access_key=$(jq -r .AccessKey.SecretAccessKey /tmp/JeanDev.json)

[eksInteg]
aws_access_key_id=$(jq -r .AccessKey.AccessKeyId /tmp/PierreInteg.json)
aws_secret_access_key=$(jq -r .AccessKey.SecretAccessKey /tmp/PierreInteg.json)

EoF

 ㅇ dev profile로 테스트 진행

$ aws sts get-caller-identity --profile dev
{
    "Account": "221745184950", 
    "UserId": "AROATHIILAC3ASVXO43WT:botocore-session-1614202940", 
    "Arn": "arn:aws:sts::221745184950:assumed-role/k8sDev/botocore-session-1614202940"
}

--profile dev parameter는 자동적으로 k8sDev role에 임시 credential을 요청한다.

 

admin으로 해도 동일하다.

$ aws sts get-caller-identity --profile admin
{
    "Account": "221745184950", 
    "UserId": "AROATHIILAC3II7YDHWPU:botocore-session-1614203086", 
    "Arn": "arn:aws:sts::221745184950:assumed-role/k8sAdmin/botocore-session-1614203086"
}

--profile admin parameter는 자동적으로 k8sAdmin role에 임시 credential을 요청한다.

 

ㅇ 테스트를 위해 새로운 KUBECONFIG file을 생성한다.

export KUBECONFIG=/tmp/kubeconfig-dev && eksctl utils write-kubeconfig eks-newelite-eksctl
cat $KUBECONFIG | yq e '.users.[].user.exec.args += ["--profile", "dev"]' - -- | sed 's/eks-newelite-eksctl./eks-newelite-eksctl-dev./g' | sponge $KUBECONFIG

 

 

--profile dev 파라미터를 kubectl config 파일에 추가하여 kubectl에게 dev 프로필에 연결된 IAM 역할을 사용하도록 요청하고 prefix -dev를 사용하여 컨텍스트 이름을 바꾼다.

이 구성을 사용하여 RBAC Role이 정의되므로 development namespace와 interact가 가능하다.

 

 ㅇ 테스트를 위한 Pod를 만든다.

kubectl run --generator=run-pod/v1 nginx-dev --image=nginx -n development

다른 namespace 조회 시 오류 발생

ㅇ integ 프로필로 테스트

 

integ로 전환

export KUBECONFIG=/tmp/kubeconfig-integ && eksctl utils write-kubeconfig eks-newelite-eksctl
cat $KUBECONFIG | yq e '.users.[].user.exec.args += ["--profile", "integ"]' - -- | sed 's/eks-newelite-eksctl./eks-newelite-eksctl-integ./g' | sponge $KUBECONFIG

 integration namespace에 포드 생성 후 조회

kubectl run --generator=run-pod/v1 nginx-integ --image=nginx -n integration

 

 

ㅇ admin profile로 테스트

 

admin으로 전환

export KUBECONFIG=/tmp/kubeconfig-admin && eksctl utils write-kubeconfig eks-newelite-eksctl
cat $KUBECONFIG | yq e '.users.[].user.exec.args += ["--profile", "admin"]' - -- | sed 's/eks-newelite-eksctl./eks-newelite-eksctl-admin./g' | sponge $KUBECONFIG

기본 네임스페이스에 포드 생성 후 조회

모든  namespace의 pods 나열

ㅇ 다른 Context간 전환

 

동일한 KUBECONFIG 파일에서 여러 Kubernetes API 엑세스 키를 구성하거나 Kubectl에 여러 파일을 조회하도록 지시할 수 있다.

export KUBECONFIG=/tmp/kubeconfig-dev:/tmp/kubeconfig-integ:/tmp/kubeconfig-admin

kubectx / kubens tool로 여러 context로 KUBECONFIG를 관리하는데 도움이 될 수 있다.

curl -sSLO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubectx && chmod 755 kubectx && sudo mv kubectx /usr/local/bin
$ kubectx

 

ㅇ Cleanup 스크립트는 아래와 같다.

 

unset KUBECONFIG

kubectl delete namespace development integration
kubectl delete pod nginx-admin

eksctl delete iamidentitymapping --cluster eks-newelite-eksctl --arn arn:aws:iam::${ACCOUNT_ID}:role/k8sAdmin
eksctl delete iamidentitymapping --cluster eks-newelite-eksctl --arn arn:aws:iam::${ACCOUNT_ID}:role/k8sDev
eksctl delete iamidentitymapping --cluster eks-newelite-eksctl --arn arn:aws:iam::${ACCOUNT_ID}:role/k8sInteg

aws iam remove-user-from-group --group-name k8sAdmin --user-name PaulAdmin
aws iam remove-user-from-group --group-name k8sDev --user-name JeanDev
aws iam remove-user-from-group --group-name k8sInteg --user-name PierreInteg

aws iam delete-group-policy --group-name k8sAdmin --policy-name k8sAdmin-policy 
aws iam delete-group-policy --group-name k8sDev --policy-name k8sDev-policy 
aws iam delete-group-policy --group-name k8sInteg --policy-name k8sInteg-policy 

aws iam delete-group --group-name k8sAdmin
aws iam delete-group --group-name k8sDev
aws iam delete-group --group-name k8sInteg

aws iam delete-access-key --user-name PaulAdmin --access-key-id=$(jq -r .AccessKey.AccessKeyId /tmp/PaulAdmin.json)
aws iam delete-access-key --user-name JeanDev --access-key-id=$(jq -r .AccessKey.AccessKeyId /tmp/JeanDev.json)
aws iam delete-access-key --user-name PierreInteg --access-key-id=$(jq -r .AccessKey.AccessKeyId /tmp/PierreInteg.json)

aws iam delete-user --user-name PaulAdmin
aws iam delete-user --user-name JeanDev
aws iam delete-user --user-name PierreInteg

aws iam delete-role --role-name k8sAdmin
aws iam delete-role --role-name k8sDev
aws iam delete-role --role-name k8sInteg

rm /tmp/*.json
rm /tmp/kubeconfig*

# reset aws credentials and config files
rm  ~/.aws/{config,credentials}
aws configure set default.region ${AWS_REGION}

'AWS EKS 실습 > EKS Beginner' 카테고리의 다른 글

Security Groups For Pods  (0) 2021.02.26
Create An OIDC Identity Provider  (0) 2021.02.25
Intro to RBAC  (0) 2021.02.24
Autoscaling with HPA and CA  (0) 2021.02.24
HEALTH CHECKS 실습 (Liveness Probe/Readiness Probe)  (0) 2021.02.22