Jenkins

Jenkins 개요

  • Jenkins is a free and open source automation server
  • It helps automate the parts of software development related to building, testing and deploying, facilitating continuous integration and continuous delivery

Jenkins 특징

  • 오픈소스인 자동화 서버
  • 다양한 플러그인 제공
    • Pipeline
    • Authentication / Authorization
    • Git
    • Docker
  • 다양하게 확장

Jenkins 설치 및 실행 with Docker-compose

Jenkins Pipeline of Sample

  • pipeline {
    	agent any
    	stages {
    		stage("Build") {
    			steps {
    				echo "Jenkins Pipeline running"
    			}
    		}
    	}
    }

Jenkins Pipeline

Jenkins Pipeline 개요

  • Jenkins 2.x or later (older versions back to 1.642.3 may work but are not recommended)
  • Required Plugin 'Pipeline plugin'
  • Support CD
  • Pipeline as code (DSL, Jenkinsfile)

Jenkins Pipeline Script

  • Scripted pipeline

    • inject groovy script
    • Java API reference
  • Declarative pipeline (recommended)

    • Jenkins DSL
    • Isolate complex logic into Jenkins plugin
  • Jenkins Pipeline Syntax

    • Section

      • agent
        • pipeline or stage가 실행될 노드 지정
          • node
          • any
          • label
          • node
          • docker
          • dockerfile
          • kubernetes
      • stages
        • 순차적인 작업의 명세인 stage들의 묶음
      • steps
        • stage안에서의 실행되는 단계
      • post
        • 위치에 따라 stages들의 작업이 끝난 후 추가적인 steps 혹은 stage에 steps들의 작업이 끝난 후 추가적인 step
        • Condition
          • always
          • changed
          • fixed
          • regression
          • aborted
          • failure
          • success
          • unstable
          • unsuccessful
          • cleanup
    • Directive

      • parameters
        • key = value
        • pipeline 내부에서 사용할 환경변수
        • credentials()를 통해 Jenkins credential에 접근 가능
      • environments
        • pipeline을 trigger할 때 입력 받아야 할 변수를 정의
        • Type
          • string
          • text
          • booleanParam
          • choice
          • password
      • when
        • stage를 실핼 할 조건 설정
      • ...

Jenkins Pipeline Overview

Jenkins 설치 with Docker

  • https://github.com/Sanses/devops_06_03_jenkins/blob/master/src/jenkins_remote_docker/Dockerfile

    Dockerfile
    FROM jenkins/jenkins:lts
    ARG DOCKER_GID=1000
    USER root
    
    # docker install
    COPY scripts/install_docker.sh /install_docker.sh
    RUN chmod +x /install_docker.sh && \
        /install_docker.sh
    
    # aws cli install
    COPY scripts/install_aws.sh /install_aws.sh
    RUN chmod +x /install_aws.sh && \
        /install_aws.sh
    
    # set jenkins user to host docker group
    RUN /usr/sbin/groupadd -g ${DOCKER_GID:-1000} -f docker && \
        /usr/sbin/usermod -aG docker jenkins
    
    USER jenkins
    docker-compose.yml
    version: '3.8'
    services:
      jenkins:
        build:
          context: ""
          args:
            DOCKER_GID: ${DOCKER_GID}
        container_name: jenkins
        environment:
          TZ: "Asia/Seoul"
          JAVA_OPTS: "-Dhudson.model.DownloadService.noSignatureCheck=true"
          DOCKER_GID: ${DOCKER_GID}
        ports:
          - "8080:8080"
        volumes:
          - "./data:/var/jenkins_home"
          - "/var/run/docker.sock:/var/run/docker.sock"

Jenkins Pipeline - Jenkinsfile

  • https://github.com/Sanses/devops_sample_app_python/blob/master/deploy/Jenkinsfile

    pipeline {
      agent { label 'master' }
    
      parameters {
        booleanParam(name : 'BUILD_DOCKER_IMAGE', defaultValue : true, description : 'BUILD_DOCKER_IMAGE')
        booleanParam(name : 'RUN_TEST', defaultValue : true, description : 'RUN_TEST')
        booleanParam(name : 'PUSH_DOCKER_IMAGE', defaultValue : true, description : 'PUSH_DOCKER_IMAGE')
        booleanParam(name : 'PROMPT_FOR_DEPLOY', defaultValue : false, description : 'PROMPT_FOR_DEPLOY')
        booleanParam(name : 'DEPLOY_WORKLOAD', defaultValue : true, description : 'DEPLOY_WORKLOAD')
    
        // CI
        string(name : 'AWS_ACCOUNT_ID', defaultValue : '657976307134', description : 'AWS_ACCOUNT_ID')
        string(name : 'DOCKER_IMAGE_NAME', defaultValue : 'demo', description : 'DOCKER_IMAGE_NAME')
        string(name : 'DOCKER_TAG', defaultValue : '1.0.0', description : 'DOCKER_TAG')
    
        // CD
        string(name : 'TARGET_SVR_USER', defaultValue : 'ec2-user', description : 'TARGET_SVR_USER')
        string(name : 'TARGET_SVR_PATH', defaultValue : '/home/ec2-user/', description : 'TARGET_SVR_PATH')
        string(name : 'TARGET_SVR', defaultValue : '10.0.3.61', description : 'TARGET_SVR')
      }
    
      environment {
        REGION = "ap-northeast-2"
        ECR_REPOSITORY = "${params.AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com"
        ECR_DOCKER_IMAGE = "${ECR_REPOSITORY}/${params.DOCKER_IMAGE_NAME}"
        ECR_DOCKER_TAG = "${params.DOCKER_TAG}"
      }
    
      stages {
        stage('============ Build Docker Image ============') {
            when { expression { return params.BUILD_DOCKER_IMAGE } }
            agent { label 'build' }
            steps {
                dir("${env.WORKSPACE}") {
                    sh 'docker build -t ${ECR_DOCKER_IMAGE}:${ECR_DOCKER_TAG} .'
                }
            }
            post {
                always {
                    echo "Docker build success!"
                }
            }
        }
        stage('============ Run test code ============') {
            when { expression { return params.RUN_TEST } }
            agent { label 'build' }
            steps {
                sh'''
                    aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ECR_REPOSITORY}
                    docker run --rm ${ECR_DOCKER_IMAGE}:${ECR_DOCKER_TAG} /root/.local/bin/pytest -v
                '''
            }
        }
        stage('============ Push Docker Image ============') {
            when { expression { return params.PUSH_DOCKER_IMAGE } }
            agent { label 'build' }
            steps {
                echo "Push Docker Image to ECR"
                sh'''
                    aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ECR_REPOSITORY}
                    docker push ${ECR_DOCKER_IMAGE}:${ECR_DOCKER_TAG}
                '''
            }
        }
        stage('Prompt for deploy') {
            when { expression { return params.PROMPT_FOR_DEPLOY } }
            agent { label 'deploy' }
            steps {
                script {
                    env.APPROAL_NUM = input message: 'Please enter the approval number',
                                      parameters: [string(defaultValue: '',
                                                   description: '',
                                                   name: 'APPROVAL_NUM')]
                }
    
                echo "${env.APPROAL_NUM}"
            }
        }
        stage('============ Deploy workload ============') {
            when { expression { return params.DEPLOY_WORKLOAD } }
            agent { label 'deploy' }
            steps {
                sshagent (credentials: ['aws_ec2_user_ssh']) {
                    sh """#!/bin/bash
                        scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
                            deploy/docker-compose.yml \
                            ${params.TARGET_SVR_USER}@${params.TARGET_SVR}:${params.TARGET_SVR_PATH};
    
                        ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
                            ${params.TARGET_SVR_USER}@${params.TARGET_SVR} \
                            'aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ECR_REPOSITORY}; \
                             export IMAGE=${ECR_DOCKER_IMAGE}; \
                             export TAG=${ECR_DOCKER_TAG}; \
                             docker-compose -f docker-compose.yml down;
                             docker-compose -f docker-compose.yml up -d';
                    """
                }
            }
        }
      }
    
      post {
        failure {
          slackSend(
            channel: "#jenkins_test",
            color: "danger",
            message: "[Failed] Job:${env.JOB_NAME}, Build num:#${env.BUILD_NUMBER} @channel (<${env.RUN_DISPLAY_URL}|open job detail>)"
          )
        }
      }
    }


  • No labels

1 Comment

  1. Anonymous

    1. You are not logged in. Any changes you make will be marked as anonymous. You may want to Log In if you already have an account.