본문으로 건너뛰기
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을 지정한다.