Jenkins 建構Docker image傳入AWS ECR

Jenkins 建構Docker image傳入AWS ECR

目前在Container image倉庫 是使用 Harbor ,但擔心有天異常而造成損失所以才打算使用AWS Elastic Container Registry(ECR),而以下是建構過程。

容器化Jenkins

因為容器會調用宿主機的Docker,以及方便管理容器也會安裝docker-compose,所以要先在宿主機安裝這兩樣以下提供一鍵安裝指令。

# install Docker
curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh get-docker.sh 

# install Docker-Compose
curl -L "https://github.com/docker/compose/releases/download/v2.30.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose

以下準備進行安裝 請注意安裝目錄為

├── docker-compose.yml
├── jenkins
│   ├── Dockerfile
│   └── conf
  # 若無想要把容器內的數據保留下來 可以註解 jenkins-data這段 
services:
  jenkins:
    build:
      context: jenkins
      dockerfile: Dockerfile
    container_name: jenkins
    restart: always
    volumes:
      - jenkins-data:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - 9000:8080

volumes:
  jenkins-data:
FROM jenkins/jenkins:lts

ARG TARGETARCH

# 確保 jenkins_home 權限正確
RUN mkdir -p /var/jenkins_home && \
    chown -R jenkins:jenkins /var/jenkins_home && \
    chmod -R 755 /var/jenkins_home
USER root
RUN apt update && \
    apt-get install -y \
    python3 \
    python3-pip \
    python3-setuptools \
    ansible \
    groff \
    less \
    curl \
    unzip \
    vim \
    sshpass \
    && curl -fsSL https://get.docker.com | sh \
    && usermod -aG docker jenkins 

RUN case "${TARGETARCH}" in \
    amd64) ARCH='x86_64' ;; \
    arm64) ARCH='aarch64' ;; \
    *) echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \
    esac && \
    curl "https://awscli.amazonaws.com/awscli-exe-linux-${ARCH}.zip" -o "awscliv2.zip" && \
    unzip awscliv2.zip && \
    ./aws/install

USER jenkins

而本次在Jenkins Plug 依賴套件 總共使用到這些

  • AWS Credentials
  • Amazon ECR
  • Docker Pipeline

在安裝時 可以先執行以下步驟

  1. 創建 AWS AMI 並且給予 AmazonEC2ContainerRegistryFullAccess 權限即可,之後再去創建訪問密鑰。
  1. 將創建好的 AWS key 輸入至裡面

以下提供一個 Jenkinsfile範例,上面environment 可以設置自己的資訊即可。

pipeline {
    agent any

    environment {
        //aws
        AWS_ECR_REPO="1238542.dkr.ecr.ap-southeast-1.amazonaws.com/test"
        AWS_REGION="ap-southeast-1"
        
        // 版本標籤
        // IMAGE_TAG = "${BUILD_NUMBER}"
        DEV_BRANCH_IMAGE_TAG = "dev"
        TEST_BRANCH_IMAGE_TAG = "test"
        MASTER_BRANCH_IMAGE_TAG = "master"

        // 不使用docker buildx
        DOCKER_BUILDKIT = "0"
    }

    stages {
        stage('建立鏡像'){
            steps{
                script{
                    docker.build(
                        "${AWS_ECR_REPO}:${TEST_BRANCH_IMAGE_TAG}",
                        """--label 'git.commit=${gitCommitMessage}' \
                        -f dockerfile ."""
                    )
                }
            }
        }     

        stage('推送aws') {
            steps {
                script{
                    withCredentials([[
                        $class: 'AmazonWebServicesCredentialsBinding',
                        credentialsId: 'aws-credentials',
                        accessKeyVariable: 'AWS_ACCESS_KEY_ID',
                        secretKeyVariable: 'AWS_SECRET_ACCESS_KEY'
                    ]]) {
                        def dockerImage
                            
                        // ECR 登入
                        def ecrLogin = sh(script: "aws ecr get-login-password --region ${AWS_REGION}", returnStdout: true).trim()
                        
                        docker.withRegistry("https://${AWS_ECR_REPO}", "ecr:${AWS_REGION}:aws-credentials") {
                            // 建構映像
                            dockerImage = docker.build("${AWS_ECR_REPO}:${TEST_BRANCH_IMAGE_TAG}")   
                            
                            // 推送到 ECR
                            dockerImage.push()
                        }
                    }
                }
            }
        }
    }
}