目的
通過目前文檔的内容,可以将springboot類的微服務項目基于Docker自動建構出成品,可以省去了大量的項目部署時間以及項目依賴環境的部署時間。
閱讀本章内容,請確定你已掌握Docker到基本使用,如未滿足該要求,請到Docker操作指南中進行學習。
處理流程
- 送出項目業務代碼和建構代碼到SVN
- Jenkins 建構任務
- 部署包上傳FTP
- 測試人員從FTP下載下傳部署包,使用腳本一鍵安裝部署包,開始測試
整體流程如圖所示:
下面就圍繞上面到處理流程進行微服務項目在Docker環境下到建構及部署教程。
微服務項目
下圖是整個項目到結構圖:
業務代碼及配置說明
業務代碼正常修改,正常送出到SVN
在src/main/resources下到application.yml檔案中,有如下代碼:
db:
server: 192.168.7.200
port: 3306
user: root
pwd: [email protected]
redis:
host: 127.0.0.1
pwd: [email protected]
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}
其中,關于db部分的,是我自定義的,用于在單個docker容器啟動的時候,可以動态的設定其對應的參數值,其實這個參數值,可以使用原生的配置項,隻不過我感覺原生的太長了,不利于敲寫docker的啟動指令,比如,設定資料庫的連接配接位址,如果使用原生的配置項,則需要以下形式:
docker run image-app --spring.datasource.url=jdbc:mysql://x.x.x.x:port/ms-user?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
這樣的編寫,是很不優雅的,是以,我設定了一個簡短的參數用來映射到已經固定到其他參數項中。
例如,設定連接配接資料庫的位址,可以在啟動的時候,指定為 --DB_SERVER=x.x.x.x。
部署代碼配置說明
在項目目錄中的Docker目錄中,存在mysql,redis的項目環境依賴的部署配置,如圖所示:
項目依賴環境:mysql鏡像配置
mysql的基礎鏡像已經在192.168.7.68上建構完成,且鏡像中已經包含了很多配置項,可以直接拿過來使用,而不用再次的去繼承mysql官方鏡像并且定制各項配置。
項目依賴的mysql鏡像中,包含了一個初始化的sql腳本,通過繼承基礎mysql鏡像,生成一個新的帶目前項目資料庫的鏡像。
鏡像配置
具體的鏡像建構,請參照以下代碼或在項目中檢視:
#繼承mysql的基礎鏡像
FROM 192.168.7.68:5000/sbr/mysql:1.0.0
#指定維護人
MAINTAINER 聖博潤研發中心
#将容器啟動後,執行的腳本拷貝到容器内的/docker-entrypoint-initdb.d下,該目錄會自動執行sql腳本
COPY ms-user.sql /docker-entrypoint-initdb.d
RUN chmod 775 /docker-entrypoint-initdb.d/ms-user.sql
#聲明容器暴漏的端口,隻是聲明,沒有其他作用
EXPOSE 3306
該建構檔案中,需要注意以下情況:
- 在将資料庫腳本複制到鏡像中後,需要為該腳本設定權限,否則,在啟動容器的時,會導緻mysql的容器啟動失敗,原因是(ms-user.sql)腳本沒有執行權限。
初始化腳本内容需要注意:在mysql官方鏡像中提供了容器啟動時自動執行/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就會讀取其中的檔案并執行,但是,執行順序,我們是無法控制的,是以,請盡量将初始化腳本内容寫到一個檔案中。
項目依賴環境:redis鏡像配置
項目同樣也依賴redis服務,是以,也需要建立一個redis的鏡像。
鏡像配置
具體的鏡像建構,請參照以下代碼或在項目中檢視:
#繼承redis基礎鏡像,用來添加屬于項目的一些配置
FROM 192.168.7.68:5000/sbr/redis:1.0.0
#編寫人/維護人
MAINTAINER 聖博潤研發中心
#聲明容器暴漏的端口
EXPOSE 6379
該鏡像,在目前來看,并沒有什麼需要注意的地方。
項目鏡像配置
将項目的jar包打進基于jre的鏡像中,可以生成我們的項目鏡像。
鏡像配置
具體的鏡像建構,請參照以下代碼或在項目中檢視:
#繼承jre8的基礎鏡像
FROM 192.168.7.68:5000/sbr/jre8:1.0.0
#編寫人/維護人
MAINTAINER 聖博潤研發中心
#将jar包複制到容器根目錄
COPY ms-auth-2.1.2051-SNAPSHOT.jar /ms-auth-2.1.2051-SNAPSHOT.jar
#聲明端口
EXPOSE 9003
#容器啟動後,執行的指令
ENTRYPOINT ["java", "-jar", "/ms-auth-2.1.2051-SNAPSHOT.jar"]
至此,我們的微服務項目的所有鏡像已經制作完畢,後續需要在jenkins中稍加配置處理,就可以生成我們想要的鏡像。
compose一鍵建構
在Docker操作指南中,我們知道,使用compose可以僅僅通過一個指令來根據配置檔案建構多個鏡像及容器。
鏡像建構(build-compose.yml) 配置
使用如下配置檔案:
#使用的compose版本
version: '3'
#compose關鍵字,定義services
services:
#service的名稱 sbr_redis
sbr_redis:
#service中容器的名稱
container_name: sbr_redis
#使用目前目錄下的redis目錄下的Dockerfile來建立鏡像
build: ./redis
#目前服務向外暴漏的端口
ports:
- "6379:6379"
#service的名稱 sbr_mysql
sbr_mysql:
#service中容器的名稱
container_name: sbr_mysql
#使用目前目錄下的mysql目錄下的Dockerfile來建立鏡像
build: ./mysql
#目前服務向外暴漏的端口
ports:
- "3306:3306"
#service的名稱 sbr_user_auth
sbr_user_auth:
#service中容器的名稱
container_name: sbr_app
#使用目前目錄下的app目錄下的Dockerfile來建立鏡像
build: ./app
#目前服務向外暴漏的端口
ports:
- "9003:9003"
通過
docker-compose build
來進行上述mysql、redis、微服務項目鏡像的的建構和容器的啟動。我們同樣可以将這段建構指令配置到jenkins中去。
部署配置
在項目源碼目錄中,我們發現,還有兩個檔案沒有介紹其内容:
現在,我們來看以下這兩個檔案是幹什麼到。
deploy-compose.yml配置
我們已經知道,通過compose可以一鍵啟動docker到多個容器,我們這裡就采用來這種方式,而在上一節中,也有一個build-compose.yml到配置檔案,那個檔案中,其實配置的是,在jenkins建構伺服器中到建構鏡像到配置。而在測試端也需要提供一個一鍵啟動到compose檔案。是以這個deploy-compose.yml檔案就是幹這個用但。通過jenkins建構後,我們已經明确的知道了我們的鏡像名稱,是以,可以通過以下配置來一鍵啟動容器,啟動的容器都是受compose管理,而不用我們人工去run/create等操作:
#使用的compose版本
version: '3'
#compose關鍵字,定義services
services:
#service的名稱 sbr_redis
sbr_redis:
#service中容器的名稱
container_name: sbr_redis
#使用目前目錄下的redis目錄下的Dockerfile來建立鏡像
image: docker_sbr_redis
#目前服務向外暴漏的端口
ports:
- "6379:6379"
#service的名稱 sbr_mysql
sbr_mysql:
#service中容器的名稱
container_name: sbr_mysql
#使用目前目錄下的mysql目錄下的Dockerfile來建立鏡像
image: docker_sbr_mysql
#目前服務向外暴漏的端口
ports:
- "3306:3306"
#service的名稱 sbr_user_auth
sbr_user_auth:
#service中容器的名稱
container_name: sbr_app
#使用目前目錄下的app目錄下的Dockerfile來建立鏡像
image: docker_sbr_user_auth
#目前服務向外暴漏的端口
ports:
- "9003:9003"
#目前容器使用的環境變量
environment:
- DB_SERVER=sbr_mysql
- DB_REDIS_HOST=sbr_redis
#目前服務依賴depends_on配置的服務,docker compose會優先啟動依賴的服務
depends_on:
- sbr_mysql
- sbr_redis
具體說明已經在配置檔案中以注解的方式說明來出來。
部署腳本
我們沒有必要提供compose相關的配置檔案給測試人員,除非對方堅決的要這個檔案,以達到他們自己控制容器操作的目的。
那麼,我們可以提供一個更加簡便的操作方式來啟動各個容器,那就是一個shell腳本:
#!/bin/bash
#定義可執行函數的參數數組
parr=(load startup stop rm rma)
#定義檢查本機是否安裝了docker
checkDocker(){
dockerpath=$(which docker)
if [ ! -n "#dockerpath" ]; then
echo "未檢測到Docker..."
exit 1
fi
}
#載入tar包中的鏡像
load(){
checkDocker
#導入docker鏡像:mysql
echo "開始導入mysql鏡像...."
docker load < sbr_mysql.tar
#導入docker鏡像:redis
echo "開始導入redis鏡像...."
docker load < sbr_redis.tar
#導入docker鏡像:user_auth
echo "開始導入微服務應用鏡像...."
docker load < user_auth.tar
}
#開始執行docker容器的啟動
startup(){
checkDocker
echo "準備啟動容器...."
docker-compose -f deploy-compose.yml up
}
#停止容器
stop(){
checkDocker
echo "準備停止容器...."
docker-compose -f deploy-compose.yml stop
}
#删除容器
rm(){
checkDocker
stop
echo "準備删除容器...."
docker-compose -f deploy-compose.yml rm
}
#删除容器以及鏡像
rma(){
checkDocker
rm
echo "準備删除鏡像...."
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":參數不能執行,請輸入正确參數!"
exit
fi
fi
通過這個腳本,測試人員可以執行以下指令來簡單的進行容器管理:
- load:載入/導入所有鏡像,如 ./deploy load
- startup:啟動容器,如 ./deploy startup
- stop:停止容器,如 ./deploy stop
- rm:删除容器,如 ./deploy rm
- rma:删除鏡像及容器,如 ./deploy rma
README檔案介紹
該檔案是交給測試人員進行檢視到,有以下幾點内容:
- 部署腳本如何使用
- 項目更新說明
- 其他備注資訊
Jenkins建構
jenkins建構系統:http://192.168.7.26/jenkins/
jenkins的界面如圖所示:
我們的建構任務在88.技術中,點選去後,如下圖所示:
建構配置
SVN配置
svn配置資訊如下圖所示:
- Repository URL:填寫項目svn位址
- Credentials:SVN賬戶資訊
- Local module directory:将SVN項目down到什麼位置,如果是一個點(.),則表示将項目中到内容down到88.技術/微服務2.0目錄下,如果什麼也沒有,則會在微服務2.0目錄下建立一個項目名稱到目錄,然後再将項目内容down到該目錄下
建構配置
這一個配置是整個自動化建構的核心
- maven配置:
- shell 操作代碼
#先查找jenkins伺服器中是否已經建構了微服務項目鏡像
#如果已經建構,則删除
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伺服器中是否已經建構了微服務項目依賴的redis鏡像
#如果已經建構,則删除
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伺服器中是否已經建構了微服務項目依賴的mysql鏡像
#如果已經建構,則删除
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檔案進行建構鏡像
docker-compose -f ./docker/build-compose.yml build
#如果88.技術/微服務2.0目錄下不存在deploy目錄,則建立deploy目錄
#如果存在deploy目錄,則删除deploy目錄下的所有檔案,保留一個幹淨的deploy目錄
if [ ! -d "deploy" ];then
mkdir deploy
else
rm -rf deploy/*
fi
#将項目源碼的docker目錄下的deploy-compose.yml 複制到deploy目錄下
cp docker/deploy-compose.yml deploy/deploy-compose.yml
#将将項目源碼的docker目錄下的script目錄下的deploy.sh複制到deploy目錄下
cp docker/script/deploy.sh deploy/deploy.sh
#将部署說明複制到deploy目錄
cp docker/README.txt deploy/README.txt
#進入deploy目錄,并進行鏡像的儲存,儲存的鏡像會存到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
#将導出的鏡像打成gz包,并删除源包
tar -zcvf deploy.tar.gz * --remove-files
FTP檔案傳輸配置
此時,jenkins已經在本機建構好了所需的鏡像,并且,已經在指定目錄将導出的鏡像打成了gz包,然後我們将該檔案發送到FTP伺服器之後,測試人員就可以下載下傳到本機進行測試了。
- FTP配置
到此,整個jenkins到建構已經完成,我們也可以通過建構控制台來檢視實時到建構資訊。
部署簡要
測試人員操作說明:
- 到FTP伺服器ftp://192.168.7.220中的【測試版本】-【88.技術】-【微服務2.0】中下載下傳最新部署包和部署說明
- 部署包:deploy.tar.gz 部署說明:README.txt
- 部署包包含:user_auth.tar(微服務項目鏡像),sbr_redis.tar(微服務項目依賴的redis鏡像),sbr_mysql.tar(微服務項目依賴的mysql鏡像),deploy-compose.yml(測試人員無需關注),deploy.sh(測試人員主要的操作檔案)
- deploy.sh的使用:
- 使用 tar -zxvf deploy.tar.gz來解壓部署包
- 腳本一鍵執行:
- 腳本會檢查本機是否安裝docker,如果未安裝,會給出提示
- 給腳本賦予可執行權限: chmod 775 deploy.sh
-
腳本參數介紹:
如果隻是輸入了 ./deploy 而不附帶任何參數,該腳本會自動導入鏡像并啟動容器
load:載入所有鏡像,如 ./deploy load
startup:啟動容器,如 ./deploy startup
stop:停止容器,如 ./deploy stop
rm:删除容器,如 ./deploy rm
rma:删除鏡像及容器,如 ./deploy rma
至此,微服務項目在jenkins中基于Docker的建構的内容已經完畢,若有不足之處,請予以支援與補充。謝謝。