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 설정을 업데이트 합니다.
-
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}