【问题标题】:Push docker image to ECR using cloudformation使用 cloudformation 将 docker 镜像推送到 ECR
【发布时间】:2018-09-14 18:59:53
【问题描述】:

我是 Devops 的新手,所以如果您觉得这个问题很尴尬,请不要介意。

作为 gitci 的一部分。我在 gitlab 中有一个 docker 文件。我打算创建一个 docker 映像并将其推送到 ECR,然后使用该映像进行批处理。

我已经使用 ECR 中的现有图像完成了批处理部分。但无法使用 cloudformation 创建 docker image n push。

请指导我。我应该在 init 中使用命令吗?

提前感谢大师

【问题讨论】:

    标签: amazon-cloudformation gitlab-ci docker-registry


    【解决方案1】:

    我在工作中遇到了同样的问题,并且偶然发现了这个已经提出的问题,但没有正确的答案,所以我将说明我是如何做到的。

    基线:你不能用 cloudformation 做到这一点,cloudformation 用于创建基础设施和自动化。不过,您可以使用 codebuild 完成此操作,并且可以使用 cloudformation 创建 codebuild 项目。这个repository 是一个实际的例子。

    您要做的是:创建一个 cloudformation 模板来创建一个代码构建项目,并在您的代码构建中创建一个 buildspec.yml(指定构建的文件),它将您的图像推送到 ECR。

    codebuild 项目如下所示:

    CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Description: "Codebuild project to push flask api image to ecr"
      Environment:
        ComputeType:
          !FindInMap [CodeBuildComputeTypeMap, !Ref GithubBranch, type]
        EnvironmentVariables:
          - Name: AWS_DEFAULT_REGION
            Value: !Ref AWS::Region
          - Name: AWS_ACCOUNT_ID
            Value: !Ref "AWS::AccountId"
          - Name: AWS_ECR_REPOSITORY_URI
            Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${EcrRepository}
          - Name: IMAGE_REPO_NAME
            Value: !Ref GithubRepository
          - Name: IMAGE_TAG
            Value: "latest"
        Image: "aws/codebuild/standard:5.0"
        PrivilegedMode: true
        Type: "LINUX_CONTAINER"
      ServiceRole: !GetAtt CodeBuildRole.Arn
      Source:
        Type: "CODEPIPELINE"
        BuildSpec: buildspec.yml
    
    EcrRepository:
         Type: AWS::ECR::Repository
         Properties:
           RepositoryName: !Ref GithubRepository
    
    CodeBuildRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codebuild.amazonaws.com
            Action:
              - "sts:AssumeRole"
      Policies:
        - PolicyName: "PushImageToEcr"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ecr:BatchGetImage
                  - ecr:BatchCheckLayerAvailability
                  - ecr:CompleteLayerUpload
                  - ecr:GetDownloadUrlForLayer
                  - ecr:InitiateLayerUpload
                  - ecr:PutImage
                  - ecr:UploadLayerPart
                  - ecr:GetAuthorizationToken
                Resource: "*"
        - PolicyName: "CodeBuildLogsRole"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*"
        - PolicyName: "GetAndPutArtifacts"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Action:
                  - s3:GetObject
                  - s3:PutObject
                  - s3:ListBucket
                Resource:
                  - !GetAtt ArtifactBucket.Arn
                  - !Sub ${ArtifactBucket.Arn}/*
    
    ArtifactBucket:
        Type: AWS::S3::Bucket
    

    这应该进入 cloudformation 的 Resources 部分,并将创建代码构建项目、ecr 存储库、代码构建服务角色和工件的 s3 存储桶。

    然后你需要一个 buildspec.yml 模板来推送你的图片,它看起来像这样:

    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...
          - cd app/
          - 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
    

    【讨论】:

      【解决方案2】:

      您将无法使用 CloudFormation 执行此操作,因为它不打算执行这种操作方式。

      但是,您提到您正在使用 gitlab-ci。这意味着您可以轻松创建构建 docker 映像并将其上传到 ECR 的作业。

      在我看来,创建处理 Docker 映像的构建和上传的 CodeBuild 项目(使用 CloudFormation、IaC FTW!)更加容易。 CodeBuild 优于 GitLab-ci 的优势在于,您将能够为 CodeBuild 工作人员提供适当的 ECR 访问权限,以便将图像上传到存储库。

      【讨论】:

      • 您认为将 buildspec.yml 直接放入您的 cloudformation 模板还是在存储库中为该用例保留一个 buildspec 文件更好?
      • 这是一个很好的问题 JIMPRO,我认为拥有它的存储库可以为您提供更大的灵活性,您可以为不同的分支使用不同的构建规范。但是,如果 repo 的维护者不是自动化的直接利益相关者(可能出于安全考虑),您可以在 CodeBuild 项目定义中“隐藏”构建规范。
      猜你喜欢
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多