실습 4탄 = 9/17
아래 내용은 주말 EKS 스터디 하며 , 해당 내용을 참고하여 작성 되었습니다.
쿠버네티스 인증,인가에 대해 알아보자
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 서버로 로그온한다.
쿠버네티스에 서비스 어카운드 (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 를 지정하여 권한에 대한 테스트를 진행
실습 환경
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
사이트에서 보면 디코드 해서 볼수 있다.
서비스 어카운트를 지정하여, 파드 생성후 권한 테스트 해보자!!!
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 바인딩을 해야 사용가능 하다.
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
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
감사합니다.