Security - CSR API

2026. 1. 1. 19:34·CKA

운영 중인 Kubernetes 클러스터에서 “인증서 관련 이슈(만료, 신규 관리자 온보딩, 교체/회전)”가 생기면, 결국 아래 두 가지 질문으로 귀결됩니다.

  1. 누가 인증서를 서명(sign)하는가? (CA는 어디 있는가?)
  2. 새 사용자가 들어올 때마다, 만료 때마다 그 서명을 어떻게 안전하게/체계적으로 처리하는가?

이 강의는 위 두 질문에 대한 답으로 Kubernetes Certificate API(= CSR API)를 설명합니다.


1) “CA 서버”는 별도 제품이 아니라, 사실상 “CA 파일(키/인증서)”이다

많이 헷갈리는 표현이 “CA 서버”인데, Kubernetes 맥락에서 CA는 보통 이 두 파일을 의미합니다.

  • CA 인증서: ca.crt (공개)
  • CA 개인키: ca.key (절대 보호해야 함)

이 파일 쌍에 접근 가능한 사람은 곧바로 이런 일을 할 수 있습니다.

  • 원하는 사용자/컴포넌트 인증서를 원하는 권한(Subject/CN/O 등)으로 발급
  • 결과적으로 클러스터에 대한 접근권한을 임의로 만들어낼 수 있음

그래서 “CA 서버”라고 부르는 것은 보통 아래 같은 운영 정책을 의미합니다.

  • ca.key를 아무나 접근 못 하는 안전한 머신/영역에 보관
  • 인증서 서명이 필요할 때만 그곳에서 수행

kubeadm 클러스터에서는 현실적으로 CA 파일이 control plane 노드(/etc/kubernetes/pki)에 존재하는 경우가 흔해서, “control plane이 CA 서버 역할을 한다”라고 말하게 됩니다.


2) 수동 방식의 문제: 사람이 늘면 서명 업무가 병목/리스크가 된다

초기(관리자 1명)에는 보통 이렇게 합니다.

  1. 새 관리자가 개인키 생성 → CSR 생성 → 관리자에게 전달
  2. 관리자가 CA 키로 CSR에 서명 → 인증서 발급 → 사용자에게 전달
  3. 만료 시 반복

문제는 팀이 커지면:

  • CSR 요청이 계속 쌓이고
  • 사람이 직접 서명하는 과정이 반복되고
  • 추적/감사/승인 흐름(누가 왜 승인했는지)이 약해지고
  • 운영 실수로 잘못된 권한의 인증서를 발급할 위험이 커집니다.

3) 해결: Kubernetes Certificate API (CSR API)

Kubernetes는 인증서 요청을 “Kubernetes 오브젝트”로 받아서 관리할 수 있습니다.

  • 사용자가 CSR을 만들고
  • 관리자는 CSR을 클러스터 내부 객체로 등록하고
  • 관리자는 kubectl로 요청을 검토/승인승인(approve) 하고
  • Kubernetes(정확히는 controller-manager)가 CA로 서명해서
  • 발급된 인증서를 추출해서 사용자에게 전달합니다.

핵심 장점:

  • 요청이 클러스터 리소스로 남으므로 추적/감사가 쉬움
  • 승인(approve)이라는 명시적 단계로 운영 통제가 가능
  • 자동화(예: 워크플로우/정책)로 확장하기 쉬움

4) 실제 흐름: “새 관리자(user)를 클러스터에 추가” 예시

아래는 가장 흔한 “사용자 클라이언트 인증서” 발급 흐름입니다.

4.1 사용자가 로컬에서 키/CSR 생성 (개인키는 절대 공유하지 않음)

# 1) 개인키 생성
openssl genrsa -out jane.key 2048

# 2) CSR 생성 (CN=사용자명, O=그룹)
openssl req -new -key jane.key -out jane.csr -subj "/CN=jane/O=devs"
  • jane.key는 사용자의 개인키(비밀번호 같은 것)라서 절대 외부로 보내면 안 됩니다.
  • 관리자가 필요한 것은 보통 jane.csr 입니다.

4.2 관리자가 CSR API 오브젝트 생성 (CSR은 base64로 넣어야 함)

CSR PEM을 base64로 인코딩합니다.

CSR_BASE64=$(cat jane.csr | base64 -w0)
echo $CSR_BASE64 | head

그리고 CertificateSigningRequest 오브젝트를 만듭니다(예시).

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: jane-csr
spec:
  request: <위에서 만든 CSR_BASE64 값>
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth

적용:

kubectl apply -f jane-csr.yaml

4.3 관리자가 CSR 목록 확인/검토

kubectl get csr
kubectl describe csr jane-csr

여기서 “누구 요청인지”, “용도(usages)가 적절한지”, “이름이 정책에 맞는지(CN/O 등)” 확인합니다.

4.4 관리자가 승인(Approve)

kubectl certificate approve jane-csr

승인되면, 컨트롤러 매니저가 CA 키로 서명하고 .status.certificate에 발급 인증서가 채워집니다.

4.5 발급된 인증서 추출 (base64 decode)

kubectl get csr jane-csr -o jsonpath='{.status.certificate}' | base64 -d > jane.crt

이제 사용자에게 전달할 것은 보통:

  • jane.crt (인증서)
  • (추가로) 클러스터 접속에 필요한 ca.crt (서버 검증용 CA)
  • 그리고 사용자는 이미 본인 jane.key를 가지고 있음

5) kubectl이 쓰려면 kubeconfig까지 만들어주는 게 실무적이다

사용자가 매번 --client-certificate, --client-key, --certificate-authority를 치는 대신, kubeconfig로 묶는 게 일반적입니다.

예시(개념):

kubectl config set-cluster my-cluster \
  --server=https://<API_SERVER_ENDPOINT>:6443 \
  --certificate-authority=ca.crt \
  --embed-certs=true

kubectl config set-credentials jane \
  --client-certificate=jane.crt \
  --client-key=jane.key \
  --embed-certs=true

kubectl config set-context jane@my-cluster \
  --cluster=my-cluster \
  --user=jane

kubectl config use-context jane@my-cluster

그리고 실제 권한은 인증서만으로 끝나는 게 아니라 RBAC(Role/RoleBinding/ClusterRoleBinding)으로 부여해야 합니다.


6) “누가 서명하나?” → controller-manager가 CSR 서명 컨트롤러를 가진다

강의 포인트 그대로:

  • CSR 생성/승인/서명 같은 인증서 관련 작업은 kube-controller-manager 내부 컨트롤러들이 담당합니다.
    • CSR을 보고,
    • 승인 상태를 보고,
    • CA 키로 서명해서 status에 인증서를 채웁니다.

그럼 controller-manager는 CA 키를 어디서 가져오나?

kube-controller-manager 설정에 보통 다음이 들어갑니다(대표 개념).

  • --cluster-signing-cert-file=<CA_CERT>
  • --cluster-signing-key-file=<CA_KEY>

kubeadm이라면 대개 이 값이 /etc/kubernetes/pki/ca.crt, /etc/kubernetes/pki/ca.key를 가리키는 형태로 구성됩니다.


7) 운영 관점의 핵심 보안 포인트

7.1 CA 개인키(ca.key)는 최상위 민감정보

  • 유출되면 “클러스터 접근권한을 원하는 대로 발급” 가능
  • 접근권한 최소화/파일 권한 강화/백업 및 접근 감사가 필요

7.2 CSR API를 쓰면 “승인”이라는 통제 지점이 생긴다

  • 무작정 서명하는 게 아니라,
  • 관리자가 CSR을 보고 승인해야 서명됨(정책/프로세스 구축 가능)

7.3 인증서 만료는 “정기점검+회전”이 필요

  • kubeadm certs check-expiration 같은 점검으로 만료를 미리 발견
  • 사용자 인증서는 만료 시 CSR 재발급 흐름을 반복

8) 요약

  • CA는 “서버”라기보다 CA 키/인증서 파일 쌍
  • 사람이 늘면 수동 서명이 병목/리스크가 되어 CSR API가 필요
  • CSR API 흐름:
    1. 사용자: 개인키 생성 → CSR 생성
    2. 관리자: CSR 오브젝트 생성
    3. 관리자: 검토 후 approve
    4. controller-manager: CA로 서명
    5. 관리자: 발급 cert 추출 → 사용자에게 전달
  • 최우선 보안은 CA 개인키 보호와 승인 프로세스

 

Practice Test: https://uklabs.kodekloud.com/topic/practice-test-certificates-api-2/

'CKA' 카테고리의 다른 글

Security - 정리(1)  (2) 2026.01.01
Security - Kubeconfig  (0) 2026.01.01
Security - 인증서 상태 점검 방법  (1) 2026.01.01
Security - 인증서 생성 방법  (0) 2026.01.01
Security - TLS in Kubernetes  (0) 2026.01.01
'CKA' 카테고리의 다른 글
  • Security - 정리(1)
  • Security - Kubeconfig
  • Security - 인증서 상태 점검 방법
  • Security - 인증서 생성 방법
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)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

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

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    Security - CSR API
    상단으로

    티스토리툴바