一、概述
講正文開始前先回顧一下以往傳統的代碼部署方式。
通常運維人員在接到代碼(新項目)上線的任務前都要做大量的准備工作,包括:物理主機、虛擬機、代碼運行環境、數據庫安裝配置、各種帳號創建,、運行后期的系統監控、應用的日志收集,性能優化等一系列的工作。
想一想這個流程不是很復雜但是很繁瑣,效率低下,如需要調試還需要給開發人員提供線上系統權限等等,細節沒有注意的話,還會造成解決問題的難度等各種問題。
OK,說完以上的問題,那接下來就有相對應的解決方案。
方案大概的架構組成:
Jenkins+Gitlab+Harbor+Rancher+k8s
各個組件的功能描述
Jenkins
(1)下載gitlab中項目代碼
(2)負載執行鏡像的構建、上傳下載
(3)部署到k8s集群
Gitlab
(1)項目代碼以及配置
(2)Dockerfile文件
Harbor
這個是vmware公司開源的docker鏡像倉庫管理系統,比較方便管理維護鏡像
(1)負責構建后鏡像的存儲
Rancher
容器編排管理工具
(1)更新stack/service
(2)實現服務的擴容縮容
k8s
(1)簡化應用部署
(2)提高硬件資源利用率
(3)健康檢查和自修復
(4)自動擴容縮容
(5)服務發現和負載均衡
架構圖
架構圖說明
項目開發語言是java,使用了比較流行的spring boot框架,manven更新源采用阿里雲,編譯生成jar文件
① 開發人員提交代碼到gitlab
② 手動執行jenkins構建(或者gitlab鈎子觸發jenkins執行構建),下載最新版本的代碼,代碼里面包含Dockerfile
③ jenkins執行shell腳本:mvn編譯生成jar文件。通過docker build 指令打包成鏡像
④ 上傳構建好的鏡像push到harbor鏡像倉庫
⑤ jenkins遠程到k8s master節點,更新service鏡像地址,達到更升級容器的目的(也就是更新代碼版本)。
以上流程完整的實現了CI/CD,這里主要是jenkins部分是關鍵位置之一。
二、准備環境
環境說明
系統 | ip | 主機名 | 配置 | 版本 |
CentOS 7.6 | 10.212.20.94 | k8s-master | 2核4g | Kubernetes1.18.1 |
CentOS 7.6 | 10.212.20.240 | k8s-node01 | 2核4g | Kubernetes1.18.1 |
CentOS 7.6 | 10.212.82.89 | jenkins | 2核4g | 2.222.4 |
CentOS 7.6 | 10.212.82.90 | gitlab | 2核4g | 10.5.1 |
CentOS 7.6 | 10.212.82.86 | harbor | 2核4g | v2.0.0 |
CentOS 7.6 | 10.212.82.87 | rancher | 2核4g | v2.4.3 |
關於k8s 1.18.1安裝,請參考鏈接:
https://www.cnblogs.com/xiao987334176/p/12696740.html
關於jenkins安裝,請參考鏈接:
https://www.cnblogs.com/xiao987334176/p/13032339.html
關於Gitlab和Harbor安裝,請自行百度
關於rancher安裝以及導入現有k8s集群,請參考鏈接:
https://www.cnblogs.com/xiao987334176/p/12965945.html
項目說明
基於Spring Boot/Spring Security/thymeleaf的通用后台管理系統
項目地址:
https://github.com/jonsychen/admin
此項目依賴於mysql,因此需要提前在Rancher里面部署mysql才行。
三、Rancher操作
mysql部署
登錄k8s-node01主機,創建數據目錄
mkdir -p /data/mysql/data
訪問Harbor后台,點擊部署服務
端口映射
設置環境變量
TZ=Asia/Shanghai MYSQL_ROOT_PASSWORD=abcd@1234
數據卷映射
點擊啟動
代碼配置
下載代碼:https://github.com/jonsychen/admin
解壓之后,進入目錄admin-master\src\main\resources
修改application-default.yaml,修改紅色部分。
server: port: 8088 compression: enabled: true connection-timeout: 3000 debug: false ##登錄記住我的token加密key remember: key: yintong ##actuator config,actuator運行在一個獨立的webappcontext中,see AnnotationConfigEmbeddedWebApplicationContext management: context-path: /management security: enabled: false spring: application: name: admin datasource: url: jdbc:mysql://db-mysql.default.svc.cluster.local:3306/admin?characterEncoding=utf-8 username: root password: abcd@1234
說明:
port: 8088 項目運行的端口號
db-mysql.default.svc.cluster.local 表示db-mysql服務的svc地址。
格式說明:服務名.命令空間.default.svc.cluster.local ,其中服務名和命名空間是根據實際情況來的,后半部分是固定的。這一長串域名,會解析為svc地址。
password: abcd@1234 mysql的root用戶密碼
application-prod.yaml的配置修改同上。
在此項目的根目錄創建dockerfile
FROM mayan31370/openjdk-alpine-with-chinese-timezone:8-jdk ADD admin-0.1.0.jar / EXPOSE 8088 ENTRYPOINT [ "java","-jar","/admin-0.1.0.jar"]
此時頂層目錄結構如下:
# tree -L 1 . ├── dockerfile ├── etc ├── pom.xml ├── README.md └── src
將此項目代碼,提交到gitlab中。
sql導入
登錄k8s-master節點,查看svc映射端口。因為使用Rancher部署mysql時,nodeport端口是隨機的。
# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE db-mysql ClusterIP 10.1.116.0 <none> 3306/TCP 61s db-mysql-nodeport NodePort 10.1.86.36 <none> 3306:31959/TCP 61s kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 20d
可以看到隨機映射的端口是31959
使用navicat軟件連接mysql
新建數據庫book
create database admin default character set utf8mb4 collate utf8mb4_unicode_ci;
進入book,執行項目中的sql文件,路徑為:etc/ddl.sql
執行成功后,表如下:
Harbor配置
新建一個項目java,訪問級別是公開。注意:設置公開后,下載鏡像不需要認證。
推送鏡像
進入jenkins主機,下載gitlab代碼。
git clone ssh://git@10.212.20.94:/home/git/git_storage/admin-master
修改docker配置,增加Harbor庫地址。
vim /etc/docker/daemon.json
增加insecure-registries
{"insecure-registries": ["10.212.82.86"]}
重啟服務
systemctl restart docker
登錄Harbor,否則無法推送鏡像
docker login 10.212.82.86:1180
進入項目目錄,使用mvn編譯代碼
mvn -f pom.xml clean package
推送鏡像,執行命令:
cp dockerfile target/ cd target docker build -t 10.212.82.86:1180/java/admin-master:1 . docker push 10.212.82.86:1180/java/admin-master:1 docker rmi 10.212.82.86:1180/java/admin-master:1
admin-master部署
登錄k8s-node01節點
修改docker配置,增加Harbor庫地址。
vim /etc/docker/daemon.json
增加insecure-registries
{"insecure-registries": ["192.168.10.122"]}
重啟服務
systemctl restart docker
訪問Harbor后台,點擊部署服務
端口映射
點擊啟動
等待幾分鍾,Running表示運行正常。
登錄k8s-master節點,查看svc映射端口。因為使用Rancher部署時,nodeport端口是隨機的。
# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE admin-master ClusterIP 10.1.10.23 <none> 8088/TCP 10m admin-master-nodeport NodePort 10.1.238.46 <none> 8088:31581/TCP 10m db-mysql ClusterIP 10.1.116.0 <none> 3306/TCP 61s db-mysql-nodeport NodePort 10.1.86.36 <none> 3306:31959/TCP 61s kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 20d
可以看到nodeport映射的隨機端口是31581
訪問admin-master
http://10.212.20.94:31581/
輸入用戶名和密碼,都是root
首頁效果如下:
四、jenkins操作
前面已經通過Rancher部署了mysql和admin-master,接下來演示一下,如何通過jenkins實現基於Pipeline,實現發布和回滾。
安裝插件
Git Parameter
這個插件是用來做參數化構建的
新建job
新建一個job,名稱為:test_admin,選擇流水線。
通用設置
參數化構建
Pipeline腳本
完整代碼如下:
env.CREDENTIALSID = '7a294fc5-2b2b-4d2d-92ff-54324e1b032a' env.BRANCHES = 'master' env.GIT_URL = 'ssh://git@10.212.20.94:/home/git/git_storage/admin-master' env.HARBOR_PROJECT = '10.212.82.86:1180/java/admin-master' env.PROJECT = 'admin-master' env.K8S_MASTER = '10.212.20.94' env.NAMESPACE = 'default' node { if (env.Status == 'Deploy'){ stage('code pull') { checkout([$class: 'GitSCM', branches: [[name: env.BRANCHES]], doGenerateSubmoduleConfigurations: false, userRemoteConfigs: [[credentialsId: env.CREDENTIALSID, url: env.GIT_URL]]]) } stage('code Build') { sh 'mvn -f pom.xml clean package' } stage('docker push') { sh 'cd ${WORKSPACE} && cp dockerfile target' sh 'cd ${WORKSPACE}/target && docker build -t ${HARBOR_PROJECT}:${BUILD_NUMBER} .' sh 'docker push ${HARBOR_PROJECT}:${BUILD_NUMBER}' sh 'docker rmi ${HARBOR_PROJECT}:${BUILD_NUMBER}' } stage('k8s deploy') { sh 'ssh ${K8S_MASTER} "kubectl -n ${NAMESPACE} set image deploy ${PROJECT} *=${HARBOR_PROJECT}:${BUILD_NUMBER}"' } }else{ stage('k8s rollback') { sh 'ssh ${K8S_MASTER} "kubectl -n ${NAMESPACE} set image deploy ${PROJECT}*=${HARBOR_PROJECT}:${BUILD_ID}"' } } }
根據實際情況,修改紅色文字參數,也就是全局變量。
說明:
7a294fc5-2b2b-4d2d-92ff-54324e1b032a 這個是jenkins全局憑據,針對gitlab設置的。
點擊構建
直接點擊構建
構建成功后,效果如下:
如果需要回滾到上一個版本,輸入BUILD_ID。
由於最近成功一次的BUILD_ID是10,所以輸入9
效果如下:
本文參考鏈接:
https://blog.51cto.com/andylhz2009/2053741