在平常開發中,常常會有發佈的需求,並且常常會碰到各類環境,好比:開發環境、測試環境、生產環境。雖然可使用手動構建、上傳服務器部署的方式,但在微服務架構下一個項目常常包含多個微服務的部署,若是用手動方式就會很是繁瑣並且容易出錯。使用jenkins結合SCM能夠實現代碼的整個自動化構建部署過程。java
本文中自動構建部署過程大體完成了如下步驟:linux
本文中採用jenkins pipeline執行整個jenkins的構建過程,在pipeline中使用docker執行maven構建。文中構建的docker鏡像的tag直接採用git中的tag。git
下面的示例中,jenkins版本爲2.121.3,gitlab版本爲10.0.2-ce,若是使用的版本不一致可能會有部分設置差別。web
這裏採用docker的方式部署jenkins。spring
docker run -d -u root -p 8080:8080 -v jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean
注:因爲後面jenkins pipeline任務會上傳docker鏡像至harbor倉庫,若是harbor使用http須要在/etc/docker/daemon.json中將地址配置到insecure-registries;若是harbor使用自簽名https證書,須要將ca證書放入/etc/docker/certs.d/目錄下。設置完須要重啓docker服務。docker
下面新建spring boot示例工程,示例工程的代碼地址爲:https://gitee.com/tinylk/pipe...express
1.經過 https://start.spring.io/ 生成spring boot基礎工程,添加一個示例Controller類。package com.example.demo.controller;json
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HomeController { @GetMapping("") public String hello() { return "Hello!"; } }
2.修改application配置文件,設置端口。api
spring.application.name=pipeline-demo server.port=40080
3.編譯運行,訪問 http://localhost:40080 地址能夠看到示例運行結果。服務器
添加Dockerfile
在工程根目錄建立Dockerfile,用來構建docker鏡像。其中${JAR_FILE}參數在pipeline執行docker build時,經過build-arg參數傳入。
FROM openjdk:8-jdk-alpine #構建參數 ARG JAR_FILE ARG WORK_PATH="/opt/demo" # 環境變量 ENV JAVA_OPTS="" JAR_FILE=${JAR_FILE} #設置時區 RUN apk update && apk add ca-certificates && apk add tzdata && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone COPY target/$JAR_FILE $WORK_PATH/ WORKDIR $WORK_PATH ENTRYPOINT exec java $JAVA_OPTS -jar $JAR_FILE
添加k8s的Deployment配置
在工程根目錄建立k8s-deployment.tpl文件,此文件用來做爲k8s的yaml文件模板。在jenkens pipeline執行時,會先將tpl文件中{}括起來的自定義參數用sed命令替換爲實際的內容。(因爲對k8s的瞭解有限,不知道有沒有更好的方式來實現)
apiVersion: apps/v1 kind: Deployment metadata: name: {APP_NAME}-deployment labels: app: {APP_NAME} spec: replicas: 1 selector: matchLabels: app: {APP_NAME} template: metadata: labels: app: {APP_NAME} spec: containers: - name: {APP_NAME} image: {IMAGE_URL}:{IMAGE_TAG} ports: - containerPort: 40080 env: - name: SPRING_PROFILES_ACTIVE value: {SPRING_PROFILE}
添加Jenkinsfile
在工程根目錄建立Jenkinsfile,用來執行jenkins pipeline任務。Jenkinsfile文件的大概內容描述以下:
HARBOR_HOST:harbor鏡像倉庫地址。 DOCKER_IMAGE:docker鏡像名,包含harbor項目名稱。 APP_NAME:k8s中的標籤名稱,對應k8s的yaml模板中的{APP_NAME}。 K8S_NAMESPACE:k8s中的namespace名稱,執行kubectl命令會部署至此命名空間。
parameters中的參數在pipeline任務執行一次後,第二次執行時能夠在界面上修改參數值。
這裏的stage都是一個接一個自動執行,若是須要手動執行可使用input指令實現。參見:https://jenkins.io/zh/doc/boo...
// 須要在jenkins的Credentials設置中配置jenkins-harbor-creds、jenkins-k8s-config參數 pipeline { agent any environment { HARBOR_CREDS = credentials('jenkins-harbor-creds') K8S_CONFIG = credentials('jenkins-k8s-config') GIT_TAG = sh(returnStdout: true,script: 'git describe --tags --always').trim() } parameters { string(name: 'HARBOR_HOST', defaultValue: '172.23.101.66', description: 'harbor倉庫地址') string(name: 'DOCKER_IMAGE', defaultValue: 'tssp/pipeline-demo', description: 'docker鏡像名') string(name: 'APP_NAME', defaultValue: 'pipeline-demo', description: 'k8s中標籤名') string(name: 'K8S_NAMESPACE', defaultValue: 'demo', description: 'k8s的namespace名稱') } stages { stage('Maven Build') { when { expression { env.GIT_TAG != null } } agent { docker { image 'maven:3-jdk-8-alpine' args '-v $HOME/.m2:/root/.m2' } } steps { sh 'mvn clean package -Dfile.encoding=UTF-8 -DskipTests=true' stash includes: 'target/*.jar', name: 'app' } } stage('Docker Build') { when { allOf { expression { env.GIT_TAG != null } } } agent any steps { unstash 'app' sh "docker login -u ${HARBOR_CREDS_USR} -p ${HARBOR_CREDS_PSW} ${params.HARBOR_HOST}" sh "docker build --build-arg JAR_FILE=`ls target/*.jar |cut -d '/' -f2` -t ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG} ." sh "docker push ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}" sh "docker rmi ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}" } } stage('Deploy') { when { allOf { expression { env.GIT_TAG != null } } } agent { docker { image 'lwolf/helm-kubectl-docker' } } steps { sh "mkdir -p ~/.kube" sh "echo ${K8S_CONFIG} | base64 -d > ~/.kube/config" sh "sed -e 's#{IMAGE_URL}#${params.HARBOR_HOST}/${params.DOCKER_IMAGE}#g;s#{IMAGE_TAG}#${GIT_TAG}#g;s#{APP_NAME}#${params.APP_NAME}#g;s#{SPRING_PROFILE}#k8s-test#g' k8s-deployment.tpl > k8s-deployment.yml" sh "kubectl apply -f k8s-deployment.yml --namespace=${params.K8S_NAMESPACE}" } } } }
建立jenkins pipeline任務,並設置須要的參數。
點擊「新建任務」,輸入名稱並選擇「流水線」(pipeline),而後點擊肯定。
進入任務的配置界面,在流水線(pipeline)設置部分,選擇「Pipeline script from SCM」。SCM選項選爲「Git」,配置好工程的git地址以及獲取代碼的憑證信息。而後在「Additional Behaviours」中添加「Clean before checkout」。
選擇「憑據」,而後在下圖所示位置點擊「添加憑據」。在新憑據設置界面,類型選擇爲「Username with password」,ID設置爲「jenkins-harbor-creds」(此處的ID必須與Jenkinsfile中的保持一致)。Username與Password分別設置爲harbor鏡像私庫的用戶名和密碼。
添加憑證
設置habor帳號密碼
k8s中使用kubectl命令時須要yaml格式的服務器及受權信息配置文件。這裏將kubectl的yaml配置文件的內容以base64編碼後保存在jenkins的憑據中。pipeline任務執行時,先從jenkins憑據中獲取內容,進行base64解碼後將配置保存爲~/.kube/config文件。kubectl的配置文件的內容以下:
apiVersion: v1 kind: Config clusters: - name: "test" cluster: server: "https://xxxxx" api-version: v1 certificate-authority-data: "xxxxxx" users: - name: "user1" user: token: "xxxx" contexts: - name: "test" context: user: "user1" cluster: "test" current-context: "test"
能夠在linux中採用下面命令將kubectl的yaml配置文件進行base64編碼。
base64 kube-config.yml > kube-config.txt
而後相似上一步,在jenkins憑據中增長配置文件內容。在憑據設置界面,類型選擇爲「Secret text」,ID設置爲「jenkins-k8s-config」(此處的ID必須與Jenkinsfile中的保持一致),Secret設置爲上面通過base64編碼後的配置文件內容。
在建立的pipeline任務中,點擊「當即構建」便可當即執行pipeline任務。
在jenkins中存在一個名爲Blue Ocean的新界面,在新界面中也能夠執行pipeline任務,並且新的界面中查看任務的執行結果更加清晰,因此執行結果日誌建議在新界面中查看。點擊「Open Blue Ocean」菜單進入新界面。
在Blue Ocean新界面中,能夠點擊「運行」執行pipeline任務。
在執行pipeline任務,執行「git describe --tags」命令出錯,這是因爲上面示例的Jenkinsfile中要求必須有git的tag。在git中增長tag,並提交上傳至gitlab後便可解決。
在git中增長tag,並提交上傳至gitlab後從新執行pipeline任務,全部步驟都執行成功。
執行成功後,查看harbor鏡像倉庫,docker鏡像成功上傳至harbor。
執行成功後,查看k8s中pod運行日誌,服務啓動成功。
前面的步驟中已經完成了手動執行jenkins執行pipeline任務完成構建部署任務,下面說明如何在代碼提交後讓gitlab自動觸發jenkins執行pipeline任務。
要實現gitlab自動觸發jenkins任務,須要在jenkins中安裝gitlab插件。從jenkins的「系統管理」-「管理插件」中找到gitlab插件並下載安裝,重啓jenkins後生效。
安裝的gitlab插件在配置時,須要gitlab的訪問token,先要在gitlab中建立訪問的token。點擊「用戶設置」-「Access Tokens」菜單,進入訪問token設置界面。而後輸入「Name」,並在「Scopes」中勾選「api」,點擊「Create ...」按鈕便可建立訪問token。建立成功後,必定要將生成的token保存下來,後面將沒法再查看生成的token,若是未保存後面只能從新生成。
在jenkins中,進入「系統管理」-「系統設置」-「Gitlab」配置。
輸入「Connection name」、「Gitlab host URL」,在「Credentials」中點擊「Add」添加gitlab的受權token。
點擊添加後,會進入添加憑據界面。在添加界面,選擇類型爲「GitLab API token」,API token設置爲前面在gitlab中建立的token值。而後點擊「添加」按鈕建立憑據。
添加完gitlab api token,在Gitlab設置界面「Credentials」中選擇前面添加的token,而後點擊「Test Connection」測試是否成功。測試成功後保存。
進入jenkins的任務設置界面,在「構建觸發器」中,勾上「Build when a change pushed to Gitlab.Gitlab webhook URL ...」(這裏的webhook URL在後面配置gitlab時須要),根據本身的須要設置其它的選項。點擊「高級」按鈕,而後點擊「Generate」按鈕生成Secret token(這裏的token後面配置gitlab時須要)。
gitlab配置webhook
在gitlab的項目設置中選擇「Integrations」,而後在URL和Secret token中填入上一步jenkins設置中的到的內容。因爲本文中是在git上打了tag後才觸發jenkins執行任務,因此這裏勾選「Tag push events」,而後去掉「Enable SSL verification」的勾選項,並點擊「Add webhook」按鈕添加。若是須要每次提交代碼都觸發則應該選「Push events」(注意:這裏選擇Push events後,Jenkinsfile中也須要作相應的修改,去掉git的tag相關內容,不然執行時會出錯)。
添加完成後,在下面能夠看到剛纔添加的webhook,點擊「Test」按鈕在彈出的菜單中選擇「Tag push events」發送測試請求,發送成功後會顯示「Hook executed successfully」信息。
Tag push Test
push成功
webhook發送成功後,到jenkins中能夠看到正在執行觸發的任務。配置成功後,後面只要有git的tag提交到gitlab便可直接觸發jenkins執行pipline任務。
webhook觸發執行
做者:tinylk
原文:www.jianshu.com/p/2d89fd1b4403