一、環境版本清單:
- docker??26.1.4
- JDK 17.0.28
- Mysql 8.0.27
- Redis 6.0.5
- nacos 2.5.1
- maven 3.8.8
- jenkins 2.492.2
二、服務架構:有gateway,archives,system這三個服務
三、部署步驟
四、安裝linux
五、在linux上安裝redis,nacos,mysql, maven
六、安裝docker-ce?
可以參考這個文章?Linux安裝最新版Docker完整教程(建議收藏)_linux安裝docker教程-CSDN博客
七、使用docker部署安裝jenkins
可以參考這個文章
【Docker安裝Jenkins打包SpringBoot應用為docker鏡像并運行】_jenkins打包docker鏡像-CSDN博客
?#創建jenkins_home數據掛載目錄
mkdir /usr/local/jenkins_home
#賦值權限,否則后慢慢掛載會失敗,這里我們給最高權限
chmod -R 777 /usr/local/jenkins_home
#拉取jenkins鏡像?
docker pull jenkins/jenkins:lts
#啟動jenkins容器
docker run -d --name=jenkins -p 8080:8080 --privileged=true \
-v /usr/local/jenkins_home:/var/jenkins_home \
-v /usr/local/java/jdk-17.0.12:/usr/local/java/jdk-17.0.12?\
-v /usr/local/apache-maven-3.8.8:/usr/local/apache-maven-3.8.8 \
-v $(which docker):/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock jenkins/jenkins:lts
#授予docker的操作權限給jenkins等容器使用
chmod a+rw /var/run/docker.sock
參數說明:
-v /usr/local/jenkins_home:/var/jenkins_home:是對容器內存儲Jenkins的一些配置信息的文件夾
-v /usr/local/java/jdk-17.0.12:/usr/local/java/jdk-17.0.12?:是把linux下的jdk和容器內的關聯(配置Jenkins時使用)
-v /usr/local/apache-maven-3.8.8:/usr/local/apache-maven-3.8.8:是把linux下的maven和容器內的關聯(配置Jenkins時使用)
-v $(which docker):/usr/bin/docker:是把linux下的docker和容器內的關聯
-v /var/run/docker.sock:/var/run/docker.sock:是可以在Jenkins容器里使用我們Linux下的docker
其中容易踩坑的是:授予docker的操作權限給jenkins等容器使用,如果不賦予權限,后面在jenkins中使用shell腳本執行docker命令時,會報沒有權限執行docker命令
#授予docker的操作權限給jenkins等容器使用
chmod a+rw /var/run/docker.sock
后面就開始部署項目,其中容易踩坑的就是,shell腳本和Dockerfile文件
首先,我們已經將 Linux 上的 jenkins_home
目錄掛載到了 Jenkins 容器內,作為數據卷。這意味著 Jenkins 容器使用這個目錄來存儲其所有數據,包括構建后的 Java 程序包。通過這種方式,我們可以確保 Jenkins 容器內的 jenkins_home
目錄與主機上的對應目錄保持同步。因此,在部署過程中,Java 應用程序會在 Jenkins 容器中的 jenkins_home
目錄下被打包,并且由于該目錄被掛載到 Linux 主機上,我們可以在主機上直接訪問這些打包好的文件。接下來,讓我們看一下打包后我們的服務架構是如何組織的。
從上面可以看到默認工作目錄是jenkins_home/workspace/項目名稱(jenkins新建任務時的項目名稱)
首先要明白一件事,就是我們有是微服務,那就會有很多個服務,難道要為每一個服務都重新從git上拉代碼,打包,發布嗎?那肯定是不對的,因為jenkins會對每一個任務都進行打包,那么這個workspace目錄下就會多很多個只是名字不一樣但是內容一模一樣的目錄,就會導致內存不足。
所以我想到一個解決方法就是,先新建一個jenkins任務使用maven打包但不執行shell腳本,也就是 上面的 lx-root,然后再為每一個服務新建一個任務不打包,只去執行shell腳本運行上面已經打包好的jar包。
步驟:先執行 lx-root 再執行別的服務
shell腳本:
#!/bin/bash
# 服務名稱
SERVER_NAME=lx-modules-archives
echo $JAVA_HOME
java -version
# 源jar名稱,mvn打包之后,target目錄下的jar包名稱
JAR_NAME=lx-modules-archives
# jenkins下的我們要執行的目錄,target上一級目錄
JENKINS_HOME=/var/jenkins_home/workspace/lx-root/lx-modules/lx-modules-archives
# 等待三秒
echo sleep 3s
sleep 1
echo sleep 2s
sleep 1
echo sleep 1s
sleep 1
echo "結束進程完成"
cd $JENKINS_HOME/target
cp $JENKINS_HOME/Dockerfile $JENKINS_HOME/target
# 修改文件權限
chmod 755 $JAR_NAME.jar
echo "看看docker能不能用"
docker -v
echo "停止容器"
# 停止容器
docker stop $SERVER_NAME
echo "刪除容器"
# 刪除容器
docker rm $SERVER_NAME
echo "刪除鏡像"
# 刪除鏡像
docker rmi $SERVER_NAME
echo "打包鏡像"
# 打包鏡像
docker build -t "$SERVER_NAME" .
echo "運行鏡像"
# 運行鏡像
docker run -d --network host --name ${SERVER_NAME} $SERVER_NAME
Dockerfile:
FROM openjdk:17
# 設置維護者信息(可選)
LABEL maintainer="lx"
# 設置工作目錄
WORKDIR /app# 將當前目錄下的 jar 包復制到容器中的 /app 目錄下
COPY lx-modules-archives.jar /app/lx-modules-archives.jar# 暴露應用程序運行時的端口(這里假設你的 Spring Boot 應用監聽的是 9999 端口)
EXPOSE 9302# 定義環境變量(可選)
ENV JAVA_OPTS=""# 啟動應用
ENTRYPOINT ["sh", "-c", "java -jar /app/lx-modules-archives.jar"]
注意點一、?需要注意的是,shell腳本里我們已經使用 cd $JENKINS_HOME/target 進入了 target 目錄,后面在Dockerfile里使用COPY lx-modules-archives.jar /app/lx-modules-archives.jar 時,要直接使用COPY lx-modules-archives.ja 而不需要 COPY /target/lx-modules-archives.jar,否則會找到jar包。
注意點二、還有一個注意點是我在運行我們build好的鏡像之后
# 運行鏡像
docker run -d --network host --name ${SERVER_NAME} $SERVER_NAME
運行鏡像加了一個?--network host,這個主要是為了讓docker容器和linux使用同一個網絡通信,不使用端口映射。為什么要這樣呢?
因為我在配置文件里連接nacos和redis寫的127.0.0.1,那么docker在運行我們的服務時就會連接本地,但是我沒在docker容器內部部署nacos和redis,而是部署在了linux上,而linux和nacos默認使用的是不同的網絡,默認是橋接模式。
因為我們知道正常運行容器時 docker run -d --name=jenkins -p 8080:8080 使用的是端口映射的方式進行類似反向代理的功能,實際上網絡還是不通信的。
詳細的可以看下這個文章
詳解Docker的網絡模式之host模式(host網絡模式)_docker host網絡-CSDN博客
注意點三、我們在啟動服務時連接nacos可能會出現超時現象,發現8848端口也開放防火墻了,
從日志看到有一個9848的端口也一直報錯,所有把9848端口也開放防火墻就可以了
firewall-cmd --permanent --add-port=9848/tcp?
八、效果預覽
?
?