8.2 인증서(Certificates)
CloudNativePG의 모든 암호화 연결 — Operator와 인스턴스 사이, primary와 replica 사이, 클라이언트와 데이터베이스 사이 — 은 TLS 인증서 위에서 돌아간다. 다행히 DBA가 인증서를 손으로 발급하고 갱신할 필요는 없다. 기본값에서는 Operator가 자체 CA를 만들어 필요한 인증서를 발급하고, 만료 전에 알아서 갱신한다. 손을 대야 하는 경우는 조직 표준 CA나 cert-manager를 붙일 때뿐이다.
두 가지 운영 모드
인증서 관리에는 두 가지 방식이 있다.
| 모드 | 설명 | 언제 |
|---|---|---|
| Operator-managed | Operator가 자체 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 Secret —
ca.crt(검증용)와ca.key(서명용)를 담는다. - Server TLS Secret — 타입
kubernetes.io/tls,tls.crt와tls.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에 붙을 때 이 인증서로 인증한다.
User-provided 모드
조직 표준 CA를 쓰거나 cert-manager로 인증서를 관리하려면, 인증서를 담은 Secret을 만들어 Cluster 스펙의 certificates 항목에 지정한다.
| 필드 | 담는 Secret |
|---|---|
serverTLSSecret | tls.crt·tls.key (서버 인증서) |
serverCASecret | ca.crt (서버 검증용 CA) |
replicationTLSSecret | streaming_replica client 인증서 |
clientCASecret | client 검증용 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을 지정한다.