Jenkins+harbor+gitlab+k8s 部署maven專案
Jenkins+harbor+gitlab+k8s 部署maven專案
一、概述
maven專案部署流程圖如下:
環境介紹
作業系統 | ip | 角色 | 版本 |
ubuntu-16.04.4-server-amd64 | 192.168.10.122 | Jenkins+harbor | Jenkins 2.176.2,harbor 1.8.1 |
ubuntu-16.04.4-server-amd64 | 192.168.10.134 | gitlab | gitlab-ce_12.1.4 |
ubuntu-16.04.4-server-amd64 | 192.168.10.130 | k8s master | kubernetes 1.15.2 |
ubuntu-16.04.4-server-amd64 | 192.168.10.131 | k8s node | kubernetes 1.15.2 |
由於資源緊張,Jenkins+harbor合併為一臺了。實際上,應該是要單獨部署的。
k8s安裝,請參考連結:
https://www.cnblogs.com/xiao987334176/p/11317844.html
gitlab安裝,請參考連結:
https://www.cnblogs.com/xiao987334176/p/11329018.html
harbor安裝,請參考連結:
https://www.cnblogs.com/xiao987334176/p/11326467.html
Jenkins安裝,請參考連結:
https://www.cnblogs.com/xiao987334176/p/11323795.html
注意:Jenkins安裝之後,還需要做以下配置。否則無法實現本文章的功能!!!
Jenkins基於https的k8s配置,請參考連結:
https://www.cnblogs.com/xiao987334176/p/11338827.html
GitLab+Jenkins持續整合,請參考連結:
https://www.cnblogs.com/xiao987334176/p/11425560.html
Jenkins配置maven,請參考連結:
https://www.cnblogs.com/xiao987334176/p/11433636.html
二、gitlab建立maven專案
首先從github上面,找一個基於maven的專案,地址如下:
https://github.com/solochen84/SpringBootDemo
使用git客戶端,下載此專案程式碼
建立專案
登入gitlab,建立一個專案springbootdemo
點選 設定--> 成員
新增2個成員,一個是jenkins使用者,用來拉取程式碼的。一個是我,用來提交程式碼的。
注意:我的賬號,許可權要高一些,可以直接提交到master分支。
將github下載的程式碼,提交到剛剛建立的專案中。效果如下:
三、harbor 建立使用者和專案
建立jenkins使用者
登入到harbor後臺,點選建立使用者
注意,每一項都填寫一項。尤其是密碼,必須符合密碼複雜性要求。
建立專案
點選新建專案
輸入名字,java。這就是私有專案。
點選java
點選成員-->使用者
輸入jenkins,會有提示的。角色選擇 開發人員。
四、jenkins修改預設使用者
使用jenkins執行shell命令時,可能會出現許可權不足的情況。
檢視jenkins預設使用者
cat /etc/default/jenkins
內容如下:
# pulled in from the init script; makes things easier.
NAME=jenkins
# arguments to pass to java
# Allow graphs etc. to work even when an X server is present
JAVA_ARGS="-Djava.awt.headless=true"
#JAVA_ARGS="-Xmx256m"
# make jenkins listen on IPv4 address
#JAVA_ARGS="-Djava.net.preferIPv4Stack=true"
PIDFILE=/var/run/$NAME/$NAME.pid
# user and group to be invoked as (default to jenkins)
JENKINS_USER=$NAME
JENKINS_GROUP=$NAME
...
可以發現JENKINS_USER和JENKINS_GROUP變數的值是jenkins
修改預設使用者為root
將下面2個變數,修改為root
JENKINS_USER=root
JENKINS_GROUP=root
重啟jenkins服務
service jenkins restart
五、jenkins和k8s master做ssh免密
為什麼要和k8s master做ssh免密呢?因為jenkins需要登入到k8s master,做一些pod操作。
生成祕鑰
登入到jenkins伺服器,生成祕鑰
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
copy祕鑰
ssh-copy-id 192.168.10.130
測試root免密
ssh 192.168.10.130
如果沒有提示輸入密碼,說明成功了!
六、jenkins登入harbor
修改docker配置檔案,新增harbor地址
vim /etc/docker/daemon.json
內容如下:
{"insecure-registries": ["192.168.10.122"]}
重新載入docker配置
/etc/init.d/docker reload
測試登入
root@ubuntu:~/docker_dir# docker login 192.168.10.122 -u jenkins -p Jenkins@1234
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
如果出現
Error response from daemon: Get https://192.168.10.122/v2/: dial tcp 192.168.10.122:443: connect: connection refused
表示/etc/docker/daemon.json 檔案修改不正確
七、jenkins建立maven專案
新建任務
登入到jenkins後臺,點選新建Item
輸入名稱,選擇構建一個maven專案。注意:任務名稱最好是專案名,因為下面的deploy_docker.sh指令碼,會呼叫這個變數。
設定引數化構建
丟棄舊的構建,保留2天
設定原始碼
輸入倉庫下載地址,選擇使用者root
設定maven構建命令
輸入命令:clean package
mvn clean package依次執行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7個階段。
package命令完成了專案編譯、單元測試、打包功能,但沒有把打好的可執行jar包(war包或其它形式的包)佈署到本地maven倉庫和遠端maven私服倉庫
jar包打包成docker映象並推送
執行shell命令
build完成之後,選擇執行shell命令
將下面的內容,貼過去
#!/bin/bash
jarName=spring-boot-demo-0.0.1-SNAPSHOT.jar
jarFolder=$JOB_NAME
harborPro=java
projectName=$JOB_NAME
docker_path=${WORKSPACE}
cp ${WORKSPACE}/target/${jarName} ${docker_path}
bash -x /root/docker_dir/deploy_docker.sh ${harborPro} ${projectName} ${docker_path} ${jarName}
內容解釋:
jarName jar包的檔名,名字隨便
jarFolder jar包的資料夾
harborProharbor裡面的專案,在上面步驟中,建立java私有專案。
projectName 專案名,名字隨便
docker_path docker命令的工作目錄
最後一步,會執行一個shell指令碼。下面說到!
效果如下:
定義shell指令碼
登入到jenkins伺服器,建立目錄
mkdir /root/docker_dir
編輯deploy_docker.sh指令碼
cd /root/docker_dir/
vim deploy_docker.sh
內容如下:
#!/bin/bash
# maven $workspace $jarname
# ${harborPro} ${projectName} ${docker_path} ${jarName}
set -e
harbor_project=$1
projectName=$2
docker_path=$3
appName=$4
# harbor認證使用者
user_name=jenkins
password=Jenkins@1234
# harbor地址以及tag
tag=$(date +%s)
harbor_server=192.168.10.122
server_path=${harbor_server}
taget_image=${projectName}:${tag}
#${BUILD_NUMBER}
echo ${taget_image}
# 登入docker
cd ${docker_path}
sudo docker login ${harbor_server} -u ${user_name} -p ${password}
# 生成映象並推送到harbor,最後刪除本地映象
sudo docker build --build-arg app=${appName} -t ${taget_image} .
sudo docker tag ${taget_image} ${server_path}/${harbor_project}/${projectName}
echo "The name of image is ${server_path}/${harbor_project}/${projectName}"
sudo docker push ${server_path}/${harbor_project}/${projectName}:latest
sudo docker rmi -f $(docker images|grep ${projectName}|grep ${tag}|awk '{print $3}'|head -n 1)
新增執行許可權
chmod 755 /root/docker_dir/deploy_docker.sh
yaml檔案拷貝到k8s master上並運用應用
k8s master 操作
登入到k8s master,建立目錄
mkdir kube-conf
刪除gitlab springbootdemo專案中的kube.yaml,新增2個yaml檔案。
ph-service.yaml
apiVersion: v1
kind: Service
metadata:
name: ph-service
spec:
type: NodePort
ports:
- name: ph
port: 8080
nodePort: 31002
targetPort: 8080
protocol: TCP
selector:
app: ph
ph-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: ph-rc
spec:
replicas: 1
template:
metadata:
labels:
app: ph
spec:
imagePullSecrets:
- name: harborsecret
containers:
- name: ph
image: 192.168.10.122/java/ph:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
env:
- name: key
value: "value"
將2個yaml檔案提交到gitlab
k8s 生成imagePullSecrets,請參考以下連結
https://www.cnblogs.com/xiao987334176/p/11434326.html
注意:使用docker登入使用者時,指定jenkins
docker login 192.168.10.122 -u jenkins -p Jenkins@1234
jenkins操作
登入到jenkins伺服器,新增重啟應用指令碼
cd /root/docker_dir
vim reboot_app.sh
內容如下:
#!/bin/bash
MASTER="192.168.10.130"
CONF_DIR="/root/kube-conf"
ProJ=${JOB_NAME}
scp ${WORKSPACE}/*.yaml ${MASTER}:${CONF_DIR}
# Pod running process
RUN=$(ssh $MASTER kubectl get po|grep -w ${ProJ}|wc -l)
if [ $RUN -eq 0 ];then
ssh ${MASTER} kubectl apply -f ${CONF_DIR}/${ProJ}-rc.yaml
ssh ${MASTER} kubectl apply -f ${CONF_DIR}/${ProJ}-service.yaml
else
# Delete pod
podname=$(ssh ${MASTER} kubectl get po|grep -w ${ProJ}|awk '{print $1}')
ssh ${MASTER} kubectl delete po $podname --grace-period=0 --force
ssh ${MASTER} kubectl get po|grep ${ProJ}
fi
新增執行許可權
chmod 755 /root/docker_dir/reboot_app.sh
新增執行shell命令
將下面的內容,貼過去
#!/bin/bash
bash -x /root/docker_dir/reboot_app.sh
效果如下:
手動構建應用
點選Build Now
點選#1
點選控制檯輸出
它會自己下載一些元件,需要等待一段時間。
出現spring圖示,表示應用開始啟動構建了。
最後出現錯誤
為啥呢? 檢視springbootdemo 的Dockerfile檔案,檢視第一行
FROM registry-scu.cloudtogo.cn/ubuntu:jdk
需要把registry-scu.cloudtogo.cn 新增到/etc/docker/daemon.json中
登入到jenkins伺服器,修改/etc/docker/daemon.json
vim /etc/docker/daemon.json
內容如下:
{"insecure-registries": ["192.168.10.122","registry-scu.cloudtogo.cn"]}
重新載入docker
/etc/init.d/docker reload
再次手動構建一次,點選Build Now
檢視構建過程
出現以下提示,說明正在下載映象registry-scu.cloudtogo.cn/ubuntu:jdk
最後提示執行完成
檢視harbor倉庫
會發現多了一個映象,這個映象,就是剛剛構建時,提交的。
八、訪問k8s 應用
檢視Pod狀態
root@k8s-master:~# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ph-rc-nj7j2 0/1 ImagePullBackOff 0 5m19s 192.168.36.68 k8s-node1 <none> <none>
發現pod執行在k8s-node1 這臺伺服器,狀態是ImagePullBackOff
檢視pod詳細資訊
kubectl describe po maven-deployment-7bd87867f8-6tlgp
輸出:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 7m15s default-scheduler Successfully assigned default/maven-deployment-7bd87867f8-6tlgp to k8s-node1
Normal Pulling 5m49s (x4 over 7m14s) kubelet, k8s-node1 Pulling image "192.168.10.122/maven:latest"
Warning Failed 5m49s (x4 over 7m14s) kubelet, k8s-node1 Failed to pull image "192.168.10.122/maven:latest": rpc error: code = Unknown desc = Error response from daemon: Get https://192.168.10.122/v2/: dial tcp 192.168.10.122:443: connect: connection refused
Warning Failed 5m49s (x4 over 7m14s) kubelet, k8s-node1 Error: ErrImagePull
Normal BackOff 5m36s (x6 over 7m13s) kubelet, k8s-node1 Back-off pulling image "192.168.10.122/maven:latest"
Warning Failed 2m11s (x20 over 7m13s) kubelet, k8s-node1 Error: ImagePullBackOff
出現
Get https://192.168.10.122/v2/: dial tcp 192.168.10.122:443: connect: connection refused
說明,k8s-node1這臺伺服器的 /etc/docker/daemon.json 沒有更改
登入到k8s-node1這臺伺服器,修改檔案
vim /etc/docker/daemon.json
內容如下:
{"insecure-registries": ["192.168.10.122"]}
重新載入docker
/etc/init.d/docker reload
重新載入pod
登入到k8s master伺服器,刪除pod,重新應用
root@k8s-master:~# cd /root/kube-conf/
root@k8s-master:~/kube-conf# kubectl delete -f ph-rc.yaml
service "maven-service" deleted
deployment.extensions "maven-deployment" deleted
root@k8s-master:~/kube-conf# kubectl apply -f ph-rc.yaml
service/maven-service created
deployment.extensions/maven-deployment created
再次檢視狀態
root@k8s-master:~/kube-conf# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ph-rc-7bd7475544-q9b6j 1/1 Running 0 27s 192.168.36.77 k8s-node1 <none> <none>
發現處於Running狀態了
訪問應用頁面
檢視svc暴露的埠
root@k8s-master:~/kube-conf# kubectl get svc|grep maven
ph-service NodePort 10.98.152.31 <none> 8080:31002/TCP 4m
可以發現,暴露的埠是31002
使用谷歌訪問頁面
http://192.168.10.130:31002/
效果如下:
使用k8s-node1 的ip
http://192.168.10.131:31002/
效果同上!
九、更新應用程式碼
開啟本地的專案springbootdemo,修改檔案IndexController.java
路徑如下:
springbootdemo\src\main\java\com\example\demo\web\controller
修改下面2行內容,把數字加1
jsonObject.put("welcome2", "2");
jsonObject.put("welcome7", "7");
重新提交到gitlab,然後重新構建一次,點選Build Now
等待構建成功後,重新整理頁面
發現內容已經更新了!
文字參考連結:
https://linux265.com/news/3465.html
https://www.cnblogs.com/aguncn/p/9789320.html
https://juejin.im/post/5c07b1126fb9a049e82b4cfe
分類: python 運維開發 標籤: Jenkins