AI Conductor Installation
Table of Contents
Detailed Steps
For detailed explanations of {variables}, please refer to the Terminology page.
-
Set the {variables}.
- NOTE: AIC_ADMIN_PASSWD_ENCRYPT contains special characters, so input it as 'value'
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-${DOCKER_NAME}/api/v1/docs
export AIC_FRONTEND_URL=aicond-${DOCKER_NAME}
export AIC_KUBEFLOW_URL=aicond-kf-${DOCKER_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/ encrypt ${AIC_ADMIN_PASSWD}'
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. Create AI Conductor Tables
- Create tables in the ai_conductor Database for AI Conductor operations.
-
Create a file named 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 -
Run the following command to create the tables.
mysql -h ${DB_HOST} -P ${DB_PORT} -u ${DB_ADMIN_USERNAME} -p < create-ai-conductor-table.sql
# Insert : ${DB_ADMIN_PASSWORD}
-
- Create an ADMIN user account in the member table.
-
Create a file named 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 -
Run the following command to create the ADMIN user account.
mysql -h ${DB_HOST} -P ${DB_PORT} -u ${DB_ADMIN_USERNAME} -p < create-admin-user.sql
# Insert : ${DB_ADMIN_PASSWORD}
-
2. Deploy AI Conductor
-
Clone the AI Conductor Deployment repository using the command below.
git clone https://github.com/mellerikat/AI-Conductor
-
Deploy AI Conductor.
- Update the AI Conductor settings.
- NOTE : If already configured, please disregard.
# path : ${TOP}/AI-Conductor
cd AI-Conductor
git checkout chartmuseum
# Set 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-
Update LDAP settings of the AI Conductor Backend. (Settings required when using LDAP)
- NOTE : If already configured, please disregard.
[Expand AI Conductor LDAP Settings]
# path : ${TOP}/AI-Conductor
# Set 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- Receive lge_root_ca.crt from the infrastructure manager and save it to {TOP}/AI-Conductor/ai-conductor-charts/params/lge_root_ca.crt.
-
Deploy the image of AI Conductor
# path : ${TOP}/AI-Conductor
# Deploy 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 - Update the AI Conductor settings.
-
Verify AI Conductor deployment.
kubectl get pod -n ai-conductor
[Expand Verify AI Conductor deployment]
Once the deployment is complete, the STATUS of the pod will be 'Running' as shown below.
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. Access AI Conductor
- Kubeflow Dashboard: {AIC_KUBEFLOW_URL}
- AI Conductor Frontend: {AIC_FRONTEND_URL}
- AI Conductor Backend: {AIC_BACKEND_URL}
4. Update AI Conductor Version
- Access {AIC_BACKEND_URL}
- Login to POST/api/v1/auth/login as admin.
- login_id: {AIC_ADMIN_USER}
- login_pw: {AIC_ADMIN_PASSWD}
- Update version via POST/api/v1/versions.
- ver_str: {AIC_RELEASE_VERSION}
- frontend_hash: {AIC_FRONTEND_TAG}
- backend_hash: {AIC_BACKEND_TAG}
- description: desired text (not visible to users)
[Option] Add Workspace of AI Conductor
- To add a {Workspace}, refer to the Workspace 추가 page