Kubernetes에서 Active Directory 그룹 지원 통합

문서 버전을 선택합니다.

이 페이지에서는 Kubernetes에 배포된 AlloyDB Omni에서 Active Directory 그룹 기반 인증 및 승인을 설정하고 관리하는 방법을 설명합니다. Active Directory 그룹 기반 지원은 Active Directory의 사용자 그룹 멤버십을 기반으로 PostgreSQL 역할 멤버십 관리를 자동화하여 사용자 관리를 간소화하고 권한이 동기화되도록 합니다. 자세한 내용은 Active Directory 개요를 참조하세요.

이 문서에서는 사용자가 Kubernetes 매니페스트 파일 적용 및 kubectl 명령줄 도구 사용에 익숙하다고 가정합니다. 자세한 내용은 명령줄 도구(kubectl)를 참조하세요.

Active Directory 통합 워크플로

Active Directory 통합은 다음 워크플로에서 PostgreSQL 확장 프로그램(google_pg_auth)을 사용하여 구현됩니다.

  1. 사용자 로그인: 사용자가 일반 보안 서비스 애플리케이션 프로그래밍 인터페이스 (GSSAPI)를 사용하여 표준 Active Directory 사용자 인증 정보를 사용하여 AlloyDB Omni에 인증합니다.
  2. 자동 역할 생성: 사용자의 해당 PostgreSQL 역할이 없으면 시스템에서 자동으로 역할을 생성합니다(예: CREATE ROLE "user@REALM" WITH LOGIN;).
  3. LDAP 그룹 확인: 시스템이 LDAP를 사용하여 Active Directory에 안전하게 연결하여 사용자의 현재 그룹 멤버십을 가져옵니다.
  4. 멤버십 동기화: 시스템에서 사용자의 Active Directory 그룹을 구성된 매핑과 비교합니다.

    • 사용자가 매핑된 Active Directory 그룹에 있지만 해당 PostgreSQL 그룹에 없는 경우 사용자에게 멤버십이 부여됩니다.
    • 사용자가 매핑된 Active Directory 그룹에 없지만 해당 PostgreSQL 그룹에 있는 경우 사용자의 멤버십이 취소됩니다.
  5. 로그인 완료: 사용자의 연결이 완료되고 데이터베이스에 로그인됩니다. 사용자의 권한은 사용자가 속한 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 그룹 역할에 데이터베이스 권한(예: SELECTINSERT)을 수동으로 할당해야 합니다. 통합은 멤버십만 관리하며 다시 예시와 같이 그룹 자체의 권한은 관리하지 않습니다.

    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 커스텀 리소스를 적용해야 합니다.

  1. 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
    

    다음을 바꿉니다.

    • 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 비밀에 대한 참조입니다. 이 보안 비밀의 키는 password이어야 합니다.
    • LDAPS_CERT_SECRET_REF: (선택사항) LDAPS 인증서가 있는 Kubernetes 보안 비밀에 대한 참조입니다. 이 보안 비밀의 키는 ldap.crt이어야 합니다.
    • CACHE_TTL_SECONDS: (선택사항) LDAP 그룹 구성원 동기화를 트리거하기 전에 기다릴 최대 시간(초)입니다. 기본값은 3,600초입니다.
    • LDAP_CONNECTION_TIMEOUT: (선택사항) LDAP 연결 제한 시간(밀리초)입니다. 기본값은 5,000밀리초입니다.

    아래 예시를 참조하세요.

    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
    

그룹 매핑 만들기

이미 만든 PostgreSQL 그룹 역할에 Active Directory 그룹을 매핑하려면 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() 함수를 사용합니다. unmap_ad_group() 함수는 사용자가 이미 회원인 경우 PostgreSQL 그룹에서 사용자를 삭제하지 않습니다.

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 포드에는 kinitpsql이 설치되어 있으며 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_developerspostgres_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

다음 예시에서는 Active Directory의 ad_developers 그룹에서 Quinn이 삭제됩니다.

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 조회로 인해 초기 사용자 로그인 프로세스에 약간의 지연 시간이 추가됩니다. 캐싱은 구성된 TTL (auth_cache_ttl_sec) 내에서 후속 로그인에 대한 이 지연 시간을 완화하는 데 도움이 됩니다.
  • 오류 처리: LDAP 서버에 연결할 수 없거나 동기화 프로세스 중에 다른 오류가 발생하면 AlloyDB Omni가 오류를 기록합니다. 하지만 GSSAPI 인증이 성공했으므로 사용자의 로그인은 계속 성공합니다. 해당 세션의 그룹 멤버십 동기화만 실패합니다.

다음 단계