jenkins流水線部署springboot應用到k8s集群(k3s+jenkins+gitee+maven+docker)(2)
前言:上篇已介紹了jenkins在k3s環境部署,本篇繼續上篇講述流水線構建部署流程
1、從gitlab上拉取程式碼步驟
-
在jenkins中,新建一個憑證;Manage Jenkins -> Manage Credentials
-
點擊jenkins -> 全局憑據 -> 添加憑據;選擇用戶名和密碼類型,輸入用戶名和密碼,點擊創建
-
編寫pipeline script腳本,拉取程式碼
-
選擇git程式碼倉庫還有憑證等資訊,點擊「生成流水線腳本」,即幫我們生成了拉取程式碼的腳本
-
複製腳本,粘貼到流水線拷貝程式碼段中
-
運行構建項目,發現拉取程式碼成功,且已返回程式碼最後提交的tag
程式碼塊:
stage('Clone') { echo "1.Clone Stage" git url: "//gitee.com/xujk-27400861/springboot-dubbo.git" script { build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() } echo "${build_tag}" }
2、maven構建springboot程式碼項目
-
編寫腳本,因為我們要編譯構建項目的子項目,所以需要跳轉到子目錄去構建
stage('執行構建') { container('maven') { sh "mvn --version" sh 'pwd' sh '''cd provider/ mvn clean package -DskipTests''' //sh 'mvn package' echo '構建完成' } }
-
provider/為項目子目錄,我們要編譯的項目;-DskipTests參數,表示跳過程式碼測試
3、構建docker鏡像
-
編寫腳本,構建docker鏡像;
stage('Build') { echo "3.Build Stage" container('docker') { sh "docker -v" sh 'pwd' sh """cd /home/jenkins/agent/workspace/linetest/provider/ ls docker -H tcp://192.168.231.132:2375 build -t xjk27400861/springbootapp:${build_tag} .""" } }
-
我這裡通過調用單機節點獨立的docker進行鏡像打包,jenkins內部新構建的docker無法打包,因許可權問題
4、推送docker鏡像到docker hub上,以備後續部署應用時使用
-
編寫腳本,推送docker鏡像;
stage('Push') { echo "4.Push Docker Image Stage" container('docker') { sh "docker -H tcp://192.168.231.132:2375 login --username=xjk27400861 -p xujingkun@123" sh "docker -H tcp://192.168.231.132:2375 push xjk27400861/springbootapp:${build_tag}" } }
-
docker login登錄到docker hub上,然後使用docker push命令推送;- H 使用其他節點的docker
-
Ubuntu開啟Docker遠程訪問
輸入命令:
sudo gedit /lib/systemd/system/docker.service
找到ExecStart段,修改為
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -H fd:// --containerd=/run/containerd/containerd.sock
保存並退出編輯後,重載守護進程以及重啟Docker
sudo systemctl daemon-reload sudo service docker restart
可通過執行命令查看是否開放了遠程訪問埠
sudo systemctl status docker.service
5、拉取docker鏡像,部署到k8s環境中
-
編寫腳本,部署應用
stage('Deploy') { echo "5. Deploy Stage" container('kubectl') { sh "kubectl version" def namespace="jenkinsdemo"//springboot2node sh """cd /home/jenkins/agent/workspace/linetest/provider/ ls sed -i 's/<BUILD_TAG>/${build_tag}/' k8s.yaml sed -i 's/<BUILD_NAMESPACE>/${namespace}/' k8s.yaml kubectl delete -f . kubectl apply -f k8s.yaml --record """ } }
-
部署成功後,通過k8s主機節點+埠,訪問應用
6、完整pipeline腳本
def label = "jnlp"
podTemplate (label: label,cloud: 'kubernetes',containers: [
//image: 'datorresf/jenkins-agent-mvn',
//image: 'maven:latest',
containerTemplate(
name: 'maven',
image: 'maven:3.8.1-ibmjava-8',
alwaysPullImage: false,
ttyEnabled: true,
command:'cat'
),//docker:19.03.8
containerTemplate(
name: 'docker',
image: "docker:stable",
ttyEnabled: true,
command: 'cat',
),
containerTemplate(name: 'kubectl', image: 'bibinwilson/docker-kubectl:latest', command: 'cat', ttyEnabled: true)
],serviceAccount: 'jenkinsbuild',//jenkinsbuild
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
hostPathVolume(mountPath: '/root/.m2', hostPath: '/root/.m2'),
hostPathVolume(mountPath: '/home/jenkins/.kube', hostPath: '/root/.kube'),
hostPathVolume(mountPath: '/etc/kubernetes/pki', hostPath: '/etc/kubernetes/pki'),
])
{
node('jnlp') {
stage('Clone') {
echo "1.Clone Stage"
git credentialsId: '56cc9ad2-aafa-41f3-bc6b-2d7d66c52f32', url: "//gitee.com/xujk-27400861/springboot-dubbo.git"
script {
build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
}
echo "${build_tag}"
}
stage('Test') {
echo "2.Test Stage"
}
stage('執行構建') {
container('maven')
{
sh "mvn --version"
sh 'pwd'
sh '''cd provider/
mvn clean package -DskipTests'''
//sh 'mvn package'
echo '構建完成'
}
}
stage('Build') {
echo "3.Build Stage"
container('docker') {
sh "docker -v"
sh 'pwd'
sh """cd /home/jenkins/agent/workspace/linetest/provider/
ls
docker -H tcp://192.168.231.132:2375 build -t xjk27400861/springbootapp:${build_tag} ."""
}
}
stage('Push') {
echo "4.Push Docker Image Stage"
container('docker') {
sh "docker -H tcp://192.168.231.132:2375 login --username=xjk27400861 -p xujingkun@123"
sh "docker -H tcp://192.168.231.132:2375 push xjk27400861/springbootapp:${build_tag}"
}
}
stage('Deploy') {
echo "5. Deploy Stage"
container('kubectl') {
sh "kubectl version"
def namespace="jenkinsdemo"//springboot2node
sh """cd /home/jenkins/agent/workspace/linetest/provider/
ls
sed -i 's/<BUILD_TAG>/${build_tag}/' k8s.yaml
sed -i 's/<BUILD_NAMESPACE>/${namespace}/' k8s.yaml
kubectl delete -f .
kubectl apply -f k8s.yaml --record
"""
}
}
}
}
7、完整pipeline腳本說明
-
創建一個pod,裡面包含構建有三個docker容器,maven,docker與kubectl,分別進行程式碼maven構建,docker打包鏡像,kubectl部署應用到k8s環境
-
程式碼段:serviceAccount: ‘jenkinsbuild’;指定操作k8s環境的賬戶;這個是rancher2.6.3部署jenkins的時候,自動創建的賬戶(service account)
-
程式碼段:docker -H tcp://192.168.231.132:2375;操控單節點docker進行鏡像打包及推送操作
-
部署應用的時候,可能會提示用戶jenkinsbuild沒有構建pod或者services的許可權,可以通過rancher的rbac編輯用戶許可權(Roles&RoleBindings)
Roles設置
編輯配置
RoleBindings無需修改,後面如果有需要其他用戶操作k8s的話,可以通過創建Role與RoleBindings,賦予其他賬戶對應的許可權來操作k8s環境 -
jenkins的k8s連通環境配置
Manage Jenkins -> Manage nodes and clouds 依次點擊,進入配置頁面
點擊:Configure Clouds;名稱默認:kubernetes,我們的腳本里用cloud屬性指定的k8s集群
由於我使用的是rancher通過應用市場安裝的,此處的kubernetes設置的都是默認值,無需修改
-
配置連接集群外的k8s集群方法
修改k8s集群的地址(//192.168.231.133:6443)
連接k8s集群的認證方式,我這裡配置了3種,用戶名密碼&秘鑰文本&kube.config文件
用戶名密碼方式,就直接輸入我們k8s集群的訪問用戶名和密碼,在jenkins創建全局憑證,配置時選中即可
秘鑰文本方式,我們通過rancher,下載k8s的配置文件
打開配置文件,把下圖圈起來的數據,在jenkins創建憑據,secret text類型
使用k8s的配置文件,創建secret file類型的憑證,上傳我們的配置文件,測試;由於文件里配置的是k8s集群的訪問域名,所以提示失敗,如果域名可通的話,也是可以的
-
流水線腳本配置maven鏡像文件的時候,要注意與你springboot項目中使用的版本保持一致,否則會出現編譯構建錯誤
-
關於serviceAccount: ‘jenkinsbuild’,這段,需要設置訪問k8s集群的用戶名,同時需要設置role與rolebindings賦予用戶應有的許可權,否則會提示許可權錯誤
-
本文使用的程式碼見倉庫,含有k8s部署文件,//gitee.com/xujk-27400861/springboot-dubbo/tree/master/provider
-
同時,也可以通過jenkinsfile構建,在項目中相應目錄創建jenkinsfile,裡面參考流水線腳本,也是可以實現構建發布的,此處不詳述
好的,本篇到此為止