PostgreSQL Role management
CloudNativePGは、当初から、PostgreSQLインスタンスで必要な特定のロールの作成を管理してきました。
postgresスーパーユーザー、streaming_replica、cnpg_pooler_pgbouncerなどの一部の予約済みユーザーPgBouncerPoolerを使用する場合アプリケーションデータベースの低特権の所有者として設定されたアプリケーションユーザー
このプロセスは、 Bootstrap セクションで説明しています。
クラスター仕様のmanaged
スタンザにより、CloudNativePGは.spec.managed.roles
で指定されたロールの完全なライフサイクル管理を提供するようになりました。
この機能により、既存のロールの宣言的管理と、データベースにまだ存在しない場合は新しいロールの作成が可能になります。ロールの作成は、データベースのブートストラップが完了した後*に発生します。
宣言的ロール管理を使用するクラスターのマニフェストの例は、ファイル
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
.spec.managed.roles のロール仕様は、
PostgreSQL structure and naming conventions に従います。ロールごとに定義できる属性の完全なリストについては、
API Reference を参照してください。
いくつかの点に注意してください。
ensure属性はPostgreSQLの ではありません 。これにより、宣言的なロール管理でロールを作成および削除できます。 2つの値は、presentデフォルトとabsentです。inherit属性は、PostgreSQLの規則に従って、デフォルトでtrueです。connectionLimit属性は、PostgreSQLの規約に従って、デフォルトの-1に設定されます。inRolesのロールメンバーシップは、デフォルトでメンバーシップなしです。
宣言的ロール管理により、PostgreSQLインスタンスが仕様に準拠していることが保証されます。ユーザーがデータベースでロール属性を直接変更した場合、CloudNativePGオペレーターは、次の調整サイクル中にこれらの変更を元に戻します。
パスワード管理
宣言的ロール管理機能には、ロールパスワードの調整が含まれます。パスワードはKubernetesの世界とPostgreSQLでは根本的に異なる方法で管理されており、その結果、いくつかの注意事項があります。
管理対象ロール構成は、オプションでユーザー名とパスワードが保存される シークレット の名前を指定できます。Kubernetesで通常のようにBase64でエンコードされます。例
managed:
roles:
- name: dante
ensure: present
[… snipped …]
passwordSecret:
name: cluster-example-dante
これは、ユーザー名とパスワードを含むcluster-example-dante
と呼ばれるシークレットの存在を前提としています。ユーザー名は、パスワードを設定しているロールと一致する必要があります。例
apiVersion: v1
data:
username: ZGFudGU=
password: ZGFudGU=
kind: Secret
metadata:
name: cluster-example-dante
labels:
cnpg.io/reload: "true"
type: kubernetes.io/basic-auth
ロールにpasswordSecret
が指定されていない場合、インスタンスマネージャーはパスワードを使用してロールを作成/変更しようとしません。これは、
WITH PASSWORD
で指示されない限り、ALTERがパスワードを更新しないPostgreSQL規約に従います。
ロールが最初にパスワードを使用して作成され、PostgreSQLでパスワードをNULLに設定したい場合、これはCloudNativePGのユーザー側で明示的にする必要があります。
「仕様で提供されているパスワードなし」と「パスワードをNULLに設定する」を区別するには、フィールド
DisablePassword を使用する必要があります。
データベースのdante
ロールにパスワードを設定しないことにしたとします。このような場合、次を指定します。
managed:
roles:
- name: dante
ensure: present
[… snipped …]
disablePassword: true
注特定のロールでpasswordSecret とdisablePassword
の両方を設定することはエラーとみなされます。この構成は、検証Webhookによって拒否されます。
パスワードの有効期限 VALID UNTIL
PostgreSQLのVALID UNTIL
ロール属性は、パスワードの有効期限を制御します。 VALID UNTIL
を指定せずに作成されたロールは、PostgreSQLでデフォルトでNULLを取得します。これは、パスワードの有効期限が無期限であることを意味します。
PostgreSQLは、 VALID UNTIL
のタイムスタンプタイプを使用します。これには、パスワードの有効期限が無期限であることを示す値'infinity'
のサポートが含まれます。 PostgreSQL documentation を参照してください。
参考までに。
宣言的ロール管理では、管理対象ロールのvalidUntil
属性がパスワードの有効期限を制御します。 validUntil
は以下のみを取ることができます。
Kubernetesタイムスタンプ、または
省略しますデフォルト
null
最初のケースでは、指定されたvalidUntil
タイムスタンプは、ロールのVALID UNTIL
属性としてデータベースに設定されます。
2番目のケースvalidUntil 省略
オペレーターは、パスワードの有効期限が決してないことを保証し、PostgreSQLの動作をミラーリングします。具体的には
新しいロールの場合、ロール作成ステートメントの
VALID UNTIL句を省略します既存のロールの場合、データベースで
VALID UNTILがNULLに設定されていない場合、VALID UNTILをinfinityに設定します。これは、PostgreSQLがALTER ROLESQLステートメントでVALID UNTIL NULLを許可していないためです。
警告
passwordSecret を使用せずに作成された新しいロールは、PostgreSQL内に`NULL` パスワードがあります。
パスワードがハッシュ化されました
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>
実現不可能なロール構成
PostgreSQLでは、場合によっては、コマンドはデータベースが受け入れられず、拒否されます。 PostgreSQL documentation on error codes を参照してください。
詳細については。
ロール操作では、このような基本的なエラーが発生する可能性があります。 2つの例
PostgreSQLに、ロールグループ
poetsのメンバーとしてロールpetrarcaを作成するように依頼しますが、poetsは存在しません。PostgreSQLにロール
danteを削除するように求めますが、ロールdanteはデータベースinfernoの所有者です。
これらの基本的なエラーは、人間の管理者の説明がない限り、データベースまたはCloudNativePGオペレーターによって修正できません。上記の2つの例は、それぞれロールpoets
を作成するか、データベースinferno
を削除することにより修正できますが、それらは人的エラーが原因で発生した可能性があり、そのような場合、提案された「修正」は間違ったものである可能性があります。
CloudNativePGは、このような基本的なエラーが発生すると記録し、クラスターステータスに表示します。どちらが続くか…
管理対象ロールのステータス
クラスターステータスには、以下に示すように、管理対象ロールのステータスのセクションが含まれます。
status:
[…snipped…]
managedRolesStatus:
byStatus:
not-managed:
- app
pending-reconciliation:
- dante
- petrarca
reconciled:
- ariosto
reserved:
- postgres
- streaming_replica
cannotReconcile:
dante:
- could not perform DELETE on role dante: owner of database inferno
petrarca:
- could not perform UPDATE_MEMBERSHIPS on role petrarca: role "poets" does not exist
データベースおよびCloudNativePGが受け入れられない操作、および人間の介入を必要とする操作用の特別なサブセクションcannotReconcile
に注意してください。
このセクションでは、オペレーター使用のために予約されているロールと、宣言的管理の下ではない**ロールをカバーし、データベースインスタンスのロールの包括的なビューを提供します。
Kubectl Plugin は、 status
サブコマンドで管理対象ロールのステータスも表示します。
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
注釈
下位互換性の観点から、宣言的ロール管理は、データベースには存在するが仕様に含まれていないロールを無視するように設計されています。これらのロールのライフサイクルは、引き続きPostgreSQL内で管理されるため、CloudNativePGユーザーは自分の都合に合わせてこの機能を採用できます。