目的
? ? ? ?通過當(dāng)前文檔的內(nèi)容赔退,可以將springboot類的微服務(wù)項目基于Docker自動構(gòu)建出成品,可以省去了大量的項目部署時間以及項目依賴環(huán)境的部署時間已骇。
? ? ? ?閱讀本章內(nèi)容离钝,請確保你已掌握Docker到基本使用票编,如未滿足該要求,請到Docker操作指南中進(jìn)行學(xué)習(xí)卵渴。
處理流程
- 提交項目業(yè)務(wù)代碼和構(gòu)建代碼到SVN
- Jenkins 構(gòu)建任務(wù)
- 部署包上傳FTP
- 測試人員從FTP下載部署包慧域,使用腳本一鍵安裝部署包,開始測試
整體流程如圖所示:
下面就圍繞上面到處理流程進(jìn)行微服務(wù)項目在Docker環(huán)境下到構(gòu)建及部署教程浪读。
微服務(wù)項目
下圖是整個項目到結(jié)構(gòu)圖:
業(yè)務(wù)代碼及配置說明
? ? ? ?業(yè)務(wù)代碼正常修改昔榴,正常提交到SVN
? ? ? ?在src/main/resources下到application.yml文件中,有如下代碼:
db:
server: 192.168.7.200
port: 3306
user: root
pwd: Admin@123
redis:
host: 127.0.0.1
pwd: Admin@123
spring:
profiles: dev
redis:
host: ${db.redis.host}
password: ${db.redis.pwd}
datasource:
url: jdbc:mysql://${db.server}:${db.port}/ms-user?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
driver-class-name: com.mysql.jdbc.Driver
username: ${db.user}
password: ${db.pwd}
其中碘橘,關(guān)于db部分的互订,是我自定義的,用于在單個docker容器啟動的時候痘拆,可以動態(tài)的設(shè)置其對應(yīng)的參數(shù)值仰禽,其實(shí)這個參數(shù)值,可以使用原生的配置項纺蛆,只不過我感覺原生的太長了吐葵,不利于敲寫docker的啟動命令,比如桥氏,設(shè)置數(shù)據(jù)庫的連接地址温峭,如果使用原生的配置項,則需要以下形式:
docker run image-app --spring.datasource.url=jdbc:mysql://x.x.x.x:port/ms-user?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
這樣的編寫字支,是很不優(yōu)雅的凤藏,所以,我設(shè)置了一個簡短的參數(shù)用來映射到已經(jīng)固定到其他參數(shù)項中堕伪。
例如揖庄,設(shè)置連接數(shù)據(jù)庫的地址,可以在啟動的時候刃跛,指定為 --DB_SERVER=x.x.x.x抠艾。
部署代碼配置說明
? ? ? ?在項目目錄中的Docker目錄中,存在mysql桨昙,redis的項目環(huán)境依賴的部署配置检号,如圖所示:
項目依賴環(huán)境:mysql鏡像配置
? ? ? ?mysql的基礎(chǔ)鏡像已經(jīng)在192.168.7.68上構(gòu)建完成,且鏡像中已經(jīng)包含了很多配置項蛙酪,可以直接拿過來使用齐苛,而不用再次的去繼承mysql官方鏡像并且定制各項配置。
? ? ? ?項目依賴的mysql鏡像中桂塞,包含了一個初始化的sql腳本凹蜂,通過繼承基礎(chǔ)mysql鏡像,生成一個新的帶當(dāng)前項目數(shù)據(jù)庫的鏡像。
鏡像配置
? ? ? ?具體的鏡像構(gòu)建玛痊,請參照以下代碼或在項目中查看:
#繼承mysql的基礎(chǔ)鏡像
FROM 192.168.7.68:5000/sbr/mysql:1.0.0
#指定維護(hù)人
MAINTAINER 圣博潤研發(fā)中心
#將容器啟動后汰瘫,執(zhí)行的腳本拷貝到容器內(nèi)的/docker-entrypoint-initdb.d下,該目錄會自動執(zhí)行sql腳本
COPY ms-user.sql /docker-entrypoint-initdb.d
RUN chmod 775 /docker-entrypoint-initdb.d/ms-user.sql
#聲明容器暴漏的端口擂煞,只是聲明混弥,沒有其他作用
EXPOSE 3306
? ? ? ?該構(gòu)建文件中,需要注意以下情況:
- 在將數(shù)據(jù)庫腳本復(fù)制到鏡像中后对省,需要為該腳本設(shè)置權(quán)限蝗拿,否則,在啟動容器的時蒿涎,會導(dǎo)致mysql的容器啟動失敗哀托,原因是(ms-user.sql)腳本沒有執(zhí)行權(quán)限。
初始化腳本內(nèi)容需要注意:在mysql官方鏡像中提供了容器啟動時自動執(zhí)行/docker-entrypoint-initdb.d文件夾下的腳本的功能(包括shell腳本和sql腳本) docker-entrypoint.sh中的代碼如下:
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done
就是說只要把你自己的初始化腳本放到/docker-entrypoint-initdb.d/文件夾下劳秋,mysql就會讀取其中的文件并執(zhí)行仓手,但是,執(zhí)行順序玻淑,我們是無法控制的俗或,所以,請盡量將初始化腳本內(nèi)容寫到一個文件中岁忘。
項目依賴環(huán)境:redis鏡像配置
? ? ? ?項目同樣也依賴redis服務(wù),所以区匠,也需要創(chuàng)建一個redis的鏡像干像。
鏡像配置
? ? ? ?具體的鏡像構(gòu)建,請參照以下代碼或在項目中查看:
#繼承redis基礎(chǔ)鏡像驰弄,用來添加屬于項目的一些配置
FROM 192.168.7.68:5000/sbr/redis:1.0.0
#編寫人/維護(hù)人
MAINTAINER 圣博潤研發(fā)中心
#聲明容器暴漏的端口
EXPOSE 6379
該鏡像麻汰,在目前來看,并沒有什么需要注意的地方戚篙。
項目鏡像配置
? ? ? ?將項目的jar包打進(jìn)基于jre的鏡像中五鲫,可以生成我們的項目鏡像。
鏡像配置
? ? ? ?具體的鏡像構(gòu)建岔擂,請參照以下代碼或在項目中查看:
#繼承jre8的基礎(chǔ)鏡像
FROM 192.168.7.68:5000/sbr/jre8:1.0.0
#編寫人/維護(hù)人
MAINTAINER 圣博潤研發(fā)中心
#將jar包復(fù)制到容器根目錄
COPY ms-auth-2.1.2051-SNAPSHOT.jar /ms-auth-2.1.2051-SNAPSHOT.jar
#聲明端口
EXPOSE 9003
#容器啟動后位喂,執(zhí)行的命令
ENTRYPOINT ["java", "-jar", "/ms-auth-2.1.2051-SNAPSHOT.jar"]
至此,我們的微服務(wù)項目的所有鏡像已經(jīng)制作完畢乱灵,后續(xù)需要在jenkins中稍加配置處理塑崖,就可以生成我們想要的鏡像。
compose一鍵構(gòu)建
? ? ? ?在Docker操作指南中痛倚,我們知道规婆,使用compose可以僅僅通過一個命令來根據(jù)配置文件構(gòu)建多個鏡像及容器。
鏡像構(gòu)建(build-compose.yml) 配置
使用如下配置文件:
#使用的compose版本
version: '3'
#compose關(guān)鍵字,定義services
services:
#service的名稱 sbr_redis
sbr_redis:
#service中容器的名稱
container_name: sbr_redis
#使用當(dāng)前目錄下的redis目錄下的Dockerfile來創(chuàng)建鏡像
build: ./redis
#當(dāng)前服務(wù)向外暴漏的端口
ports:
- "6379:6379"
#service的名稱 sbr_mysql
sbr_mysql:
#service中容器的名稱
container_name: sbr_mysql
#使用當(dāng)前目錄下的mysql目錄下的Dockerfile來創(chuàng)建鏡像
build: ./mysql
#當(dāng)前服務(wù)向外暴漏的端口
ports:
- "3306:3306"
#service的名稱 sbr_user_auth
sbr_user_auth:
#service中容器的名稱
container_name: sbr_app
#使用當(dāng)前目錄下的app目錄下的Dockerfile來創(chuàng)建鏡像
build: ./app
#當(dāng)前服務(wù)向外暴漏的端口
ports:
- "9003:9003"
通過
docker-compose build
來進(jìn)行上述mysql抒蚜、redis掘鄙、微服務(wù)項目鏡像的的構(gòu)建和容器的啟動。我們同樣可以將這段構(gòu)建指令配置到j(luò)enkins中去嗡髓。
部署配置
? ? ? ?在項目源碼目錄中操漠,我們發(fā)現(xiàn),還有兩個文件沒有介紹其內(nèi)容:
現(xiàn)在器贩,我們來看以下這兩個文件是干什么到颅夺。
deploy-compose.yml配置
? ? ? ?我們已經(jīng)知道,通過compose可以一鍵啟動docker到多個容器蛹稍,我們這里就采用來這種方式吧黄,而在上一節(jié)中,也有一個build-compose.yml到配置文件唆姐,那個文件中拗慨,其實(shí)配置的是,在jenkins構(gòu)建服務(wù)器中到構(gòu)建鏡像到配置奉芦。而在測試端也需要提供一個一鍵啟動到compose文件赵抢。所以這個deploy-compose.yml文件就是干這個用但。通過jenkins構(gòu)建后声功,我們已經(jīng)明確的知道了我們的鏡像名稱烦却,所以,可以通過以下配置來一鍵啟動容器先巴,啟動的容器都是受compose管理其爵,而不用我們?nèi)斯とun/create等操作:
#使用的compose版本
version: '3'
#compose關(guān)鍵字,定義services
services:
#service的名稱 sbr_redis
sbr_redis:
#service中容器的名稱
container_name: sbr_redis
#使用當(dāng)前目錄下的redis目錄下的Dockerfile來創(chuàng)建鏡像
image: docker_sbr_redis
#當(dāng)前服務(wù)向外暴漏的端口
ports:
- "6379:6379"
#service的名稱 sbr_mysql
sbr_mysql:
#service中容器的名稱
container_name: sbr_mysql
#使用當(dāng)前目錄下的mysql目錄下的Dockerfile來創(chuàng)建鏡像
image: docker_sbr_mysql
#當(dāng)前服務(wù)向外暴漏的端口
ports:
- "3306:3306"
#service的名稱 sbr_user_auth
sbr_user_auth:
#service中容器的名稱
container_name: sbr_app
#使用當(dāng)前目錄下的app目錄下的Dockerfile來創(chuàng)建鏡像
image: docker_sbr_user_auth
#當(dāng)前服務(wù)向外暴漏的端口
ports:
- "9003:9003"
#當(dāng)前容器使用的環(huán)境變量
environment:
- DB_SERVER=sbr_mysql
- DB_REDIS_HOST=sbr_redis
#當(dāng)前服務(wù)依賴depends_on配置的服務(wù)伸蚯,docker compose會優(yōu)先啟動依賴的服務(wù)
depends_on:
- sbr_mysql
- sbr_redis
具體說明已經(jīng)在配置文件中以注解的方式說明來出來摩渺。
部署腳本
? ? ? ?我們沒有必要提供compose相關(guān)的配置文件給測試人員,除非對方堅決的要這個文件剂邮,以達(dá)到他們自己控制容器操作的目的摇幻。
? ? ? ?那么,我們可以提供一個更加簡便的操作方式來啟動各個容器挥萌,那就是一個shell腳本:
#!/bin/bash
#定義可執(zhí)行函數(shù)的參數(shù)數(shù)組
parr=(load startup stop rm rma)
#定義檢查本機(jī)是否安裝了docker
checkDocker(){
dockerpath=$(which docker)
if [ ! -n "#dockerpath" ]; then
echo "未檢測到Docker..."
exit 1
fi
}
#載入tar包中的鏡像
load(){
checkDocker
#導(dǎo)入docker鏡像:mysql
echo "開始導(dǎo)入mysql鏡像...."
docker load < sbr_mysql.tar
#導(dǎo)入docker鏡像:redis
echo "開始導(dǎo)入redis鏡像...."
docker load < sbr_redis.tar
#導(dǎo)入docker鏡像:user_auth
echo "開始導(dǎo)入微服務(wù)應(yīng)用鏡像...."
docker load < user_auth.tar
}
#開始執(zhí)行docker容器的啟動
startup(){
checkDocker
echo "準(zhǔn)備啟動容器...."
docker-compose -f deploy-compose.yml up
}
#停止容器
stop(){
checkDocker
echo "準(zhǔn)備停止容器...."
docker-compose -f deploy-compose.yml stop
}
#刪除容器
rm(){
checkDocker
stop
echo "準(zhǔn)備刪除容器...."
docker-compose -f deploy-compose.yml rm
}
#刪除容器以及鏡像
rma(){
checkDocker
rm
echo "準(zhǔn)備刪除鏡像...."
docker_sbr_user_auth_image=$(docker image ls | grep docker_sbr_user_auth)
if [ -n "#docker_sbr_user_auth_image" ]; then
docker rmi docker_sbr_user_auth:latest
fi
docker_sbr_redis_image=$(docker image ls | grep docker_sbr_redis)
if [ -n "#docker_sbr_redis_image" ]; then
docker rmi docker_sbr_redis:latest
fi
docker_sbr_mysql_image=$(docker image ls | grep docker_sbr_mysql)
if [ -n "#docker_sbr_mysql_image" ]; then
docker rmi docker_sbr_mysql:latest
fi
}
if [ ! -n "$1" ] ;then
load
startup
else
if [[ "${parr[@]/$1/}" != "${parr[@]}" ]]; then
$1
else
echo $1":參數(shù)不能執(zhí)行绰姻,請輸入正確參數(shù)!"
exit
fi
fi
通過這個腳本,測試人員可以執(zhí)行以下命令來簡單的進(jìn)行容器管理:
- load:載入/導(dǎo)入所有鏡像,如 ./deploy load
- startup:啟動容器,如 ./deploy startup
- stop:停止容器瑞眼,如 ./deploy stop
- rm:刪除容器龙宏,如 ./deploy rm
- rma:刪除鏡像及容器,如 ./deploy rma
README文件介紹
該文件是交給測試人員進(jìn)行查看到,有以下幾點(diǎn)內(nèi)容:
- 部署腳本如何使用
- 項目升級說明
- 其他備注信息
Jenkins構(gòu)建
? ? ? ?jenkins構(gòu)建系統(tǒng):http://192.168.7.26/jenkins/
? ? ? ?jenkins的界面如圖所示:
我們的構(gòu)建任務(wù)在88.技術(shù)中伤疙,點(diǎn)擊去后银酗,如下圖所示:
構(gòu)建配置
SVN配置
svn配置信息如下圖所示:
- Repository URL:填寫項目svn地址
- Credentials:SVN賬戶信息
- Local module directory:將SVN項目down到什么位置辆影,如果是一個點(diǎn)(.),則表示將項目中到內(nèi)容down到88.技術(shù)/微服務(wù)2.0目錄下黍特,如果什么也沒有蛙讥,則會在微服務(wù)2.0目錄下創(chuàng)建一個項目名稱到目錄,然后再將項目內(nèi)容down到該目錄下
構(gòu)建配置
這一個配置是整個自動化構(gòu)建的核心
-
maven配置:
shell 操作代碼
#先查找jenkins服務(wù)器中是否已經(jīng)構(gòu)建了微服務(wù)項目鏡像
#如果已經(jīng)構(gòu)建灭衷,則刪除
docker_sbr_user_auth_image=$(docker image ls | grep docker_sbr_user_auth)
if [ -n "#docker_sbr_user_auth_image" ]; then
docker rmi docker_sbr_user_auth:latest
fi
#先查找jenkins服務(wù)器中是否已經(jīng)構(gòu)建了微服務(wù)項目依賴的redis鏡像
#如果已經(jīng)構(gòu)建次慢,則刪除
docker_sbr_redis_image=$(docker image ls | grep docker_sbr_redis)
if [ -n "#docker_sbr_redis_image" ]; then
docker rmi docker_sbr_redis:latest
fi
#先查找jenkins服務(wù)器中是否已經(jīng)構(gòu)建了微服務(wù)項目依賴的mysql鏡像
#如果已經(jīng)構(gòu)建,則刪除
docker_sbr_mysql_image=$(docker image ls | grep docker_sbr_mysql)
if [ -n "#docker_sbr_mysql_image" ]; then
docker rmi docker_sbr_mysql:latest
fi
#使用項目中的docker目錄下的build-compose.yml文件進(jìn)行構(gòu)建鏡像
docker-compose -f ./docker/build-compose.yml build
#如果88.技術(shù)/微服務(wù)2.0目錄下不存在deploy目錄翔曲,則創(chuàng)建deploy目錄
#如果存在deploy目錄迫像,則刪除deploy目錄下的所有文件,保留一個干凈的deploy目錄
if [ ! -d "deploy" ];then
mkdir deploy
else
rm -rf deploy/*
fi
#將項目源碼的docker目錄下的deploy-compose.yml 復(fù)制到deploy目錄下
cp docker/deploy-compose.yml deploy/deploy-compose.yml
#將將項目源碼的docker目錄下的script目錄下的deploy.sh復(fù)制到deploy目錄下
cp docker/script/deploy.sh deploy/deploy.sh
#將部署說明復(fù)制到deploy目錄
cp docker/README.txt deploy/README.txt
#進(jìn)入deploy目錄瞳遍,并進(jìn)行鏡像的保存闻妓,保存的鏡像會存到deploy目錄下
cd deploy
docker save -o user_auth.tar docker_sbr_user_auth:latest
docker save -o sbr_redis.tar docker_sbr_redis:latest
docker save -o sbr_mysql.tar docker_sbr_mysql:latest
#將導(dǎo)出的鏡像打成gz包,并刪除源包
tar -zcvf deploy.tar.gz * --remove-files
FTP文件傳輸配置
此時,jenkins已經(jīng)在本機(jī)構(gòu)建好了所需的鏡像掠械,并且由缆,已經(jīng)在指定目錄將導(dǎo)出的鏡像打成了gz包,然后我們將該文件發(fā)送到FTP服務(wù)器之后猾蒂,測試人員就可以下載到本機(jī)進(jìn)行測試了均唉。
-
FTP配置
到此,整個jenkins到構(gòu)建已經(jīng)完成肚菠,我們也可以通過構(gòu)建控制臺來查看實(shí)時到構(gòu)建信息舔箭。
部署簡要
測試人員操作說明:
到FTP服務(wù)器ftp://192.168.7.220中的【測試版本】-【88.技術(shù)】-【微服務(wù)2.0】中下載最新部署包和部署說明
部署包:deploy.tar.gz 部署說明:README.txt
部署包包含:user_auth.tar(微服務(wù)項目鏡像),sbr_redis.tar(微服務(wù)項目依賴的redis鏡像)蚊逢,sbr_mysql.tar(微服務(wù)項目依賴的mysql鏡像)限嫌,deploy-compose.yml(測試人員無需關(guān)注),deploy.sh(測試人員主要的操作文件)
-
deploy.sh的使用:
- 使用 tar -zxvf deploy.tar.gz來解壓部署包
- 腳本一鍵執(zhí)行:
- 腳本會檢查本機(jī)是否安裝docker时捌,如果未安裝,會給出提示
- 給腳本賦予可執(zhí)行權(quán)限: chmod 775 deploy.sh
- 腳本參數(shù)介紹:
如果只是輸入了 ./deploy 而不附帶任何參數(shù)炉抒,該腳本會自動導(dǎo)入鏡像并啟動容器
load:載入所有鏡像,如 ./deploy load
startup:啟動容器,如 ./deploy startup
stop:停止容器奢讨,如 ./deploy stop
rm:刪除容器,如 ./deploy rm
rma:刪除鏡像及容器,如 ./deploy rma
至此焰薄,微服務(wù)項目在jenkins中基于Docker的構(gòu)建的內(nèi)容已經(jīng)完畢拿诸,若有不足之處,請予以支持與補(bǔ)充塞茅。謝謝亩码。