이 글은 CloudNet@팀의 AWS EKS Workshop Study(AEWS) 3기 스터디 내용을 바탕으로 작성되었습니다.
AEWS는 CloudNet@의 '가시다'님께서 진행하는 스터디로, EKS를 학습하는 과정입니다.
EKS를 깊이 있게 이해할 기회를 주시고, 소중한 지식을 나눠주시는 가시다님께 다시 한번 감사드립니다.
이 글이 EKS를 학습하는 분들께 도움이 되길 바랍니다.
Kubernetes에서는 API 서버(Kube API Server)를 통해 클러스터 내 리소스에 접근하며, 보안 강화를 위해 인증(Authentication)과 인가(Authorization) 과정을 거칩니다.
Kubernetes API 서버는 클러스터 내 리소스를 관리하는 핵심 컴포넌트이며, 클라이언트(예: kubectl)가 API 요청을 보낼 때 다음과 같은 방법으로 인증을 수행합니다.
kubectl은 Kubernetes API 서버와 상호작용하는 CLI 도구입니다.kubeconfig 파일에 CA 인증서(CA crt), 클라이언트 인증서(Client crt), 클라이언트 키(Client key)를 포함하여 인증을 수행합니다.client certificate authentication을 설정할 수 있습니다.Kubernetes에서 클라이언트가 API 서버에 접근하는 과정은 인증(Authentication) → 인가(Authorization) → Admission Control(승인 제어)의 3단계로 진행됩니다.
X.509 인증서, Service Account, Bearer Token 등의 방식을 활용합니다.ResourceQuota, LimitRange 등을 활용하여 리소스 사용량 제한을 설정할 수 있습니다.Kubernetes에서는 다양한 인증 방식을 지원하며, 대표적인 방법은 다음과 같습니다.
kubeconfig 파일에서 CA 인증서(CA crt), 클라이언트 인증서(Client crt), 클라이언트 개인 키(Client key) 정보를 사용하여 인증을 수행합니다.kubectl은 kubeconfig를 기반으로 여러 개의 클러스터를 관리할 수 있습니다.contexts를 사용하여 서로 다른 클러스터와 유저 정보를 설정할 수 있습니다.default Service Account가 할당됩니다.Kubernetes에서 인증된 사용자에 대해 API 요청을 허용할지 결정하는 과정이 인가(Authorization)입니다.
대표적인 인가 방식은 다음과 같습니다.
RBAC(Role-Based Access Control)
RBAC 개념
Role : 특정 네임스페이스 내에서만 적용되는 권한ClusterRole : 클러스터 전체에서 적용되는 권한RoleBinding : 특정 네임스페이스 내에서 Role을 서비스 어카운트에 바인딩ClusterRoleBinding : 클러스터 전체에서 ClusterRole을 서비스 어카운트에 바인딩기타 인가 방식
Kubernetes에서는 특정 사용자나 애플리케이션이 클러스터 내 리소스에 접근할 수 있도록 Service Account를 생성하고, 역할(Role)을 부여하여 권한을 제한할 수 있습니다.
이번 실습에서는 다음과 같은 환경을 구성합니다.
실습 목표
실습 환경
dev-k8s: dev-team 네임스페이스에서 모든 리소스 조작 가능infra-k8s: infra-team 네임스페이스에서 모든 리소스 조작 가능dev-k8s → dev-team 내 리소스 조작 가능infra-k8s → infra-team 내 리소스 조작 가능TokenRequest API 활용)# 네임스페이스(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

Kubernetes에서 서비스 어카운트(Service Account)를 지정하여 파드를 생성하고, 해당 파드에서 Kubernetes API 접근 권한을 테스트합니다.
# 각각 네임스피이스에 kubectl 파드 생성 - 컨테이너이미지
# docker run --rm --name kubectl -v /path/to/your/kube/config:/.kube/config bitnami/kubectl:latest
# dev-team 네임스페이스에서 파드 생성
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
# infra-team 네임스페이스에서 파드 생성
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
# dev-kubectl 파드의 서비스 어카운트 확인
kubectl get pod -o dev-kubectl -n dev-team -o yaml
serviceAccount: dev-k8s
...
# infra-kubectl 파드의 서비스 어카운트 확인
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



=> 권한이 없으니 에러나는게 정상
Kubernetes에서 사용자 또는 서비스 어카운트의 권한을 제한하고 관리하는 방식 중 하나는 RBAC(Role-Based Access Control)을 활용하여 Role과 RoleBinding을 설정하는 것입니다.
각각의 네임스페이스 내에서 특정 리소스에 대한 권한을 설정하는 Role을 생성하고, 이를 Service Account와 바인딩하는 과정을 정리합니다.
Kubernetes의 RBAC(Role-Based Access Control)에서 권한을 부여하는 방식은 다음과 같은 구조로 이루어집니다.
Role(롤)
RoleBinding(롤 바인딩)
# Print the supported API resources on the server.
# 지원되는 API 리소스 목록 확인
kubectl api-resources
# Print the supported API resources with more information
# API 리소스의 상세 정보 확인
kubectl api-resources -o wide
# Print the supported API resources with a specific APIGroup
# 특정 API 그룹의 리소스 조회
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



각 네임스페이스에서 서비스 어카운트에 특정 권한을 부여하기 위해 Role을 생성합니다.
# 각각 네임스페이스내의 모든 권한에 대한 롤 생성
# dev-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
# infra-team 네임스페이스의 Role 생성
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
🔹 설명
apiGroups: ["*"] : 모든 API 그룹을 포함합니다.resources: ["*"] : 해당 네임스페이스 내 모든 리소스에 대한 권한을 설정합니다.verbs: ["*"] : 생성, 삭제, 조회 등 모든 작업을 허용합니다.
# 롤 확인
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
--------- ----------------- -------------- -----
*.* [] [] [*]
=> 해당 Role이 네임스페이스 내의 모든 리소스에 대한 모든 권한을 가지고 있음을 의미합니다.

생성된 Role을 각 네임스페이스의 서비스 어카운트와 바인딩하여 해당 권한을 적용합니다.
# 롤바인딩 생성 : '서비스어카운트 <-> 롤' 간 서로 연동
# dev-team 네임스페이스에서 RoleBinding 생성
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
# infra-team 네임스페이스에서 RoleBinding 생성
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
🔹 설명
roleRef : RoleBinding이 참조하는 Role을 지정합니다.subjects : Role을 적용할 Service Account를 명시합니다.kind: ServiceAccount : Service Account와 연결됨을 의미합니다.
# 롤바인딩 확인
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

# 각각 파드로 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은 dev-kubectl 파드에서 실행하는 kubectl 명령을 의미합니다.k2는 infra-kubectl 파드에서 실행하는 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 auth can-i 로 kubectl 실행 사용자가 특정 권한을 가졌는지 확인
k1 auth can-i get pods
yes
🔹 설명
dev-k8s 서비스 어카운트)가 get pods 명령을 실행할 수 있는지 확인합니다.yes가 출력되면 해당 네임스페이스에서 파드 조회 권한이 있음을 의미합니다.no가 출력되면 해당 권한이 없음을 의미하며, 추가적인 RoleBinding 설정이 필요합니다.
kubectl delete ns dev-team infra-team
안녕하세요 주영님
IT교육 전문플랫폼 스나이퍼팩토리입니다!
AI·클라우드 개발을 배우고 싶은 분들께 도움이 될 것 같아 공유 드립니다.
현재 카카오엔터프라이즈X고용노동부가 함께하는 ‘카카오클라우드 AIaaS’ 과정이 열리고 있습니다.
✔️ 내일배움카드만 있으면 전액 무료 수강 가능
✔️ 매달 훈련장려금 + 국취제 최대 80만 원 지원
✔️ 실무 중심 교육 + 취업 포트폴리오 제작 기회
3/19(수)에 모집이 마감되오니,
아래 링크 또는 저희 스나이퍼팩토리 블로그 내용 확인해보시고
참여를 원하시는 경우 신청해보시기를 추천 드립니다 :)
감사합니다.
관련 링크 : https://buly.kr/APuaouj