1. 程式人生 > 其它 >jenkins pipeline實現自動構建並部署至k8s

jenkins pipeline實現自動構建並部署至k8s

在日常開發中,經常會有釋出的需求,而且經常會碰到各種環境,比如:開發環境、測試環境、生產環境。雖然可以使用手動構建、上傳伺服器部署的方式,但在微服務架構下一個專案經常包含多個微服務的部署,如果用手動方式就會非常繁瑣而且容易出錯。使用jenkins結合SCM可以實現程式碼的整個自動化構建部署過程。

本文中自動構建部署過程大致完成了以下步驟:

  1. 提交spring boot專案程式碼並打上git tag,上傳程式碼及tag至gitlab

  2. gitlab通過webhook自動觸發jenkins執行任務

  3. jenkins獲取程式碼,執行程式碼編譯、構建docker映象、上傳docker映象至harbor映象倉庫、執行kubectl命令部署至k8s。

本文中採用jenkins pipeline執行整個jenkins的構建過程,在pipeline中使用docker執行maven構建。文中構建的docker映象的tag直接採用git中的tag。
下面的示例中,jenkins版本為2.121.3,gitlab版本為10.0.2-ce,如果使用的版本不一致可能會有部分設定差異。

部署jenkins

這裡採用docker的方式部署jenkins。

  1. 在終端中執行docker命令,使用jenkinsci/blueocean映象執行容器。

dockerrun\
-d\
-uroot\
-p8080:8080\
-vjenkins_home:/var/jenkins_home\
-v/var/run/docker.sock:/var/run/docker.sock\
jenkinsci/blueocean
  1. 訪問http://localhost:8080地址,等待出現下面解鎖介面。

    解鎖jenkins

  2. 使用docker logs 命令從日誌資訊中 複製自動生成的密碼(在兩組星號之間)。

    預設密碼

  3. 在 解鎖Jenkins 頁面, 貼上密碼並繼續。

  4. 解鎖jenkins後,在介面中選擇“安裝建議的外掛”。

  5. 最後,jenkins要求建立管理員使用者。建立新使用者或使用admin使用者,按照步驟完成後即可登入使用jenkis了。

注:由於後面jenkins pipeline任務會上傳docker映象至harbor倉庫,如果harbor使用http需要在/etc/docker/daemon.json中將地址配置到insecure-registries;如果harbor使用自簽名https證書,需要將ca證書放入/etc/docker/certs.d/目錄下。設定完需要重啟docker服務。

準備java示例工程

下面新建spring boot示例工程,示例工程的程式碼地址為:https://gitee.com/tinylk/pipeline-demo

建立spring boot示例工程

  1. 通過https://start.spring.io/生成spring boot基礎工程,新增一個示例Controller類。

packagecom.example.demo.controller;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;@RestControllerpublicclassHomeController{@GetMapping("")publicStringhello(){return"Hello!";
}
}
  1. 修改application配置檔案,設定埠。

spring.application.name=pipeline-demo
server.port=40080
  1. 編譯執行,訪問http://localhost:40080地址可以看到示例執行結果。

新增Dockerfile

在工程根目錄建立Dockerfile,用來構建docker映象。其中${JAR_FILE}引數在pipeline執行docker build時,通過build-arg引數傳入。

FROMopenjdk:8-jdk-alpine#構建引數ARGJAR_FILE
ARGWORK_PATH="/opt/demo"#環境變數ENVJAVA_OPTS=""\
JAR_FILE=${JAR_FILE}#設定時區RUNapkupdate&&apkaddca-certificates&&\
apkaddtzdata&&\
ln-sf/usr/share/zoneinfo/Asia/Shanghai/etc/localtime&&\echo"Asia/Shanghai">/etc/timezone

COPYtarget/$JAR_FILE$WORK_PATH/

WORKDIR$WORK_PATHENTRYPOINTexecjava$JAVA_OPTS-jar$JAR_FILE

新增k8s的Deployment配置

在工程根目錄建立k8s-deployment.tpl檔案,此檔案用來作為k8s的yaml檔案模板。在jenkens pipeline執行時,會先將tpl檔案中{}括起來的自定義引數用sed命令替換為實際的內容。(由於對k8s的瞭解有限,不知道有沒有更好的方式來實現)

apiVersion:apps/v1kind:Deploymentmetadata:name:{APP_NAME}-deploymentlabels:app:{APP_NAME}spec:replicas:1selector:matchLabels:app:{APP_NAME}template:metadata:labels:app:{APP_NAME}spec:containers:-name:{APP_NAME}image:{IMAGE_URL}:{IMAGE_TAG}ports:-containerPort:40080env:-name:SPRING_PROFILES_ACTIVEvalue:{SPRING_PROFILE}

新增Jenkinsfile

在工程根目錄建立Jenkinsfile,用來執行jenkins pipeline任務。Jenkinsfile檔案的大概內容描述如下:

  • environment中變數說明,environment的文件說明參見:https://jenkins.io/zh/doc/book/pipeline/jenkinsfile/#%E5%A4%84%E7%90%86%E5%87%AD%E8%AF%81

    • HARBOR_CREDS為harbor映象倉庫的使用者密碼,資料儲存為jenkins的“username and password”型別的憑據,用credentials方法從憑據中獲取。使用時通過HARBOR_CREDS_USR獲取使用者名稱,HARBOR_CREDS_PSW獲取密碼。

    • K8S_CONFIG為k8s中kubectl命令的yaml配置檔案內容,資料儲存為jenkins的“Secret Text”型別的憑據,用credentials方法從憑據中獲取。這裡儲存的yaml配置檔案內容以base64編碼格式儲存,在設定憑據時先要進行base64編碼。(此base64編碼是非必須的,如果直接儲存原文,下面Jenkinsfile中需要去掉base64 -d 解碼)

    • GIT_TAG變數通過執行sh命令獲取當前git的tag值。由於後面構建docker映象時使用git的tag作為映象的標籤,所以這個變數也不能為空。

  • parameters中變數說明

    • HARBOR_HOST:harbor映象倉庫地址。

    • DOCKER_IMAGE:docker映象名,包含harbor專案名稱。

    • APP_NAME:k8s中的標籤名稱,對應k8s的yaml模板中的{APP_NAME}。

    • K8S_NAMESPACE:k8s中的namespace名稱,執行kubectl命令會部署至此名稱空間。

  • stages說明:

    • Maven Build:使用docker的方式執行maven命令,args引數中將.m2目錄映射出來,避免執行時重複從遠端獲取依賴;stash步驟中將jar檔案儲存下來,供後面的stage使用。

    • Docker Build:unstash獲取jar檔案。通過sh依次執行docker命令登入harbor、構建映象、上傳映象、移除本地映象。構建映象時,會獲取jar檔名傳入JAR_FILE引數。

    • Deploy:使用docker的方式執行kubectl命令。在執行前先將K8S_CONFIG中的內容進行base64解密並存為~/.kube/config配置檔案,然後執行sed命令將k8s-deployment.tpl檔案中“{引數名}”形式引數替換為實際的引數值,最後執行kubectl命令部署至k8s。

parameters中的引數在pipeline任務執行一次後,第二次執行時可以在介面上修改引數值。
這裡的stage都是一個接一個自動執行,如果需要手動執行可以使用input指令實現。參見:https://jenkins.io/zh/doc/book/pipeline/syntax/#input

//需要在jenkins的Credentials設定中配置jenkins-harbor-creds、jenkins-k8s-config引數
pipeline{ agentany environment{ HARBOR_CREDS=credentials('jenkins-harbor-creds') K8S_CONFIG=credentials('jenkins-k8s-config') GIT_TAG=sh(returnStdout:true,script:'gitdescribe--tags').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('MavenBuild'){ when{expression{env.GIT_TAG!=null}} agent{ docker{ image'maven:3-jdk-8-alpine' args'-v$HOME/.m2:/root/.m2' } } steps{ sh'mvncleanpackage-Dfile.encoding=UTF-8-DskipTests=true' stashincludes:'target/*.jar',name:'app' } } stage('DockerBuild'){ when{ allOf{ expression{env.GIT_TAG!=null} } } agentany steps{ unstash'app' sh"dockerlogin-u${HARBOR_CREDS_USR}-p${HARBOR_CREDS_PSW}${params.HARBOR_HOST}" sh"dockerbuild--build-argJAR_FILE=`lstarget/*.jar|cut-d'/'-f2`-t${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}." sh"dockerpush${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}" sh"dockerrmi${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"kubectlapply-fk8s-deployment.yml--namespace=${params.K8S_NAMESPACE}" } } } }

配置jenkins pipeline任務

建立jenkins pipeline任務,並設定需要的引數。

新建pipeline任務

點選“新建任務”,輸入名稱並選擇“流水線”(pipeline),然後點選確定。

新建pipeline

配置 pipeline任務

進入任務的配置介面,在流水線(pipeline)設定部分,選擇“Pipeline script from SCM”。SCM選項選為“Git”,配置好工程的git地址以及獲取程式碼的憑證資訊。然後在“Additional Behaviours”中新增“Clean before checkout”。

配置pipeline

配置harbor賬號與密碼

選擇“憑據”,然後在下圖所示位置點選“新增憑據”。在新憑據設定介面,型別選擇為“Username with password”,ID設定為“jenkins-harbor-creds”(此處的ID必須與Jenkinsfile中的保持一致)。Username與Password分別設定為harbor映象私庫的使用者名稱和密碼。

新增憑證

設定harbor賬號密碼

配置k8s的kube.config配置資訊

k8s中使用kubectl命令時需要yaml格式的伺服器及授權資訊配置檔案。這裡將kubectl的yaml配置檔案的內容以base64編碼後儲存在jenkins的憑據中。pipeline任務執行時,先從jenkins憑據中獲取內容,進行base64解碼後將配置儲存為~/.kube/config檔案。kubectl的配置檔案的內容如下:

apiVersion:v1kind:Configclusters:-name:"test"cluster:server:"https://xxxxx"api-version:v1certificate-authority-data:"xxxxxx"users:-name:"user1"user:token:"xxxx"contexts:-name:"test"context:user:"user1"cluster:"test"current-context:"test"

可以在linux中採用下面命令將kubectl的yaml配置檔案進行base64編碼。

base64kube-config.yml>kube-config.txt

然後類似上一步,在jenkins憑據中增加配置檔案內容。在憑據設定介面,型別選擇為“Secret text”,ID設定為“jenkins-k8s-config”(此處的ID必須與Jenkinsfile中的保持一致),Secret設定為上面經過base64編碼後的配置檔案內容。

配置kube配置

測試pipeline任務

在建立的pipeline任務中,點選“立即構建”即可立即執行pipeline任務。

立即構建

在jenkins中存在一個名為Blue Ocean的新介面,在新介面中也可以執行pipeline任務,而且新的介面中檢視任務的執行結果更加清晰,所以執行結果日誌建議在新介面中檢視。點選“Open Blue Ocean”選單進入新介面。

開啟Blue Ocean新介面

在Blue Ocean新介面中,可以點選“執行”執行pipeline任務。

在新介面中執行

在執行pipeline任務,執行“git describe --tags”命令出錯,這是由於上面示例的Jenkinsfile中要求必須有git的tag。在git中增加tag,並提交上傳至gitlab後即可解決。

git無tag時執行錯誤

在git中增加tag,並提交上傳至gitlab後重新執行pipeline任務,所有步驟都執行成功。

打上tag執行成功

執行成功後,檢視harbor映象倉庫,docker映象成功上傳至harbor。

harbor中映象

執行成功後,檢視k8s中pod執行日誌,服務啟動成功。

k8s中執行成功

設定gitlab自動觸發jenkins

前面的步驟中已經完成了手動執行jenkins執行pipeline任務完成構建部署任務,下面說明如何在程式碼提交後讓gitlab自動觸發jenkins執行pipeline任務。

jenkins中安裝gitlab外掛

要實現gitlab自動觸發jenkins任務,需要在jenkins中安裝gitlab外掛。從jenkins的“系統管理”-“管理外掛”中找到gitlab外掛並下載安裝,重啟jenkins後生效。

選擇gitlab外掛

安裝gitlab外掛

在gitlab中建立訪問token

安裝的gitlab外掛在配置時,需要gitlab的訪問token,先要在gitlab中建立訪問的token。點選“使用者設定”-“Access Tokens”選單,進入訪問token設定介面。然後輸入“Name”,並在“Scopes”中勾選“api”,點選“Create ...”按鈕即可建立訪問token。建立成功後,一定要將生成的token儲存下來,後面將無法再檢視生成的token,如果未儲存後面只能重新生成。

建立token


作者:幕布斯6054654
連結:https://www.imooc.com/article/278426
來源:慕課網

我們只需要努力,然後剩下的交給時間。