마루옵스서버 · 네트워크 · AI 기술 노트

소개문의

[쿠버네티스 학습 08] RBAC·NetworkPolicy·Pod 실행 권한

랙 안에 모인 다수의 네트워크 케이블

참고 사진 · 랙 안에 모인 다수의 네트워크 케이블 · 사진: Xbspiro / 원본 / CC BY-SA 3.0 · 목록용 크기 조정

전체 연재 안내 · 실습 파일 ZIP

Windows 11 · VMware · Rocky Linux Kubernetes 연재 08/10

앞에서 만든 관리자 kubeconfig를 모든 앱과 자동화에 넣을 필요는 없습니다. 작업에 맞는 권한을 따로 주는 편이 유출 시 범위를 줄일 수 있어요. 이 글에서는 API 권한, Pod 통신, 컨테이너 실행 조건을 각각 제한해 봅니다.

1. 읽기 전용 ServiceAccount·Role

cp01의 ~/k8s-lab/app/rbac-reader.yaml로 저장합니다. ServiceAccount는 워크로드 등이 사용하는 API 주체이며, 이번 계정은 자동 토큰 마운트를 사용하지 않습니다.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: lab-reader
  namespace: lab
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: workload-reader
  namespace: lab
rules:
  - apiGroups: [""]
    resources: [pods, services]
    verbs: [get, list, watch]
  - apiGroups: [apps]
    resources: [deployments]
    verbs: [get, list, watch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: lab-reader-binding
  namespace: lab
subjects:
  - kind: ServiceAccount
    name: lab-reader
    namespace: lab
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: workload-reader
kubectl apply -f ~/k8s-lab/app/rbac-reader.yaml
kubectl auth can-i list pods -n lab \
  --as=system:serviceaccount:lab:lab-reader
kubectl auth can-i get secrets -n lab \
  --as=system:serviceaccount:lab:lab-reader
kubectl auth can-i delete deployments -n lab \
  --as=system:serviceaccount:lab:lab-reader

출력이 차례로 yes, no, no인지 확인합니다. 관리자가 impersonation으로 권한 판단을 조회하는 검사입니다. ServiceAccount 토큰으로 실제 로그인하는 인증 과정까지 시험한 것은 아닙니다. 로그를 읽으려면 pods/log 같은 하위 리소스의 권한도 별도로 필요합니다.

Role은 네임스페이스 범위이고 ClusterRole은 클러스터 범위의 권한 정의에도 사용합니다. ClusterRole을 RoleBinding으로 한 네임스페이스에 연결할 수도 있어요. 이름만 보지 말고 어떤 바인딩으로 어디에 연결됐는지 확인합니다. Secret 읽기나 Pod 생성은 권한 확대에 이어질 수 있어 필요한 범위만 부여합니다.

2. 자동 토큰 마운트 해제

정적 웹 서버는 Kubernetes API에 접근할 필요가 없습니다. web-deployment.yaml의 spec.template.spec에 아래 값을 추가한 뒤 다시 apply합니다.

automountServiceAccountToken: false
kubectl apply -f ~/k8s-lab/app/web-deployment.yaml
kubectl -n lab rollout status deployment/web --timeout=180s

API 접근이 필요한 자동화에는 TokenRequest 기반의 짧은 수명 토큰과 필요한 Role을 사용합니다. 관리자 kubeconfig나 만료 없는 레거시 토큰을 기본으로 Pod에 넣지 않습니다. 토큰은 공개 예제나 이슈, 터미널 기록에 남기지 않습니다.

3. Ingress NetworkPolicy

정책은 app=web Pod로 들어오는 연결을 제한합니다. 적용 뒤 Windows NodePort도 막힐 수 있어요. 의도한 차단 시험이므로 아래의 허용 확인과 정책 정리까지 이어서 진행합니다. 이 과정에서 Calico가 Pod의 패킷 경로에 규칙을 적용합니다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: web-default-deny
  namespace: lab
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes: [Ingress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: web-allow-trusted
  namespace: lab
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes: [Ingress]
  ingress:
    - from:
        - podSelector:
            matchLabels:
              role: trusted
      ports:
        - protocol: TCP
          port: 8080

web-networkpolicy.yaml로 저장하고 실행합니다. from의 podSelector만 쓰면 같은 네임스페이스에서 고릅니다. NetworkPolicy의 허용 규칙은 합쳐지므로 다른 정책이 허용한 연결을 기본 차단 정책 하나로 다시 취소하는 구조가 아닙니다.

kubectl apply -f ~/k8s-lab/app/web-networkpolicy.yaml
kubectl -n lab run trusted --image=busybox:1.37.0 \
  --labels=role=trusted --restart=Never --command -- sleep 3600
kubectl -n lab run stranger --image=busybox:1.37.0 \
  --restart=Never --command -- sleep 3600
kubectl -n lab wait --for=condition=Ready pod/trusted pod/stranger --timeout=120s
kubectl -n lab exec trusted -- wget -T 3 -qO- http://web/
kubectl -n lab exec stranger -- wget -T 3 -qO- http://web/

기존 연결 대신 새 연결로 시험해 trusted는 페이지를 받고 stranger는 제한 시간 안에 연결하지 못하는지 확인합니다. 예제는 Ingress만 제한합니다. 나중에 Egress 기본 차단을 넣는다면 CoreDNS의 UDP/TCP 53과 외부 의존성을 별도로 허용해야 합니다. 정책 집행은 CNI 지원에 달려 있으며 여기서는 Calico가 맡습니다.

4. 정책 정리와 Pod Security

kubectl -n lab delete pod trusted stranger
kubectl -n lab delete networkpolicy web-default-deny web-allow-trusted

이제 Windows의 NodePort 접속도 다시 확인합니다. 다음 단계의 제한 정책은 5편의 웹 Deployment처럼 비특권 실행 조건을 갖춘 Pod를 기준으로 합니다. 순서를 바꿔 먼저 적용하면 방금 사용한 기본 busybox 점검 Pod 생성이 거절될 수 있습니다.

kubectl label namespace lab \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=v1.36 \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/warn-version=v1.36 \
  --overwrite
kubectl apply --dry-run=server -f ~/k8s-lab/app/volume-check.yaml

restricted 기준은 호스트 네임스페이스, 권한 상승, capabilities 등의 사용을 제한합니다. 기존 Pod를 즉시 종료하는 대신 다음 생성·변경 요청을 검사합니다. 시스템 네임스페이스에 일괄 적용하면 필수 구성 요소를 막을 수 있으므로 lab에서만 시험합니다.

5. 권한·통신·실행 제한의 차이

장치제어하는 것이 실습의 확인
RBACAPI로 할 수 있는 작업Pod 조회 yes, Secret 조회 no
NetworkPolicy선택된 Pod의 L3/L4 통신trusted만 웹 8080 접근
Pod Security AdmissionPod 생성 시의 보안 조건비특권 실행 조건 검증

RBAC는 API 권한을, NetworkPolicy는 통신을 제한합니다. 앱 취약점이나 관리자 자격증명 유출까지 서로 대신 막아 주지는 않습니다. 어떤 제한이 어느 경로에 적용됐는지 나눠 두면 접속 실패를 진단할 때도 도움이 됩니다.

참고 자료

공식 문서와 배포 파일 확인 기준: 2026년 10월 18일. 출력은 완료 여부를 판단하기 위한 예시이며 환경별로 달라질 수 있습니다.


← 07편 · 09편 →

전체 10편 목차 펼치기

전체 연재 안내와 실습 기준

댓글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

닉네임·이메일·댓글 내용·IP 주소·브라우저 정보는 댓글 게시 및 관리에 사용됩니다. 이메일과 접속 정보는 공개 댓글에 표시하지 않습니다. 개인정보 요청은 운영자 이메일로 보내 주세요. 개인정보처리방침