Unity ML-AgentsのDockerイメージを作成するのに、AWS CodeBuild(CodeBuild)を利用してみました。
CodeBuildでUnity ML-Agentsのソースを取得してビルド、ビルドができたらAmazon Elastic Container Registry(ECR)のリポジトリにイメージをPushします。
Unity ML-AgentsやCodeBuildについては省略。
同じようなことをGCPのGoogle Cloud Buildでもやっているので、GCPな方はそちらをご参考ください。
Google Cloud Buildを利用してUnity ML-AgentsのDockerイメージを作成する(v0.9.1対応) – Qiita
https://cloudpack.media/49196
前提
- AWSアカウントがある
- ローカルで
aws
コマンドが利用できる - ローカルでDockerが実行できる
手順
AWS CloudFormation(CFn)で環境構築する
CFnを利用して、必要となるリソースを作成します。
- InputBucket: S3バケット。ソース置き場(使わない)
- OutputBucket: S3バケット。アーティファクト(使わない)
- ECRRepository: ECRリポジトリ。DockerイメージをPushします
- CodeBuildServiceRole: CodeBuildで利用するサービスロール
- CodeBuildProject: CodeBuildのプロジェクト
InputBucket
とOutputBucket
は利用しないのですが、CodeBuildのプロジェクトを作成・実行する際に必須となるので用意しています。
テンプレート作成するのに下記を参考にさせてもらいました。
AWS CodeBuildを使ってDockerイメージをビルドし、Amazon EC2 Container Registry(ECR)へpushする | DevelopersIO
https://dev.classmethod.jp/tool/docker/20170225-codebuild-docker/
CodeBuild で Docker イメージに Git のコミットIDをタグ付けてバージョン管理する | DevelopersIO
https://dev.classmethod.jp/cloud/aws/docker-image-tag-git-commit-id-by-codebuild/
DockerイメージをCodeBuildでビルドする場合、プロジェクト作成時にPrivilegedMode
を指定しないとだめだったのがポイントです。
CodeBuildでDocker in Dockerする(CloudFormation) – Qiita
https://qiita.com/sot528/items/ab0285b9907a29be840a
AWS::CodeBuild::Project Environment – AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-environment.html
ECRリポジトリにpositoryPolicyText
を指定していますが、これはPushしたイメージを別のCodeBuildでPullする場合に必要となります。
CodeBuild の Amazon ECR サンプル – AWS CodeBuild
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-ecr.html
template.yaml
--- AWSTemplateFormatVersion: 2010-09-09 Description: Create Unity ML-Agents Docker Image Parameters: ProjectName: Description: Project Name for CodeBuild Default: ml-agents-build-test Type: String InputBucketName: Description: Input Bucket Name Default: codebuild-input Type: String OutputBucketName: Description: Output Bucket Name Default: codebuild-output Type: String ECRRepositoryName: Description: ECR Repository Name Default: ml-agents Type: String Resources: InputBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub ${InputBucketName} AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True OutputBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub ${OutputBucketName} AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True ECRRepository: Type: AWS::ECR::Repository Properties: RepositoryName: !Sub ${ECRRepositoryName} RepositoryPolicyText: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - codebuild.amazonaws.com Action: - ecr:GetDownloadUrlForLayer - ecr:BatchGetImage - ecr:BatchCheckLayerAvailability CodeBuildServiceRole: Type: AWS::IAM::Role Properties: Path: / AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - codebuild.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: !Sub CodeBuildPolicy-${ProjectName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Resource: - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${ProjectName} - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${ProjectName}:* Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - Effect: Allow Resource: - !Sub arn:aws:s3:::codepipeline-${AWS::Region}-* Action: - s3:PutObject - s3:GetObject - s3:GetObjectVersion - Effect: Allow Resource: - !Sub arn:aws:s3:::${InputBucketName}/* Action: - s3:GetObject - s3:GetObjectVersion - Effect: Allow Resource: - !Sub arn:aws:s3:::${OutputBucketName}/* Action: - s3:PutObject - Effect: Allow Resource: - "*" Action: - ecr:BatchCheckLayerAvailability - ecr:CompleteLayerUpload - ecr:GetAuthorizationToken - ecr:InitiateLayerUpload - ecr:PutImage - ecr:UploadLayerPart CodeBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Ref ProjectName Description: this is a test prj ServiceRole: !Ref CodeBuildServiceRole Artifacts: Location: !Ref OutputBucketName Type: S3 Name: artifacts Path: !Sub ${ProjectName} NamespaceType: BUILD_ID Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:2.0 PrivilegedMode: True Source: Location: !Join [ "/", [ !Ref InputBucketName, "dummy.zip" ] ] Type: S3 TimeoutInMinutes: 10 Tags: - Key: Name Value: !Ref ProjectName
テンプレートが用意できたらAWS CLIでスタック作成します。サービスロールを作成するので--capabilities CAPABILITY_IAM
が必要になります。--stack-name
や--region
はお好みで。--parameters
を指定するとバケット名やプロジェクト名も指定できます。
> cd テンプレートがあるディレクトリ > aws cloudformation create-stack \ --stack-name kai-ml-agents-build \ --template-body file://template.yaml \ --capabilities CAPABILITY_IAM \ --region ap-northeast-1 \ --parameters '[ { "ParameterKey": "ProjectName", "ParameterValue": "ml-agents-build-test" }, { "ParameterKey": "InputBucketName", "ParameterValue": "kai-ml-agents-build-input" }, { "ParameterKey": "OutputBucketName", "ParameterValue": "kai-ml-agents-build-output" }, { "ParameterKey": "ECRRepositoryName", "ParameterValue": "ml-agents" } ]' { "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/kai-ml-agents-build/0fa901a0-f56f-11e9-b734-06fcc76a2472" }
スタック実行が完了したか確認します。"CREATE_COMPLETE"
になったらOK。
> aws cloudformation describe-stacks \ --region ap-northeast-1 \ --stack-name kai-ml-agents-build \ --query "Stacks[0].StackStatus" "CREATE_COMPLETE"
CodeBuildのビルド実行準備
作成したCodeBuildのプロジェクトでビルド実行するための前準備をします。
S3バケットにダミーファイルをアップロードする
Unity ML-Agentsのソースはビルド実行時に取得するので、ビルドに必要となるソースがありません。
それでも、CodeBuildでビルド実行するにはCFnでプロジェクト作成時に指定したSource.Location
のファイルがないとビルド実行時にダウンロードエラーとなるのでダミーのファイルを用意します。ファイルはZipファイルじゃないとだめでした。
> touch dummy.txt > zip dummy.zip dummy.txt adding: dummy.txt (stored 0%) > aws s3 cp dummy.zip s3://kai-ml-agents-build-input/ upload: ./dummy.zip to s3://kai-ml-agents-build-input/dummy.zip
buildspec.yamlを用意する
CodeBuildのプロジェクトでビルド実行する際の手順を記述したbuildspec.yaml
を用意します。
buildspec.yaml
version: 0.2 phases: install: runtime-versions: docker: 18 pre_build: commands: - echo Clone ML-Agents... - git clone https://github.com/Unity-Technologies/ml-agents.git -b $IMAGE_TAG --depth 1 - echo Logging in to Amazon ECR... - $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION) - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay& - timeout 15 sh -c "until docker info; do echo .; sleep 1; done" - AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text) build: commands: - docker build -t $ECR_REPOSITORY_NAME:$IMAGE_TAG ./ml-agents - docker tag $ECR_REPOSITORY_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:$IMAGE_TAG post_build: commands: - echo Pushing the Docker image... - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:$IMAGE_TAG
ポイントは以下となります。
DockerイメージをビルドするのにDockerデーモンを初期化する
DockerイメージをCodeBuildでビルドするのに、プロジェクト作成時にPrivilegedMode
を指定しましたが、ビルド時にもDockerデーモンを初期化する必要がありました。
AWS::CodeBuild::Project Environment – AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-environment.html
ビルドが Docker デーモンと連係動作できるように、Docker デーモンも起動する必要があります。これを行う 1 つの方法は、以下のビルドコマンドを実行してビルド仕様のインストールフェーズで Docker デーモンを初期化することです。(指定したビルド環境イメージの提供元が Docker 対応の AWS CodeBuild である場合は、これらのコマンドを実行しないでください。)
buildspec.yaml抜粋
pre_build: commands: (略) - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay& - timeout 15 sh -c "until docker info; do echo .; sleep 1; done" (略)
ビルド実行する
buildspec.yaml
が用意できたらCodeBuildのプロジェクトでビルド実行します。
だいたい10分くらいでビルド完了します。CFnでプロジェクト作成時にタイムアウト時間を10分にしましたが、念の為--timeout-in-minutes-override
オプションで20分に変更しています。
> aws codebuild start-build \ --region ap-northeast-1 \ --project-name ml-agents-build-test \ --buildspec-override file://buildspec.yaml \ --timeout-in-minutes-override 20 \ --environment-variables-override '[ { "name": "ECR_REPOSITORY_NAME", "value": "ml-agents", "type": "PLAINTEXT" }, { "name": "IMAGE_TAG", "value": "0.9.1", "type": "PLAINTEXT" } ]' { "build": { "id": "ml-agents-build-test:17bfb5c6-8c8e-480c-a445-9e5dbb4b6004", "arn": "arn:aws:codebuild:ap-northeast-1:xxxxxxxxxxxx:build/ml-agents-build-test:17bfb5c6-8c8e-480c-a445-9e5dbb4b6004", "startTime": 1571821284.995, "currentPhase": "QUEUED", "buildStatus": "IN_PROGRESS", (略)
aws codebuild batch-get-builds
コマンドでビルドが完了したか確認します。各フェーズのステータスがSUCCEEDED
で最後に"phaseType": "COMPLETED"
があったらビルド完了です。
> aws codebuild batch-get-builds \ --region ap-northeast-1 \ --ids ml-agents-build-test:17bfb5c6-8c8e-480c-a445-9e5dbb4b6004 \ --query "builds[0].phases" [ { "phaseStatus": "SUCCEEDED", "endTime": 1571821285.18, "phaseType": "SUBMITTED", "durationInSeconds": 0, "startTime": 1571821284.995 }, { "phaseStatus": "SUCCEEDED", "endTime": 1571821286.424, "phaseType": "QUEUED", "durationInSeconds": 1, "startTime": 1571821285.18 }, { "contexts": [ { "message": "", "statusCode": "" } ], "phaseType": "PROVISIONING", "phaseStatus": "SUCCEEDED", "durationInSeconds": 21, "startTime": 1571821286.424, "endTime": 1571821307.801 }, { "contexts": [ { "message": "", "statusCode": "" } ], "phaseType": "DOWNLOAD_SOURCE", "phaseStatus": "SUCCEEDED", "durationInSeconds": 0, "startTime": 1571821307.801, "endTime": 1571821308.509 }, { "contexts": [ { "message": "", "statusCode": "" } ], "phaseType": "INSTALL", "phaseStatus": "SUCCEEDED", "durationInSeconds": 0, "startTime": 1571821308.509, "endTime": 1571821308.667 }, { "contexts": [ { "message": "", "statusCode": "" } ], "phaseType": "PRE_BUILD", "phaseStatus": "SUCCEEDED", "durationInSeconds": 17, "startTime": 1571821308.667, "endTime": 1571821326.049 }, { "contexts": [ { "message": "", "statusCode": "" } ], "phaseType": "BUILD", "phaseStatus": "SUCCEEDED", "durationInSeconds": 744, "startTime": 1571821326.049, "endTime": 1571822070.764 }, { "contexts": [ { "message": "", "statusCode": "" } ], "phaseType": "POST_BUILD", "phaseStatus": "SUCCEEDED", "durationInSeconds": 38, "startTime": 1571822070.764, "endTime": 1571822109.51 }, { "contexts": [ { "message": "", "statusCode": "" } ], "phaseType": "UPLOAD_ARTIFACTS", "phaseStatus": "SUCCEEDED", "durationInSeconds": 0, "startTime": 1571822109.51, "endTime": 1571822109.701 }, { "contexts": [ { "message": "", "statusCode": "" } ], "phaseType": "FINALIZING", "phaseStatus": "SUCCEEDED", "durationInSeconds": 2, "startTime": 1571822109.701, "endTime": 1571822111.876 }, { "phaseType": "COMPLETED", "startTime": 1571822111.876 } ]
AWS ECRのリポジトリからイメージを取得する
AWS ECRのリポジトリにイメージが登録されたか確認して、実際にイメージを取得・利用してみます。<AWS_ACCOUNT_ID>
と<REGION>
は置き換えてください。
> aws ecr list-images \ --repository-name ml-agents \ --region <REGION> { "imageIds": [ { "imageTag": "0.9.1", "imageDigest": "sha256:b9da2732606536ada8d3eabe258ac44286ae8c0706c9325d008880a2f2855f1c" } ] } # デフォルトレジストリに対してDockerを認証する > $(aws ecr get-login --no-include-email --region <REGION>) WARNING! Using --password via the CLI is insecure. Use --password-stdin. Login Succeeded > docker pull <AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/ml-agents:0.9.1 (略) 1b38598abf23: Pull complete Digest: sha256:b9da2732606536ada8d3eabe258ac44286ae8c0706c9325d008880a2f2855f1c Status: Downloaded newer image for <AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/ml-agents:0.9.1 <AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/ml-agents:0.9.1 > docker run -it --rm \ <AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/ml-agents:0.9.1 ▄▄▄▓▓▓▓ ╓▓▓▓▓▓▓█▓▓▓▓▓ ,▄▄▄m▀▀▀' ,▓▓▓▀▓▓▄ ▓▓▓ ▓▓▌ ▄▓▓▓▀' ▄▓▓▀ ▓▓▓ ▄▄ ▄▄ ,▄▄ ▄▄▄▄ ,▄▄ ▄▓▓▌▄ ▄▄▄ ,▄▄ ▄▓▓▓▀ ▄▓▓▀ ▐▓▓▌ ▓▓▌ ▐▓▓ ▐▓▓▓▀▀▀▓▓▌ ▓▓▓ ▀▓▓▌▀ ^▓▓▌ ╒▓▓▌ ▄▓▓▓▓▓▄▄▄▄▄▄▄▄▓▓▓ ▓▀ ▓▓▌ ▐▓▓ ▐▓▓ ▓▓▓ ▓▓▓ ▓▓▌ ▐▓▓▄ ▓▓▌ ▀▓▓▓▓▀▀▀▀▀▀▀▀▀▀▓▓▄ ▓▓ ▓▓▌ ▐▓▓ ▐▓▓ ▓▓▓ ▓▓▓ ▓▓▌ ▐▓▓▐▓▓ ^█▓▓▓ ▀▓▓▄ ▐▓▓▌ ▓▓▓▓▄▓▓▓▓ ▐▓▓ ▓▓▓ ▓▓▓ ▓▓▓▄ ▓▓▓▓` '▀▓▓▓▄ ^▓▓▓ ▓▓▓ └▀▀▀▀ ▀▀ ^▀▀ `▀▀ `▀▀ '▀▀ ▐▓▓▌ ▀▀▀▀▓▄▄▄ ▓▓▓▓▓▓, ▓▓▓▓▀ `▀█▓▓▓▓▓▓▓▓▓▌ ¬`▀▀▀█▓ Usage: mlagents-learn <trainer-config-path> [options] mlagents-learn --help
Dockerコンテナでmlagents-learn
コマンドが実行されたのが確認できました。やったぜ
実際にML-Agentsを動作させる手順は下記をご参考ください。
DockerでUnity ML-Agentsを動作させる(v0.9.1対応) – Qiita
https://cloudpack.media/49085
参考
DockerイメージをCodeBuildでビルドするのに、プロジェクト作成時にPrivilegedMode
を指定しましたが、ビルド時にもDockerデーモンを初期化する必要がありました。
Google Cloud Buildを利用してUnity ML-AgentsのDockerイメージを作成する(v0.9.1対応) – Qiita
https://cloudpack.media/49196
AWS CodeBuildを使ってDockerイメージをビルドし、Amazon EC2 Container Registry(ECR)へpushする | DevelopersIO
https://dev.classmethod.jp/tool/docker/20170225-codebuild-docker/
CodeBuild で Docker イメージに Git のコミットIDをタグ付けてバージョン管理する | DevelopersIO
https://dev.classmethod.jp/cloud/aws/docker-image-tag-git-commit-id-by-codebuild/
CodeBuildでDocker in Dockerする(CloudFormation) – Qiita
https://qiita.com/sot528/items/ab0285b9907a29be840a
AWS::CodeBuild::Project Environment – AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-environment.html
Amazon ECR で AWS CLI を使用する – Amazon ECR
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/ECR_AWSCLI.html
CodeBuild のビルドの詳細を表示する – AWS CodeBuild
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/view-build-details.html#view-build-details-cli
ビルド環境の環境変数 – AWS CodeBuild
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-env-ref-env-vars.html
CodeBuildでビルドプロジェクトを作成する-AWS CodeBuild
https://docs.aws.amazon.com/codebuild/latest/userguide/create-project.html#create-project-cli
CodeBuild のビルドの詳細を表示する – AWS CodeBuild
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/view-build-details.html
CodeBuild のビルド仕様に関するリファレンス – AWS CodeBuild
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html#runtime-versions-buildspec-file
CodeBuild でビルドを実行する – AWS CodeBuild
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/run-build.html#run-build-cli
CodeBuild の Docker サンプル – AWS CodeBuild
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-docker.html
Amazon ECR レジストリ – Amazon ECR
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/Registries.html#registry_auth
CodeBuild の Amazon ECR サンプル – AWS CodeBuild
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-ecr.html
元記事はこちら
「AWS CodeBuildを利用してUnity ML-AgentsのDockerイメージを作成する(v0.9.1対応)」