自動部署Java項目
一、實驗環境:
Dev: 192.168.10.11
Gitlab-server: 192.168.10.12
Jenkins-server: 192.168.10.13
Web-server: 192.168.10.15
# Java應用的打包格式:war包、jar包
JAR包部署
獨立應用:通過java -jar命令運行JAR文件,適用於命令行工具或獨立的桌面應用
WAR包部署
將WAR包部署到Servlet容器(如Tomcat)中,容器會自動解壓並啓動Web應用。
將WAR文件放入webapps目錄,Tomcat會自動解壓並加載應用。
如果是獨立的Java應用或工具,使用JAR包。
如果是Web應用,需要部署到Servlet容器,使用WAR包。
二、創建新項目及新業務上線
1、在web-server上配置運行tomcat
安裝jdk:
tar xf jdk-8u91-linux-x64.tar.gz
mv jdk1.8.0_91/ /usr/local/jdk
#修改配置文件:
vim /etc/profile
文件最後添加如下內容:
export TOMCAT_HOME=/usr/local/tomcat8
export JAVA_HOME=/usr/local/jdk
export PATH=${TOMCAT_HOME}/bin:${JAVA_HOME}/bin:$PATH
export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
#使配置生效:
source /etc/profile
#安裝tomcat:
tar xf apache-tomcat-8.5.78.tar.gz
mv apache-tomcat-8.5.78 /usr/local/tomcat8
/usr/local/tomcat8/bin/startup.sh
#驗證:
netstat -lntp | grep :8080
瀏覽器:http://192.168.10.15:8080
2、在web-server主機上安裝配置數據庫
首先需要確保在自己的電腦上已經安裝有mysql或mariadb(包mariadb-server)數據庫,在該數據庫下創建一個數據庫實例,名稱為demo
[root@web-server ~]# yum -y install mariadb-server mariadb
[root@web-server ~]# systemctl start mariadb
[root@web-server ~]# mysqladmin -uroot -p password "123456"
配置root密碼123456(密碼不要變)
[root@web-server ~]# mysql -uroot -p123456
MariaDB [(none)]> create database demo;
MariaDB [(none)]> use demo;
3、在demo下執行以下語句,用於創建數據庫表及初始化數據
CREATE TABLE `customer` (
(自增主鍵)',
客户名稱',
聯繫人',
電話號碼',
郵箱地址',
備註',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
添加記錄
-- ----------------------------
INSERT INTO `customer` VALUES (1, 'customer1', 'Jack', '13569548632', 'Jack@gmail.com', NULL);
INSERT INTO `customer` VALUES (2, 'customer2', 'Rose', '13896542847', 'Rose@gmail.com', NULL);
INSERT INTO `customer` VALUES (3, 'customer3', 'Visa', '13286549874', NULL, NULL);
SET FOREIGN_KEY_CHECKS = 1;
2、在gitlab-server主機上創建新項目
創建用户dev_adm(master身份)、新組dev、項目dev1
3、在dev主機上pull/push代碼
開發人員將個人主機ssh公鑰複製到gitlab個人賬號(dev_adm)--setting--SSH KEYS中克隆下載項目(以dev_adm為例)
git clone git@192.168.10.12:dev/dev1.git
修改文件內容,再推送上傳代碼(管理員身份)
cd dev1/
echo 123456 > new.txt
git add -A .
git commit -m "add new.txt"
git push -u origin master
4、jenkis上關聯gitlab
點擊左上角logo--回到主頁面--選擇新項目“New Item”--填寫項目名dev1--選擇項目類型“Freestyle project”--save保存
配置項目dev1--源代碼管理--git--填寫gitlab網址(git@192.168.10.12:dev/dev1.git)--save保存
選擇項目dev1--左側選擇“build now”--下面構建歷史出現藍色標誌--選擇藍色標誌下拉列表--console output--輸出執行過程
jenkins服務器上查看/var/lib/jenkins/workspace目錄,會有項目同名文件夾dev1,保存了git clone 的所有代碼
5、在jenkins上編寫上傳到目標主機的腳本
vim /scripts/dev1.sh
添加:
#!/bin/sh
CODE_DIR=/var/lib/jenkins/workspace/dev1/
WEB_DIR=/usr/local/tomcat8/
IP=192.168.8.19
TIME=$(date +%F-%H-%M-%S)
cd $CODE_DIR && tar zcf /tmp/web-${TIME}.tar.gz ./*
scp /tmp/web-${TIME}.tar.gz $IP:$WEB_DIR
ssh root@$IP "cd $WEB_DIR && mkdir web-$TIME"
ssh root@$IP "cd $WEB_DIR && tar xf web-${TIME}.tar.gz -C web-$TIME && rm -rf web-${TIME}.tar.gz"
ssh root@$IP "cd $WEB_DIR && rm -rf webapps/* "
ssh root@$IP "cd $WEB_DIR && mv web-${TIME}/* webapps && rm -rf web-${TIME}"
保存退出
6、如果目標主機是新主機,需要將jenkins公鑰傳到目標主機,執行腳本
ssh-copy-id root@192.168.10.15
sh /scripts/dev1.sh
目標主機測試並查看新業務文件
ls /usr/local/tomcat8/webapps/
7、手動構建,關聯腳本,自動上傳
項目dev1 -- configure -- buildsteps-- (Add build step)Execute shell -- sh /scripts/dev1.sh
8、jenkins關聯gitlab,實現自動構建上傳代碼
(1)jenkins:
dev1項目-- configure -- build triggers -- 勾選最長選項 -- 點擊高級advanced
-- 選擇Filter branches by name --在include填寫master -- 點擊generate生成令牌 -- 複製令牌和觸發器頂部url路徑-- save保存
e9316685f7303d23e4ceb9588d8740c9 用自己的令牌和URL路徑
http://192.168.8.17:8080/project/dev1
(2)gitlab:
dev1項目 -- settings -- integrations -- 把複製的令牌和url粘貼過來 -- add webhook
(3)開發人員dev_adm更新並push代碼,測試自動構建上傳。
克隆下載項目(如果不存在)
git clone git@192.168.10.12:dev/dev1.git
修改文件內容,再推送上傳代碼(管理員身份)
cd dev1/
複製代碼文件到當前目錄 (如chapter2-1.0.0.war)
git add -A
git commit -m "add war包"
git push -u origin master
(4)登錄tomcat網站,查看更新內容。
[root@localhost ~]# ls /usr/local/tomcat8/webapps/
chapter2-1.0.0 chapter2-1.0.0.war
客户端訪問:http://192.168.10.15:8080/chapter2-1.0.0/customer
以上實驗過程僅供於實驗,真實生產環境中還需針對真實環境做出變化。
下面我寫一些在真實生產環境中所需注意的事項:
1、安全性與訪問控制:
這是最核心的問題,也是最需要注意的。上面的實驗步驟的配置為了簡便,犧牲了大量安全性,這在生產環境中是絕對不允許的。
1)、harbor必須啓用HTTPS:
文檔問題:註釋掉了HTTPS配置,使用HTTP和不安全註冊表(insecure-registries)。
生產建議:
申請正式的SSL/TLS證書(或使用內部CA簽發的證書)
在harbor.yml中正確配置https相關路徑和端口(如443)
所有docker主機移除insecure-registries配置,改為信任harbor的CA證書(將CA證書放入/etc/docker/certs.d/your-harbor-ip/)目錄
這確保了鏡像推送、拉取過程中的通信安全,防止中間人做破壞。
2)、弱密碼與默認憑證:
文檔問題:使用了harbor12345、數據庫123456等簡單密碼。(在真實環境中,當然不能用!)
生產建議:為harbor、Maria DB、Jenkins等所有組件使用強密碼,比如大小寫字母+數字組合。定期更換密碼或者使用密鑰管理服務(如hashicorp vault)
3)、系統服務安全加固:
文檔問題:直接關閉了防火牆和SELinux。
生產建議:
不能完全禁用防火牆規則(如firewalld或iptables),只開放必要的端口(如harbor80/443,Jenkins8080,web80,ssh22)
建議將 SELinux 設置為 enforcing 模式,並針對 Docker 容器和數據目錄配置正確的 SELinux 策略,而不是直接禁用。這是重要的安全邊界。
4)、網絡隔離與安全組:
生產建議:將Jenkins、harbor、數據庫、web服務器等部署在不同的網絡分區或安全組中,嚴格控制它們之間的網絡訪問。例如,數據庫應該只允許web服務器訪問,而不應該暴露給Jenkin
2、高可用與可靠性
生產環境需要保證服務不中斷。
1)、單點故障:
文檔問題:所有服務(gitlab、Jenkins、harbor、DB)都是單節點。
生產建議:
Jenkins:搭建 Jenkins Master-Agent 集羣,避免構建任務阻塞和單點故障。
harbor:部署 Harbor 高可用集羣,通常需要共享存儲(如 NFS、Ceph)和外置數據庫/Redis。
數據庫:對 MariaDB 做主從複製或集羣
web服務:通過負載均衡器(如 Nginx, HAProxy)後面部署多個容器實例
2)、數據備份與恢復:
文檔問題:沒有提及任何備份策略,備份時在生產環境中最核心的防範後手,也是最重要的安全意識。
生產建議:
zhiding定期備份策略:
gitlab:備份代碼倉庫和配置
harbor:定期對鏡像倉庫進行全量備份
Jenkins:備份JENKINS_HOME目錄(包含任務、配置、憑證)
數據庫:定期進行mysqldump或使用武力備份工具
定期演練恢復流程,確保備份有效
3、配置管理與最佳:
1)、dockerfile優化:
文檔問題:基礎鏡像使用龐大的centos:7,構建過程冗長。
生產建議:
使用更小、更安全的基礎鏡像,如eclipse-temurin:8-jre(僅包含 JRE)或 alpine 版本。
使用.dockerignore 文件避免將不必要的文件(如本地 target/)加入構建上下文。
2)、鏡像版本管理:
文檔問題:使用了簡單的tag參數,容易混亂
生產建議:
鏡像Tag應包含有意義的版本號和Git Commit SHA (例如solo:1.0.0-abc1234)。這提供了完美的可追溯性。
避免使用latest等標籤用於生產環境
3)、數據庫連接:
文檔問題:應用直接通過IP連接單點數據庫
生產建議:
使用數據庫連接字符串(如MySQL Router)或服務發現,而不是硬編碼IP
在配置中使用數據庫秘密(從環境變量後密鑰管理服務讀取),而不是硬編碼在代碼裏
4)、Jenkins憑證管理:
文檔問題:將SSH密碼明文存儲在Jenkins憑證中。
生產建議:
優先使用SSH私鑰而不是用户名和密碼的組合進行遠程連接
定期更換密鑰
4、監控和日誌:
生產環境必須可觀測,還會有專門的監控人員全程監控,這點不需要擔心,只是需要在故障時及時進行排查以及恢復。
1)、監控:
生產建議:
為所有主機和容器部署監控(如prometheus Node Exporter)
監控關鍵指標:CPU、內存、磁盤、網絡
對Docker Daemon、容器狀態、Harbor服務狀態進行監控
使用Grafana進行可視化。
2)、日誌:
文檔問題:容器日誌默認存儲在比如年底,難以排查問題
生產建議:
配置docker的日誌驅動,將容器日誌集中收集到ELK或loki等日誌系統中。
這便於日誌聚合、搜索和分析
總結: