构建容器镜像

在之前的实验中我们把Java应用部署到EC2上。本节我们将修改流水线,使用CodeBuild来构建Docker镜像,并将它发布到Elastic Container Registry (ECR)仓库:

Container Diagram

添加Dockerfile

首先我们需要在项目下添加一个Dockerfile,里面声明如何构建我们的容器镜像。

回到Cloud 9,在项目根目录下新建Dockerfile,内容如下:

FROM public.ecr.aws/bitnami/tomcat:9.0

COPY ./target/unicorn-web-project.war /usr/local/tomcat/webapps/ROOT.war

image-20220312162724575

在同目录下新建buildspec_docker.yml文件,内容如下。这个文件中声明了构建容器镜像的命令,并将它推到ECR。

version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...          
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG      
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG  

修改buildspec.yml文件,将上面的两个文件加入到构建生成的zip包中:

version: 0.2

phases:
  install:
    runtime-versions:
      java: corretto8
  build:
    commands:
      - echo Build started on `date`
      - mvn test
  post_build:
    commands:
      - echo Build completed on `date`
      - mvn package
artifacts:
  files:
    - target/unicorn-web-project.war
    - appspec.yml
    - scripts/**/*
    - Dockerfile
    - buildspec_docker.yml
  discard-paths: no

提交更改:

git add *
git commit -m "Adding container support"
git push -u origin main

创建ECR仓库

进入ECR( Elastic Container Registry )服务, 点击Create repository

image-20220312163254986

将仓库命名为java-app, 其他保持默认,点击Create repository

image-20220312163353041

创建新的CodeBuild项目

现在我们需要创建一个新的CodeBuild项目,它使用buildspec_docker.yml来构建我们的镜像并将其发布到ECR中。

切换到CodeBuild页面,点击Create build project:

image-20220312163439766

项目名称为java-container-builder, 使用S3作为Source provider,桶名为之前创建的那个, S3 object key = unicorn-web-build.zip

image-20220312163551783

Environment配置

  • Environment image = Managed image
  • Operating system = Amazon Linux 2
  • Runtime = Standard
  • Image = aws/codebuild/amazonlinux2-x86_64-standard:3.0
  • Image version = Always use the latest image for this runtime version
  • Environment Type = Linux
  • Privileged = 打钩,对于Docker构建必须选择这个
  • Service role = New service role (使用默认名称)

image-20220312170400212

展开Additional configuration选项,添加以下环境变量:

  • Name = AWS_DEFAULT_REGION; Value = <your-region e.g. eu-west-1>
  • Name = AWS_ACCOUNT_ID; Value = <your account id>
  • Name = IMAGE_REPO_NAME; Value = java-app
  • Name = IMAGE_TAG; Value = latest

image-20220312163832134

Buildspecs配置: Buildspec name = buildspec_docker.yml

Artifacts选择:Type = No artifacts

image-20220312165029742

Logs配置:

  • Group name = unicorn-build-logs
  • Stream name = container

image-20220312163941795

点击 Create build project

添加IAM权限

在上面创建CodeBuild项目时,为我们自动创建好了一个codebuild-java-container-builder-service-role, 但这个role默认没有访问ECR的权限,我们需要手动为其添加上去

进入到IAM页面,搜索codebuild-unicorn-web-build-container-service-role并进入:

image-20220312165833379

添加一条inline policy:

image-20220312165856320

内容如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:CompleteLayerUpload",
                "ecr:GetAuthorizationToken",
                "ecr:InitiateLayerUpload",
                "ecr:PutImage",
                "ecr:UploadLayerPart"
            ],
            "Resource": "*"
        }
    ]
}

image-20220312164147310

进入下一步,命名为ECRPush并保存

测试CodeBuild项目

在进入测试之前,我们需要S3中的zip文件先包含Dockerfile,所以不得不重新运行一次之前的unicorn-web-build 项目

进入CodeBuild页面,进入unicorn-web-build项目,点击Start build,等待其构建完成。

image-20220312164449577

回到我们刚才创建的java-container-builder项目,点击Start build

image-20220312164819994

等待构建完成,回到ECR页面,会发现里面有一个新的镜像:

image-20220312170719896

恭喜,目前你已将web应用打包成镜像并可以将它部署到容器平台(例如ECS)上,本Workshop中不继续做详细介绍。