本文档假定您熟悉应用 Kubernetes 清单文件和使用 kubectl 命令行工具。如需了解详情,请参阅命令行工具 (kubectl)。
Active Directory 集成工作流
Active Directory 集成通过以下工作流中的 PostgreSQL 扩展程序 (google_pg_auth) 实现:
- 用户登录:用户使用通用安全服务应用编程接口 (GSSAPI) 通过其标准 Active Directory 凭证向 AlloyDB Omni 进行身份验证。
- 自动创建角色:如果不存在与用户对应的 PostgreSQL 角色,系统会自动创建一个角色,例如
CREATE ROLE "user@REALM" WITH LOGIN;。 - LDAP 群组检查:系统使用 LDAP 安全地连接到您的 Active Directory,以检索用户的当前群组成员资格。
成员资格同步:系统会将用户的 Active Directory 群组与您配置的映射进行比较。
- 如果用户属于已映射的 Active Directory 群组,但不属于相应的 PostgreSQL 群组,则系统会授予该用户成员资格。
- 如果用户不在已映射的 Active Directory 群组中,但位于相应的 PostgreSQL 群组中,则系统会撤消该用户的成员资格。
登录完成:用户连接已最终确定,且用户已登录到数据库。用户的权限由其所属的 PostgreSQL 角色决定,这些角色与其 Active Directory 群组状态保持同步。
此同步会在每次用户登录时自动进行,确保 PostgreSQL 访问权限反映 Active Directory 的当前状态。
准备工作
在将 Active Directory 群组支持与 AlloyDB Omni 集成之前,请确保您满足以下要求。
- GSSAPI 身份验证:您必须为 AlloyDB Omni 实例配置基于 GSSAPI 的身份验证并使其正常运行。如需了解详情,请参阅将 Active Directory 与 AlloyDB Omni 集成。
PostgreSQL 群组角色:您必须手动创建打算映射到 Active Directory 群组的 PostgreSQL 群组角色,如以下示例所示:
CREATE ROLE "postgres_developers"; CREATE ROLE "postgres_read_only";
权限:您必须手动为这些 PostgreSQL 群组角色分配数据库权限,例如
SELECT和INSERT。集成功能仅管理成员资格,但不管理群组本身的权限,如以下示例所示:GRANT SELECT ON ALL TABLES IN SCHEMA sales TO postgres_read_only; GRANT USAGE ON SCHEMA finance TO postgres_developers; GRANT USAGE ON SCHEMA sales TO postgres_read_only; GRANT SELECT, INSERT ON finance.transactions TO postgres_developers;
配置 Active Directory 群组支持
如需配置 Active Directory 群组支持,您必须在现有数据库集群上应用 UserDefinedAuthentication 自定义资源。
使用 LDAP 服务器凭证配置 AlloyDB Omni。应用以下用户定义的身份验证自定义资源清单:
apiVersion: alloydbomni.dbadmin.goog/v1 kind: UserDefinedAuthentication metadata: name: USER_DEFINED_AUTHENTICATION_NAME namespace: DB_CLUSTER_NAMESPACE spec: dbclusterRef: name: DB_CLUSTER_NAME keytabSecretRef: name: KEYTAB_SECRET_NAME pgHbaEntries: PG_HBA_ENTRIES pgIdentEntries: PG_IDENT_ENTRIES ldapConfiguration: enableGroupMapping: true ldapURI: LDAP_URI ldapBaseDN: LDAP_BASE_DN ldapBindDN: LDAP_BIND_DN cacheTTLSeconds: CACHE_TTL_SECONDS ldap_connection_timeout_ms: LDAP_CONNECTION_TIMEOUT ldapBindPasswordSecretRef: name: LDAP_PASSWORD_SECRET_REF ldapsCertificateSecretRef: name: LDAPS_CERT_SECRET_REF allow_unmapped_ad_users: ALLOW_UNMAPPED_AD_USERS进行以下替换:
USER_DEFINED_AUTHENTICATION_NAME:UserDefinedConfiguration 的名称,例如DB_CLUSTER_NAME-ad-auth。DB_CLUSTER_NAMESPACE:此备份方案的 Kubernetes 命名空间。 该命名空间必须与数据库集群的命名空间一致。DB_CLUSTER_NAME:您的数据库集群的名称(您在创建数据库集群时分配该名称)。LDAP_URI:LDAP 服务器 URI,例如ldaps://ad.example.com:636。LDAP_BASE_DN:LDAP 搜索的基本 DN。(例如 DC=ad,DC=alloydb,DC=COM)LDAP_BIND_DN:LDAP 绑定用户的标识名 (DN)。LDAP_PASSWORD_SECRET_REF:对包含密码 LDAP 密码的 Kubernetes Secret 的引用。此 Secret 的键必须为password。LDAPS_CERT_SECRET_REF:(可选)对包含 LDAPS 证书的 Kubernetes Secret 的引用。此 Secret 的键必须为ldap.crt。CACHE_TTL_SECONDS:(可选)触发 LDAP 群组成员资格同步之前等待的最长时间(以秒为单位)。默认值为 3,600 秒。LDAP_CONNECTION_TIMEOUT:(可选)LDAP 连接超时(以毫秒为单位)。默认值为 5,000 毫秒。ALLOW_UNMAPPED_AD_USERS:(可选)如果设置为true,则未映射到任何 Active Directory 群组的用户也将被允许登录。默认值为false。
请参阅以下示例:
apiVersion: v1 kind: Secret metadata: name: ldaps-secret type: Opaque data: ldap.crt: LDAPS_CERTIFICATE_CONTENT_BASE64_ENCODED --- apiVersion: v1 kind: Secret metadata: name: ldap-password-dbcluster-sample type: Opaque data: password: LDAPS_PASSWORD_CONTENT_BASE64_ENCODED --- apiVersion: v1 kind: Secret metadata: name: db-pw-dbcluster-sample type: Opaque data: dbcluster-sample: POSTGRES_PASSWORD --- apiVersion: alloydbomni.dbadmin.goog/v1 kind: DBCluster metadata: name: dbcluster-sample spec: databaseVersion: 16.8.0 primarySpec: adminUser: passwordRef: name: db-pw-dbcluster-sample resources: memory: 5Gi cpu: 1 disks: - name: DataDisk size: 10Gi --- apiVersion: v1 kind: Secret metadata: name: db-keytab-dbcluster-sample type: Opaque data: krb5.keytab: | DUMMY_KEYTAB --- apiVersion: alloydbomni.dbadmin.goog/v1 kind: UserDefinedAuthentication metadata: name: dbcluster-sample-ad-auth spec: dbclusterRef: name: dbcluster-sample keytabSecretRef: name: db-keytab-dbcluster-sample pgHbaEntries: - hostgssenc all all 0.0.0.0/0 gss - hostgssenc all all ::1/128 gss - hostssl all all 0.0.0.0/0 scram-sha-256 - hostssl all all ::/0 scram-sha-256 ldapConfiguration: enableGroupMapping: true ldapURI: ldaps://ad.alloydb.com:636 ldapBaseDN: DC=ad,DC=alloydb,DC=COM ldapBindDN: read-only-admin@ad.alloydb.com cacheTTLSeconds: 60 ldapBindPasswordSecretRef: name: ldap-password-dbcluster-sample ldapsCertificateSecretRef: name: ldaps-secret
管理群组映射
您可以使用 SQL 函数创建和管理 Active Directory 群组与 PostgreSQL 角色之间的映射。
登录集群并加载扩展程序
连接到 Kubernetes 上运行的 AlloyDB Omni。
export DBPOD=`kubectl get pod --selector=alloydbomni.internal.dbadmin.goog/dbcluster=DB_CLUSTER_NAME,alloydbomni.internal.dbadmin.goog/task-type=database -n DB_CLUSTER_NAMESPACE -o jsonpath='{.items[0].metadata.name}'` kubectl exec -ti $DBPOD -n DB_CLUSTER_NAMESPACE -c database -- psql -h localhost -U postgres postgres=# CREATE EXTENSION google_pg_auth; CREATE EXTENSION
创建群组映射
如需将 Active Directory 群组映射到您已创建的 PostgreSQL 群组角色,请使用 map_ad_group() 函数。
SELECT google_pg_auth.map_ad_group(ad_group_name TEXT, ad_group_sid TEXT, pg_role_name TEXT);
在以下示例中,ad-developers Active Directory 群组映射到 pg-developers PostgreSQL 角色:
SELECT google_pg_auth.map_ad_group('ad-developers', 'S-1-5-21-.....', 'postgres_read_only');
如需检索 Active Directory 中特定群组的 SID,请在 Active Directory 服务器上使用以下命令:
C:\Users\Admin> Get-ADGroup -Identity ad-developers | select SID
SID
-----------------------------------------------
S-1-5-21-3168537779-1985441202-1799118680-1612
移除群组映射
如需移除现有映射,请使用 unmap_ad_group() 函数,该函数会停止相应群组的同步。如果用户已经是 PostgreSQL 群组的成员,unmap_ad_group() 函数不会将其从该群组中移除。
SELECT google_pg_auth.unmap_ad_group(ad_group_sid TEXT, pg_role_name TEXT);
请参阅以下示例:
SELECT google_pg_auth.unmap_ad_group('S-1-5-21-.....', ''postgres_read_only'');
创建用户映射
如需将单个 Active Directory 用户映射到您已创建的 PostgreSQL 角色,请使用 map_ad_user() 函数。
SELECT google_pg_auth.map_ad_user(ad_username TEXT, pg_role_name TEXT);
例如,如需将 quinn@google.com Active Directory 用户映射到 pg-developers PostgreSQL 角色,请执行以下操作:
SELECT google_pg_auth.map_ad_user('quinn@google.com', ''postgres_read_only'');
移除用户映射
如需移除现有映射,请使用 unmap_ad_user() 函数。
SELECT google_pg_auth.unmap_ad_user(ad_username TEXT, pg_role_name TEXT);
例如,如需从 pg-developers PostgreSQL 角色取消映射 quinn@google.com Active Directory 用户,请执行以下操作:
SELECT google_pg_auth.unmap_ad_user('quinn@google.com', ''postgres_read_only'');
连接到 AlloyDB Omni 数据库
使用 Active Directory 用户登录 AlloyDB Omni 数据库。
您必须在所连接的客户端中启用 kinit。
在以下示例中,postgres-client Pod 已安装 kinit 和 psql,并配置为使用 psql 客户端连接到 AlloyDB Omni 集群。
root@postgres-client:/# kinit AD_USER_NAME Password for user1REALM: root@postgres-client:/# psql -h ALLOYDB_SERVER_HOST_NAME -U AD_USER_NAME -d postgres psql (16.6 (Ubuntu 16.6-0ubuntu0.24.04.1), server 16.3) GSSAPI-encrypted connection Type "help" for help. user1=#
AlloyDB Omni 数据库中的访问权限是根据以下因素自动确定的:
- 您当前在 Active Directory 群组中的成员资格。
- 管理员在这些 Active Directory 群组与 PostgreSQL 角色之间定义的映射。
- 管理员向这些 PostgreSQL 角色授予的权限。
如果您是首次连接,系统会自动创建 PostgreSQL 用户角色 (your_ad_user@YOURDOMAIN.COM)。
每次登录时,系统都会检查您当前的 Active Directory 群组成员资格,并更新您对应的 PostgreSQL 角色成员资格,以保持一致。您无需采取任何具体操作即可实现此同步。
数据库连接示例
在以下示例中,用户 Quinn 属于名为 ad_developers 的 Active Directory 群组。管理员已将 ad_developers 映射到名为 postgres_read_only 的 postgres 角色。此角色对名为 sales 的表具有读取权限。用户登录后,即可访问该表格。
root@postgres-client:/# kinit quinnREALM Password for quinn@YOUR.REALM: root@postgres-client:/# psql -h ALLOYDB_SERVER_HOST_NAME -U quinnREALM -d postgres psql (16.6 (Ubuntu 16.6-0ubuntu0.24.04.1), server 16.3) GSSAPI-encrypted connection Type "help" for help. postgres=# select * from sales; // Query will be run successfully
在以下示例中,Quinn 已从 Active Directory 中的 ad_developers 群组中移除。
root@postgres-client:/# kinit quinnREALM Password for quinn@YOUR.REALM: root@postgres-client:/# psql -h ALLOYDB_SERVER_HOST_NAME -U quinnREALM -d postgres psql (16.6 (Ubuntu 16.6-0ubuntu0.24.04.1), server 16.3) GSSAPI-encrypted connection Type "help" for help. postgres=# select * from sales; // Query will fail
限制
- 手动群组和权限管理:此功能仅自动管理现有 PostgreSQL 群组中的用户成员资格。创建这些群组并授予其权限是一项手动管理任务。
- 同步延迟时间:只有在用户登录时才会同步成员资格。 用户在 Active Directory 中的群组成员资格发生任何更改后,只有在下次登录 AlloyDB Omni 时才会反映出来。
- 性能:LDAP 查找会给初始用户登录流程增加少量延迟。缓存有助于在配置的存留时间 (
auth_cache_ttl_sec) 内缓解后续登录的这种延迟。 - 错误处理:如果 LDAP 服务器无法访问,或者在同步过程中发生其他错误,AlloyDB Omni 会记录该错误。 不过,由于 GSSAPI 身份验证成功,用户仍可成功登录。只有相应会话的群组成员资格同步会失败。