728x90
K8S 인증/인가
Kubernetes에서는 API 통신을 위하여 인증(Authentication), 인가/권한(Authorization), Admission Control(승인제어) 단계를 거치게 된다.

인증(Authentication): Kubernetes를 사용하는 사용자가 검증된 사용자인지를 확인하는 절차
- X.509 Client Certs : kubeconfig 에 CA crt(발급 기관 인증서) , Client crt(클라이언트 인증서) , Client key(클라이언트 개인키) 를 통해 인증
- kubectl : 여러 클러스터(kubeconfig)를 관리 가능 - contexts 에 클러스터와 유저 및 인증서/키 참고
- Service Account : 기본 서비스 어카운트(default) - 시크릿(CA crt 와 token)

인증서를 통한 인증(Authentication) 실습

# 하위 인증서를 위한 비밀키 생성
openssl genrsa -out yjsong.key 2048

# 인증서 사인 요청 파일(.csr) 파일 생성
openssl req -new -key yjsong.key -out yjsong.csr -subj "/O=kubeadm:cluster-admins/CN=yjsong-cert"

# 출력 값을 아래 request 에 붙여넣기 : 끝에 == 빼먹지 말것!
cat yjsong.csr | base64 | tr -d '\n'
# CSR 요청 : k8s 내부적으로 루트인증서의 비밀키로 서명해 반환. 즉 간접적으로 루트 인증서의 비밀키를 사용할 수 있음 셈.
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: yjsong-csr
spec:
signerName: kubernetes.io/kube-apiserver-client
groups:
- system:masters
- system:authenticated
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ2ZEQ0NBV1FDQVFBd056RWZNQjBHQTFVRUNnd1dhM1ZpWldGa2JUcGpiSFZ6ZEdWeUxXRmtiV2x1Y3pFVQpNQklHQTFVRUF3d0xlV3B6YjI1bkxXTmxjblF3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUUNyUVdKOW5GNWs5VWZraUw3QndncXRhN0ZsMklBc3YxdVpIU1ZjRkQ5WXNnZlhKQ1doZldSWVpwUm0KbUQ1OWgyODFMV3Zma0ZyaXBkNkpMdXY4K2JUbFJ6NC9SVUNjQ0JyTUpSZjNRenhaYWs5RllLaUZ0VkI2TXdMdQorN1hpaWZ0ZXBaa0ZFeDJ5Uk1kaHk2elI2YmpBWDdVSEhjSXJ5ekhESHB6eHlzeXRGSG9MU2dzYW5PakVTdXpXClZac09ocDk5ZU1LQjFZUUo2NnZzVGwvSUJ0UHlUWmZCU2QzT1JFendZRk1TbkdrYmxBMmU3WGY4MFhnWEQ3RU8KRVQxdXVjQVJXZ3NsUWpEWklUYTBzbTJOVE9Tcm1TVFd1OWgrUGFrbVRnWDBvcmRBQVFhSXdldHcxMFpUbEtrVQpxeXBtSEpFbXpZZU8xanVUODc3ZkFJWGFaUTl4QWdNQkFBR2dBREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBClZxbGZNS0pZR0VrNUJnV1F5NXBSQWgyMlNtZnRiQjlSN1hPeTVWME5JY1RPN3ZEQUx3akZGTVVJeHlnNGlvaG0KRVg3YVdacmdQMXFJbzY2aUFEKzlYakYxQzNBYXlHVHh3QkVsSXpPNnpTUFF0bzFmZFRtcUhWcGc2dUNiSWNXcgpxYWRGUzdEcWUzU0gyYzBNdnhScER5TUdzcllsZ0JWaW9IWUtZcTc5czJnRTduazNodi9LVDM1YjdFSkhHTGZDCm9BelVIdy9iRVlQNWJzeTI5ZU90SjgxNlZiRjFSd2V3eS9nM1lmMkJBQ1dtYlJ4OFRxMXNPUWkxb1VzWTJQNEgKWGl6RXk0SWR2RXpUV0dGVy9mMjYxR3ZIYkNDYlRMR1N5Q2ZaVWY0R0V1QVNpSXV4bGh4ZWhuVjRncWpUQXhhTQpQcG1oWFJBbk1BQmxsa2pZWHZkblh3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
usages:
- digital signature
- key encipherment
- client auth
EOF

# csr 확인 : 아직은 펜딩 상테
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
yjsong-csr 71s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Pending

# 'k8s 관리자' 입장에서 해당 서명 요청을 승인하자
kubectl certificate approve yjsong-csr
certificatesigningrequest.certificates.k8s.io/yjsong-csr approved

# 확인 : 정상적으로 하위 인증서가 발급됨
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
yjsong-csr 3m11s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Approved,Issued

# csr 에서 하위 인증서 추출
kubectl get csr yjsong-csr -o jsonpath='{.status.certificate}' | base64 -d
kubectl get csr yjsong-csr -o jsonpath='{.status.certificate}' | base64 -d > yjsong.crt
openssl x509 -in yjsong.crt -noout -text


# kubeconfig 에 새로운 사용자 등록
kubectl config set-credentials yjsong-user --client-certificate=yjsong.crt --client-key=yjsong.key
kubectl config set-context kind-yjsong --cluster=kind-myk8s --user=yjsong-user
cat ~/.kube/config
kubectl config use-context kind-yjsong # 혹은 kubectl ctx kind-yjsong
# ctx kind-yjsong 로 k8s 정보 확인 시도
kubectl get node


kube/config 파일 내용
- clusters : kubectl 이 사용할 쿠버네티스 API 서버의 접속 정보 목록. 원격의 쿠버네티스 API 서버의 주소를 추가해 사용 가능
- users : 쿠버네티스의 API 서버에 접속하기 위한 사용자 인증 정보 목록. (서비스 어카운트의 토큰, 혹은 인증서의 데이터 등)
- contexts : cluster 항목과 users 항목에 정의된 값을 조합해 최종적으로 사용할 쿠버네티스 클러스터의 정보(컨텍스트)를 설정

인가/권한(Authorization): 사용자 행위에 대해서 권한이 있는지를 확인하는 절차
- RBAC : 역할 기반의 권한 관리, 사용자와 역할을 별개로 선언 후 두가지를 조합(binding)해서 사용자에게 권한을 부여하여 kubectl or API로 관리 가능
- Namespace/Cluster - Role/ClusterRole, RoleBinding/ClusterRoleBinding, Service Account
- Role(롤) - (RoleBinding 롤 바인딩) - Service Account(서비스 어카운트) : 롤 바인딩은 롤과 서비스 어카운트를 연결
- Role(네임스페이스내 자원의 권한) vs ClusterRole(클러스터 수준의 자원의 권한)
- - User Account 별 Role/Rolebinding / Cluster Role/ Cluster Rolebinding
- Service Account 별로 Role/Rolebinding / Cluster Role/ Cluster Rolebinding

Service Account 인가(Autorization) 실습




- 서비스 어카운트(Service Account, SA)를 생성 : dev-k8s, infra-k8s
- 서비스 어카운트 별 Pod 생성 및 권한 Test
- 서비스 어카운트 별 권한(Role, 인가)생성 : dev-k8s(dev-team 네임스페이스 내 모든 동작) , infra-k8s(dev-team 네임스페이스 내 모든 동작)
- SA 를 지정하여 권한에 대한 테스트를 진행
1. 네임스페이스와 서비스 어카운트 생성 후 확인
# 네임스페이스(Namespace, NS) 생성 및 확인
kubectl create namespace dev-team
kubectl create ns infra-team
# 네임스페이스 확인
kubectl get ns
# 네임스페이스에 각각 서비스 어카운트 생성 : serviceaccounts 약자(=sa)
kubectl create sa dev-k8s -n dev-team
kubectl create sa infra-k8s -n infra-team
# 서비스 어카운트 정보 확인
kubectl get sa -n dev-team
kubectl get sa dev-k8s -n dev-team -o yaml
kubectl get sa -n infra-team
kubectl get sa infra-k8s -n infra-team -o yaml


2. 서비스 어카운트 별 Pod 생성 및 권한 Test
# 각각 네임스피이스에 kubectl 파드 생성 - 컨테이너이미지
# docker run --rm --name kubectl -v /path/to/your/kube/config:/.kube/config bitnami/kubectl:latest
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.31.4
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.31.4
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
# 확인
kubectl get pod -A
kubectl get pod -o dev-kubectl -n dev-team -o yaml
serviceAccount: dev-k8s
...
kubectl get pod -o infra-kubectl -n infra-team -o yaml
serviceAccount: infra-k8s
...
# 파드에 기본 적용되는 서비스 어카운트(토큰) 정보 확인
kubectl exec -it dev-kubectl -n dev-team -- ls /run/secrets/kubernetes.io/serviceaccount
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
# 각각 파드로 Shell 접속하여 정보 확인 : 단축 명령어(alias) 사용
alias k1='kubectl exec -it dev-kubectl -n dev-team -- kubectl'
alias k2='kubectl exec -it infra-kubectl -n infra-team -- kubectl'
# 권한 테스트
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 # 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
# (옵션) kubectl auth can-i 로 kubectl 실행 사용자가 특정 권한을 가졌는지 확인
k1 auth can-i get pods
no




3. 서비스 어카운트 별 권한(Role, 인가)생성 : role-dev-team(dev-team 네임스페이스 내 모든 동작) , role-infra-team(infra-team 네임스페이스 내 모든 동작)
- 롤(Role) : apiGroups 와 resources 로 지정된 리소스에 대해 verbs 권한을 인가
- 실행 가능한 조작(verbs) : *(모두 처리), create(생성), delete(삭제), get(조회), list(목록조회), patch(일부업데이트), update(업데이트), watch(변경감시)


# Print the supported API resources on the server.
kubectl api-resources
# Print the supported API resources with more information
kubectl api-resources -o wide
# Print the supported API resources with a specific APIGroup
kubectl api-resources --api-group=""
kubectl api-resources --api-group="apps"
kubectl api-resources --api-group=metrics.k8s.io
kubectl api-resources --api-group=admissionregistration.k8s.io
kubectl api-resources --api-group=rbac.authorization.k8s.io
kubectl api-resources --api-group=apiextensions.k8s.io
# 각각 네임스페이스내의 모든 권한에 대한 롤 생성
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
# 롤 확인
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
# 롤바인딩 생성 : '서비스어카운트 <-> 롤' 간 서로 연동
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
# 롤바인딩 확인
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




4. SA 를 지정하여 권한에 대한 테스트를 진행
# 각각 파드로 Shell 접속하여 정보 확인 : 단축 명령어(alias) 사용
alias k1='kubectl exec -it dev-kubectl -n dev-team -- kubectl'
alias k2='kubectl exec -it infra-kubectl -n infra-team -- kubectl'
# 권한 테스트
k1 get pods
k1 run nginx --image nginx:1.20-alpine
k1 get pods
k1 delete pods nginx
k1 get pods -n kube-system
k1 get pods -n kube-system -v=6
k1 get nodes
k1 get nodes -v=6
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
# (옵션) kubectl auth can-i 로 kubectl 실행 사용자가 특정 권한을 가졌는지 확인
k1 auth can-i get pods
k2 auth can-i get pods

728x90
'2025_AEWS Study' 카테고리의 다른 글
6주차 - EKS Security - IRSA & Pod Identity(3) (0) | 2025.03.16 |
---|---|
6주차 - EKS Security - EKS 인증/인가(2) (0) | 2025.03.16 |
5주차 - EKS Autoscaling(Karpenter) (0) | 2025.03.07 |
5주차 - EKS Autoscaling(CAS→Node Autoscaling) (0) | 2025.03.07 |
5주차 - EKS Autoscaling(HPA/KEDA/VPA → Pod Autoscaling ) (0) | 2025.03.07 |