تعلم نشر الخدمات الصغيرة. الجزء 4. جنكينز


مرحبا يا هابر!


" ", Jenkins . Jenkins , Docker-, Docker- . Jenkins , Helm ( ).


:


  1. Spring Boot, Docker


    : Java 11, Spring Boot, Docker, image optimization


  2. Kubernetes Google Kubernetes Engine


    : Kubernetes, GKE, resource management, autoscaling, secrets


  3. Helm 3


    : Helm 3, chart deployment


  4. Jenkins


    : Jenkins configuration, plugins, separate configs repository



Jenkins — , Java. - . Groovy, (Jenkinsfile) . , , .


GitHub .


Jenkins



Jenkins:


  • war-
  • Docker-
  • Kubernetes

War- (№ Apache Tomcat). , .


, Jenkins Docker. Jenkins , . — ( ), 'docker:dind', Jenkins'.


Jenkins Kubernetes. Jenkins, . , . . Jenkins Google Kubernetes Engine .


, Jenkins Docker . , stateful Kubernetes. Jenkins Kubernetes.


, Jenkins . , , Google Compute Engine. , Jenkins Raspberry Pi, - "" Docker-. Raspberry Pi .


docker network create jenkins

docker volume create jenkins-docker-certs
docker volume create jenkins-data

docker container run \
  --name jenkins-docker \
  --detach \
  --privileged \
  --network jenkins \
  --network-alias docker \
  --env DOCKER_TLS_CERTDIR=/certs \
  --volume jenkins-docker-certs:/certs/client \
  --volume jenkins-data:/var/jenkins_home \
  --publish 2376:2376 \
  docker:dind

docker container run \
  --name jenkins-blueocean \
  --detach \
  --network jenkins \
  --env DOCKER_HOST=tcp://docker:2376 \
  --env DOCKER_CERT_PATH=/certs/client \
  --env DOCKER_TLS_VERIFY=1 \
  --publish 8080:8080 \
  --publish 50000:50000 \
  --volume jenkins-data:/var/jenkins_home \
  --volume jenkins-docker-certs:/certs/client:ro \
  jenkinsci/blueocean

Jenkins http://localhost:8080/ . Jenkins UI, . " " (IaC). — Groovy. . .



(Manage Jenkins -> Manage Plugins). . 'Blue Ocean', .


: Remote File Plugin Kubernetes CLI. Remote File Plugin Jenkinsfile , Kubernetes CLI kubectl .


Helm


Helm-, Helm. Helm , . (docker exec -it jenkins-blueocean bash), /usr/bin. Helm-:


helm repo add msvc-repo https://anshelen.imtqy.com/microservices-deploy/
helm repo update


, . , . , , Jenkins. , — .


(Manage Jenkins -> Configure System -> Global properties -> Environment Variables):


  • CLUSTER_URL — - Kubernetes. kubectl cluster-info
  • CLUSTER_NAMESPACE —
  • HELM_PROJECT — Helm
  • HELM_CHART — Helm-. 'msvc-repo/msvc-chart'


Jenkins , , -, , . Credentials -> System -> Global credentials -> Add Credentials:


github-credsusername with password/ git-
dockerhub-credsusername with password/ Docker-
kubernetes-credssecret text

NOTES.txt . , Helm- (helm status msvc-project).



, Groovy, . .


Jenkins () (stage). (agent).


:


  1. Build.
  2. Test. . , Maven
  3. Package. jar-
  4. Push Images. Docker- . — latest
  5. Trigger Kubernetes. Kubernetes Docker-



:


pipeline {
  agent none
  options { ... }
  environment { ... }
  stages {
    stage("Prepare container") {
      agent {
        docker {
          image 'openjdk:11.0.5-slim'
          args '-v $HOME/.m2:/root/.m2'
        }
      }
      stages {
        stage('Build') { ... }
        stage('Test') { ... }
        stage('Package') { ... }
      }
    }

    stage('Push images') {
      agent any
      when { branch 'master' }
      steps { ... }
    }

    stage('Trigger kubernetes') {
      agent any
      when { branch 'master' }
      steps { ... }
    }
  }
}

Jenkins "" — , . pipeline . , . pipeline 'none'. , - .


Build, Test Package Docker- . Docker- Java 11 (Jenkins Java 8). , 'Prepare container' 'docker'. args .m2 Jenkins'. .m2 Maven, , .


Push Images Trigger Kubernetes 'any'. , . Jenkins'. - (when { branch 'master' }).


, options environment.



options {
  skipStagesAfterUnstable()
  skipDefaultCheckout()
}

. :


  • skipStagesAfterUnstable Jenkins , e . UNSTABLE . .


  • skipDefaultCheckout . Jenkins force ( Prepare Checkout, Push images Trigger Kubernetes). . . — Build. skipDefaultCheckout, . , Jenkins . , , Build Test.




environment {
  IMAGE_BASE = 'anshelen/microservices-backend'
  IMAGE_TAG = "v$BUILD_NUMBER"
  IMAGE_NAME = "${env.IMAGE_BASE}:${env.IMAGE_TAG}"
  IMAGE_NAME_LATEST = "${env.IMAGE_BASE}:latest"
  DOCKERFILE_NAME = "Dockerfile-packaged"
}

, . , - . Docker-.


latest , , - . , , . IMAGE_TAG , BUILD_NUMBER. , ( ). BUILD_NUMBER , "". — . , .


, ,


stage("Prepare container") {
  agent {
    docker {
      image 'openjdk:11.0.5-slim'
      args '-v $HOME/.m2:/root/.m2'
    }
  }
  stages {
    stage('Build') {
      steps {
        checkout scm
        sh './mvnw compile'
      }
    }
    stage('Test') {
      steps {
        sh './mvnw test'
        junit '**/target/surefire-reports/TEST-*.xml'
      }
    }
    stage('Package') {
      steps {
        sh './mvnw package -DskipTests'
      }
    }
  }
}

, , . Maven , .


checkout scm. , Jenkins. bash- .


junit '**/target/surefire-reports/TEST-*.xml' Jenkins' . -.


jar- .


Docker-


Docker- . Jenkins, Maven-.


- , . - . , Jenkins. Dockerfile-packaged.


Dockerfile
FROM adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine as builder
ADD . /src
WORKDIR /src
RUN ./mvnw package -DskipTests

FROM alpine:3.10.3 as packager
RUN apk --no-cache add openjdk11-jdk openjdk11-jmods
ENV JAVA_MINIMAL="/opt/java-minimal"
# build minimal JRE
RUN /usr/lib/jvm/java-11-openjdk/bin/jlink \
    --verbose \
    --add-modules \
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument \
    --compress 2 --strip-debug --no-header-files --no-man-pages \
    --release-info="add:IMPLEMENTOR=radistao:IMPLEMENTOR_VERSION=radistao_JRE" \
    --output "$JAVA_MINIMAL"

FROM alpine:3.10.3
LABEL maintainer="Anton Shelenkov anshelen@yandex.ru"
ENV JAVA_HOME=/opt/java-minimal
ENV PATH="$PATH:$JAVA_HOME/bin"
COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
COPY --from=builder /src/target/microservices-backend-*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

Dockerfile-packaged:


FROM alpine:3.10.3 as packager
RUN apk --no-cache add openjdk11-jdk openjdk11-jmods
ENV JAVA_MINIMAL="/opt/java-minimal"
# build minimal JRE
RUN /usr/lib/jvm/java-11-openjdk/bin/jlink \
    --verbose \
    --add-modules \
        java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument \
    --compress 2 --strip-debug --no-header-files --no-man-pages \
    --release-info="add:IMPLEMENTOR=radistao:IMPLEMENTOR_VERSION=radistao_JRE" \
    --output "$JAVA_MINIMAL"

FROM alpine:3.10.3
LABEL maintainer="Anton Shelenkov anshelen@yandex.ru"
ENV JAVA_HOME=/opt/java-minimal
ENV PATH="$PATH:$JAVA_HOME/bin"
COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
COPY /target/microservices-backend-*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

- .


Push Images:


stage('Push images') {
  agent any
  when {
    branch 'master'
  }
  steps {
    script {
      def dockerImage = docker.build("${env.IMAGE_NAME}", "-f ${env.DOCKERFILE_NAME} .")
      docker.withRegistry('', 'dockerhub-creds') {
        dockerImage.push()
        dockerImage.push("latest")
      }
      echo "Pushed Docker Image: ${env.IMAGE_NAME}"
    }
    sh "docker rmi ${env.IMAGE_NAME} ${env.IMAGE_NAME_LATEST}"
  }
}

Jenkins , . Jenkins , script.


docker.build . ( ) ${env.IMAGE_NAME}. docker.build , -.


docker.withRegistry('', 'dockerhub-creds') , 'dockerhub-creds'. , 'latest'. echo.


.


Kubernetes


Kubernetes, , .


stage('Trigger kubernetes') {
  agent any
  when {
    branch 'master'
  }
  steps {
    withKubeConfig([credentialsId: 'kubernetes-creds', serverUrl: "${CLUSTER_URL}", namespace: "${CLUSTER_NAMESPACE}"]) {
      sh "helm upgrade ${HELM_PROJECT} ${HELM_CHART} --reuse-values --set backend.image.tag=${env.IMAGE_TAG}"
    }
  }
}

withKubeConfig Kubernetes CLI kubectl . Helm-. Jenkins, , , ${CLUSTER_URL}.


Jenkinsfile


Jenkins-backend
pipeline {
  agent none
  options {
    skipStagesAfterUnstable()
    skipDefaultCheckout()
  }
  environment {
    IMAGE_BASE = 'anshelen/microservices-backend'
    IMAGE_TAG = "v$BUILD_NUMBER"
    IMAGE_NAME = "${env.IMAGE_BASE}:${env.IMAGE_TAG}"
    IMAGE_NAME_LATEST = "${env.IMAGE_BASE}:latest"
    DOCKERFILE_NAME = "Dockerfile-packaged"
  }
  stages {
    stage("Prepare container") {
      agent {
        docker {
          image 'openjdk:11.0.5-slim'
          args '-v $HOME/.m2:/root/.m2'
        }
      }
      stages {
        stage('Build') {
          steps {
            checkout scm
            sh './mvnw compile'
          }
        }
        stage('Test') {
          steps {
            sh './mvnw test'
            junit '**/target/surefire-reports/TEST-*.xml'
          }
        }
        stage('Package') {
          steps {
            sh './mvnw package -DskipTests'
          }
        }
      }
    }

    stage('Push images') {
      agent any
      when {
        branch 'master'
      }
      steps {
        script {
          def dockerImage = docker.build("${env.IMAGE_NAME}", "-f ${env.DOCKERFILE_NAME} .")
          docker.withRegistry('', 'dockerhub-creds') {
            dockerImage.push()
            dockerImage.push("latest")
          }
          echo "Pushed Docker Image: ${env.IMAGE_NAME}"
        }
        sh "docker rmi ${env.IMAGE_NAME} ${env.IMAGE_NAME_LATEST}"
      }
    }

    stage('Trigger kubernetes') {
      agent any
      when {
        branch 'master'
      }
      steps {
        withKubeConfig([credentialsId: 'kubernetes-creds', serverUrl: "${CLUSTER_URL}", namespace: "${CLUSTER_NAMESPACE}"]) {
          sh "helm upgrade ${HELM_PROJECT} ${HELM_CHART} --reuse-values --set backend.image.tag=${env.IMAGE_TAG}"
        }
      }
    }
  }
}


Jenkinsfile .



Jenkins . Multibranch pipeline. , .


, Jenkins. New Item -> Multibranch Pipeline. :


  • Branch sources. GitHub, 'Credentials' / URL .


  • Build Configuration. Mode 'by Remote File Plugin', — Repository URL, Jenkinsfile, Script Path .



  • Scan Repository Triggers. , Jenkins , - . , Jenkins , . — -. . , , Jenkins ( , Jenkins IP-). - .




, . Blue Ocean (Open Blue Ocean). , Maven-. , (helm get values msvc-project).


Jenkins .



Jenkins هو نظام مرن للغاية يسمح لك بتنفيذ عملية تكامل ونشر مستمر لأي تعقيد. في هذه المقالة ، تطرقنا للتو إلى هذه الأداة ، مما أدى إلى إنشاء خط أنابيب بسيط للخدمات الصغيرة لمشروعنا. في المستقبل ، يمكن تحسين هذا الخط وتحسينه بشكل كبير ، على سبيل المثال ، عن طريق إضافة الإخطارات ، والخطوات الإضافية ، وخطافات الويب والمزيد.


All Articles