Security - Authentication 기초

2025. 12. 31. 20:27·CKA

이 강의의 핵심은 단순합니다.

  • Kubernetes에서 “관리 목적 접근”은 전부 kube-apiserver로 들어온다
  • API 서버는 요청을 처리하기 전에 Authentication(인증) 을 수행한다
  • 인증이 끝나면 다음 단계로 Authorization(인가/RBAC) 이 이어진다

아래는 강의 내용을 개발 블로그 형태로 정리하면서, 실무에서 헷갈리기 쉬운 포인트(“쿠버네티스는 유저를 관리하나?”, “정적 비밀번호/토큰은 왜 위험한가?”, “kubeadm에서 어디를 만져야 하나?”)를 보완한 내용입니다.


1) 사용자 유형부터 정리: 사람(Human) vs 로봇(Robot)

클러스터에 접근하는 주체는 대략 이렇게 나뉩니다.

사람(Human)

  • 클러스터 운영자(관리자)
  • 개발자(배포/디버깅/테스트)

로봇(Robot)

  • CI/CD 파이프라인, 배포 자동화 도구
  • 외부 통합(모니터링/보안 스캐너 등) 시스템

애플리케이션 “최종 사용자(end-user)”의 인증/보안은 보통 앱 자체의 로그인/토큰 체계에서 처리하므로, Kubernetes “클러스터 인증”과는 별개로 보는 게 일반적입니다.


2) 중요한 사실: Kubernetes는 “사용자 계정”을 기본으로 관리하지 않는다

강의에서 강조한 부분입니다.

  • Kubernetes에는 “User”라는 리소스가 없습니다.
  • 즉, kubectl create user ... 같은 방식으로 클러스터에 유저를 생성/조회하는 모델이 아닙니다.
  • 대신 Kubernetes는 외부 인증원(External source) 에 의존합니다.
    • 예: 클라이언트 인증서(x509), OIDC(SSO), Webhook, 외부 IdP 등 (Kubernetes)

반면,

  • ServiceAccount는 Kubernetes 리소스이므로, API로 생성/조회/관리 가능합니다.
    • kubectl get sa -A
    • 워크로드(파드)가 API 서버에 접근할 때 표준적으로 사용합니다. (Kubernetes)

3) 요청 흐름: kubectl이든 API 호출이든 “전부 API 서버로 간다”

  • kubectl은 결국 HTTPS로 kube-apiserver에 요청합니다.
  • 외부 시스템의 API 호출도 동일합니다.

그리고 API 서버는 보통 아래 순서로 요청을 처리합니다.

  1. Authentication(인증): 누가 왔는지 식별
  2. Authorization(인가): 무엇을 할 수 있는지 확인(RBAC 등)
  3. Admission: 정책/검증/변환(추후 섹션)

이 글(강의)은 1) 인증(Authentication) 에 집중합니다.


4) kube-apiserver 인증 방식들(개요)

Kubernetes는 플러그인 형태로 여러 인증 전략을 지원합니다. (Kubernetes)
강의에서 언급한 대표 옵션들은 아래와 같습니다.

(1) 정적(Static) 비밀번호 파일 / 정적 토큰 파일

  • 파일(CSV)에 자격증명을 넣고, API 서버에 “이 파일을 읽어라”라고 플래그로 전달
  • 학습용으로는 직관적이지만, 운영에서는 비추천

(2) 인증서(x509 client certificate)

  • 개발/랩 환경에서 많이 쓰는 방식
  • CN/Organization(O) 등에 사용자/그룹을 담아 RBAC과 연결

(3) 외부 인증 연동(OIDC/LDAP/Kerberos 등)

  • 실무에서 가장 흔한 흐름은 OIDC(SSO) 로 API 서버를 붙이고, RBAC으로 권한을 제어하는 패턴

(4) Webhook Token Authenticator

  • Bearer token을 외부 서비스에 검증 위임(토큰 검증을 API 서버가 직접 안 하고 “물어보는” 구조)

5) 강의의 “정적 비밀번호/토큰 파일”은 왜 위험한가?

공식 하드닝 가이드가 딱 잘 요약합니다.

  • 자격증명이 컨트롤 플레인 노드 디스크에 평문으로 저장될 수 있음
  • 변경/추가/회수에 API 서버 재시작이 필요(가용성 영향)
  • 사용자별 자격증명 회전(rotate) 메커니즘 부재
  • 락아웃/브루트포스 방어 같은 계정 보호 기능 없음 (Kubernetes)

즉, “동작은 단순하지만 운영 보안 모델로는 취약”합니다.


6) 매우 중요한 업데이트: Basic Auth(정적 비밀번호)는 이미 제거됨

강의 하단 문서에 적힌 것처럼, --basic-auth-file 기반 Basic Auth는 Kubernetes v1.19에서 제거되었고, 이후 릴리스에서는 사용할 수 없습니다. (Google Cloud Documentation)

반면 --token-auth-file(정적 토큰 파일)은 최신 kube-apiserver 플래그 목록에도 남아있지만, 운영 관점에서는 여전히 “레거시/비권장”에 가깝게 취급하는 편이 안전합니다. (Kubernetes)


7) 실습 파트 1: (참고용) Basic Auth 방식 — “구버전에서만 가능”

아래 실습은 Kubernetes 1.19 미만에서만 의미가 있습니다. 최신 클러스터에서는 안 됩니다. (Google Cloud Documentation)

7.1 사용자 파일 생성(예시)

sudo mkdir -p /tmp/users
cat <<'EOF' | sudo tee /tmp/users/user-details.csv
password123,user1,u0001
password123,user2,u0002
password123,user3,u0003
password123,user4,u0004
password123,user5,u0005
EOF

7.2 kubeadm 환경에서 kube-apiserver에 파일 마운트 + 플래그 추가

kubeadm을 쓰면 API 서버는 static pod로 뜨므로, 아래 파일을 수정합니다.

  • /etc/kubernetes/manifests/kube-apiserver.yaml

핵심은 2가지입니다.

  1. 호스트의 /tmp/users를 컨테이너로 volumeMount
  2. API 서버 실행 옵션에 --basic-auth-file=/tmp/users/user-details.csv 추가

(개념 예시)

spec:
  containers:
  - name: kube-apiserver
    command:
    - kube-apiserver
    - --authorization-mode=Node,RBAC
    - --basic-auth-file=/tmp/users/user-details.csv
    volumeMounts:
    - mountPath: /tmp/users
      name: usr-details
      readOnly: true
  volumes:
  - name: usr-details
    hostPath:
      path: /tmp/users
      type: DirectoryOrCreate

static pod manifest를 저장하면 kubelet이 변경을 감지해 API 서버 컨테이너를 재생성합니다(즉, 사실상 재시작).

7.3 RBAC Role/RoleBinding으로 권한 부여

인증만으로는 아무것도 못 합니다. 최소한의 Role을 붙여야 합니다.

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","watch","list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: user1
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

7.4 호출 테스트(curl)

curl -k https://localhost:6443/api/v1/pods -u "user1:password123"

8) 실습 파트 2: 정적 토큰 파일(Static Token File) — 동작은 가능하지만 운영 비권장

정적 토큰은 basic auth가 제거된 이후 “비슷한 학습” 용도로 다뤄지곤 합니다. 다만 운영에서는 앞서 언급한 이유로 권장하지 않습니다. (Kubernetes)

8.1 토큰 파일(CSV) 예시

형식: token,username,uid,(optional)group

sudo mkdir -p /tmp/tokens
cat <<'EOF' | sudo tee /tmp/tokens/tokens.csv
aVeryLongRandomTokenValue1234567890,user1,u0001,dev-team
anotherLongTokenValue0987654321,user2,u0002,dev-team
EOF

8.2 API 서버에 마운트 + --token-auth-file 플래그

/etc/kubernetes/manifests/kube-apiserver.yaml에 아래를 추가(개념 예시):

- --token-auth-file=/tmp/tokens/tokens.csv

그리고 volumeMount:

volumeMounts:
- mountPath: /tmp/tokens
  name: token-file
  readOnly: true
volumes:
- name: token-file
  hostPath:
    path: /tmp/tokens
    type: DirectoryOrCreate

--token-auth-file 플래그는 최신 kube-apiserver 문서에도 존재합니다. (Kubernetes)

8.3 호출 테스트(curl: Bearer token)

TOKEN="aVeryLongRandomTokenValue1234567890"
curl -k https://localhost:6443/api/v1/pods \
  -H "Authorization: Bearer ${TOKEN}"

9) 실무 권장 패턴: “인증은 OIDC/인증서, 권한은 RBAC”

정적 파일 방식은 “개념 학습”에는 좋지만, 실무에서는 보통 아래로 갑니다.

사람(Human) 접근

  • OIDC(SSO) 연동 + RBAC
  • (랩/소규모) x509 client cert + RBAC

로봇/워크로드(클러스터 내부)

  • ServiceAccount 토큰(JWT) + RBAC
  • 가능하면 짧은 수명(단기) 토큰/회전 가능한 구조로 운영

추가로, 최근 Kubernetes는 인증 구성을 파일 기반으로 더 구조화하는 방향(예: JWT authenticator 설정의 구조화)을 발전시키고 있습니다. (Kubernetes)


10) kubeadm에서 꼭 기억할 것(강의 마지막 포인트 보강)

강의에서 말한 “kubeadm에서는 볼륨 마운트도 고려해야 한다”는 말이 핵심입니다.

  • kubeadm 설치 시 API 서버는 static pod
  • 그래서 --xxx-auth-file 같은 “호스트 파일”을 쓰려면:
    • hostPath로 컨테이너에 파일/디렉토리를 마운트
    • kube-apiserver.yaml에 플래그를 추가
  • 그리고 “새 사용자”를 만들었다면 반드시:
    • RBAC(Role/RoleBinding) 으로 권한을 부여해야 실제로 API 호출이 됩니다.

요약

  • Kubernetes는 “유저 계정”을 내부 리소스로 관리하지 않음(외부 인증원 의존) (Kubernetes)
  • 모든 관리 요청은 kube-apiserver로 들어오며, 먼저 인증을 거침
  • 정적 비밀번호/토큰 파일은 학습용으로는 직관적이지만 운영에는 취약점이 많음 (Kubernetes)
  • Basic Auth는 v1.19에서 제거됨(최신 클러스터에서 실습 불가) (Google Cloud Documentation)
  • 실무는 보통 OIDC/인증서 기반 인증 + RBAC로 간다

'CKA' 카테고리의 다른 글

Security - SSH 프로세스 정리  (0) 2026.01.01
Security - 대칭키/비대칭키/CA  (0) 2026.01.01
Security - 개요  (0) 2025.12.31
Cluster Maintenance - 총 정리  (0) 2025.12.31
Cluster Maintenance - 백업 방법(yaml 및 etcd)  (0) 2025.12.31
'CKA' 카테고리의 다른 글
  • Security - SSH 프로세스 정리
  • Security - 대칭키/비대칭키/CA
  • Security - 개요
  • Cluster Maintenance - 총 정리
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (243)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (119)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      조회 성능 최적화
      @args
      jdk 동적 프록시
      페치 조인
      JPQL
      @within
      고급
      Target
      hibernate5module
      락
      단방향 맵핑
      버퍼
      log trace
      Thread
      스레드
      reentarantlock
      jpq
      @discriminatorcolumn
      requset scope
      양방향 맵핑
      @discriminatorvalue
      WAS
      김영한
      프록시
      자바
      cglib
      빈 후처리기
      gesingleresult
      typequery
      프록시 팩토리
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    Security - Authentication 기초
    상단으로

    티스토리툴바