본문으로 건너뛰기
8.2 인증서(Certificates)

8.2 인증서(Certificates)

CloudNativePG의 모든 암호화 연결 — Operator와 인스턴스 사이, primary와 replica 사이, 클라이언트와 데이터베이스 사이 — 은 TLS 인증서 위에서 돌아간다. 다행히 DBA가 인증서를 손으로 발급하고 갱신할 필요는 없다. 기본값에서는 Operator가 자체 CA를 만들어 필요한 인증서를 발급하고, 만료 전에 알아서 갱신한다. 이 절에서는 그 자동 발급 체계가 어떻게 생겼는지, 그리고 조직의 CA나 cert-manager를 붙이려면 무엇을 바꿔야 하는지를 정리한다.

두 가지 운영 모드

인증서 관리에는 두 가지 방식이 있다.

모드설명언제
Operator-managedOperator가 자체 CA로 발급·갱신기본. 대부분의 경우
User-provided외부 발급 인증서를 Secret으로 제공조직 CA·cert-manager 연동

Operator-managed 모드

기본값이다. Operator는 server용 CA와 client용 CA를 만들고, 거기서 서버 인증서와 복제용 client 인증서를 발급한다. 발급된 인증서는 90일 유효기간을 갖고, 만료 7일 전에 자동으로 갱신된다. 이 값들은 CERTIFICATE_DURATION, EXPIRING_CHECK_THRESHOLD 환경 변수로 조정한다.

    flowchart TD
  SCA["Server CA<br/>ca.crt·ca.key"]
  CCA["Client CA<br/>ca.crt·ca.key"]
  SRV["Server TLS<br/>tls.crt·tls.key"]
  REP["streaming_replica<br/>client cert"]
  APP["app client cert<br/>(요청 시 발급)"]

  SCA -->|서명| SRV
  CCA -->|서명| REP
  CCA -->|서명| APP

  classDef node fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
  class SCA,CCA,SRV,REP,APP node
  

server 쪽 인증서

  • Server CA Secretca.crt(검증용)와 ca.key(서명용)를 담는다.
  • Server TLS Secret — 타입 kubernetes.io/tls, tls.crttls.key를 담는다. 클라이언트가 서버의 신원을 검증하는 데 쓴다.

기본 Kubernetes 클러스터 도메인은 cluster.local이며 KUBERNETES_CLUSTER_DOMAIN으로 바꿀 수 있다. server TLS Secret에 대체 DNS 이름을 추가로 지정할 수도 있다.

client 쪽 인증서

  • Client CA Secret — 기본값에서는 server와 같은 자체 서명 CA를 공유한다.
  • Replication 인증서 — 사용자명 streaming_replica, 타입 kubernetes.io/tls. replica가 primary에 붙을 때 이 인증서로 인증한다.
Operator와 인스턴스는 서버 인증서를 검증할 때 CA 일치만 보고 DNS 이름은 무시한다. 클러스터 내부 통신 서비스의 DNS 특성상 그렇게 설계되었다. 즉 내부 통신의 신뢰 근거는 “같은 CA가 서명했는가"이다.

User-provided 모드

조직 표준 CA를 쓰거나 cert-manager로 인증서를 관리하려면, 인증서를 담은 Secret을 만들어 Cluster 스펙의 certificates 항목에 지정한다.

필드담는 Secret
serverTLSSecrettls.crt·tls.key (서버 인증서)
serverCASecretca.crt (서버 검증용 CA)
replicationTLSSecretstreaming_replica client 인증서
clientCASecretclient 검증용 CA

cert-manager 연동

cert-manager로 발급한 인증서를 그대로 물릴 수 있다. Issuer와 Certificate 리소스를 만든 뒤, 그 Secret 이름을 Cluster에서 참조한다.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: my-postgres-server-cert
spec:
  secretName: my-postgres-server-cert
  usages:
    - server auth
  issuerRef:
    name: selfsigned-issuer
    kind: Issuer
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-example
spec:
  certificates:
    serverTLSSecret: my-postgres-server-cert
    serverCASecret: my-postgres-server-cert

복제 인증서 이름 커스터마이징

외부 CA가 발급한 복제 인증서의 common name이 streaming_replica와 다르다면, pg_ident 매핑으로 이어 준다.

spec:
  postgresql:
    pg_ident:
    - cnpg_streaming_replica streaming-replica.cnpg.svc.cluster.local streaming_replica

갱신과 재적용

인증서 Secret에 cnpg.io/reload: "" 레이블이 붙어 있으면 내용이 바뀔 때 자동으로 다시 로드된다. 수동으로 반영하려면 다음을 실행한다.

kubectl cnpg reload <cluster-name>

모든 인증서 Secret과 그 만료일은 Cluster의 status에 나타나므로, 만료 전 갱신을 미리 계획할 수 있다.

kubectl get cluster cluster-example -o yaml | grep -A20 certificates

정리

  • 기본은 Operator-managed — 자체 CA로 발급, 90일 유효·만료 7일 전 자동 갱신
  • server CA / client CA 두 갈래에서 서버 인증서와 streaming_replica 인증서가 나온다
  • 내부 통신 검증은 DNS가 아니라 CA 일치 기준
  • 조직 CA·cert-manager를 쓰려면 serverTLSSecret 등 네 필드에 Secret 지정
  • 인증서 만료일은 Cluster status에서 확인하고 미리 갱신 계획

다음 절(8.3)에서는 이 인증서로 클라이언트가 비밀번호 없이 접속하는 방법을 본다.