본문 바로가기

개발하자

젠킨스를 사용하여 kubernetes 배포 업데이트

반응형

젠킨스를 사용하여 kubernetes 배포 업데이트

Kubernetes Cluster에서 배포를 배포하고 업그레이드하는 데 사용하고 있습니다. 파이프라인을 사용하고 있는데 이건 젠킨스 파일입니다:

pipeline {
    environment {
        JOB_NAME = "${JOB_NAME}".replace("-deploy", "")
        REGISTRY = "my-docker-registry"
    }
    agent any
    stages {
        stage('Fetching kubernetes config files') {
            steps {
                git 'git_url_of_k8s_configurations'
            }
        }
        stage('Deploy on kubernetes') {
            steps {
                kubernetesDeploy(
                    kubeconfigId: 'k8s-default-namespace-config-id',
                    configs: 'deployment.yml',
                    enableConfigSubstitution: true
                )
            }
        }
    }
}

Deployment.yml 대신 다음과 같습니다:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: ${JOB_NAME}
spec:
  replicas: 1
  template:
    metadata:
      labels:
        build_number: ${BUILD_NUMBER}
        app: ${JOB_NAME}
        role: rolling-update
    spec:
      containers:
      - name: ${JOB_NAME}-container        
        image: ${REGISTRY}/${JOB_NAME}:latest
        ports:
        - containerPort: 8080
        envFrom:
            - configMapRef:
                name: postgres
      imagePullSecrets:
      - name: regcred
  strategy:
    type: RollingUpdate

Kubernetes가 Deployment가 변경되었다는 것을 이해하도록 하기 위해 (그래서 그것과 포드를 업그레이드하기 위해) Jenkins 빌드 번호를 주석으로 사용했다:

...
metadata:
  labels:
    build_number: ${BUILD_NUMBER}
...

문제나 나의 오해:

배포가 Kubernetes에 없는 경우에는 배포와 복제 세트를 하나씩 생성하여 모든 것이 정상적으로 작동합니다.

배포가 여전히 존재하고 업그레이드가 적용된 경우 Kubernetes는 다음과 같은 새 ReplicaSet을(를):

첫 배포 전

before first deploy

첫 배포

first deploy

2차 배포

second deploy

세 번째 배포

enter image description here

보시다시피 Jenkins 배포판은 배포판을 올바르게 업데이트하지만 이전 배포판을 제거하지 않고 새 ReplicaSet을 만듭니다.

무엇이 문제가 될 수 있을까요?




예상되는 동작입니다. 배포를 업데이트할 때마다 새 복제 세트가 만들어집니다. 그러나 업데이트된 Deployment에서 문제가 발생한 경우 이전 상태로 롤백할 수 있도록 이전 ReplicaSet가 유지됩니다.

참조:

그러나 ReplicaSet을 통과 필드에 보관할 수 있는 수를 제한할 수 있습니다. 기본값은 10입니다. 참조:




견본 파이프라인

pipeline {
    agent any
    tools {nodejs "node"}
    environment {
        CI = 'true'
        PROJECT_ID = 'marshmallow'
        CLUSTER_NAME = 'cluster-1'
        LOCATION = 'us-central1-c'
        CREDENTIALS_ID = 'kubernetes'
        DOCKER_FILE_PATH="${FOLDER_NAME}/Dockerfile"
        SERVICE_NAME='auth'
        FOLDER_NAME='prod-config'
        K8_FILE_PATH="${FOLDER_NAME}/k8.yaml"
        IMAGE_TAG = "us.gcr.io/${PROJECT_ID}/${SERVICE_NAME}:${env.BUILD_NUMBER}"
    }
    
    stages {
        stage('Scm Checkout') {
            steps {
                checkout scm
            }
        }
        stage('Build') {
            steps {
                dir("${SERVICE_NAME}/"){
                  sh 'npm install'
                }
            }
        }
        
        stage('Build Docker Image') {
            steps {
                sh 'whoami'
                script {
                    dockerImage = docker.build("${IMAGE_TAG}","-f ${SERVICE_NAME}/${DOCKER_FILE_PATH} ${SERVICE_NAME}")
                }
            }
        }
        

        stage("Push Docker Image") {
            steps {
                script {
                    echo "Push Docker Image"
                    docker.withRegistry('https://us.gcr.io', "gcr:google-container-registry") {
                    dockerImage.push()
                }
                    
                }
            }
        }

        stage('Change image version') {
            steps {
                dir("${SERVICE_NAME}/prod-config"){
                  sh """
                    cat k8.yaml | grep image
                    sed -i 's|image: .*|image: "${IMAGE_TAG}"|' k8.yaml
                    cat k8.yaml | grep image
                    """
                }
            }
        }
        stage('Deploy to K8s') {
            steps{
                echo "Deployment started ..."
                sh 'ls -ltr'
                sh 'pwd'
                echo "Start deployment of ${SERVICE_NAME} service."
                step([
                    $class: 'KubernetesEngineBuilder',
                    projectId: env.PROJECT_ID, 
                    clusterName: env.CLUSTER_NAME, 
                    location: env.LOCATION, 
                    manifestPattern: "${SERVICE_NAME}/${K8_FILE_PATH}",
                    credentialsId: env.CREDENTIALS_ID, 
                    // verifyDeployments: true 
                 ])
                echo "Deployment Finished ..."
            }
        }
    }
    post {
        always {
           echo "Deleting docker iamge ..."
           sh "docker rmi -f ${IMAGE_TAG}"

        }
    }
}

반응형