brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Sep 05. 2021

EKS 4탄-10. EKS클러스터 인증과 AWS IAM

실습 4탄 =  10/17

아래 내용은  주말  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> 인증 순서




인증


토큰 요청

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에서 기본 환경을 만들자!!!!




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 인증/인가 통합




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 







8

결론 

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

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







<12> K8S RBAC 설정





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



감사합니다.

매거진의 이전글 EKS 4탄-9. K8S 인증,인가
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari