TheKoguryo's 기술 블로그

 Version 2023.11.20

5.4 OKE에서 OCI 자원관리를 위한 Service Operator 사용하기

OCI Service Operator for Kubernetes(OSOK)는 OCI 자원을 Kubernetes API를 통해 관리할 수 있도록 도와주는 도구입니다. Autonomous Database 서비스를 Kubernetes API, kubectl을 통해 인스턴스를 생성, 삭제 등을 할 수 있게 해준다고 이해하면 됩니다. Kubernetes에서 사용하는 오픈소스 Operator Framework을 기반으로 작성되었습니다. 관련 참고 사이트는 아래와 같습니다.

현재 v1.1.8 기준 지원하고 있는 OCI 서비스는 다음과 같습니다.

  • Autonomous Database 서비스
  • MySQL Database 서비스
  • Streaming 서비스
  • Service Mesh 서비스

OCI Service Operator for Kubernetes를 OKE Cluster에 설치

제품 설치문서를 따라 설치한 내용으로 자세한 사항은 아래 문서를 참고합니다.

Operator SDK 설치

공식 설치 문서에 따라 설치합니다.

Cloud Shell 기준 설치 명령 예시

  • 아래 명령어로 설치하여 operator-sdk cli가 정상동작하는 지 확인합니다.

    # Download the release binary 
    export ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(uname -m) ;; esac)
    export OS=$(uname | awk '{print tolower($0)}')
    export OPERATOR_SDK_DL_URL=https://github.com/operator-framework/operator-sdk/releases/download/v1.30.0
    curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH}
    
    # Verify the downloaded binary 
    gpg --keyserver keyserver.ubuntu.com --recv-keys 052996E2A20B5C7E
    curl -LO ${OPERATOR_SDK_DL_URL}/checksums.txt
    curl -LO ${OPERATOR_SDK_DL_URL}/checksums.txt.asc
    gpg -u "Operator SDK (release) <cncf-operator-sdk@cncf.io>" --verify checksums.txt.asc
    grep operator-sdk_${OS}_${ARCH} checksums.txt | sha256sum -c -
    
    # Install the release binary in your PATH
    mkdir -p ~/.local/bin
    chmod +x operator-sdk_${OS}_${ARCH} && mv operator-sdk_${OS}_${ARCH} ~/.local/bin/operator-sdk
    
    operator-sdk version
    
Operator Lifecycle Manager (OLM) 설치
  • 아래 명령으로 현재 OKE 클러스터에 OLM 자원을 설치 및 확인합니다.

    operator-sdk olm install
    operator-sdk olm status
    
OCI Service Operator for Kubernetes 설치
권한 설정

OCI Service Operator for Kubernetes가 OCI 서비스에 대한 작업을 위한 권한이 필요합니다. OSOK가 OCI 내부에 있는 OKE에 같이 설치되어 있는 경우, Instance Principal을 통해 권한을 부여할 수 있습니다. OSOK가 OCI 외부 환경에 설치된 경우 또는 OSOK가 사용할 사용자 그룹에 권한을 부여하고자 하는 경우 User Principal을 통해 권한을 부여할 수 있습니다. OKE에서 권한을 설정할 것이므로 여기서는 Instance Principal을 사용합니다.

  • User Principal을 사용하고자 하는 경우 OCI Service Operator 사이트에 있는 Enable User Principal를 참고하여 구성합니다.
OKE Worker Node에 대한 Dynamic Group 만들기
  1. OCI 콘솔에 로그인 하여 Identity & Security > Identity > Compartments로 이동하여 OKE 클러스터가 있는 Compartment의 OCID를 복사합니다.
  2. 좌측 Dynamic Group 메뉴로 이동하여 복사한 OCID로 아래 규칙을 가진 Dynamic Group을 만듭니다.
    • Name: 예) oke-nodes-dynamic-group
    • Rule: instance.compartment.id = '<compartment-ocid>'
Dynamic Group을 위한 Policy 만들기
  1. 좌측 Policies 메뉴로 이동하여 만든 Dynamic Group에 아래와 같이 권한을 부여합니다.

    Allow dynamic-group <DYNAMICGROUP_NAME> to manage <OCI_SERVICE_1> in compartment <COMPARTMENT_NAME>
    ...
    
  2. 예시

OCI Service Operator for Kubernetes(OSOK) 배포
  1. OSOK가 배포될 namespace를 만듭니다.

    kubectl create ns oci-service-operator-system
    
  2. OSOK Operator 설치

    docker pull iad.ocir.io/oracle/oci-service-operator-bundle:1.1.8
    operator-sdk run bundle iad.ocir.io/oracle/oci-service-operator-bundle:1.1.8 -n oci-service-operator-system --timeout 5m
    
  3. OSOK 설치후 OCI 서비스를 위한 CustomResource가 추가된 것을 알 수 있습니다.

    $ kubectl api-resources | grep oci.oracle.com
    autonomousdatabases                            oci.oracle.com/v1beta1                 true         AutonomousDatabases
    mysqldbsystems                                 oci.oracle.com/v1beta1                 true         MySqlDbSystem
    streams                                        oci.oracle.com/v1beta1                 true         Stream
    accesspolicies                                 servicemesh.oci.oracle.com/v1beta1     true         AccessPolicy
    ingressgatewaydeployments                      servicemesh.oci.oracle.com/v1beta1     true         IngressGatewayDeployment
    ingressgatewayroutetables                      servicemesh.oci.oracle.com/v1beta1     true         IngressGatewayRouteTable
    ingressgateways                                servicemesh.oci.oracle.com/v1beta1     true         IngressGateway
    meshes                                         servicemesh.oci.oracle.com/v1beta1     true         Mesh
    virtualdeploymentbindings                      servicemesh.oci.oracle.com/v1beta1     true         VirtualDeploymentBinding
    virtualdeployments                             servicemesh.oci.oracle.com/v1beta1     true         VirtualDeployment
    virtualserviceroutetables                      servicemesh.oci.oracle.com/v1beta1     true         VirtualServiceRouteTable
    virtualservices                                servicemesh.oci.oracle.com/v1beta1     true         VirtualService
    

OSOK로 Autonomous Database Service 관리하기

참고 문서

ADB(Autonomous Database) Binding

OCI 콘솔에서 만든 ADB 인스턴스를 Kubernetes의 자원으로 Binding하는 경우입니다.

  1. OCI 콘솔에 로그인하여 바인딩할 Autonomous Database의 인스턴스를 생성합니다.

  2. Binding을 위해 필요한 명세 yaml을 확인하여 작성합니다.

    • spec.id: 기 존재하는, 바인딩할 ADB의 OCID를 입력
    • walletName: 바인딩후에 wallet이 저장될 kubernetes secret의 이름 입력
    • walletPassword.secret.secretName: wallet에 사용할 암호가 저장된 secret 이름, 바인딩 전에 미리 secret을 생성합니다.
      • The wallet download password should contain at least 1 number or special character
    apiVersion: oci.oracle.com/v1beta1
    kind: AutonomousDatabases
    metadata:
      name: <CR_OBJECT_NAME>
    spec:
      id: <AUTONOMOUS_DATABASE_OCID>
      wallet:
        walletName: <WALLET_SECRET_NAME>
        walletPassword:
          secret:
            secretName: <WALLET_PASSWORD_SECRET_NAME>
    
  3. 실행 예시

    • walletPassword 생성

      • The wallet download password should contain at least 1 number or special character
      kubectl create secret generic ociadb-wallet-password-secret --from-literal=walletPassword='xxxxxxxxxxxx'
      
    • YAML 파일 생성

      cat <<EOF > autonomousdatabases-bind.yaml
      apiVersion: oci.oracle.com/v1beta1
      kind: AutonomousDatabases
      metadata:
        name: ociadb
      spec:
        id: ocid1.autonomousdatabase.oc1.ap-chuncheon-1.an4w4__________________________________________________7rlbq  
        wallet:
          walletName: ociadb-wallet-secret
          walletPassword:
            secret:
              secretName: ociadb-wallet-password-secret
      EOF
      
    • 실행

      kubectl apply -f autonomousdatabases-bind.yaml
      
  4. 결과 확인

    kubectl describe 명령을 통해 에러없이 바인딩이 성공했는지 확인합니다.

    $ kubectl get autonomousdatabases
    NAME     DBWORKLOAD   STATUS   AGE
    ociadb                Active   11s
    $ kubectl describe autonomousdatabases ociadb
    Name:         ociadb
    ...
    Kind:         AutonomousDatabases
    ...
    Status:
      Status:
        Conditions:
          Last Transition Time:  2023-07-06T10:47:58Z
          Message:               AutonomousDatabase Bound success
    ...
    Events:
      Type    Reason   Age                From                 Message
      ----    ------   ----               ----                 -------
      Normal  Success  32s                AutonomousDatabases  Finalizer is added to the object
      Normal  Success  29s (x2 over 29s)  AutonomousDatabases  Create or Update of resource succeeded
    
  5. wallet 확인

    바인딩 결과 ociadb-wallet-secret secret이 생성되며, 내용을 보면 wallet 상에 있는 파일들이 Base64로 인코딩된 형태로 있는 것을 확인할 수 있습니다. 애플리케이션 컨테이너에서 secret을 마운트하여 ADB 연결시 사용하면 됩니다.

    $ kubectl get secret
    NAME                            TYPE     DATA   AGE
    ociadb-wallet-password-secret   Opaque   1      8m18s
    ociadb-wallet-secret            Opaque   9      2m18s
    $ kubectl get secret ociadb-wallet-secret -o yaml
    apiVersion: v1
    data:
      README: V2FsbGV0IE...
      cwallet.sso: ofhONgAAAA...
      ewallet.p12: MIIZ/AIBAz...
      keystore.jks: /u3+7QAAA...
      ojdbc.properties: IyBDb2...
      sqlnet.ora: V0FMTE...
      tnsnames.ora: b2NpYWR...
      truststore.jks: /u3+7QAAAA...
    kind: Secret
    metadata:
    ...
      name: ociadb-wallet-secret
    ...
    type: Opaque
    
ADB(Autonomous Database) Provisioning
  1. Provisioning을 위해 필요한 명세 yaml을 확인하여 작성합니다.

    • spec.compartmentId: 생성될 ADB가 위치할 Compartment의 OCID를 입력
    • walletName: 바인딩후에 wallet이 저장될 kubernetes secret의 이름 입력
    • walletPassword.secret.secretName: wallet에 사용할 암호가 저장된 secret 이름, 바인딩 전에 미리 secret을 생성합니다.
    • 나머지 항목은 OCI 콘솔에서 ADB 생성시 입력하는 것과 동일하게 원하는 값 입력 - 항목 명세 참조
    apiVersion: oci.oracle.com/v1beta1
    kind: AutonomousDatabases
    metadata:
      name: <CR_OBJECT_NAME>
    spec:
      compartmentId: <COMPARTMENT_OCID>
      displayName: <DISPLAY_NAME>
      dbName: <DB_NAME>
      dbWorkload: <OLTP/DW>
      isDedicated: <false/true>
      dbVersion: <ORABLE_DB_VERSION>
      dataStorageSizeInTBs: <SIZE_IN_TBs>
      cpuCoreCount: <COUNT>
      adminPassword:
        secret:
          secretName: <ADMIN_PASSWORD_SECRET_NAME>
      isAutoScalingEnabled: <true/false>
      isFreeTier: <false/true>
      licenseModel: <BRING_YOUR_OWN_LICENSE/LICENSE_INCLUDEE>
      wallet:
        walletName: <WALLET_SECRET_NAME>
        walletPassword:
          secret:
            secretName: <WALLET_PASSWORD_SECRET_NAME>
      freeformTags:
        <KEY1>: <VALUE1>
      definedTags:
        <TAGNAMESPACE1>:
          <KEY1>: <VALUE1>
    
  2. 실행 예시

    • adminPassword, walletPassword 생성

      • The wallet download password should contain at least 1 number or special character
      kubectl create secret generic ociadb-by-osok-admin-password-secret --from-literal=password='xxxxxxxxxxxx'
      kubectl create secret generic ociadb-by-osok-wallet-password-secret --from-literal=walletPassword='xxxxxxxxxxxx'
      
    • YAML 파일 생성

      cat <<EOF > autonomousdatabases-provision.yaml
      apiVersion: oci.oracle.com/v1beta1
      kind: AutonomousDatabases
      metadata:
        name: ociadbbyosok
      spec:
        compartmentId: ocid1.compartment.oc1..aaaaaaaa_______________________________________________toqhq
        displayName: OCIADBbyOSOK
        dbName: ociadbbyosok
        dbWorkload: OLTP
        isDedicated: false
        dbVersion: 19c
        dataStorageSizeInTBs: 1
        cpuCoreCount: 1
        adminPassword:
          secret:
            secretName: ociadb-by-osok-admin-password-secret
        isAutoScalingEnabled: false
        isFreeTier: false
        licenseModel: LICENSE_INCLUDED
        wallet:
          walletName: ociadb-by-osok-wallet-secret
          walletPassword:
            secret:
              secretName: ociadb-by-osok-wallet-password-secret
      EOF
      
    • 실행

      kubectl apply -f autonomousdatabases-provision.yaml
      
  3. 결과 확인

    kubectl describe 명령을 통해 에러없이 바인딩이 성공했는지 확인합니다.

    $ kubectl get autonomousdatabases
    NAME           DBWORKLOAD   STATUS   AGE
    ...
    ociadbbyosok   OLTP         Active   92s
    $ kubectl describe autonomousdatabases ociadbbyosok
    Name:         ociadbbyosok
    ...
    Kind:         AutonomousDatabases
    ...
    Status:
      Status:
        Conditions:
          Last Transition Time:  2023-07-06T10:58:15Z
          Message:               AutonomousDatabase Provisioning
          Status:                True
          Type:                  Provisioning
          Last Transition Time:  2023-07-06T10:59:20Z
          Message:               AutonomousDatabase OCIADBbyOSOK is Active
          Status:                True
          Type:                  Active
    ...
    Events:
      Type    Reason   Age                From                 Message
      ----    ------   ----               ----                 -------
      Normal  Success  99s                AutonomousDatabases  Finalizer is added to the object
      Normal  Success  29s (x2 over 30s)  AutonomousDatabases  Create or Update of resource succeeded
    
  4. wallet 확인

    바인딩 결과 ociadb-wallet-secret secret이 생성되며, 내용을 보면 wallet 상에 있는 파일들이 Base64로 인코딩된 형태로 있는 것을 확인할 수 있습니다. 애플리케이션 컨테이너에서 secret을 마운트하여 ADB 연결시 사용하면 됩니다.

    $ kubectl get secret
    NAME                                    TYPE     DATA   AGE
    ociadb-by-osok-admin-password-secret    Opaque   1      8m23s
    ociadb-by-osok-wallet-password-secret   Opaque   1      8m20s
    ociadb-by-osok-wallet-secret            Opaque   9      2m23s
    ...
    $ kubectl get secret ociadb-by-osok-wallet-secret -o yaml
    apiVersion: v1
    data:
      README: V2FsbGV0IE...
      cwallet.sso: ofhONgAAAA...
      ewallet.p12: MIIZ/AIBAz...
      keystore.jks: /u3+7QAAA...
      ojdbc.properties: IyBDb2...
      sqlnet.ora: V0FMTE...
      tnsnames.ora: b2NpYWR...
      truststore.jks: /u3+7QAAAA...
    kind: Secret
    metadata:
    ...
      name: ociadb-by-osok-wallet-secret
    ...
    type: Opaque
    
ADB(Autonomous Database) Update

OCI API에서 제공하는 Autonomous Database에 대한 Update 지원 항목내에서 OSOK GitHub 문서의 예시를 참고합니다.

  • https://github.com/oracle/oci-service-operator/blob/main/docs/adb.md#updating-an-autonomous-database

  • GitHub 문서 기준

    apiVersion: oci.oracle.com/v1beta1
    kind: AutonomousDatabases
    metadata:
      name: <CR_OBJECT_NAME>
    spec:
      id: <AUTONOMOUS_DATABASE_OCID>
      displayName: <DISPLAY_NAME>
      dbName: <DB_NAME>
      dbWorkload: <OLTP/DW>
      isDedicated: <false/true>
      dbVersion: <ORABLE_DB_VERSION>
      dataStorageSizeInTBs: <SIZE_IN_TBs>
      cpuCoreCount: <COUNT>
      adminPassword:
        secret:
          secretName: <ADMIN_PASSWORD_SECRET_NAME>
      isAutoScalingEnabled: <true/false>
      isFreeTier: <false/true>
      licenseModel: <BRING_YOUR_OWN_LICENSE/LICENSE_INCLUDEE>
      wallet:
        walletName: <WALLET_SECRET_NAME>
        walletPassword:
          secret:
            secretName: <WALLET_PASSWORD_SECRET_NAME>
      freeformTags:
        <KEY1>: <VALUE1>
      definedTags:
        <TAGNAMESPACE1>:
          <KEY1>: <VALUE1>
    
Binding 한 경우

기존 YAML 또는 배포된 YAML에 업데이트 항목을 추가 하여 반영합니다.

  • 스토리지 증가 예시

    앞선 autonomousdatabases-bind.yaml 파일에 dataStorageSizeInTBs 항목을 추가하여 배포합니다.

    apiVersion: oci.oracle.com/v1beta1
    kind: AutonomousDatabases
    metadata:
      name: ociadb
    spec:
      id: ocid1.autonomousdatabase.oc1.ap-chuncheon-1.an4w4__________________________________________________7rlbq 
      wallet:
        walletName: ociadb-wallet-secret
        walletPassword:
          secret:
            secretName: ociadb-wallet-password-secret
      dataStorageSizeInTBs: 2
    
Provisioning 한 경우
  • 스토리지 증가 예시

    앞선 autonomousdatabases-provision.yaml 파일에 생성된 ADB의 OCID를 spec.id에 추가합니다. 그리고 dataStorageSizeInTBs 값을 변경합니다.

    apiVersion: oci.oracle.com/v1beta1
    kind: AutonomousDatabases
    metadata:
      name: ociadbbyosok
    spec:
      id: ocid1.autonomousdatabase.oc1.ap-chuncheon-1.an4w4__________________________________________________eb46a  
      compartmentId: ocid1.compartment.oc1..aaaaaaaa_______________________________________________toqhq
      displayName: OCIADBbyOSOK
      dbName: ociadbbyosok
      dbWorkload: OLTP
      isDedicated: false
      dbVersion: 19c
      dataStorageSizeInTBs: 2
      cpuCoreCount: 1
      adminPassword:
        secret:
          secretName: ociadb-by-osok-admin-password-secret
      isAutoScalingEnabled: false
      isFreeTier: false
      licenseModel: LICENSE_INCLUDED
      wallet:
        walletName: ociadb-by-osok-wallet-secret
        walletPassword:
          secret:
            secretName: ociadb-by-osok-wallet-password-secret
    
  • 업데이트 실행결과

    image-20230706201444871

    $ kubectl describe autonomousdatabases ociadbbyosok
    Name:         ociadbbyosok
    ...
    Status:
      Status:
        Conditions:
          Last Transition Time:  2023-07-06T10:58:15Z
          Message:               AutonomousDatabase Provisioning
          Status:                True
          Type:                  Provisioning
          Last Transition Time:  2023-07-06T10:59:20Z
          Message:               AutonomousDatabase OCIADBbyOSOK is Active
          Status:                True
          Type:                  Active
          Last Transition Time:  2023-07-06T11:13:46Z
          Message:               AutonomousDatabase Update success
          Status:                True
          Type:                  Active
    ...
    
ADB(Autonomous Database) Delete

현재 버전 기준으로 Delete 기능을 따로 제공하지 않아, OKE 클러스터에서 autonomousdatabases 자원을 kubectl delete 명령으로 삭제해도 실제 ADB 인스턴스가 OCI에서 삭제되지는 않습니다.



이 글은 개인으로서, 개인의 시간을 할애하여 작성된 글입니다. 글의 내용에 오류가 있을 수 있으며, 글 속의 의견은 개인적인 의견입니다.

Last updated on 5 Jul 2023