101. 서비스 어카운트 (ServiceAccount) 및 K8s RBAC 권한 통제

⚠️ 이 문서는 쿠버네티스 클러스터에서 사람이 치는 kubectl 명령어를 통제하는 것을 넘어, 클러스터 뱃속에 떠 있는 수만 개의 기계 봇(Pod 내의 애플리케이션)들이 맘대로 쿠버네티스 심장부(API Server)를 찔러 남의 파드를 지우거나 비밀번호(Secret)를 훔쳐보는 참사를 막기 위해, 파드(기계)에게 부여하는 고유한 로봇 신분증인 '서비스 어카운트(SA)'와, 그 신분증의 등급에 따라 할 수 있는 짓(Read/Write)을 깐깐하게 제한하는 '역할 기반 접근 제어(RBAC)' 보안 아키텍처를 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 쿠버네티스에는 사용자가 두 종류다. 사람(User)과 기계(Pod). 사람은 사내 AD나 OIDC 연동으로 인증하지만, 기계(Pod)는 쿠버네티스 자체가 직접 발급하고 인증해 주는 **'ServiceAccount(로봇 사원증)'**를 목에 걸고 다녀야 한다.
  2. 가치: 모니터링 파드에게는 "다른 파드의 상태를 볼 수만 있는 권한(Read Only)"을 주고, 배포 파이프라인(ArgoCD 파드)에게는 "새로운 파드를 생성할 수 있는 권한(Create)"을 정확히 쪼개어(최소 권한의 원칙), 해커가 1번 파드를 해킹해 점령하더라도 클러스터 전체를 붕괴시킬 수 없도록 완벽한 방폭벽을 친다.
  3. 기술 체계: 신분증인 **ServiceAccount**를 만들고, 권한의 묶음인 Role(예: 보기만 가능)을 만든 뒤, 이 둘을 이어주는 결재 서류인 **RoleBinding**을 통해 최종적으로 봇(Pod)에게 칼날 같은 권한을 부여하는 3단 분리 구조(RBAC)로 돌아간다.

Ⅰ. 파드(Pod)의 쿠데타: 내부 해킹의 무서움

성문(방화벽)을 뚫고 들어온 자객이 성의 통제권마저 빼앗으려 한다.

  1. API Server의 절대 권력:
    • 쿠버네티스의 심장(Master Node)에 있는 kube-apiserver는 신이다. 여기에 DELETE POD라는 API 찌름 한 번이면 클러스터의 모든 시스템이 날아간다.
    • 외부 인터넷 방화벽을 쳐서 해커가 밖에서 찌르는 건 막아놨다.
  2. 내부자(Pod)의 배신 (기본 SA의 위험성):
    • 하지만 해커가 웹 취약점을 통해 Nginx 웹 서버 파드(Pod) 내부로 침투하는 데 성공했다.
    • 쿠버네티스는 깡통 상태에서 아무런 설정을 안 하면, 파드가 생성될 때마다 default라는 이름의 만능 프리패스 신분증(ServiceAccount 토큰)을 파드 뱃속에 몰래 숨겨둔다(Auto-mounting).
    • 해커는 Nginx 파드 뱃속을 뒤져 이 프리패스 토큰을 훔쳐낸 뒤, 그 파드 안에서 신인 척하며 kube-apiserver를 찌른다. "야! 나 관리자인데, 이 클러스터에 있는 DB 비밀번호(Secret) 좀 다 까봐!"
    • API 서버는 신분증이 유효하니까 해커에게 회사 전체 DB 비밀번호를 다 뱉어버린다. 클러스터가 5초 만에 통째로 점령당했다.

📢 섹션 요약 비유: 회사 정문(방화벽)은 철통같이 막았는데, 1층 청소부(웹 파드)로 위장 취업한 스파이가 들어왔습니다. 문제는 회사가 멍청하게 청소부를 고용할 때 실수로 사장님 방 금고까지 열 수 있는 '마스터 키(디폴트 토큰)'를 청소부 주머니에 다 넣어준 것입니다. 스파이는 청소하다 말고 그 키를 꺼내 사장실(API 서버)을 털어버렸습니다. 이것이 권한 통제(RBAC)를 안 한 K8s의 참혹한 최후입니다.


Ⅱ. ServiceAccount와 RBAC: 권한을 갈기갈기 찢어라

로봇(파드)에게는 마스터 키 대신 오직 빗자루 하나만 주어라.

  1. Role (역할, 무엇을 할 수 있는가?):
    • 보안 관리자는 먼저 템플릿(권한 묶음)을 만든다.
    • Role 1 (모니터링 알바): "너는 클러스터의 Pod들 이름과 상태를 **보는 것(GET, LIST)**만 허락한다. 삭제나 생성은 절대 불가."
    • Role 2 (배포 매니저): "너는 Deployment를 새로 만들고(CREATE), 기존 것을 **삭제(DELETE)**할 수 있는 막강한 권한을 준다."
  2. ServiceAccount (로봇 신분증, 누가 할 것인가?):
    • 해커가 침투하기 쉬운 단순 웹 서버(Nginx 파드)를 띄울 때는, 아예 권한이 0인 완전 깡통 신분증(예: web-sa)을 하나 만들어 목에 걸어준다.
    • 프로메테우스(모니터링) 파드에게는 monitor-sa라는 이름표를 만들어 준다.
  3. RoleBinding (신분증과 권한의 결합):
    • 이제 신분증과 역할을 찰칵 이어붙여야(Binding) 마법이 완성된다.
    • RoleBinding 설정 파일에 이렇게 적는다. "방금 만든 monitor-sa(신분증)를 가진 로봇에게, 아까 만든 Role 1(모니터링 알바)의 권한을 합체시켜라!"
    • 결과: 프로메테우스 파드는 클러스터를 모니터링할 순 있지만, 해커가 거길 뚫고 들어와 "DB 파드 지워!"라고 명령하면 API 서버가 "네 까짓 모니터링 알바 신분증으로 지우기(Delete)를 시도해? 꺼져(403 Forbidden)!"라며 완벽하게 방어해 낸다.

📢 섹션 요약 비유: 군대에 비유하면 Role은 "소총 쏘기, 탱크 몰기, 핵버튼 누르기" 같은 행동 규정(매뉴얼)입니다. ServiceAccount는 "김이병, 박대장" 같은 군번줄(신분증)입니다. RoleBinding은 사령관이 결재 서류를 펴고 "오늘부터 김이병(SA)에게는 소총 쏘기(Role) 권한만 부여하고, 박대장에게는 핵버튼 누르기(Role) 권한을 합체(Binding)시켜라"라고 선언하는 임명장입니다. 이렇게 해두면 스파이가 김이병을 납치(해킹)해서 핵버튼을 누르려고 해도 시스템이 "이등병 주제에 핵버튼 접근 금지!"라며 원천 차단해 버리는 완벽한 최소 권한 통제입니다.


Ⅲ. 실무 팁: 디플로이먼트 적용과 네임스페이스 격리

아무리 좋은 제도를 만들어도 파드 엉덩이에 붙여주지 않으면 소용이 없다.

  1. 파드에 신분증 명시 (spec.serviceAccountName):
    • 권한 세팅을 다 끝냈으면, Nginx나 모니터링 파드를 띄우는 Deployment yaml 파일 맨 밑에 serviceAccountName: monitor-sa 라고 단 한 줄을 적어줘야 한다.
    • 이걸 안 적으면 쿠버네티스는 또다시 바보같이 막강한 default 깡통 토큰을 파드에 몰래 밀어 넣어(Auto-mount) 보안 구멍을 활짝 열어버린다.
    • (참고로 똑똑한 보안팀은 아예 클러스터 전역에 automountServiceAccountToken: false 옵션을 박아버려, 묻지도 따지지도 않고 디폴트 토큰 주입을 아예 100% 막아버리는 하드닝(Hardening) 조치를 취한다.)
  2. Role vs ClusterRole (동네 경찰과 국가 정보원):
    • 그냥 **Role**은 101동 네임스페이스(namespace: dev) 안에서만 힘을 쓰는 동네 파출소장이다. 다른 네임스페이스(운영망)의 파드는 절대 건드릴 수 없다 (격리 완벽).
    • 반면 **ClusterRole**은 네임스페이스의 벽을 부수고 K8s 클러스터 전체(모든 동네)를 휘젓고 다니며 노드 자체를 껐다 켤 수 있는 FBI 국가 정보원급의 절대 권력이다.
    • 해커가 ClusterRole이 바인딩된 파드(예: Calico CNI, Ingress Controller)를 털면 클러스터는 끝장나므로, 이 파드들의 취약점 관리는 목숨을 걸고 챙겨야 한다.

📢 섹션 요약 비유: 파드를 띄울 때 serviceAccountName을 명시하는 것은, 출근하는 신입사원 목에 "넌 1층만 출입 가능한 파란색 사원증(SA) 껴라"라고 목걸이를 강제로 채워주는 행위입니다. 이걸 안 해주면 인사팀(K8s)이 바보같이 전 층 출입 마스터키(Default 토큰)를 그냥 줘버립니다. 또한 Role은 "강남점 매장 관리만 해라"는 지점장 발령장이고, ClusterRole은 "전국 100개 매장의 돈통을 다 열어봐라"는 본사 감사팀 발령장이므로, 이 전국구 완장(ClusterRole)은 아무 파드에게나 남발하면 회사가 통째로 털리게 되는 치명적 권력입니다.