[Kubernetes] kubectl 연습 - RoleBinding
실제 회사 클러스터에서는 누가 뭘 할 수 있는지를 제어해야 한다. Role-Based Access Control이 필요함.
secret을 다룰 때도 사실 그냥 인코딩일 뿐이니 진짜 secret처럼 다루려면 RBAC로 아무나 get secret을 수행하지 못하게 해야한다.
주체 : 쿠버 밖의 사람, ServiceAccount
Role: 권한의 목록으로 뭘 할 수 있느닞를 정의한다.
RoleBinding : 주체와 Role을 묶는다. 특정 사람에게 이 Role을 준다.

Role과 RoleBinding은 특정 namespace 안에서만 유효하고, ClusterRole과 ClusterRoleBinding은 클러스터 전체에서 유효하다.
13months@13monthsBook k8s % k create serviceaccount pod-viewer
serviceaccount/pod-viewer created
13months@13monthsBook k8s % k create role pod-reader --verb=get --verb=list --resource=pods
role.rbac.authorization.k8s.io/pod-reader created
13months@13monthsBook k8s % k create rolebinding pod-viewer-binding --role=pod-reader --serviceaccount=default:pod-viewer
rolebinding.rbac.authorization.k8s.io/pod-viewer-binding created
13months@13monthsBook k8s % k get serviceaccount
NAME AGE
default 5h38m
pod-viewer 17s
13months@13monthsBook k8s % k get role
NAME CREATED AT
pod-reader 2026-07-23T07:47:21Z
13months@13monthsBook k8s % k get rolebinding
NAME ROLE AGE
pod-viewer-binding Role/pod-reader 11s
13months@13monthsBook k8s %
User는 인증서 설정이 복잡하니 ServiceAccount를 사용해보자.
Pod에게 제한된 권한을 주고 실제로 그 권한만 줄 수 있는지 확인하면 됨.
pod-viewer라는 앱 계정과 Pod를 대상으로 get과 list를 수행할 수 있는 role을 만들어주자.
이후 RoleBinding으로 ServiceAccount와 role을 연결해준다.
13months@13monthsBook k8s % kubectl auth can-i get pods
yes
13months@13monthsBook k8s % kubectl auth can-i get pods --as=system:serviceaccount:default:pod-viewer
yes
13months@13monthsBook k8s % kubectl auth can-i list pods --as=system:serviceaccount:default:pod-viewer
yes
13months@13monthsBook k8s % kubectl auth can-i delete pods --as=system:serviceaccount:default:pod-viewer
no
13months@13monthsBook k8s % kubectl auth can-i get secrets --as=system:serviceaccount:default:pod-viewer
no
13months@13monthsBook k8s %
역할이 제대로 연결됐는지 확인해보자.
can-i 명령어를 사용하면 특정 계정으로 특정 작업을 수행할 수 있는지 확인할 수 있다.
관리자 계정으로 물어보면 무조건 yes라고 뜸.
의도된대로 나타남을 확인할 수 있다.
kubectl auth can-i <동작> <리소스> --as=<주체>
이거를 기억해두면 권한 에러를 뱉을 때 뭐가 막혔는지를 확인할 수 있다. 그러니 Role이나 RoleBinding을 고쳐주면 됨.
다만 Role은 자기 namespace 안에서만 유효하다.
Q. 웹 애플리케이션을 쿠버네티스에 배포해줘. 설정값은 외부에서 주입하고, 데이터는 영구 저장되어야 하고, 외부에서 접속 가능해야 해. 전용 namespace에 격리해서.
1. namespace
k create namespace guestbook
2. ConfigMap
k create configmap app-config \
--from-literal=APP_TITLE=MyGuestbook \
--from-literal=APP_ENV=production \
-n guestbook
3. PVC (k8s docs에서 붙여넣기)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: guestbook-data
namespace: guestbook
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
k apply -f guestbook-pvc.yaml
실수로 pvc 말고 pv 만들었으면 삭제하고 진행해야 함. 수정은 불가능하다.
k8s docs에서 복붙하거나 dry-run으로 yaml 작성하자.
Q. guestbook namespace에 guestbook-app이라는 Deployment를 만드세요. 요구사항은 네 가지입니다.
- 이미지: nginx
- replicas: 3개
- 앞에서 만든 ConfigMap app-config의 값들을 환경변수로 주입 (envFrom 방식 — 전체 주입)
- 앞에서 만든 PVC guestbook-data를 컨테이너의 /data 경로에 마운트
yaml 구조를 외우려고 하지 말고 왜 거기 있는지 이해하자.
replicas: 3은 Deployment의 속성이니 spec 바로 아래에 위치함.
image: nginx는 Container의 속성이니 containers 항목 안에 위치함.
envFrom은 Container의 속성이니 containers 항목 안에 위치함.
volumeMounts는 Container의 속성이니 containers 항목 안에 위치함.
volumes는 Pod의 속성이니 template.spec 아래 위치함.
volumeMounts는 컨테이너가 볼륨을 어디에 붙일지, volumes는 Pod가 어떤 볼륨을 가질지를 결정한다.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: guestbook-app
name: guestbook-app
namespace: guestbook
spec:
replicas: 3
selector:
matchLabels:
app: guestbook-app
strategy: {}
template:
metadata:
labels:
app: guestbook-app
spec:
containers:
- image: nginx
name: nginx
resources: {}
envFrom:
- configMapRef:
name: app-config
volumeMounts:
- name: data-vol
mountPath: /data
volumes:
- name: data-vol
persistentVolumeClaim:
claimName: guestbook-data
status: {}
dry-run 으로 템플릿 만들고 수정하되, 어디에 어떤 속성이 붙는지만 제대로 정리해두자.
yaml에서 - 는 List로 여러 요소를 나열할 때 사용한다.
그리고 이름표:값은 Map이다. 맨날 쓰는 그거임
컨테이너는 여러 개일 수 있으니 리스트이고, 각 컨테이너는 여러 속성을 가지니 맵이다.
# 단순 값 리스트
colors:
- red
- blue
# 맵 리스트 (각 항목이 속성 여러 개)
people:
- name: 철수
age: 20
- name: 영희
age: 25
# 맵 안에 리스트, 그 안에 또 맵
containers:
- name: nginx ← 컨테이너 항목
env: ← 이 컨테이너의 env (리스트)
- name: MODE ← env의 첫 항목
value: prod ← 그 항목의 속성 (name보다 안 깊고 같은 레벨)
containers: ← "containers라는 키. 값은 아래를 봐야 앎"
- name: nginx ← "-가 있네! containers는 리스트. 첫 항목 시작. name=nginx"
image: nginx ← "-가 없고 name과 들여쓰기 같음. 첫 항목에 계속 속함. image=nginx"
ports: ← "여전히 첫 항목의 속성. ports라는 키. 값은 아래 봐야 앎"
- containerPort: 80 ← "-가 있네! ports는 리스트. 그 항목은 containerPort=80"
- name: sidecar ← "-가 또 나옴! containers 리스트의 두 번째 항목 시작"
image: busybox ← "두 번째 항목에 속함"
containers: 에서 아래에 - 가 있으니까 containers가 리스트가 되는거임. - 가 없으면 그냥 맵이다.
리스트 아래에 같은 들여쓰기로 들어온다면 같은 항목이다. 새 리스트가 나오기 전까지 같은 항목으로 묶임.
envFrom은 명령어 주입도 된다. 다만 PVC는 명령어로 안되니 YAML을 직접 조작해야 함.
kubectl set env deployment/guestbook-app --from=configmap/app-config
Q. guestbook namespace에 guestbook-svc라는 NodePort Service를 만들어서 guestbook-app을 포트 80으로 노출하세요.
13months@13monthsBook k8s % kubectl expose deployment guestbook-app \
> --name=guestbook-svc \
> --type=NodePort \
> --port=80 \
> --target-port=80 \
> -n guestbook
service/guestbook-svc exposed
13months@13monthsBook k8s % kubectl get svc -n guestbook
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
guestbook-svc NodePort 10.109.94.53 <none> 80:30548/TCP 20s
13months@13monthsBook k8s % kubectl describe svc guestbook-svc -n guestbook
Name: guestbook-svc
Namespace: guestbook
Labels: app=guestbook-app
Annotations: <none>
Selector: app=guestbook-app
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.109.94.53
IPs: 10.109.94.53
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 30548/TCP
Endpoints: 10.244.1.8:80,10.244.2.6:80,10.244.0.8:80
Session Affinity: None
External Traffic Policy: Cluster
Internal Traffic Policy: Cluster
Events: <none>
13months@13monthsBook k8s %
우선 명령어로 되는지, YAML로 풀 수 있는지 판단하자. 대부분은 명령어로 된다.
YAML이 필요해도 빈 파일에서 시작하지 말고 병령어로 뼈대를 잡는게 좋다. --dry-run 을 사용하거나 k8s docs에서 긁어오자.
dry-run을 사용한 후에 필요한 부분은 또 k8s docs에서 가져오는게 좋음. envFrom을 어느 위치에 넣는지? 같은것..
그리고 다 만들었다면 검증해야 함. k get / k describe / k exec 등
'DevOps > Docker && Kubernetes' 카테고리의 다른 글
| [Kubernetes] kubectl 연습 - Deployment ReplicaSet (0) | 2026.07.21 |
|---|---|
| [Kubernetes] Kubernetes Concept (0) | 2026.07.21 |
| [k8s] 쿠버네티스 도입 (0) | 2023.12.17 |
| [Docker] 네트워킹과 Docker Compose (1) | 2023.12.10 |
| [Docker] Dockerfile 프로젝트 배포하기 (3) | 2023.12.06 |
댓글
이 글 공유하기
다른 글
-
[Kubernetes] kubectl 연습 - Deployment ReplicaSet
[Kubernetes] kubectl 연습 - Deployment ReplicaSet
2026.07.21 -
[Kubernetes] Kubernetes Concept
[Kubernetes] Kubernetes Concept
2026.07.21 -
[k8s] 쿠버네티스 도입
[k8s] 쿠버네티스 도입
2023.12.17 -
[Docker] 네트워킹과 Docker Compose
[Docker] 네트워킹과 Docker Compose
2023.12.10