brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Sep 05. 2021

EKS 4탄-9. K8S 인증,인가

실습 4탄 =  9/17

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


쿠버네티스 인증,인가에 대해 알아보자



<1> 쿠버네티스 인증,인가에 대해 알아보자

<2> K8S API 접근 

<3> 네임 스페이스와 서비스 어카운트  생성

<4> 각 네임스페이스에 kubectl 파드 생성 - 컨테이너이미지

<5> 각 네임스페이스에 롤(Role)를 생성 후 서비스 어카운트 바인딩 

<6> 서비스 어카운트를 지정하여 생성한 파드에서 다시 권한 테스트

<7> 실습4-10. EKS 클러스터 인증과 AWS IAM통합

<8> (몰아보기) EKS 실습 4 - 4주 스터디 




<1>  쿠버네티스 인증,인가에 대해 알아보자


1

쿠버네티스 설치

AWS에  쿠버네티스를 설치해 보자

도쿄 리전에 설치

EC2 키페어

seo-t6-jp-k8s-1111


admin-role 생성

seo-admin-role 


2

cloudformation  file 다운로드

kops-ec2-privatedns-japan.yaml


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


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


Stack name

k8s-jp-stackname

seo.cndk.k8s

EC2 keypair 


3

kops-ec2 에 admin role 연결


4

ec2 로그인


메뉴얼에 따라  k8s 설치

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


5

api 서버로 로그온한다.





<2>  K8S API 접근 


쿠버네티스에  서비스 어카운드 (Service Account)가 있다.

서비스 어카운드 (Service Account)에  IAM  정책을 넣어서 사용하게 된다.

인증 -> 인가 ->  Admission Controle  과정을 거친다.



1

K8S  API 접근 ?

서비스 어카운드 (Service Account)

API 서버 사용 : kubectl , 서비스 어카운트, https (x.509 client 인증)

API서버 접근 과정 : 인증 > 인가 >  Admission Control



2

인증 방식 ?

X.509 Client Certs : kubeconfig 에 CA crt(발급 기관 인증서) , Client crt(클라이언트 인증서) , Client key(클라이언트 개인키) 를 통해 인증

kubectl : 여러 클러스터(kubeconfig)를 관리 가능 - contexts 에 클러스터와 유저 및 인증서/키 참고

Service Account : 기본 서비스 어카운트(default) - 시크릿(CA crt 와 token)



3

인가 방식 : RBAC(Role, RoleBinding), ABAC, Webhook, Node Authorizatio

RBAC : 역할 기반의 권한 관리, 사용자와 역할을 별개로 선언 후 두가지를 조합(binding)해서 사용자에게 권한을 부여하여 kubectl or API로 관리 가능

Namespace/Cluster - Role/ClusterRole, RoleBinding/ClusterRoleBinding, Service Account

Role(롤) 

RoleBinding 롤 바인딩 : 롤 바인딩은 롤과 서비스 어카운트를 연결

Role(네임스페이스내 자원의 권한) 

ClusterRole(클러스터 수준의 자원의 권한) 



4

.kube/config  파일  ?

clusters : kubectl 이 사용할 쿠버네티스 API 서버의 접속 정보 목록. 원격의 쿠버네티스 API 서버의 주소를 추가해 사용 가능

users : 쿠버네티스의 API 서버에 접속하기 위한 사용자 인증 정보 목록. (서비스 어카운트의 토큰, 혹은 인증서의 데이터 등)

contexts : cluster 항목과 users 항목에 정의된 값을 조합해 최종적으로 사용할 쿠버네티스 클러스터의 정보(컨텍스트)를 설정.


5

EKS(K8S) 에 사용자를 위한 서비스 어카운트(Service Account, SA)를 생성 : dev-k8s, infra-k8s

사용자는 각기 다른 권한(Role, 인가)을 가짐 : dev-k8s(dev-team 네임스페이스 내 모든 동작) , infra-k8s(dev-team 네임스페이스 내 모든 동작)

각각 별도의 kubectl 파드를 생성하고, 해당 파드에 SA 를 지정하여 권한에 대한 테스트를 진행





<3> 실습 환경과 네임 스페이스와 서비스 어카운트  생성


실습 환경


dev

role =  네임 스패이스 안에것을 모두 할수 있음.

pod  실행 - pod 내에서 eks  클러스터 사용



1

api서버에서 

별도 터미널에서 모니터링


watch -d kubectl get ns,deploy,svc,pod

NAME                        STATUS   AGE

namespace/default           Active   78m

namespace/kube-node-lease   Active   78m

namespace/kube-public       Active   78m

namespace/kube-system       Active   78m


NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE

service/kubernetes   ClusterIP   100.64.0.1   <none>        443/TCP   78m



2

-A를 해야  전체 서비스 어카운트를 볼수 있다.

watch -d kubectl get ns,deploy,svc,pod,sa -A


3

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

dev-team, infra-team  네임스페이스 생성


kubectl create namespace dev-team

kubectl create ns infra-team


4

네임스페이스 확인

kubectl get ns

NAME              STATUS   AGE

default           Active   89m

dev-team          Active   13s

infra-team        Active   12s

kube-node-lease   Active   89m

kube-public       Active   89m

kube-system       Active   89m



kubens

NAME              STATUS   AGE

default           Active   89m

dev-team          Active   13s

infra-team        Active   12s

kube-node-lease   Active   89m

kube-public       Active   89m

kube-system       Active   89m



5

모니터링

watch -d kubectl get ns,deploy,svc,pod,sa -A


6

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

서비스 어카운트는 기본적으로 네임스페이스 안에서 동작한다.

dev-team 네임스페이스에 만들고,  infra-team에 만들자


kubectl create sa dev-k8s -n dev-team

kubectl create sa infra-k8s -n infra-team



7

서비스 어카운트, 시크릿(토큰) 정보 확인

kubectl get sa -n dev-team

kubectl get sa dev-k8s -n dev-team -o yaml

kubectl get secret -n dev-team

kubectl get secret -n dev-team -o yaml


[root@kops-ec2 ~]# kubectl get sa -n dev-team

NAME      SECRETS   AGE

default   1         89s

dev-k8s   1         28s


8

서비스 어카운트에  시크릿이 만들어 진다.


kubectl get secret -n dev-team

[root@kops-ec2 ~]# kubectl get secret -n dev-team

NAME                  TYPE                                  DATA   AGE

default-token-kj8kh   kubernetes.io/service-account-token   3      114s

dev-k8s-token-ztbz4   kubernetes.io/service-account-token   3      53s


9

토큰을 보자

kubectl get secret -n dev-team -o yaml


  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklsaHBSazFwVDBjeVUxTkpka3hYVEhZNVQyOUhNVk5xYmxSdGQzTnJVbUZa


토큰 값을 가지고 쿠버네티스 인증에 사용한다.


11

토큰 정보 확인 ?

DevTokenName=$(kubectl get sa dev-k8s -n dev-team -o jsonpath="{.secrets[0].name}") DevToken=$(kubectl get secret -n dev-team $DevTokenName -o jsonpath="{.data.token}" | base64 -d) echo $DevToken


사이트에서 보면 디코드 해서 볼수 있다.

https://jwt.io/





<4>  각 네임스페이스에 kubectl 파드 생성 - 컨테이너이미지


서비스 어카운트를 지정하여, 파드 생성후 권한 테스트 해보자!!!


1

# docker run --rm --name kubectl -v /path/to/your/kube/config:/.kube/config bitnami/kubectl:latest


2

pod  를 생성할때  서비스 어카운트를 매핑할수 있다.

그러면, 서비스 어카운트의 토큰 값이 자동으로 마운트 된다.


kubectl:1.21.2이 설치된 이미지를 설치하는 예이다.
pod 2개를 만든다.


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


// 


3

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

확인

kubectl get pod -A


pod 정보를 확인해보자.

볼륨 마운트 부분, 중간에 서비스 어카운트를 볼수 있다.


kubectl get pod -o dev-kubectl -n dev-team -o yaml

 serviceAccount: dev-k8s

 


pod 정보를 확인해보자

kubectl get pod -o infra-kubectl -n infra-team -o yaml

 serviceAccount: infra-k8s



5

파드에서 실행

기본 적용되는 서비스 어카운트(토큰) 정보 확인


파드들어가서  ls 해보면 파일이 3개 보인다.

kubectl exec -it dev-kubectl -n dev-team -- ls /run/secrets/kubernetes.io/serviceaccount

ca.crt  namespace  token


6

토큰 정보 확인 ?

kubectl exec -it dev-kubectl -n dev-team -- cat /run/secrets/kubernetes.io/serviceaccount/token


kubectl exec -it dev-kubectl -n dev-team -- cat /run/secrets/kubernetes.io/serviceaccount/namespace


kubectl exec -it dev-kubectl -n dev-team -- cat /run/secrets/kubernetes.io/serviceaccount/ca.crt


7

각각 파드로 Shell 접속하여 정보 확인 : 단축 명령어(alias) 사용

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

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



8

권한 테스트 - 기본 권한으로 실행이 안된다.


k1 get pods 

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

// pod내에서 명령어를 실행하는것이다.


k1 run nginx --image nginx:1.20-alpine


k1 get pods -n kube-system


권한 테스트 - 기본 권한으로 실행이 안된다.


[root@kops-ec2 ~]# k1 get pods

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

command terminated with exit code 1


[root@kops-ec2 ~]# k1 run nginx --image nginx:1.20-alpine

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

command terminated with exit code 1


[root@kops-ec2 ~]# k1 get pods -n kube-system

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

command terminated with exit code 1


현재 서비스 어카운트에 권한이 없다!!!

role 이 없다.

role 바인딩을 안했다.


8

k2 get pods 

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


pod 도 만들어보자 ?

k2 run nginx --image nginx:1.20-alpine

k2 get pods -n kube-system

권한 테스트 - 기본 권한으로 실행이 안된다.


9

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

k1 auth can-i get pods

no



10

role    과   role 바인딩을 해야 사용가능 하다.




<5>각 네임스페이스에 롤(Role)를 생성 후 서비스 어카운트 바인딩 


1

롤(Role) : apiGroups 와 resources 로 지정된 리소스에 대해 verbs 권한을 인가


2

실행 가능한 조작(verbs) ?

*(모두 처리), create(생성), delete(삭제), get(조회), list(목록조회), patch(일부업데이트), update(업데이트), watch(변경감시)


3

롤 생성

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

 dev-team 모두 쓸수 있는 롤을 만들자!!!


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


4

infra-team 모두 쓸수 있는 롤을 만들자!!!


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


5

롤 확인 

kubectl get roles -n dev-team

kubectl get roles -n infra-team

kubectl get roles -n dev-team -o yaml


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

PolicyRule:

  Resources  Non-Resource URLs  Resource Names  Verbs

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

  *.*        []                 []              [*]

모든 권한이 주어 졌다!!!


6

롤바인딩 생성 ?

롤 바인딩 하자!

서비스어카운트 <-> 롤 간 서로 연결

dev-k8s 사용자 = 서비스어카운트


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



7

롤 바인딩 하자!

infra-k8s  사용자 서비스어카운트


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


8

롤바인딩 확인

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

Role:

  Kind:  Role

  Name:  role-dev-team

Subjects:

  Kind            Name     Namespace

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

  ServiceAccount  dev-k8s  dev-team





<6>  서비스 어카운트를 지정하여 생성한 파드에서 다시 권한 테스트


1

각각 파드로 Shell 접속하여 정보 확인 : 단축 명령어(alias) 사용

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

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


2

권한 테스트1

k1 get pods 


k1 get pods 

성공

NAME          READY   STATUS    RESTARTS   AGE

dev-kubectl   1/1     Running   0          10m


3

생성 = 됨

k1 run nginx --image nginx:1.20-alpine

k1 delete pods nginx



4

다른 네임스페이스에 있는  pod 는 조회가 안됨

k1 get pods -n kube-system

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

command terminated with exit code 1



5

권한 테스트2

k2 get pods 

k2 run nginx --image nginx:1.20-alpine

k2 get pods

k2 delete pods nginx

k2 get pods -n kube-system

k2 get nodes


6

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

k1 auth can-i get pods

yes



7

kubectl delete ns dev-team infra-team

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




8

기타

pod삭제

kubectl delete pod my-kubectl


서비스 어카운트 삭제 

kubectl delete sa ${MySA} ; kubectl delete roles myrole-pods ; kubectl delete rolebindings myroleb-${MySA}




<7> 실습4-10. EKS 클러스터 인증과 AWS IAM통합


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



<8> (몰아보기) EKS 실습 4 - 4주 스터디 


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


감사합니다.


        

매거진의 이전글 EKS 4탄-8. EKS보안-AWS인증, 인가

작품 선택

키워드 선택 0 / 3 0

댓글여부

afliean
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari