본문으로 건너뛰기
버전: docs v25.02

AI Conductor 설치


목차

  1. AI Conductor 테이블 생성
  2. AI Conductor 배포하기
  3. AI Conductor 접속하기
  4. AI Conductor 버전 업데이트


자세한 단계

{변수}의 자세한 설명은 Terminology 페이지를 참고하세요

  • {변수} 설정을 합니다.

    • NOTE : AIC_ADMIN_PASSWD_ENCRYPT 는 특수문자가 포함되므로 '값' 으로 입력
    export AWS_ACCOUNT_ID=
    export AWS_DEFAULT_REGION=
    export AWS_DEFAULT_REGION_ALIAS=
    export DOMAIN_NAME=
    export INFRA_NAME=
    export DEPLOY_ENV=
    export REDIS_HOST=
    export REDIS_PORT=

    export AIC_RELEASE_VERSION=
    export AIC_BACKEND_URL=aicond-${DOMAIN_NAME}/api/v1/docs
    export AIC_FRONTEND_URL=aicond-${DOMAIN_NAME}
    export AIC_KUBEFLOW_URL=aicond-kf-${DOMAIN_NAME}
    export AIC_BACKEND_IMAGE_URL=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/ecr-repo-${AWS_DEFAULT_REGION_ALIAS}-${INFRA_NAME}-${DEPLOY_ENV}/ai-advisor/ai-conductor/aic-webserver
    export AIC_BACKEND_IMAGE_TAG=

    export AIC_FRONTEND_IMAGE_URL=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/ecr-repo-${AWS_DEFAULT_REGION_ALIAS}-${INFRA_NAME}-${DEPLOY_ENV}/ai-advisor/ai-conductor/aic-frontend
    export AIC_FRONTEND_IMAGE_TAG=
    export AIC_ADMIN_USER=admin
    export AIC_ADMIN_PASSWD=
    export AIC_ADMIN_PASSWD_ENCRYPT='# https://bcrypt-generator.com/ 에서 ${AIC_ADMIN_PASSWD} 의 Encrypt'
    export AIC_ADMIN_COMPANY=
    export AIC_ADMIN_DEPARTMENT=
    export AWS_SECRETS_MANAGER_RDS=/parameter/${AWS_DEFAULT_REGION}/${INFRA_NAME}/${DEPLOY_ENV}/rds
    export AIC_ECR_BASE_PATH=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/ecr-repo-${AWS_DEFAULT_REGION_ALIAS}-${INFRA_NAME}-${DEPLOY_ENV}/
    export DASHBOARD_PREFIX=https://aicond-mon.${DOMAIN_NAME}.com/d/
    export AIC_MLOPS_ENGINE=

1. AI Conductor 테이블 생성

  • ai_conductor Database 에 AI Conductor 운영을 위한 테이블을 생성합니다.
    • create-ai-conductor-table.sql 을 생성합니다.

      [Expand create-ai-conductor-table.sql]
      cat <<EOT > create-ai-conductor-table.sql
      USE ai_conductor;

      CREATE TABLE alembic_version (
      version_num VARCHAR(32) NOT NULL,
      CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num)
      );

      -- Running upgrade -> d7e09e6ff766

      CREATE TABLE `member` (
      username VARCHAR(30) NOT NULL,
      password VARCHAR(128) NOT NULL,
      display_name VARCHAR(30) NOT NULL,
      email VARCHAR(250) NOT NULL,
      company VARCHAR(250) NOT NULL,
      department VARCHAR(250) NOT NULL,
      `role` ENUM('ADMIN','DEVELOPER') NOT NULL,
      last_login_failed INTEGER NOT NULL,
      last_login_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id)
      );

      CREATE TABLE solution (
      name VARCHAR(100) NOT NULL,
      display_name VARCHAR(100) NOT NULL,
      workspace_id CHAR(32) NOT NULL,
      creator VARCHAR(30) NOT NULL,
      updator VARCHAR(30) NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id)
      );

      CREATE TABLE tag (
      tag_table_name VARCHAR(64) NOT NULL,
      sub_name VARCHAR(64) NOT NULL,
      sub_id CHAR(32) NOT NULL,
      tag_key VARCHAR(64) NOT NULL,
      tag_value VARCHAR(64) NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id)
      );

      CREATE INDEX ix_tag_tag_key ON tag (tag_key, tag_value);

      CREATE INDEX ix_tag_tag_table_name ON tag (tag_table_name, sub_name);

      CREATE TABLE version (
      ver_str VARCHAR(50) NOT NULL,
      frontend_hash VARCHAR(50) NOT NULL,
      backend_hash VARCHAR(50) NOT NULL,
      description TEXT NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id)
      );

      CREATE TABLE workspace (
      name VARCHAR(30) NOT NULL,
      display_name VARCHAR(30) NOT NULL,
      experiment_id VARCHAR(36) NOT NULL,
      experiment_name TEXT NOT NULL,
      kubeflow_user VARCHAR(100) NOT NULL,
      s3_bucket_name VARCHAR(64) NOT NULL,
      ecr_base_path TEXT NOT NULL,
      namespace VARCHAR(64) NOT NULL,
      dashboard_hash VARCHAR(50) NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id)
      );

      CREATE TABLE kubeflowaccount (
      workspace_id CHAR(32) NOT NULL,
      username VARCHAR(100) NOT NULL,
      encrypted_password VARCHAR(1000) NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id),
      FOREIGN KEY(workspace_id) REFERENCES workspace (id)
      );

      CREATE TABLE solutionversion (
      solution_id CHAR(32) NOT NULL,
      workspace_id CHAR(32) NOT NULL,
      version BIGINT NOT NULL,
      metadata_json JSON NOT NULL,
      creator VARCHAR(30) NOT NULL,
      updator VARCHAR(30) NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id),
      FOREIGN KEY(solution_id) REFERENCES solution (id)
      );

      CREATE TABLE workspaceexecutionspec (
      workspace_id CHAR(32) NOT NULL,
      name VARCHAR(30) NOT NULL,
      label VARCHAR(64) NOT NULL,
      vcpu INTEGER NOT NULL,
      ram_gb INTEGER NOT NULL,
      gpu INTEGER NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id),
      FOREIGN KEY(workspace_id) REFERENCES workspace (id)
      );

      CREATE TABLE workspacemembership (
      workspace_id CHAR(32) NOT NULL,
      member_id CHAR(32) NOT NULL,
      `role` ENUM('UNKNOWN','MANAGER','MEMBER') NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id),
      FOREIGN KEY(member_id) REFERENCES `member` (id),
      FOREIGN KEY(workspace_id) REFERENCES workspace (id),
      UNIQUE (workspace_id, member_id)
      );

      CREATE TABLE stream (
      name VARCHAR(100) NOT NULL,
      display_name VARCHAR(100) NOT NULL,
      workspace_id CHAR(32) NOT NULL,
      solution_version_id CHAR(32) NOT NULL,
      train_dataset_uri TEXT NOT NULL,
      creator VARCHAR(30) NOT NULL,
      updator VARCHAR(30) NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id),
      FOREIGN KEY(solution_version_id) REFERENCES solutionversion (id)
      );

      CREATE TABLE streamhistory (
      name VARCHAR(150) NOT NULL,
      display_name VARCHAR(150) NOT NULL,
      workspace_id CHAR(32) NOT NULL,
      solution_version_id CHAR(32) NOT NULL,
      stream_id CHAR(32) NOT NULL,
      train_pipeline_id VARCHAR(50) NOT NULL,
      train_resource VARCHAR(128) NOT NULL,
      status VARCHAR(32) NOT NULL,
      train_artifact_uri TEXT NOT NULL,
      model_version VARCHAR(32) NOT NULL,
      creator VARCHAR(30) NOT NULL,
      updator VARCHAR(30) NOT NULL,
      metadata_json JSON NOT NULL,
      id CHAR(32) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      is_deleted SMALLINT NOT NULL,
      PRIMARY KEY (id),
      FOREIGN KEY(solution_version_id) REFERENCES solutionversion (id),
      FOREIGN KEY(stream_id) REFERENCES stream (id)
      );

      INSERT INTO alembic_version (version_num) VALUES ('d7e09e6ff766');

      EOT
    • 아래 명령어로 테이블을 생성합니다.

      mysql -h ${DB_HOST} -P ${DB_PORT} -u ${DB_ADMIN_USERNAME} -p < create-ai-conductor-table.sql
      # 입력 : ${DB_ADMIN_PASSWORD}

  • 생성된 테이블의 member 에 ADMIN 사용자 계정을 생상합니다.
    • create-admin-user.sql 을 생성합니다.

      [Expand create-admin-user.sql]
      cat <<EOT > create-admin-user.sql
      INSERT INTO ai_conductor.member (username, password, display_name, email, role, id, company, department, is_deleted, last_login_failed)
      VALUES ('admin', '${AIC_ADMIN_PASSWD_ENCRYPT}', 'Admin Account', 'admin@lge.com', 'ADMIN', '24192d1913774101a1ef161163880fe9', '${AIC_ADMIN_COMPANY}', '${AIC_ADMIN_DEPARTMENT}', 0, 0);
      EOT
    • 아래 명령어로 ADMIN 사용자 계정을 생성합니다.

      mysql -h ${DB_HOST} -P ${DB_PORT} -u ${DB_ADMIN_USERNAME} -p < create-admin-user.sql
      # 입력 : ${DB_ADMIN_PASSWORD}


2. AI Conductor 배포하기

  • 아래 명령어로 AI Conductor Deployment를 clone 합니다.

    git clone https://github.com/mellerikat/AI-Conductor.git
  • AI Conductor를 배포 합니다.

    • AI Conductor 설정을 업데이트 합니다.
      • NOTE : 기존 설정된 경우 무시합니다.
    # path : ${TOP}/AI-Conductor/backend
    # path : ${TOP}/AI-Conductor
    cd AI-Conductor
    git checkout chartmuseum

    # Helm values 설정
    cp example-values.yaml ${INFRA_NAME}-${DEPLOY_ENV}-values.yaml
    yq e -i '
    .infra_name = env(INFRA_NAME) |
    .deploy_env = env(DEPLOY_ENV) |
    .redis.host = env(REDIS_HOST) |
    .redis.port = strenv(REDIS_PORT) |
    .rds_secretmanager = env(AWS_SECRETS_MANAGER_RDS) |
    .webserver.images.name = env(AIC_BACKEND_IMAGE_URL)|
    .webserver.images.tag = env(AIC_BACKEND_IMAGE_TAG) |
    .webserver.config.general.ecr_base_path = env(AIC_ECR_BASE_PATH) |
    .webserver.config.general.mysql_db = "ai_conductor" |
    .webserver.config.monitor.type = "grafana" |
    .webserver.config.monitor.grafana.org_id = "1" |
    .webserver.config.monitor.grafana.dashboard_prefix = env(DASHBOARD_PREFIX) |
    .webserver.config.mlops.engine = "kubeflow" |
    .webserver.config.mlops.kubeflow.cluster_name = env(AWS_CLUSTER_NAME) |
    .frontend.images.name = env(AIC_FRONTEND_IMAGE_URL) |
    .frontend.images.tag = env(AIC_FRONTEND_IMAGE_TAG)
    ' ${INFRA_NAME}-${DEPLOY_ENV}-values.yaml
    • AI Conductor Backend LDAP 설정을 업데이트 합니다. (LDAP 사용 시 설정 필요)

      • NOTE : 기존 설정된 경우 무시합니다.
      [Expand AI Conductor LDAP 설정]
      # path : ${TOP}/AI-Conductor/backend

      # LDAP 설정 합니다.
      yq e -i '
      .webserver.config.ldap.enabled = "true" |
      .webserver.config.ldap.enabled |= . style="double" |
      .webserver.config.ldap.ldap_crt_file = "./params/lge_root_ca.crt" |
      .webserver.config.ldap.host_name = "ldaps://lgesaapds01.lge.net" |
      .webserver.config.ldap.host_name |= . style="double" |
      .webserver.config.ldap.host_port = "636" |
      .webserver.config.ldap.host_port |= . style="double" |
      .webserver.config.ldap.base_dn = "OU=LGE Users,dc=LGE,dc=NET" |
      .webserver.config.ldap.base_dn |= . style="double" |
      .webserver.config.ldap.search_dn = "dc=lge,dc=net" |
      .webserver.config.ldap.search_dn |= . style="double" |
      .webserver.config.ldap.bind_id = "{login_id}@lge.net" |
      .webserver.config.ldap.bind_id |= . style="double" |
      .webserver.config.ldap.query = "(cn={login_id})" |
      .webserver.config.ldap.query |= . style="double"
      ' ${INFRA_NAME}-${DEPLOY_ENV}-values.yaml
      • 인프라 담당자로부터 lge_root_ca.crt 전달 받아 {TOP}/AI-Conductor/ai-conductor-charts/params/lge_root_ca.crt 위치에 저장합니다.
    • AI Conductor 이미지를 배포 합니다.

    # path : ${TOP}/AI-Conductor

    # AI Conductor 배포
    helm repo add mellerikat-aicond https://mellerikat.github.io/AI-Conductor
    helm repo update
    helm install ai-conductor mellerikat-aicond/ai-conductor --values {{INFRA_NAME}}-{{DEPLOY_ENV}}-values.yaml -n ai-conductor
  • AI Conductor 배포 확인을 합니다.

    kubectl get pod -n ai-conductor
    [Expand AI Conductor 배포 확인]

    배포가 완료되면 아래와 같이 pod의 STATUS 가 'Running' 상태입니다.

    NAME                                READY   STATUS    RESTARTS   AGE
    ai-conductor-web-749bcd95d5-jjg9d   1/1 Running 0 15s
    ai-conductor-web-749bcd95d5-r7jk5   1/1 Running 0 15s
    frontend-server-6b6994d545-5x4cc 1/1 Running 0 1m2s
    frontend-server-6b6994d545-cgq8s 1/1 Running 0          1m2s


3. AI Conductor 접속하기

  • Kubeflow Dashboard : {AIC_KUBEFLOW_URL}
  • AI Conductor Frontend : {AIC_FRONTEND_URL}
  • AI Conductor Backend : {AIC_BACKEND_URL}


4. AI Conductor 버전 업데이트

  • {AIC_BACKEND_URL} 접속
  • POST/api/v1/auth/login 에서 admin 으로 로그인
    • login_id : {AIC_ADMIN_USER}
    • login_pw : {AIC_ADMIN_PASSWD}
  • POST/api/v1/versions 으로 버전 업데이트
    • ver_str : {AIC_RELEASE_VERSION}
    • frontend_hash : {AIC_FRONTEND_TAG}
    • backend_hash : {AIC_BCAKEND_TAG}
    • description : 원하는 문장 (사용자에게 노출되지 않음)


[Option] AI Conductor Workspace 추가