データベースロール管理¶
CloudNativePGは当初から、PostgreSQLインスタンスで必要な特定のロールの作成を管理してきました。
postgresスーパーユーザー、streaming_replica、cnpg_pooler_pgbouncerなどの一部の予約ユーザー(PgBouncerPoolerを使用する場合)アプリケーションデータベースの低権限所有者として設定されたアプリケーションユーザー
このプロセスについては、 BootstrapConfiguration セクションで説明されています。
クラスター仕様のmanaged スタンザにより、CloudNativePGは、
.spec.managed.roles
で指定されたロールの完全なライフサイクル管理を提供するようになりました。
この機能により、既存のロールの宣言的管理と、新しいロールがデータベースにまだ存在しない場合は作成できます。ロールの作成は、データベースのブートストラップが完了した 後に 発生します。
宣言的なロール管理を備えたクラスターのマニフェストの例は、次のファイルにあります。
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-example-with-roles
spec:
instances: 3
storage:
size: 1Gi
managed:
roles:
- name: app
createdb: true
login: true
- name: dante
ensure: present
comment: my database-side comment
login: true
superuser: false
createdb: true
createrole: false
inherit: false
replication: false
bypassrls: false
connectionLimit: 4
validUntil: "2053-04-12T15:04:05Z"
inRoles:
- pg_monitor
- pg_signal_backend
passwordSecret:
name: cluster-example-dante
- --
apiVersion: v1
data:
username: ZGFudGU=
password: ZGFudGU=
kind: Secret
metadata:
name: cluster-example-dante
type: kubernetes.io/basic-auth
。
これはそのファイルからの抜粋です。
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リファレンス を参照してください。
いくつかの点に注意してください。
ensure属性は、PostgreSQLの 一部ではありません 。これにより、宣言的なロール管理でロールを作成および削除できます。 2つの可能な値は、present(デフォルト)とabsentです。inherit属性は、PostgreSQLの規則に従って、デフォルトでtrueです。PostgreSQLの規則に従って、
connectionLimit属性のデフォルトは-1です。inRolesを持つロールメンバーシップは、デフォルトでメンバーシップなしになります。
宣言的なロール管理により、PostgreSQLインスタンスが仕様に準拠していることを保証します。ユーザーがデータベースでロール属性を直接変更した場合、CloudNativePGオペレーターは次の調整サイクル中にそれらの変更を元に戻します。
パスワード管理¶
宣言的なロール管理機能には、ロールパスワードの調整が含まれます。パスワードは、Kubernetesの世界とPostgreSQLでは根本的に異なる方法で管理されるため、いくつか注意すべき点があります。
管理対象ロールの構成では、オプションで、ユーザー名とパスワードが保存される シークレット の名前を指定できます(Kubernetesでの通常のようにBase64でエンコードされます)。例:
managed:
roles:
- name: dante
ensure: present
[… snipped …]
passwordSecret:
name: cluster-example-dante
これは、ユーザー名とパスワードを含むcluster-example-dante
と呼ばれるSecretの存在を前提としています。ユーザー名は、パスワードを設定しているロールと一致する必要があります。例:
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
が指定されていない場合、インスタンスマネージャーはパスワードを使用してロールを作成/変更しようとしません。これはPostgreSQLの慣習に従っており、
WITH PASSWORD で指示されない限りALTERはパスワードを更新しません。
ロールが最初にパスワードで作成され、PostgreSQLでパスワードをNULLに設定したい場合、これはCloudNativePGのユーザーの側で明示的にする必要があります。
「仕様でパスワードが提供されていない」と「パスワードをNULLに設定」を区別するには、フィールドDisablePassword
を使用する必要があります。
データベースの dante
ロールにパスワードを設定しないと決めたとします。そのような場合、以下を指定します。
managed:
roles:
- name: dante
ensure: present
[… snipped …]
disablePassword: true
注:特定のロールにpasswordSecret とdisablePassword
の両方を設定するとエラーと見なされます。この構成は、検証Webhookによって拒否されます。
パスワードの有効期限、VALID UNTIL¶
PostgreSQLのVALID UNTIL
ロール属性は、パスワードの有効期限を制御します。 PostgreSQLでは、
VALID UNTIL
を指定せずに作成されたロールはデフォルトで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を許可していないためです)
警告
宣言的なロール管理機能は、初期バージョン(1.20.0)から動作が変更されました。 1.20.0では、 passwordSecret のないロールは、PostgreSQLでパスワードをNULLに設定することになりました。実際には1.20.0とほとんど違いはありません。 passwordSecret なしで作成された新しいロールには、NULL パスワードがあります。関連する変更は、管理対象ロールを使用して、以前に作成されたロールを管理する場合です。 1.20.0では、これを行うと、誤って既存のパスワードを`NULL` に設定する可能性があります。
実現不可能なロール構成¶
- PostgreSQLでは、場合によっては、データベースがコマンドを受け入れることができず、拒否されます。
PostgreSQL documentation on error codes を参照してください
詳細については。
ロール操作は、このような基本的なエラーを生成する可能性があります。 2つの例:
PostgreSQLにロール(グループ)
poetsのメンバーとしてロールpetrarcaを作成するように依頼しますが、poetsは存在しません。PostgreSQLにロール
danteを削除するように依頼しますが、ロールdanteはデータベースinfernoの所有者です。
これらの基本的なエラーは、人間の管理者からの明確化なしに、データベースでもCloudNativePGオペレーターでも修正できません。上記の2つの例は、ロールpoets
を作成するか、データベースinferno
をそれぞれ削除することで修正できますが、それらは人為的エラーが原因である可能性があり、そのような場合、提案された「修正」は間違ったことである可能性があります。
CloudNativePGは、このような基本的なエラーが発生したときに記録し、クラスターのステータスに表示します。続くのは…
管理対象ロールのステータス¶
以下に示すように、CRDステータスには、管理対象ロールのステータスのセクションが含まれます。
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
に注意してください。
このセクションでは、オペレーターの使用のために予約されているロールと、宣言管理下にないロールについて説明し、データベースインスタンス内のロールの包括的なビューを提供します。
重要
下位互換性の観点から、宣言型ロール管理は、データベースに存在するが仕様に含まれていないロールを無視するように設計されています。これらのロールのライフサイクルは引き続きPostgreSQL内で管理されるため、CloudNativePGユーザーは都合の良いときにこの機能を採用できます。