PostgreSQL 역할 관리
PostgreSQL 역할 관리 (PostgreSQL Role management)
:::info CloudNativePG는 처음부터 PostgreSQL 인스턴스에 필요한 특정 역할의 생성을 관리해왔어요:
postgres슈퍼유저,streaming_replica,cnpg_pooler_pgbouncer(PgBouncerPooler를 사용할 때) 같은 일부 예약 사용자- 애플리케이션 데이터베이스의 저권한 소유자로 설정된 애플리케이션 사용자
이 과정은 “부트스트랩(Bootstrap)” 섹션에 설명되어 있어요. :::
CloudNativePG는 PostgreSQL 데이터베이스 역할에 대한 전체 수명 주기 관리를 제공해요. 역할을 두 가지 방식으로 정의할 수 있어요:
- 독립형
DatabaseRole리소스로 (권장), 또는 Cluster스펙 안의managed스탠자를 통해
출처: 문서
본문
공존과 우선순위 (Coexistence and precedence)
두 방식은 상호 배타적이지 않아요. 동시에 각각으로 서로 다른 역할을 관리할 수 있으며, 이것이 인라인 스탠자에서 DatabaseRole 리소스로 점진적으로 마이그레이션하는 것을 가능하게 해요. 단, 양쪽 모두에 같은 역할 이름이 정의되는 경우를 위한 규칙만 있으면 돼요.
그런 경우 Cluster 스펙(managed.roles)이 항상 우선해요: DatabaseRole은 리컨실되지 않고 그 상태에 충돌을 보고해요 (DatabaseRole 리소스의 상태 참조).
:::important
선언적 역할 관리는 데이터베이스에 존재하지만 Cluster 스펙이나 DatabaseRole에 포함되지 않은 역할은 무시해요. 그런 역할들의 수명 주기는 PostgreSQL 안에서 계속 관리되므로, 편한 때에 이 기능을 도입할 수 있어요.
:::
일반적인 역할 구성 참고사항 (General role configuration notes)
관리 방식과 무관하게, 역할 스펙은 PostgreSQL 구조와 명명 규칙을 따릅니다.
:::tip 전체 속성 목록은 API 레퍼런스를 참조해주세요. :::
몇 가지 짚고 넘어갈 점이 있어요:
ensure속성은 PostgreSQL의 일부가 아니에요. 이 속성은 선언적 역할 관리가 역할을 만들거나(present, 기본값) 제거(absent)할 수 있게 해주며, 인라인managed.roles스탠자에서 만 사용할 수 있어요.DatabaseRole은ensure를 지원하지 않으며, 대신 회수 정책을 통해 역할 제거를 표현해요.inherit속성은 PostgreSQL 관례를 따라 기본값이 true예요.connectionLimit속성은 PostgreSQL 관례에 따라 기본값이 -1이에요.inRoles를 통한 역할 멤버십은 기본적으로 멤버십이 없어요.
DatabaseRole 리소스
DatabaseRole 커스텀 리소스는 PostgreSQL 데이터베이스 역할을 관리하는 전용의 Kubernetes 네이티브 방식을 제공해요.
이 방식은 역할 수명 주기를 클러스터 인프라에서 분리하므로, 현대 환경과 GitOps 워크플로에 권장되는 접근 방식이에요.
:::note
DatabaseRole은 그 스펙이나 비밀번호 Secret이 변경될 때 적용돼요. 수동 ALTER ROLE 같은 데이터베이스에 대한 직접 변경은 리소스가 다음에 적용될 때까지 감지되거나 되돌려지지 않아요. 반면 인라인 managed 역할은 주기적으로 데이터베이스 카탈로그와 비교되어 그 스펙으로 되돌려져요.
:::
DatabaseRole 리소스에 대한 접근 권한 부여의 RBAC 영향은 Security를 참조해주세요.
DatabaseRole은 네임스페이스 범위예요: 리소스, spec.cluster를 통해 참조하는 Cluster, 그리고 사용하는 passwordSecret가 모두 같은 네임스페이스에 있어야 해요.
예시 매니페스트 (Example manifest)
apiVersion: postgresql.cnpg.io/v1
kind: DatabaseRole
metadata:
name: role-dante
spec:
cluster:
name: cluster-example
name: dante
comment: "Dante Alighieri"
login: true
superuser: false
createdb: true
databaseRoleReclaimPolicy: delete
inRoles:
- pg_monitor
passwordSecret:
name: cluster-example-dante
역할 정의의 예시 매니페스트는 role-examples.yaml 파일에서 찾을 수 있어요.
역할 회수 정책 (Role reclaim policy)
databaseRoleReclaimPolicy 필드는 DatabaseRole 커스텀 리소스가 Kubernetes API에서 제거될 때 연산자의 "마지막 행동"을 정의해요. 이는 Kubernetes Persistent Volume의 동작을 반영한 것이에요.
retain(기본값): 역할이 데이터베이스에 남아요. 프로덕션에서 가장 안전한 설정으로, 매니페스트가 실수로 삭제되어도 데이터베이스 사용자(및 그가 소유한 객체들)가 그대로 남아 있도록 보장해요.delete: 연산자가 Kubernetes 객체가 파이널라이즈되기 전에 PostgreSQL에서DROP ROLE을 실행하려 시도해요. 임시적이거나 자동화된 환경에 이상적이에요.
:::note
역할이 객체(테이블, 스키마 등)를 소유하고 있으면 DROP ROLE은 실패하고 DatabaseRole은 Terminating 상태로 남아, 그 객체들이 재할당되거나 삭제될 때까지 주기적으로 재시도돼요. 연산자는 여러분을 대신해 소유 객체를 절대 삭제하지 않아요: PostgreSQL에서 재할당하거나 삭제하거나, retain으로 전환해야 삭제가 완료돼요.
:::
역할 제거 (Removing a role)
역할을 제거하는 방법은 어떻게 만들어졌는지에 따라 달라져요:
DatabaseRole을 통해 생성됨: 리소스를 삭제해요. PostgreSQL에서도 역할이 드롭되는지는 회수 정책에 따라 결정돼요.- 이미 존재했거나 다른 곳에서 관리됨:
DatabaseRole은 그 역할을 드롭하는 도구가 아니에요. 인라인managed.roles스탠자로absent를 선언하거나DROP ROLE을 직접 실행하세요.
:::warning
이미 존재하는 역할에 대해 DatabaseRole을 만드는 것은 그것을 **채택(adopt)**하는 겁니다: 연산자가 기존 역할을, 매니페스트의 모든 속성과 일치하도록 변경해요. 여기에는 생략한 속성까지 포함되며, 생략된 속성은 기본값으로 되돌려져요. 특히 inRoles에 나열되지 않은 멤버십은 회수되고, 생략된 connectionLimit은 -1(무제한)로 재설정되며, 역할에 만료일이 있었다면 생략된 validUntil은 infinity가 돼요. 역할을 채택하기 전에 현재 속성과 멤버십을 검토하고, 단지 드롭하려는 역할을 가리키도록 DatabaseRole을 만들지 마세요—제거되기 전에 수정되기 때문이에요.
:::
DatabaseRole 리소스의 상태 (Status of DatabaseRole resources)
DatabaseRole 리소스는 역할별 관찰 가능성을 위한 전용 status 섹션을 포함해요:
status:
applied: true
observedGeneration: 3
conditions:
- lastTransitionTime: "2026-04-04T15:06:23Z"
message: "2051"
reason: ChangeDetected
status: "True"
type: PasswordSecretChange
PasswordSecretChange 컨디션은 인스턴스 매니저를 위한 내부 신호로 연산자가 유지해요: 그 메시지는 연산자가 마지막으로 관찰한 비밀번호 Secret의 resourceVersion을 담고, 그 값의 변경이 비밀번호의 재적용을 트리거해요. 이 컨디션은 비밀번호 Secret이 사용 중일 때 나타나고, passwordSecret이 스펙에서 제거되면 사라져요.
DatabaseRole이 Cluster 스펙에서 이미 관리되는 이름을 대상으로 하면 (공존과 우선순위 참조), applied 필드는 다음 메시지와 함께 false가 돼요:
database role is already managed by the CNPG cluster
레플리카 클러스터에서 역할은 프라이머리 클러스터가 소유하며 로컬에서 리컨실되지 않아요. 그 경우 인스턴스 매니저는 역할을 실패가 아닌 unknown으로 보고해요: applied 필드는 설명 메시지와 함께 설정되지 않은 채(nil)로 남아요. 클러스터가 프라이머리로 승격되면 역할은 정상적으로 리컨실돼요.
클라이언트 인증서 생성 (Client Certificate Generation)
DatabaseRole 리소스는 클러스터의 클라이언트 CA가 서명하고 Kubernetes Secret에 저장되는 TLS 클라이언트 인증서의 옵트인(opt-in) 생성을 지원해요. 이는 비밀번호의 대안으로 PostgreSQL cert 인증을 가능하게 해요: 수동으로 회전할 비밀번호가 없고, 개인 키는 Kubernetes Secret으로 저장되며 클러스터 밖으로 전송되지 않아요.
이를 활성화하려면 스펙에 clientCertificate 블록을 추가해요:
apiVersion: postgresql.cnpg.io/v1
kind: DatabaseRole
metadata:
name: role-dante
spec:
cluster:
name: cluster-example
name: dante
login: true
clientCertificate:
enabled: true
databaseRoleReclaimPolicy: retain
블록이 있으면 clientCertificate.enabled는 기본값이 true이므로, clientCertificate: {}는 활성화하는 것과 동일해요. 블록을 유지하면서 발급을 끄려면 enabled: false로 설정하세요.
:::important
clientCertificate 발급이 활성화되면 login: true가 필요해요. 연산자는 검증을 통해 이를 강제하며 그렇지 않으면 리소스를 거부해요.
:::
생성된 Secret (Generated Secret)
연산자는 같은 네임스페이스에 <databaserole-name>-client-cert라는 이름의 Secret을 만들어요. 이 Secret에는 두 개의 키가 들어 있어요:
| 키 | 내용 |
|---|---|
tls.crt |
클러스터의 클라이언트 CA가 서명한 PEM-encoded 클라이언트 인증서 |
tls.key |
PEM-encoded 개인 키 |
인증서의 만료 시간은 status.clientCertificate.expiration에서 확인할 수 있어요:
status:
clientCertificate:
expiration: "2026-07-01T12:00:00Z"
pg_hba.conf 구성 (Configuring pg_hba.conf)
연산자는 인증서를 생성하지만 pg_hba.conf를 자동으로 수정하지는 않아요. 역할이 인증할 수 있도록 클러스터에 cert 방식의 hostssl 규칙을 추가해야 해요:
spec:
postgresql:
pg_hba:
- hostssl all dante all cert
생성된 Secret을 사용하는 동작하는 연결 문자열은 다음과 같아요:
psql "host=<cluster>-rw.<namespace>.svc port=5432 dbname=<db> user=dante \
sslcert=/path/to/tls.crt sslkey=/path/to/tls.key \
sslrootcert=/path/to/ca.crt sslmode=verify-full"
갱신 (Renewal)
클라이언트 인증서는 연산자의 전역 인증서 설정을 상속해요: 기본적으로 90일 수명으로 발급되고, 만료 7일 이내로 다가오면 자동으로 갱신돼요. 두 값 모두 연산자 전역이며 CERTIFICATE_DURATION과 EXPIRING_CHECK_THRESHOLD 연산자 설정으로 구성할 수 있어요. DatabaseRole별로는 구성할 수 없어요.
갱신은 리컨실 루프가 주도해요: 연산자가 인증서가 만료에 가까워지는지 확인하고 필요하면 다시 서명해요. clientCertificate 발급이 활성화되면 리컨실이 적어도 한 시간에 한 번 예약되므로, 트리거 이벤트가 없어도 갱신이 만료 훨씬 전에 일어나요. 현재 만료는 항상 status.clientCertificate.expiration에 반영돼요.
삭제와 옵트아웃 (Deletion and opt-out)
| 시나리오 | 결과 |
|---|---|
clientCertificate.enabled를 false로 설정하거나, clientCertificate 블록을 제거 |
cert Secret이 삭제됨. status.clientCertificate가 지워짐 |
DatabaseRole 삭제 |
databaseRoleReclaimPolicy와 무관하게 owner reference를 통해 cert Secret이 가비지 컬렉션됨 |
:::note
databaseRoleReclaimPolicy: retain은 PostgreSQL 역할을 유지하는 것이지, 생성된 Secret을 유지하는 게 아니에요. Secret은 연산자가 역할을 관리하는 동안에만 의미가 있으므로, 삭제 시 항상 정리돼요.
:::
BYOC(bring-your-own-CA) 제한 (Bring-your-own-CA limitation)
클러스터의 클라이언트 CA Secret에 개인 키가 없으면(즉 spec.certificates.clientCASecret로 직접 CA를 제공한 경우), 연산자는 새 인증서를 서명할 수 없어요. 그 이유를 status.clientCertificate.message에 기록하고 재시도를 중단해요:
status:
clientCertificate:
message: 'client CA secret "my-ca" has no private key; bring-your-own-CA
clusters require manual certificate management'
이 경우 클라이언트 인증서를 수동으로 발급하고 갱신해야 해요.
:::note CNPG는 CRL(Certificate Revocation Lists)을 관리하지 않아요. 인증서가 만료 전에 무효화되어야 하면 클러스터의 클라이언트 CA를 회전시켜요: 다음 리컨실에서 연산자가 기존 인증서가 더 이상 현재 CA로 서명되지 않았음을 감지하고, 관리 중인 모든 클라이언트 인증서를 다시 발급해요. 또는 인증서의 Secret을 삭제해 연산자가 현재 CA로 서명한 새 인증서를 발급하게 해도 돼요. :::
인라인 managed 역할 (Inline managed roles)
클러스터 스펙의 managed 스탠자를 통해 CloudNativePG는 .spec.managed.roles에 지정된 역할에 대한 관리를 제공해요. 이 기능은 기존 역할의 선언적 관리뿐 아니라, 아직 없으면 새 역할 생성도 가능하게 해요.
예시 매니페스트 (Example manifest)
선언적 역할 관리가 있는 클러스터의 예시 매니페스트는 cluster-example-with-roles.yaml 파일에서 찾을 수 있어요.
그 파일에서 발췌한 내용:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
spec:
managed:
roles:
- name: dante
ensure: present
comment: Dante Alighieri
login: true
superuser: false
inRoles:
- pg_monitor
- pg_signal_backend
인라인 managed 역할의 상태 (Status of inline managed roles)
인라인 방식을 사용할 때 Cluster 상태는 포괄적인 요약을 포함해요:
status:
managedRolesStatus:
byStatus:
reconciled:
- dante
reserved:
- postgres
- streaming_replica
cannotReconcile:
petrarca:
- 'could not perform UPDATE_MEMBERSHIPS on role petrarca: role "poets" does not exist'
데이터베이스(와 CloudNativePG)가 수행할 수 없어 인간의 개입이 필요한 작업을 위한 특별한 하위 섹션 cannotReconcile을 주목하세요.
이 섹션은 연산자 사용을 위해 예약된 역할과 선언적 관리 대상이 아닌 역할을 다루며, 데이터베이스 인스턴스의 역할에 대한 포괄적인 보기를 제공해요.
kubectl 플러그인도 status 서브커맨드에서 managed 역할의 상태를 보여줘요:
Managed roles status
Status Roles
------ -----
pending-reconciliation petrarca
reconciled app,dante
reserved postgres,streaming_replica
Irreconcilable roles
Role Errors
---- ------
petrarca could not perform UPDATE_MEMBERSHIPS on role petrarca: role "poets" does not exist
인라인 managed 역할에서 DatabaseRole로 마이그레이션 (Migrating from inline managed roles to a DatabaseRole)
중단 없이 역할을 인라인 managed.roles 스탠자에서 독립형 DatabaseRole로 옮길 수 있어요:
- 원하는 스펙으로
DatabaseRole을 만들어요. 두 방식 모두 동일한RoleConfiguration구조를 공유하므로, 스탠자를 그대로 복사할 수 있어요. Cluster매니페스트의.spec.managed.roles에서 해당 항목을 제거해요.- 연산자가 변경을 감지하고 관리를
DatabaseRole로 넘겨요.
둘 다 존재하는 동안 Cluster 스펙이 우선하므로(공존과 우선순위 참조), 인라인 항목이 사라진 뒤에만 핸드오버가 일어나며, 역할이 관리되지 않는 기간은 없어요.
인라인 스탠자가 ensure: absent로 제거한 역할을 변환할 때, DatabaseRole은 ensure: absent를 지원하지 않는다는 점을 주의하세요. 제거는 회수 정책으로 표현하세요: databaseRoleReclaimPolicy: delete로 리소스를 삭제해 역할을 드롭하거나, 기본 retain을 유지해 그대로 두세요. 전체 동작은 역할 제거를 참조하세요.
비밀번호 관리 (Password management)
선언적 역할 관리 기능(DatabaseRole와 인라인 managed.roles 스탠자 모두)에는 역할 비밀번호의 리컨실이 포함돼요. managed 역할 구성은 사용자 이름과 비밀번호가 저장된 Secret의 이름을 선택적으로 지정할 수 있어요:
passwordSecret:
name: cluster-example-dante
Secret은 kubernetes.io/basic-auth 타입이어야 해요. (Kubernetes에서 보통 그렇듯 Base64로 인코딩된) 사용자 이름은 비밀번호를 설정하는 역할과 일치해야 해요. 예를 들어:
apiVersion: v1
data:
username: ZGFudGU=
password: ZGFudGU=
kind: Secret
metadata:
name: cluster-example-dante
labels:
cnpg.io/reload: "true"
type: kubernetes.io/basic-auth
:::important
위 예시처럼 Secret에 cnpg.io/reload: "true" 레이블을 붙이세요. 레이블이 붙은 Secret의 비밀번호 변경은 즉시 적용되는 반면, 레이블이 없는 Secret의 변경은 연산자가 내부 캐시를 갱신할 때 같은 이후의 리컨실에서만 적용돼요.
:::
passwordSecret를 지정하지 않으면 인스턴스 매니저는 PostgreSQL 관례에 따라 비밀번호로 역할을 CREATE/ALTER하려 하지 않아요.
:::important
passwordSecret 없이 생성된 새 역할은 PostgreSQL 안에서 NULL 비밀번호를 가져요.
:::
비밀번호 비활성화 (Disabling passwords)
PostgreSQL에서 비밀번호를 명시적으로 NULL로 설정하려면(단순히 비밀번호 갱신을 생략하는 것과 구분됨), disablePassword 필드를 사용해요:
disablePassword: true
:::note
주어진 역할에 passwordSecret과 disablePassword를 모두 설정하는 것은 오류예요.
:::
비밀번호 만료, VALID UNTIL
PostgreSQL의 VALID UNTIL 역할 속성은 비밀번호 만료를 제어해요. VALID UNTIL을 지정하지 않고 생성된 역할은 PostgreSQL에서 기본적으로 NULL을 받아, 그 비밀번호가 절대 만료되지 않음을 의미해요.
PostgreSQL은 VALID UNTIL에 타임스탬프 타입을 사용하며, 비밀번호가 절대 만료되지 않음을 나타내는 'infinity' 값을 지원해요. 참고는 PostgreSQL 문서를 확인해주세요.
선언적 역할 관리에서 managed 역할의 validUntil 속성은 비밀번호 만료를 제어해요. validUntil은 다음만 받을 수 있어요:
- Kubernetes 타임스탬프, 또는
- 생략(기본값
null)
첫 번째 경우, 주어진 validUntil 타임스탬프가 데이터베이스의 역할 VALID UNTIL 속성으로 설정돼요.
두 번째 경우(생략된 validUntil) 연산자는 PostgreSQL의 동작을 반영해 비밀번호가 절대 만료되지 않도록 보장해요. 구체적으로:
- 새 역할의 경우, 역할 생성 문에서
VALID UNTIL절을 생략해요 - 기존 역할의 경우, 데이터베이스에서
VALID UNTIL이NULL로 설정되어 있지 않으면VALID UNTIL을infinity로 설정해요 (이는 PostgreSQL이ALTER ROLESQL 문에서VALID UNTIL NULL을 허용하지 않기 때문이에요)
사전 해시된 비밀번호 (Pre-hashed passwords)
비밀번호를 MD5/SCRAM-SHA-256 해시 형식으로 지정해 사전 암호화된 비밀번호를 제공할 수도 있어요:
kind: Secret
type: kubernetes.io/basic-auth
metadata:
name: cluster-example-cavalcanti
labels:
cnpg.io/reload: "true"
apiVersion: v1
stringData:
username: cavalcanti
password: SCRAM-SHA-256$<iteration count>:<salt>$<StoredKey>:<ServerKey>
:::warning
위 예시는 Kubernetes가 값을 인코딩해 주는 stringData:를 사용하는데, 이는 사전 해시된 비밀번호에 가장 안전한 경로예요. data:를 써야 한다면 printf '%s' "$hash" | base64(또는 echo -n "$hash" | base64)로 바이트를 정확히 인코딩하세요. 단순한 echo "$hash" | base64의 끝줄 개행(trailing newline) 때문에 값이 SCRAM/MD5 섀도우 형식 검사를 통과하지 못해서, 연산자가 이를 평문으로 취급해 다시 해시하게 되고 로그인이 중단돼요.
:::
평문 비밀번호 전송 시 안전성 (Safety when transmitting cleartext passwords)
역할 비밀번호는 Kubernetes에서 Secret을 사용해 안전하게 관리되지만, 연산자와 PostgreSQL 사이의 SQL 경로도 신경 써야 해요. PostgreSQL 문서에 나와 있듯이:
비밀번호는 평문으로 서버에 전송되며, 클라이언트의 명령 기록이나 서버 로그에도 기록될 수 있어요
CloudNativePG는 이 경로를 두 가지 보완적인 방식으로 보호해요:
CREATE/ALTER ROLE ... PASSWORD '...'를 내보내기 전에, 연산자는 평문 비밀번호를 연산자 측(PostgreSQL 관점에서 클라이언트 측)에서 SCRAM-SHA-256으로 인코딩해요. 이는 서버 로그와pg_stat_statements나pgaudit같은 확장에 평문이 남지 않게 하는 표준 PostgreSQL 관행이며,psql \password와 libpq의PQencryptPasswordConn이 수행하는 것과 동일한 인코딩이에요. PostgreSQL이 받는 리터럴은pg_authid.rolpassword에 저장된 SCRAM-SHA-256 검증자(verifier)예요. 이미 MD5 또는 SCRAM-SHA-256 섀도우 형태로 제공된 비밀번호는 변경 없이 전달돼요.- 동일한
CREATE/ALTER ROLE문은 문 로깅(log_statement)과 오류 문 로깅(log_min_error_statement)을 일시적으로 억제하는 트랜잭션 안에서 실행되어, 성공과 실패 시나리오 모두에서 PostgreSQL 로그로의 유출을 방지해요.
클러스터의 Status 섹션은 관리되는 역할 작업에 대한 쿼리 문을 출력하지 않아요.
연산자 측 인코딩 옵트아웃 (Opting out of operator-side encoding)
PostgreSQL(연산자가 아닌)이 비밀번호를 어떻게 해시할지 결정하게 하려면(예: password_encryption = md5로 실행되는 클러스터), basic-auth Secret에 cnpg.io/passwordPassthrough: "enabled" 어노테이션을 설정하세요. 그러면 연산자가 비밀번호 값을 그대로(verbatim) 전달해요.
:::warning
cnpg.io/passwordPassthrough 어노테이션은 Cluster 리소스가 아니라 basic-auth Secret 자체에 설정해야 해요. Cluster에 두면 효과가 없고, 연산자는 비밀번호를 PostgreSQL로 보내기 전에 계속 SCRAM-SHA-256 인코딩을 적용해요.
:::
옵트인은 Secret별로 적용되며, 연산자가 소비하는 모든 basic-auth Secret(managed-role secret뿐 아니라 슈퍼유저와 애플리케이션 사용자 secret도)에 적용되므로, 단일 클러스터가 passthrough secret과 연산자 인코딩 secret을 자유롭게 섞어 쓸 수 있어요. 위에서 설명한 문 로깅 억제 계층은 두 모드 모두에서 여전히 적용돼요.
:::warning
cnpg.io/passwordPassthrough: "enabled"로 설정하면 연산자가 Secret의 password 값을 그대로 전달해요. 그 값이 평문이면(password_encryption = md5 클러스터의 일반적인 경우) pg_stat_statements나 pgaudit 같은 확장이 이를 볼 수 있어요. 이는 PostgreSQL이 해시 형식을 선택하게 하는 데 대한 기대되는 절충이에요.
:::
실현 불가능한 역할 구성 (Unrealizable role configurations)
PostgreSQL에서 어떤 경우에는 명령을 데이터베이스가 수행할 수 없어 거부돼요. 자세한 내용은 PostgreSQL 오류 코드 문서를 참조해주세요.
역할 작업은 이런 근본적인 오류를 만들어낼 수 있어요. 두 가지 예:
poets역할(그룹)의 멤버로petrarca역할을 만들도록 PostgreSQL에 요청했지만poets가 존재하지 않음.dante역할을 드롭하도록 PostgreSQL에 요청했지만,dante역할이inferno데이터베이스의 소유자임.
이런 근본적인 오류는 데이터베이스나 CloudNativePG 연산자가 인간 관리자의 설명 없이는 고칠 수 없어요. 위 두 예는 각각 poets 역할을 만들거나 inferno 데이터베이스를 드롭하면 고칠 수 있지만, 이것이 인간의 실수로 생겼을 수도 있으며 그런 경우 제안된 "해결책"이 잘못된 것일 수도 있어요.
CloudNativePG는 이런 근본적인 오류가 발생할 때 이를 기록하고, 인라인 managed 역할의 상태에서 설명한 대로 클러스터 Status에 표시해요.