brunch

EKS 4탄-10. EKS클러스터 인증-10/17

실습 4탄 = 10/17

by Master Seo

아래 내용은 주말 EKS 스터디 하며 , 해당 내용을 참고하여 작성 되었습니다.


AWS IAM 사용자가 EKS에 있는 내용을 사용 하는것을 알아보자

인증/인가를 해보자.



<1> 인증과 인가

<2> 인증 순서

<3> kubectl 요청 확인 과정

<4> 임시 보안 자격 증명(토큰)을 요청 확인

<5> IAM OIDC(OpenID Connect) identity Provider 확인

<6> EKS(K8S) RBAC 확인 (선택)

<7> IAM 사용자 , EKS 인증 사용

<8> 실습1 - K8S RBAC 롤기반 접근 제어 설정

<9> 각각 네임스페이스내의 모든 권한에 대한 롤 생성

<10> 실습2 - EKS 인증/인가 통합

<11> EKS 연동을 위한 AWS IAM 롤과 정책 생성 및 확인

<12> Updata Config Map

<13> 각각의 사용자에게 .kube/config 업데이트 하자

<14> dev-aws , infra-aws 사용자에 kubeconfig 생성

<15> infra-aws 사용자에게 관리자 권한 부여

<16> 정리

<20> 다음편~ 4-11. EKS IRSA 실습




<1> 인증과 인가


1

아래 링크, 계정 2개와 EC2 2개 설정이 필수로 되어야 이후 작업을 할수 있다.


https://brunch.co.kr/@topasvga/1877



2

쿠버네티스 클러스터 설치

https://brunch.co.kr/@topasvga/1876


or

Cloudformation으로 설치하는 경우중 하나

access-key 필요

복사해서 넣으면 공란이 들어감. 주의!!

노트 패드에 복사해 붙여 넣고 복사필요.

프롬프트가 계정이름:클러스터 이름으로 나오니 계정이름 주의 바람

ec2-key필요

cluster name

myeks


결과

vpc1

pub2

pri2

host ec2 1개 - 작업용

node 2개

my-eks-sp.yaml (싱가포르)

tail -f /root/create-eks.log

myeks-host 생김

(30분 소요)



3

AWS 계정을 통해 쿠버네티스 인증을 하게 하자~





<2> 인증 순서


400 통합.png



인증


1

토큰 요청

AWS IAM Security Token Service(AWS STS) 에 임시 보안 자격 증명(토큰)을 요청 합니다.



2

토큰을 받고나서, 토큰을 포함한 문자열로 EKS(K8S)에 요청(kubectl)을 합니다

kubectl get pod



3

EKS는 AWS IAM 에게 사용자 맞는지 확인한다. 역할ARN 맞는지 확인 요청을 합니다.

IAM에게 사용자나 역할ARN 확인이 되며, 이후 EKS 에서 인가(RBAC)을 진행합니다.

인증은 끝난다.



4

인가는 ?

권한 확인을 한다.

configmap 에 권한을 확인한다.

RBAC 역할 기반 권한 관리.

aws-auth 컨피그맵에 'IAM 사용자, 역할 ARM, K8S 오브젝트' 로 권한 확인 후 허가 되면, 최종적으로 동작 실행을 합니다.


참고

EKS 클러스터를 배포한 IAM 사용자는 aws-auth 와 상관없이 kubernetes-admin 권한을 가지게 내부적으로 지정되어 있습니다.


AWS IAM 이 인증 역할을 한다.

role을 서비스 어카운트에 바인딩 한다.

AWS와 비슷하다. role 을 iam 계정에 바운딩 하는것과 같다.




<3> kubectl 요청 확인 과정



1

kubectl get node -v7

I.go:372] Config loaded from file: /root/.kube/config

인증정보를 가져와서 확인한다.



2

KUBECONFIG=/root/.kube/config

cat $KUBECONFIG


current-context: seo-eks-access@myeks.ap-southeast-1.eksctl.io

kind: Config

preferences: {}

users:

- name: seo-eks-access@myeks.ap-southeast-1.eksctl.io

user:

exec:

apiVersion: client.authentication.k8s.io/v1alpha1

args:

- eks

- get-token

- --cluster-name

- myeks

- --region

- ap-southeast-1

command: aws

env:

- name: AWS_STS_REGIONAL_ENDPOINTS

value: regional

provideClusterInfo: false



//

AWS IAM과 연결 되는 부분이다.

args:

- eks

- get-token

- --cluster-name

- myeks

- --region

- ap-southeast-1


아래와 같은 형식이다.

aws eks get-token --cluster-name $CLUSTER_NAME





<4> 임시 보안 자격 증명(토큰)을 요청 확인


토큰 요청


1

임시 보안 자격 증명(토큰)을 요청

expirationTimestamp 시간경과 시 토큰 재발급됨


aws eks get-token --cluster-name $CLUSTER_NAME

{"kind": "ExecCredential", "apiVersion": "client.authentication.k8s.io/v1alpha1", "spec": {}, "status": {"expirationTimestamp": "2021-09-04T12:02:28Z", "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9yd



2

위 내용을 디코딩 하면 , Access-key / Secret-key 등이 보인다.

https://jwt.io/



3

# 토큰 정보 확인

aws eks get-token --cluster-name $CLUSTER_NAME | jq -r '.status.token'

k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9ydGW9uPUdldENh




<5> IAM OIDC(OpenID Connect) identity Provider 확인


OIDC가 되도록 되어 있어야 한다.

EKS 설치시 OIDC 연결되도록 되어 있다.

확인만 하자.



1

웹 콘솔에 로그인해서 확인하자.


AWS IAM으로 처리를 할수 있다는 것이다.


IAM > Identity providers (자격 증명 공급자)에서 확인 해보자.

OpenID Connect 확인

OpenID Connect 확인



2

CLI로도 확인 가능하다.

클러스터에 대한 IAM OIDC(OpenID Connect) identity Provider 정보 확인


aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text

https://oidc.eks.ap-southeast-1.amazonaws.com/id/180B3721D



3

aws iam list-open-id-connect-providers

(seo-eks-access@myeks:default) [root@myeks-host ~]# aws iam list-open-id-connect-providers

{

"OpenIDConnectProviderList": [

{

"Arn": "arn:aws:iam::168:oidc-provider/oidc.eks.ap-northeast-2.amazonaws.com/id/898A628825A12BF9893"

},

{

"Arn": "arn:aws:iam::168:oidc-provider/oidc.eks.ap-southeast-1.amazonaws.com/id/16B663E9F8539674"

},




참고

https://docs.aws.amazon.com/eks/latest/userguide/authenticate-oidc-identity-provider.html






<6> EKS(K8S) RBAC 확인 (선택)


권한 확인


1

aws-auth 컨피그맵에 현재는 워커노드 위한 정보만 있다.

현재 권한은 없음


kubectl describe configmap -n kube-system aws-auth


seo-eks-access@myeks:default) [root@myeks-host ~]# kubectl describe configmap -n kube-system aws-auth

Name: aws-auth

Namespace: kube-system

Labels: <none>

Annotations: <none>

Data

====

mapRoles:

----

- groups:

- system:bootstrappers

- system:nodes

rolearn: arn:aws:iam::8:role/eksctl-myeks-nodegroup-ng-56968-NodeInstanceRole-1QW

// 현재 권한은 없음 , 인가가 통과가 안됨!

username: system:node:{{EC2PrivateDNSName}}

Events: <none>



2

eksctl get iamidentitymapping --cluster $CLUSTER_NAME


(seo-eks-access@myeks:default) [root@myeks-host ~]# eksctl get iamidentitymapping --cluster $CLUSTER_NAME

2021-09-06 18:19:01 [ℹ] eksctl version 0.64.0

2021-09-06 18:19:01 [ℹ] using region ap-southeast-1

ARN USERNAME GROUPS

arn:aws:iam::8:role/eksctl-myeks-nodegroup-ng-5699468-NodeInstanceRole-14LY9W system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes



3

클러스터롤, 클러스터바인딩 확인 >> 즉, 워커노드는 EKS(K8S)의 아래

kubectl get clusterrolebindings

kubectl get clusterrolebindings -o wide




4

kubectl describe clusterrolebindings eks:node-bootstrapper


(seo-eks-access@myeks:default) [root@myeks-host ~]# kubectl describe clusterrolebindings eks:node-bootstrapper

Name: eks:node-bootstrapper

Labels: eks.amazonaws.com/component=node

Annotations: <none>

Role:

Kind: ClusterRole

Name: eks:node-bootstrapper

Subjects:

Kind Name Namespace

---- ---- ---------

Group system:bootstrappers

Group system:nodes



5

kubectl get clusterrolebindings -o wide | grep system:nodes

eks:node-bootstrapper ClusterRole/eks:node-bootstrapper 9h system:bootstrappers, system:nodes





<7> IAM 사용자 , EKS 인증 사용


IAM 롤 ARN 과 EKS 에 세팅된 롤과 매핑이 가능하다.


1

2명의 AWS IAM User : dev-aws, infra-aws

각각 별도의 EC2 인스턴스(user1-host, user2-host)를 통해서 aws cli, kubectl 자격증명 및 사용



2

목표 ?

2개의 사용자가 사용가능 하게 하자.


dev-aws 사용자는 ?

dev-team 네임스페이스(Namespace, NS) 에 모든 권한을 가지고 있어야 합니다.

예) dev-team NS에 파드 생성 및 삭제


infra-aws 사용자는 ?

infra-team 네임스페이스(Namespace, NS) 에 모든 권한을 가지고 있어야 합니다

실습 마지막에 추가로 system:master 그룹 권한을 부여하여 관리자 수준의 동작이 가능하도록 하자.



3

2개 ec2에 각각 로그인 해서 자격증명 확인 ?

aws sts get-caller-identity


user/dev-aws

user/infra-aws



4

실습

각 user1-host, user2-host 인스턴스에서 아래 실행 가능 확인해보자. 안된다.!

클라스터 조회하는 권한도 없다


aws eks list-clusters

CLUSTER_NAME=first-eks

echo $CLUSTER_NAME


aws eks describe-cluster --name $CLUSTER_NAME

aws eks get-token --cluster-name $CLUSTER_NAME


[root@sing-user2-host ~]# aws eks list-clusters

안된다.!

An error occurred (AccessDeniedException) when calling the ListClusters operation: User: arn:aws:iam::68:user/infra-aws is not authorized to perform: eks:ListClusters on resource: arn:aws:eks:ap-southeast-1:168:cluster/*




5

IAM User 에게 EKS 조회만 가능하도록 정책을 인라인으로 추가하자. 최소 권한 제공

eks:DescribeCluster 는 aws eks update-kubeconfig명령을 실행에 필요


cat <<EOT> read-eks.json

{

"Version": "2012-10-17",

"Statement": [

{

"Effect": "Allow",

"Action": [

"eks:DescribeCluster",

"eks:ListClusters"

],

"Resource": "*"

}

]

}

EOT





6

IAM User 에게 EKS 조회 가능한 정책을 인라인으로 추가

dev-aws 사용자와 infra-aws 사용자에 권한 넣자.

인라인 정책으로 넣는다.

계정 삭제시 권한도 같이 삭제되는 인라인 정책이다.


aws iam put-user-policy --user-name dev-aws --policy-name read-eks --policy-document file://read-eks.json


aws iam put-user-policy --user-name infra-aws --policy-name read-eks --policy-document file://read-eks.json

(5분 걸림)



7

동작 확인

각 user1-host, user2-host 인스턴스에서 아래 실행 가능 확인


aws eks list-clusters

CLUSTER_NAME=first-eks

echo $CLUSTER_NAME


aws eks describe-cluster --name $CLUSTER_NAME

aws eks get-token --cluster-name $CLUSTER_NAME



[root@sing-user2-host ~]# aws eks list-clusters

{

"clusters": [

"myeks"

]

}




8

EKS 연동을 위해서 롤과 정책을 만들어 보자!!!


aws 계정 account id 확인

ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`

echo $ACCOUNT_ID



9

sts:AssumeRole 파일 생성


cat <<EOT> stsrole.json

{

"Version":"2012-10-17",

"Statement":[

{

"Effect":"Allow",

"Principal":{

"AWS":"arn:aws:iam::${ACCOUNT_ID}:root"

},

"Action":"sts:AssumeRole",

"Condition":{

}

}

]

}

EOT



10

IAM Role 생성

aws iam create-role --role-name dev-role --assume-role-policy-document file://stsrole.json --output text --query 'Role.Arn'


aws iam create-role --role-name infra-role --assume-role-policy-document file://stsrole.json --output text --query 'Role.Arn'



11

그룹 생성 : dev-group , infra-group

aws iam create-group --group-name dev-group

aws iam create-group --group-name infra-group


콘솔에서 그룹이 있는지 확인하자~



12

롤을 사용할 수 있는 정책 파일 생성


cat <<EOT> dev-role-policy.json

{

"Version": "2012-10-17",

"Statement": [

{

"Sid": "AllowAssumeOrganizationAccountRole",

"Effect": "Allow",

"Action": "sts:AssumeRole",

"Resource": "arn:aws:iam::${ACCOUNT_ID}:role/dev-role"

}

]

}

EOT


cat <<EOT> infra-role-policy.json

{

"Version": "2012-10-17",

"Statement": [

{

"Sid": "AllowAssumeOrganizationAccountRole",

"Effect": "Allow",

"Action": "sts:AssumeRole",

"Resource": "arn:aws:iam::${ACCOUNT_ID}:role/infra-role"

}

]

}

EOT





13

그룹에 정책 적용

aws iam put-group-policy --group-name dev-group --policy-name dev-role-policy --policy-document file://dev-role-policy.json


aws iam put-group-policy --group-name infra-group --policy-name infra-role-policy --policy-document file://infra-role-policy.json




14

그룹에 유저 추가

aws iam add-user-to-group --group-name dev-group --user-name dev-aws

aws iam add-user-to-group --group-name infra-group --user-name infra-aws





<8> 실습1 - K8S RBAC 롤기반 접근 제어 설정


쿠버네티스 롤을 만들고, 롤을 연결해보자 .


K8S에서 기본 환경을 만들자!!!!


300 k8s.png



1

순서?

네임 스페이스를 2개 만들고

pod를 만들어 조회해 확인해보자. 안된다. 권한이 없다.

그래서, 서비스 어카운트 만들고 , 롤 만들고 롤 바인딩 하자



2

네임 스페이스 확인?


kubens

cert-manager

default

eks-work

kube-node-lease

kube-public

kube-system



3

네임스페이스(Namespace, NS) 생성

kubectl create namespace dev-team

kubectl create ns infra-team


kubens

cert-manager

default

dev-team

eks-work

infra-team

kube-node-lease

kube-public

kube-system



4

사용자 계정을 만들기 ?

네임스페이스에 각각 서비스 어카운트 생성 : serviceaccounts 약자(=sa)

sa는 기본적으로 네임 스페이스 안에서만 동작하는 것이다.

dev-k8s 계정과 infra-k8s 만들자.


kubectl create sa dev-k8s -n dev-team

kubectl create sa infra-k8s -n infra-team


5

디폴트로는 안보임


# k get sa

NAME SECRETS AGE

default 1 31m


네임스페이스를 dev-team으로 조회하면 dev-k8s 계정이 보인다.

# k get sa -n dev-team

NAME SECRETS AGE

default 1 15m

dev-k8s 1 14m



6

토큰 확인

kubectl get secret -n dev-team -o yaml



7

Pod 생성


watch -d 'kubectl get ns,po -A'


watch -d 'kubectl get ns,deploy,pods,svc,ep -A'


// Pod 만들때 serviceAccount 이름을 매핑하여 생성한다.

토큰 값이 pod에 자동으로 마운트 된다.

컨테이너를 어떤 이미지를 쓸건지.

나중에 pod에 접근해 확인한다.

pod2개를 만든다.


cat <<EOF | kubectl create -f -

apiVersion: v1

kind: Pod

metadata:

name: dev-kubectl

namespace: dev-team

spec:

serviceAccountName: dev-k8s

containers:

- name: kubectl-pod

image: bitnami/kubectl:1.21.2

command: ["tail"]

args: ["-f", "/dev/null"]

terminationGracePeriodSeconds: 0

EOF



cat <<EOF | kubectl create -f -

apiVersion: v1

kind: Pod

metadata:

name: infra-kubectl

namespace: infra-team

spec:

serviceAccountName: infra-k8s

containers:

- name: kubectl-pod

image: bitnami/kubectl:1.21.2

command: ["tail"]

args: ["-f", "/dev/null"]

terminationGracePeriodSeconds: 0

EOF




8

alias k1='kubectl exec -it dev-kubectl -n dev-team -- kubectl'

alias k2='kubectl exec -it infra-kubectl -n infra-team -- kubectl'



9

# 권한 테스트

Pod 조회등 모두 안된다.

k1 get pods

k1 get pods = kubectl exec -it dev-kubectl -n dev-team -- kubectl get pods

k1 run nginx --image nginx:1.20-alpine

k1 get pods -n kube-system


k2 get pods

k2 = # kubectl exec -it infra-kubectl -n infra-team -- kubectl get pods 와 동일한 실행 명령이다!

k2 run nginx --image nginx:1.20-alpine

k2 get pods -n kube-system



10

# (옵션) kubectl auth can-i 로 kubectl 실행 사용자가 특정 권한을 가졌는지 확인

k1 auth can-i get pods

no


// 안된다. 당연하다. role이 없다. role binding을 해야 한다.





<9> 각각 네임스페이스내의 모든 권한에 대한 롤 생성


dev-team 네임스페이스에 있는것에 대해 사용할수 있는 role 생성


1

cat <<EOF | kubectl create -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

name: role-dev-team

namespace: dev-team

rules:

- apiGroups: ["*"]

resources: ["*"]

verbs: ["*"]

EOF


cat <<EOF | kubectl create -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

name: role-infra-team

namespace: infra-team

rules:

- apiGroups: ["*"]

resources: ["*"]

verbs: ["*"]

EOF





2

kubectl describe roles role-dev-team -n dev-team


# kubectl describe roles role-dev-team -n dev-team

Name: role-dev-team

Labels: <none>

Annotations: <none>

PolicyRule:

Resources Non-Resource URLs Resource Names Verbs

--------- ----------------- -------------- -----

*.* [] [] [*]


// 모든 리소스에 대해 모든 행위에 대한 role




3

롤바인딩 생성 : '서비스어카운트 <-> 롤' 간 서로 연동


cat <<EOF | kubectl create -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

name: roleB-dev-team

namespace: dev-team

roleRef:

apiGroup: rbac.authorization.k8s.io

kind: Role

name: role-dev-team

subjects:

- kind: ServiceAccount

name: dev-k8s

namespace: dev-team

EOF



cat <<EOF | kubectl create -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

name: roleB-infra-team

namespace: infra-team

roleRef:

apiGroup: rbac.authorization.k8s.io

kind: Role

name: role-infra-team

subjects:

- kind: ServiceAccount

name: infra-k8s

namespace: infra-team

EOF


// role과 서비스 어카운트를 매핑!!




4

롤 바인딩 확인

kubectl get rolebindings -n dev-team

kubectl get rolebindings -n infra-team

kubectl get rolebindings -n dev-team -o yaml

kubectl describe rolebindings roleB-dev-team -n dev-team

ame: roleB-dev-team

Labels: <none>

Annotations: <none>

Role:

Kind: Role

Name: role-dev-team

Subjects:

Kind Name Namespace

---- ---- ---------

ServiceAccount dev-k8s dev-team



5

k1 get pods


(seo-sing-admin@myeks:infra-team) [root@myeks-host ~]# k1 get pods

NAME READY STATUS RESTARTS AGE

dev-kubectl 1/1 Running 0 133m

// 성공


(seo-sing-admin@myeks:infra-team) [root@myeks-host ~]# k2 get pods

NAME READY STATUS RESTARTS AGE

infra-kubectl 1/1 Running 0 133m

// 성공




6

안될시 ?

kubens

kubens infra-team

watch -d 'kubectl get ns,po,RoleBinding -A'

k delete rolebinding.rbac.authorization.k8s.io/roleB-dev-team

다시 롤 바인딩




7

테스트 ?


잘됨

k1 run nginx --image nginx:1.20-alpine

k1 get pods

k1 delete pods nginx


아래는 안됨

k1 get pods -n kube-system

k1 get nodes


잘됨

k2 run nginx --image nginx:1.20-alpine

k2 delete pods nginx


아래는 안됨

k2 get pods -n kube-system

k2 get nodes


// 다른 name space의 pod는 안됨.




8

k1 auth can-i get pods

yes



9

삭제

kubectl delete ns dev-team infra-team

// 네임스페이스를 지우면 모두 지워진다.




<10> 실습2 - EKS 인증/인가 통합


400 통합.png



AWS에 있는 IAM 사용자가 EKS에 있는 자원을 사용할때 인증/ 인가가 필요하다.



1

인증 요청?


1) 사용자가 임시 토큰 자격증명을 AM에 요청을 한다.

발급 받음.

2) 토큰이 포함 된 요청정보는 K8S에 요청한다.

3) K8s는 IAM에 확인 요청 한다.



2

인가 요청?

4) 권한 확인

EKS 에 aws-auth 권한 정보가 있다.

권한 확인후 제공된다.


K8S 입장에서볼때, IAM에서 인증 부분을 처리하는 역할을 한다.

EKS클러스터를 배포한 사용자는 aws-auth와 상관없이 kubenetest-admin 권한이 자동 부여 된다.



3

인증 요청 확인?


1

kubectl get node -v7


# kubectl get node -v7

I0926 14:17:00.162114 28901 loader.go:372] Config loaded from file: /root/.kube/config

//.kube/config 파일을 로드해서 인증정보를 가지고 인증한다.



2

KUBECONFIG=/root/.kube/config

cat $KUBECONFIG


users:

- name: seo-sing-admin@myeks.ap-southeast-1.eksctl.io

user:

exec:

apiVersion: client.authentication.k8s.io/v1alpha1

args:

- eks

- get-token

- --cluster-name

- myeks

- --region

- ap-southeast-1

command: aws

env:

- name: AWS_STS_REGIONAL_ENDPOINTS

value: regional

provideClusterInfo: false



3

임시 자격증명 확인

aws eks get-token --cluster-name $CLUSTER_NAME

// eks , get-tocken , cluster-name 등 동일하게 질의 한다.


aws eks get-token --cluster-name $CLUSTER_NAME | jq -r '.status.token'

// https://jwt.io/ 사이트에서 디코딩 가능



4

OIDC(OpenID Connect) 가 활성화 되어 있어야 한다.

EKS 배포할때 with OIDC 활성화를 해 놓았다.

클러스터에 대한 IAM OIDC(OpenID Connect) identity Provider 정보 확인


aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text

aws iam list-open-id-connect-providers



5

권한 확인은?

kubectl describe configmap -n kube-system aws-auth


// 권한이 없다.

Namespace: kube-system

Labels: <none>

Annotations: <none>

Data

====

mapRoles:

----

- groups:

- system:bootstrappers



6

목표 ?

IAM role을 만들고 , EKS 세팅한 클러스터 role을 매핑해 사용하는 것이다.

dev-aws 사용자가 k8s dev-team 네임 스페이스 사용하도록 하게 한다.

infra-aws 사용자가 k8s infra-team 네임 스페이스 사용하도록 하게 한다.



7

// IAM User 에게 EKS 조회 가능한 정책을 인라인으로 추가

// eks:DescribeCluster 는 aws eks update-kubeconfig명령을 실행에 필요


cat <<EOT> read-eks.json

{

"Version": "2012-10-17",

"Statement": [

{

"Effect": "Allow",

"Action": [

"eks:DescribeCluster",

"eks:ListClusters"

],

"Resource": "*"

}

]

}

EOT



8

dev-aws 사용자에게 eks read 권한을 준다.

infra-aws 사용자에게 eks read 권한을 준다.


aws iam put-user-policy --user-name dev-aws --policy-name read-eks --policy-document file://read-eks.json


aws iam put-user-policy --user-name infra-aws --policy-name read-eks --policy-document file://read-eks.json



9

user1 host , user2 host에서 eks read 권한이 잘 되는지 확인해 보자.


aws eks list-clusters

aws eks get-token --cluster-name $CLUSTER_NAME


work-host에서

aws eks describe-cluster --name $CLUSTER_NAME





<11> EKS 연동을 위한 AWS IAM 롤과 정책 생성 및 확인



Assume 할수 있는 role 2개 생성


1

aws account id를 확인하고, Assume Role을 생성한다.


ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`

echo $ACCOUNT_ID


cat <<EOT> stsrole.json

{

"Version":"2012-10-17",

"Statement":[

{

"Effect":"Allow",

"Principal":{

"AWS":"arn:aws:iam::${ACCOUNT_ID}:root"

},

"Action":"sts:AssumeRole",

"Condition":{

}

}

]

}

EOT


Assume 할수 있는 role 2개 생성

dev-role

infra-role


aws iam create-role --role-name dev-role --assume-role-policy-document file://stsrole.json --output text --query 'Role.Arn'


aws iam create-role --role-name infra-role --assume-role-policy-document file://stsrole.json --output text --query 'Role.Arn'



2

실무에서는 그룹으로 관리하므로 그룹 생성. 개발자는 여러명이라 보통 그룹으로 관리한다.

사용자를 그룹에 넣고, 그룹에 권한을 준다.

aws iam create-group --group-name dev-group

aws iam create-group --group-name infra-group



3

dev-role을 assume 할수 있는 정책 설정

infra-role 을 assume 할수 있는 정책 설정


policy


cat <<EOT> dev-role-policy.json

{

"Version": "2012-10-17",

"Statement": [

{

"Sid": "AllowAssumeOrganizationAccountRole",

"Effect": "Allow",

"Action": "sts:AssumeRole",

"Resource": "arn:aws:iam::${ACCOUNT_ID}:role/dev-role"

}

]

}

EOT


cat <<EOT> infra-role-policy.json

{

"Version": "2012-10-17",

"Statement": [

{

"Sid": "AllowAssumeOrganizationAccountRole",

"Effect": "Allow",

"Action": "sts:AssumeRole",

"Resource": "arn:aws:iam::${ACCOUNT_ID}:role/infra-role"

}

]

}

EOT





4

group에 policy 적용

aws iam put-group-policy --group-name dev-group --policy-name dev-role-policy --policy-document file://dev-role-policy.json


aws iam put-group-policy --group-name infra-group --policy-name infra-role-policy --policy-document file://infra-role-policy.json



5

group에 user추가

aws iam add-user-to-group --group-name dev-group --user-name dev-aws

aws iam add-user-to-group --group-name infra-group --user-name infra-aws



6

콘솔에 가서 그룹 , 사용자, 권한을 확인하자. ?

해당 그룹에 들어간 사용자는 dev-role-policy 권한을 자동으로 사용가능하게 된다.



7

ec2 2대에 들어가서 클러스터 읽기권한이 되는지 확인하자.

aws eks list-clusters




20 iam.png




8

결론

dev-aws 사용자가 assume 할수 있다.

infra-aws 사용자가 assume 할수 있다.







<12> K8S RBAC 설정



20 iam.png



1


# 네임스페이스(Namespace, NS) 생성 및 확인

kubectl create namespace dev-team

kubectl create ns infra-team




2

# 네임스페이스에 각각 서비스 어카운트 생성

serviceaccounts 약자(=sa)

dev-k8s serviceaccounts 생성

infra-k8s serviceaccounts 생성


kubectl create sa dev-k8s -n dev-team

kubectl create sa infra-k8s -n infra-team




3

# 각각 네임스페이스내의 모든 권한에 대한 롤 생성

// dev-team 네임스페이스에서 모든걸 할수 있는 role

// infra-team 네임스페이스에서 모든걸 할수 있는 role


cat <<EOF | kubectl create -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

name: role-dev-team

namespace: dev-team

rules:

- apiGroups: ["*"]

resources: ["*"]

verbs: ["*"]

EOF


cat <<EOF | kubectl create -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

name: role-infra-team

namespace: infra-team

rules:

- apiGroups: ["*"]

resources: ["*"]

verbs: ["*"]

EOF



4

# 롤바인딩 생성

서비스어카운트 <-> role 간 서로 연동



cat <<EOF | kubectl create -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

name: roleB-dev-team

namespace: dev-team

roleRef:

apiGroup: rbac.authorization.k8s.io

kind: Role

name: role-dev-team

subjects:

- kind: User

name: dev-k8s

namespace: dev-team

EOF


cat <<EOF | kubectl create -f -

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

name: roleB-infra-team

namespace: infra-team

roleRef:

apiGroup: rbac.authorization.k8s.io

kind: Role

name: role-infra-team

subjects:

- kind: User

name: infra-k8s

namespace: infra-team

EOF






<13> Updata Config Map


1

aws-auth ConfigMap 확인 ?

kubectl describe configmap -n kube-system aws-auth

// 아무 권한이 없다.


(seo-eks-access@myeks:default) [root@myeks-host ~]# kubectl describe configmap -n kube-system aws-auth

Name: aws-auth

Namespace: kube-system

Labels: <none>

Annotations: <none>

Data

====

mapRoles:

----

- groups:

- system:bootstrappers

- system:nodes

rolearn: arn:aws:iam:::role/eksctl-myeks-nodegroup-ng-9468-NodeInstanceRole-14LYZQW

username: system:node:{{EC2PrivateDNSName}}

Events: <none>




2

쿠버네티스 사용자 dev-k8s 와 infra-k8s 를 aws dev-role과 infra-role과 매핑 하자.


Update the aws-auth ConfigMap to allow our IAM roles


eksctl create iamidentitymapping --cluster $CLUSTER_NAME --arn arn:aws:iam::${ACCOUNT_ID}:role/dev-role --username dev-k8s


eksctl create iamidentitymapping --cluster $CLUSTER_NAME --arn arn:aws:iam::${ACCOUNT_ID}:role/infra-role --username infra-k8s


// 아래 처럼 K8S 사용자와 role이 매칭 되었다!




3

aws-auth ConfigMap 확인

kubectl describe configmap -n kube-system aws-auth


Data

====

mapRoles:

----

- rolearn: arn:aws:iam::xxxxxxxxxx:role/dev-role

username: dev-k8s

- rolearn: arn:aws:iam::xxxxxxxxxxxx:role/infra-role

username: infra-k8s

// AWS IAM role과 K8s user name과 매핑이 되어 있다.




4

아래 명령어로도 맵핑 정보 확인 가능하다.

eksctl get iamidentitymapping --cluster $CLUSTER_NAME


ARN USERNAME GROUPS

arn:aws:iam::8:role/dev-role dev-k8s

arn:aws:iam::8:role/infra-role infra-k8s


// AWS IAM role과 K8s user name과 매핑이 되어 있다.





<14> dev-aws , infra-aws 사용자에 kubeconfig 생성


인증 권한 생성함


1

user1 ec2 에서 update-kubeconfig

ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`


aws eks update-kubeconfig --name $CLUSTER_NAME --role-arn arn:aws:iam::$ACCOUNT_ID:role/dev-role

Added new context arn:aws:eks:ap-northeast-1:xxxxxxxx:cluster/first-eks to /root/.kube/config



user2 ec2 에서 update-kubeconfig

ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`


aws eks update-kubeconfig --name $CLUSTER_NAME --role-arn arn:aws:iam::$ACCOUNT_ID:role/infra-role

Added new context arn:aws:eks:ap-northeast-1:xxxxxxxx:cluster/first-eks to /root/.kube/config



2

프롬프트 줄이기 ? (선택)


user1 ec2

kubectl config rename-context "arn:aws:eks:$AWS_DEFAULT_REGION:$ACCOUNT_ID:cluster/$CLUSTER_NAME" "dev-aws@$CLUSTER_NAME"


user2 ec2

kubectl config rename-context "arn:aws:eks:$AWS_DEFAULT_REGION:$ACCOUNT_ID:cluster/$CLUSTER_NAME" "infra-aws@$CLUSTER_NAME"



3

동작 확인을 위해 NS 내에 pod 생성 ?

work host ec2 에서


cat <<EOF | kubectl create -f -

apiVersion: v1

kind: Pod

metadata:

name: dev-kubectl

namespace: dev-team

spec:

serviceAccountName: dev-k8s

containers:

- name: kubectl-pod

image: bitnami/kubectl:1.21.2

command: ["tail"]

args: ["-f", "/dev/null"]

terminationGracePeriodSeconds: 0

EOF


cat <<EOF | kubectl create -f -

apiVersion: v1

kind: Pod

metadata:

name: infra-kubectl

namespace: infra-team

spec:

serviceAccountName: infra-k8s

containers:

- name: kubectl-pod

image: bitnami/kubectl:1.21.2

command: ["tail"]

args: ["-f", "/dev/null"]

terminationGracePeriodSeconds: 0

EOF




4

테스트 와 확인 ?


user1-host)

User1(dev 계정)에서 dev-team 네임스페이스에 파드 생성 ?

같은 dev-team 네임스페이스에서는 모든 권한이 있으므로 다 된다.


kubectl get pod -n dev-team

kubectl run nginx-dev --image=nginx -n dev-team

kubectl get pod -n dev-team

kubectl delete pod nginx-dev -n dev-team



된다

kubectl get pod -n dev-team

(⎈ |dev-aws@myeks:default) [root@sing-user1-host ~]# kubectl get pod -n dev-team

NAME READY STATUS RESTARTS AGE

dev-kubectl 1/1 Running 0 5m24s


kubectl run nginx-dev --image=nginx -n

(⎈ |dev-aws@myeks:default) [root@sing-user1-host ~]# kubectl run nginx-dev --image=nginx -n dev-team

pod/nginx-dev created


kubectl get pod -n dev-team

(⎈ |dev-aws@myeks:default) [root@sing-user1-host ~]# kubectl get pod -n dev-team

NAME READY STATUS RESTARTS AGE

dev-kubectl 1/1 Running 0 5m38s

nginx-dev 1/1 Running 0 6s


kubectl delete pod nginx-dev -n dev-team

(⎈ |dev-aws@myeks:default) [root@sing-user1-host ~]# kubectl delete pod nginx-dev -n dev-team

pod "nginx-dev" deleted




다른 네임스페이스 정보 확인은 안된다.


kubectl get pod -n kube-system

(⎈ |dev-aws@myeks:default) [root@sing-user1-host ~]# kubectl get pod -n kube-system

Error from server (Forbidden): pods is forbidden: User "dev-k8s" cannot list resource "pods" in API group "" in the namespace "kube-system"

// 다른 네임 스페이스 pod정보는 못가져 온다.




5

user2-host) 에서

# User2(infra 계정)에서 infra-team 네임스페이스에 파드 생성 ?

잘 된다.

infra-team 네임 스페이스 이므로 ~

kubectl get pod -n infra-team

kubectl run nginx-integ --image=nginx -n infra-team

kubectl get pod -n infra-team

kubectl delete pod nginx-integ -n infra-team


kubectl get pod -n infra-team

|infra-aws@myeks:default) [root@sing-user2-host ~]# kubectl get pod -n infra-team

No resources found in infra-team namespace.


(⎈ |infra-aws@myeks:default) [root@sing-user2-host ~]# kubectl run nginx-integ --image=nginx -n infra-team

pod/nginx-integ created


(⎈ |infra-aws@myeks:default) [root@sing-user2-host ~]# kubectl get pod -n infra-team

NAME READY STATUS RESTARTS AGE

nginx-integ 0/1 ContainerCreating 0 1s


(⎈ |infra-aws@myeks:default) [root@sing-user2-host ~]# kubectl delete pod nginx-integ -n infra-team

pod "nginx-integ" deleted



# 다른 네임스페이스 정보 확인은 안된다.

kubectl get pod -n kube-system


(⎈ |infra-aws@myeks:default) [root@sing-user2-host ~]# kubectl get pod -n kube-system

Error from server (Forbidden): pods is forbidden: User "infra-k8s" cannot list resource "pods" in API group "" in the namespace "kube-system"




<15> infra-aws 사용자에게 관리자 권한 부여


1

system:masters 그룹을 추가하자.

다른 네임스페이스의 정보까지 확인해보자~


2

system:masters 그룹을 추가!

eksctl create iamidentitymapping --cluster $CLUSTER_NAME --arn arn:aws:iam::${ACCOUNT_ID}:role/infra-role --username infra-k8s --group system:masters


system:masters 은 K8S 권한이다.



2

aws-auth ConfigMap 확인, 맵핑 확인

kubectl describe configmap -n kube-system aws-auth

eksctl get iamidentitymapping --cluster $CLUSTER_NAME


3

user2-host) 에서 다른 NS의 pod 확인 ?

이제 된다.


kubectl get pod -n kube-system


(⎈ |infra-aws@myeks:default) [root@sing-user2-host ~]# kubectl get pod -n kube-system

NAME READY STATUS RESTARTS AGE

aws-node-6rfvk 1/1 Running 0 13h

aws-node-jc4nf 1/1 Running 0 13h

coredns-55b9c7d86b-chm4z 1/1 Running 0 13h

coredns-55b9c7d86b-cr77g 1/1 Running 0 13h

kube-proxy-g25mx 1/1 Running 0 13h

kube-proxy-v48qk 1/1 Running 0 13h



kubectl get pod -A

(⎈ |infra-aws@myeks:default) [root@sing-user2-host ~]# kubectl get pod -A

NAMESPACE NAME READY STATUS RESTARTS AGE

dev-team dev-kubectl 1/1 Running 0 19m

infra-team infra-kubectl 1/1 Running 0 14m

kube-system aws-node-6rfvk 1/1 Running 0 13h

kube-system aws-node-jc4nf 1/1 Running 0 13h

kube-system coredns-55b9c7d86b-chm4z 1/1 Running 0 13h

kube-system coredns-55b9c7d86b-cr77g 1/1 Running 0 13h

kube-system kube-proxy-g25mx 1/1 Running 0 13h

kube-system kube-proxy-v48qk 1/1 Running 0 13h



3

권한 확인


eksctl get iamidentitymapping --cluster $CLUSTER_NAME


(seo-eks-access@myeks:default) [root@myeks-host ~]# eksctl get iamidentitymapping --cluster $CLUSTER_NAME

2021-09-06 23:11:32 [ℹ] eksctl version 0.64.0

2021-09-06 23:11:32 [ℹ] using region ap-southeast-1

ARN USERNAME GROUPS

arn:aws:iam::8:role/dev-role dev-k8s

arn:aws:iam::8:role/eksctl-myeks-nodegroup-ng-58-NodeInstanceRole-14 system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes

arn:aws:iam::8:role/infra-role infra-k8s

arn:aws:iam::8:role/infra-role infra-k8s system:masters


4

// 불필요한 role 삭제

aws iam delete-role --role-name infra-role




<16> 정리


1

현재 eks 권한 확인

eksctl get iamidentitymapping --cluster $CLUSTER_NAME


2

user1 ec2 에서 update-kubeconfig 만들어 현재 권한을 사용하자.

ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`

aws eks update-kubeconfig --name $CLUSTER_NAME --role-arn arn:aws:iam::$ACCOUNT_ID:role/dev-role

Added new context arn:aws:eks:ap-northeast-1:xxxxxxxx:cluster/first-eks to /root/.kube/config


3

aws-auth ConfigMap 확인 ?

kubectl describe configmap -n kube-system aws-auth




<20> 다음편~ 4-11. EKS IRSA 실습


https://brunch.co.kr/@topasvga/1885



감사합니다.

keyword
매거진의 이전글EKS 4탄-9. K8S 인증,인가-9/17