概述
????Docker 是一個開源應(yīng)用容器(當然目前也分為CE和EE版本,不完全開源化屁商,也存在收費版本),讓開發(fā)者可以打包他們的應(yīng)用以及依賴包到一個可移植的容器中颈墅,然后發(fā)布到任何流行的 Linux 機器上蜡镶,也可以實現(xiàn)虛擬化。容器是完全使用沙箱機制恤筛,相互之間不會有任何接口官还。
????Docker 作為容器工具可以把:業(yè)務(wù)邏輯容器、數(shù)據(jù)庫容器毒坛、儲存容器望伦、隊列容器使得軟件可以拆分成若干個標準化容器,然后像搭積木一樣組合起來煎殷,讓彼此通信屯伞,從而形成微服務(wù)。
????因此微服務(wù)很適合用 Docker 容器實現(xiàn)豪直,每個容器承載一個服務(wù)劣摇。一臺計算機同時運行多個容器,從而就能很輕松地模擬出復雜的微服務(wù)架構(gòu)弓乙,并能體現(xiàn)微服務(wù)產(chǎn)品架構(gòu)的輕量級末融、高并發(fā)钧惧、大數(shù)據(jù)、智能化勾习、易維護浓瞪、動態(tài)擴展的特性。
使用Docker管理項目
????本章節(jié)使用Dockerfile的方式來管理微服務(wù)項目巧婶,關(guān)于Dockerfile的指令使用或更多信息乾颁,請參照Docker操作指南
????本章節(jié)所需要的必須條件:
- jre8
- ms-auth2.0:項目SVN地址:https://192.168.7.3/svn/cppt/trunk/src/micro-service/ms-auth
- mysql
- redis
制作mysql鏡像
前期準備
- 創(chuàng)建mysql目錄,該目錄和jre目錄平級
- 導出192.168.7.200中的ms-user數(shù)據(jù)庫粹舵,將sql腳本放到mysql目錄中
mysql Dockerfile編寫
在mysql目錄中钮孵,創(chuàng)建Dockerfile文件骂倘,并將以下內(nèi)容復制到Dockerfile文件中
#指定使用的鏡像
FROM mysql:5.6
#指定為湖人
MAINTAINER caochuanhong@sbr-info.com
#將容器啟動后眼滤,執(zhí)行的腳本拷貝到容器內(nèi)的/docker-entrypoint-initdb.d下,該目錄會自動執(zhí)行sql腳本
COPY ms-user.sql /docker-entrypoint-initdb.d
#設(shè)置mysql中的參數(shù)
#服務(wù)端到數(shù)據(jù)編碼
ENV character-set-server utf8mb4
#最大數(shù)據(jù)傳送量
ENV max_allowed_packet 128M
#mysql密碼历涝,可以在run指令中诅需,附帶 -e MYSQL_ROOT_PASSWORD=xxx來設(shè)置mysql密碼
ENV MYSQL_ROOT_PASSWORD Admin@123
#聲明容器暴漏的端口,只是聲明荧库,沒有其他作用
EXPOSE 3306
構(gòu)建mysql鏡像
將命令行定位到mysql目錄堰塌,輸入
docker build -t sbr/mysql:1.0.0 .
來開始進行mysql鏡像的構(gòu)建
說明:
- -t:給要構(gòu)建的鏡像定義一個名稱
-
. 這個.代表著,讓docker去讀取當前目錄下的Dockerfile文件來構(gòu)建鏡像
此時分衫,mysql鏡像已經(jīng)制作完成场刑,可以通過以下命令來創(chuàng)建并啟動一個容器來啟動mysql服務(wù):
docker run -d -p 3306:3306 --name mymysql e2f0dc2544d5
說明:
- -d: 后臺啟動
- -p: 第一個端口是宿主機端口,第二個端口是容器端口
- --name: 為創(chuàng)建的容器設(shè)置一個名稱
通過
docker ps
來查看正在運行的容器蚪战,可以發(fā)現(xiàn)牵现,mysql已經(jīng)跑起來了,如圖所示:
通過數(shù)據(jù)庫連接工具測試也可以連接到該服務(wù)。
制作redis鏡像
redis Dockerfile編寫
創(chuàng)建redis目錄邀桑,該目錄和mysql目錄平級
在redis目錄中瞎疼,創(chuàng)建Dockerfile文件,在該文件中壁畸,輸入以下內(nèi)容:
#指定使用的鏡像
FROM redis:4.0.2
#指定維護人
MAINTAINER caochuanhong@sbr-info.com
#聲明容器暴漏的端口
EXPOSE 6379
構(gòu)建redis鏡像
將命令行定位到redis目錄贼急,輸入
docker build -t sbr/redis:1.0.0 .
來開始進行redis鏡像的構(gòu)建
說明:
- -t:給要構(gòu)建的鏡像定義一個名稱
- . 這個.代表著,讓docker去讀取當前目錄下的Dockerfile文件來構(gòu)建鏡像
此時捏萍,redis鏡像已經(jīng)制作完成太抓,可以通過以下命令來創(chuàng)建并啟動一個容器來啟動redis服務(wù):
docker run -d -p 6379:6379 --name myredis 21690d58c82d
說明:
- -d: 后臺啟動
- -p: 第一個端口是宿主機端口,第二個端口是容器端口
- --name: 為創(chuàng)建的容器設(shè)置一個名稱
- 可以在啟動命令中配置 --requirepass "mypassword" 來創(chuàng)建redis的密碼
通過
docker ps
來查看正在運行的容器令杈,可以發(fā)現(xiàn)走敌,mysql已經(jīng)跑起來了,如圖所示:
制作微服務(wù)項目鏡像
????在制作jre基礎(chǔ)鏡像一節(jié)中,已經(jīng)介紹了微服務(wù)項目必須依賴的環(huán)境的鏡像制作这揣,這一節(jié)悔常,我們來制作微服務(wù)項目的鏡像影斑,將項目打入到鏡像中,通過鏡像來啟動我們的項目机打,可以提高我們項目開發(fā)完成后很多的后續(xù)操作的效率矫户。
前期準備
- 創(chuàng)建app目錄,該目錄與jre同級
- 通過https://192.168.7.3/svn/cppt/trunk/src/micro-service/ms-auth檢出項目残邀,通過maven的clean package 對項目進行打包皆辽,打包后,會在項目目錄的target中生成一個jar包芥挣,如圖所示:
- 將jar包復制到app目錄中
微服務(wù)項目的Dockerfile編寫
在app目錄中創(chuàng)建Dockerfile文件驱闷,并在文件中輸入以下內(nèi)容:
#使用sbr/jre8:1.0.0作為基礎(chǔ)鏡像
FROM sbr/jre8:1.0.0
#編寫人/維護人
MAINTAINER caochuanhong#sbr-info.com
#java應(yīng)用文件操作
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"]
構(gòu)建微服務(wù)項目鏡像
將命令行定位到app目錄下空免,執(zhí)行以下命令:
docker build -t sbr/app:1.0.0 .
說明:
- -t:給要構(gòu)建的鏡像定義一個名稱
-
. 這個.代表著空另,讓docker去讀取當前目錄下的Dockerfile文件來構(gòu)建鏡像
微服務(wù)項目配置文件與啟動
在啟動微服務(wù)項目前,需要先看一下項目中的配置文件蹋砚,有幾點需要注意
在項目源碼的resource目錄下的application.yml文件中
????spring boot類型項目中的配置項扼菠,可以通過修改環(huán)境變量的方式來賦值,spring會優(yōu)先讀取環(huán)境變量中的配置項和配置項目值
????在docker中坝咐,訪問127.0.0.1是訪問的容器內(nèi)部循榆,而不是宿主機,所以墨坚,需要一種靈活的方式能夠動態(tài)的配置連接信息秧饮,而通過簡短的環(huán)境變量的形式來配置連接參數(shù)是一個好的選擇。
????無論是通過配置宿主機上的環(huán)境變量還是在啟動容器的時候泽篮,來動態(tài)為容器指定環(huán)境變量的值盗尸,都可以將配置的值映射到容器內(nèi)部的應(yīng)用服務(wù)的配置中,從而避免連接屬性寫死的情況咪辱。更多的關(guān)于spring boot項目配置的信息振劳,請參考如下:http://www.cnblogs.com/softidea/p/5759180.html
????所以,在啟動微服務(wù)項目的時候油狂,附帶上上圖中配置的項历恐,就可以正確的連接到mysql和redis服務(wù)中。
首先专筷,先獲取本機的IP地址弱贼,然后將本機的IP地址通過環(huán)境變量的方式配置到容器的啟動命令中,比如我的IP是192.168.6.56
通過以下命令來啟動微服務(wù)的應(yīng)用:
docker run -p 9003:9003 -e DB_SERVER=192.168.6.56 -e DB_REDIS_HOST=192.168.6.56 --name sbr-app 5b1df7a17cff
如果redis的連接密碼和項目中配置的不一致時磷蛹,可以通過 -e DB_REDIS_PWD=xxx來動態(tài)修改密碼吮旅。
該命令會在終端輸出啟動日志,如果想讓docker后臺啟動該容器,可以在命令中添加-d參數(shù)
當容器啟動后庇勃,就可以通過rest連接工具正常訪問該項目提供的服務(wù)了檬嘀,訪問情況如下圖所示:
使用Docker compose編排服務(wù)
????上一章中,已經(jīng)介紹了使用docker手動的方式來介紹微服務(wù)在docker環(huán)境下的部署责嚷。但是鸳兽,這樣去操作docker是很原始的,通過手動的一個一個的去啟動服務(wù)容器罕拂,既費時又費力揍异。
????Docker 也提供了更強大的工具 Compose 來管理容器。
????Docker Compose是一個用來定義和運行復雜應(yīng)用的Docker工具爆班。一個使用Docker容器的應(yīng)用衷掷,通常由多個容器組成。使用Docker Compose不再需要使用shell腳本來啟動容器柿菩。
????Compose 通過一個配置文件來管理多個Docker容器戚嗅,在配置文件中,所有的容器通過services來定義碗旅,然后使用docker-compose腳本來啟動渡处,停止和重啟應(yīng)用镜悉,和應(yīng)用中的服務(wù)以及所有依賴服務(wù)的容器祟辟,非常適合組合使用多個容器進行開發(fā)的場景。
????更多關(guān)于docker compose的內(nèi)容侣肄,請參考Docker操作指南中的docker compose部分旧困。
編寫compose配置文件來管理多個容器
????通過Docker操作指南中的docker compose部分我們知道,compose可以通過Dockerfile文件來創(chuàng)建鏡像和容器稼锅。
????那么下面吼具,我們通過docker compose的方式來管理我們的鏡像和容器.
??創(chuàng)建一個docker-compose.yml配置文件,該文件與jre,mysql,redis,app目錄是同級的矩距。并將以下內(nèi)容復制到docker-compose.yml文件中拗盒。
#使用的compose版本
version: '3'
#compose關(guān)鍵字,定義services
services:
#service的名稱 sbr_redis
sbr_redis:
#service中容器的名稱
container_name: sbr_redis
#使用當前目錄下的redis目錄下的Dockerfile來創(chuàng)建鏡像
build: ./redis
#當前服務(wù)向外暴漏的端口
ports:
- "6379:6379"
#指定創(chuàng)建redis容器后锥债,設(shè)置的密碼
command:
- "--requirepass Admin@123"
#service的名稱 sbr_mysql
sbr_mysql:
#service中容器的名稱
container_name: sbr_mysql
#使用當前目錄下的mysql目錄下的Dockerfile來創(chuàng)建鏡像
build: ./mysql
#當前服務(wù)向外暴漏的端口
ports:
- "3306:3306"
#service的名稱 sbr_user_auth
sbr_user_auth:
#service中容器的名稱
container_name: sbr_app
#使用當前目錄下的app目錄下的Dockerfile來創(chuàng)建鏡像
build: ./app
#當前服務(wù)向外暴漏的端口
ports:
- "9003:9003"
#當前容器使用的環(huán)境變量
environment:
- DB_SERVER=sbr_mysql
- DB_REDIS_HOST=sbr_redis
#當前服務(wù)依賴depends_on配置的服務(wù)陡蝇,docker compose會優(yōu)先啟動依賴的服務(wù)
depends_on:
- sbr_mysql
- sbr_redis
????默認情況下,Compose 會為你的應(yīng)用程序設(shè)置一個 網(wǎng)絡(luò)哮肚。服務(wù)的每個容器都加入默認網(wǎng)絡(luò)登夫,并且該網(wǎng)絡(luò)上的其他容器都可以訪問它們,并且可以通過與容器名稱相同的主機名來發(fā)現(xiàn)它們允趟。所以恼策,在設(shè)置數(shù)據(jù)庫連接和redis的連接時,沒有設(shè)置具體的IP地址潮剪,而是設(shè)置的服務(wù)名涣楷,這樣分唾,docker compose會自動去訪問對應(yīng)的服務(wù)。
輸入以下命令來構(gòu)建以上配置的所有鏡像
docker-compose build
該命令會構(gòu)建鏡像狮斗,或者輸入以下命令鳍寂,構(gòu)建鏡像并啟動容器
docker-compose up --build
該命令會在啟動前就行構(gòu)建鏡像,構(gòu)建完成后情龄,再啟動容器迄汛,如果不加參數(shù) -d 的話,會在終端輸入構(gòu)建以及啟動日志骤视,截圖如圖所示:
使用rest連接工具鞍爱,來驗證服務(wù)是否已經(jīng)成功。
至此专酗,微服務(wù)項目通過被docker compose管理的使用場景已經(jīng)整理完畢:
<font color=red>
請注意:使用compose進行啟動到容器睹逃,在日志打印時,微服務(wù)項目會報連不到數(shù)據(jù)庫到錯誤祷肯,這是正常到沉填,因為,此時佑笋,mysql容器正在啟動翼闹,而沒有啟動完畢,所以導致無法連接到數(shù)據(jù)庫蒋纬,而hibernate中有重連機制猎荠,在mysql正常啟動后,就可以連接上了蜀备。關(guān)于depend_on到設(shè)置关摇,compose只能檢測到容器到啟動狀態(tài),若容器啟動碾阁,則compose認為這已經(jīng)是成功啟動了输虱,所以,關(guān)于這一點報錯到問題脂凶,請大家知悉宪睹,這是正常到。當然艰猬,也可以通過其他到方式來處理這個問題横堡。
</font>
總結(jié)
docker 的使用過程,它分為鏡像構(gòu)建與容器啟動冠桃。
鏡像構(gòu)建:即創(chuàng)建一個鏡像命贴,它包含安裝運行所需的環(huán)境、程序代碼等。這個創(chuàng)建過程就是使用 dockerfile 來完成的胸蛛。
容器啟動:容器最終運行起來是通過拉取構(gòu)建好的鏡像污茵,通過一系列運行指令(如端口映射、外部數(shù)據(jù)掛載葬项、環(huán)境變量等)來啟動服務(wù)的泞当。針對單個容器,這可以通過 docker run 來運行民珍。
而如果涉及多個容器的運行(如服務(wù)編排)就可以通過 docker-compose 來實現(xiàn)襟士,它可以輕松的將多個容器作為 service 來運行(當然也可僅運行其中的某個),并且提供了 scale (服務(wù)擴容) 的功能嚷量。
最后陋桂,docker,Dockerfile,compose的使用情況:
Dockerfile: 構(gòu)建鏡像
docker run: 啟動容器
docker-compose: 啟動服務(wù)(包含多個容器)
以上所有章節(jié)內(nèi)容為微服務(wù)項目在docker環(huán)境下的使用情況,各位在實踐過程中蝶溶,如果出現(xiàn)了什么問題嗜历,可隨時與我聯(lián)系。
附錄
<a name=jre>制作微服務(wù)所需的jre基礎(chǔ)鏡像</a>
鏡像選擇
????在制作鏡像抖所、Docker創(chuàng)建容器時梨州,基礎(chǔ)鏡像通常選擇Ubuntu或Centos,不管哪個鏡像的大小都在100MB以上田轧。
????我們必須要知道的一個事情是暴匠,鏡像也是要占用存儲空間的。那么涯鲁,設(shè)計或者使用一個磁盤占用較小的鏡像巷查,是一個比較好的選擇。
通過對比和資料查找后抹腿,推薦使用Alpine Linux 作為jre的基礎(chǔ)鏡像。
????Alpine Linux 是一個輕量級的 Linux 發(fā)行版旭寿,基于 musl libc 及 busybox警绩。其關(guān)注于性能及安全性,追求兄殉啤(Small)肩祥、簡單(Simple)及安全(Secure)。其常被應(yīng)用于構(gòu)建 Docker 等容器缩膝。
????在使用前混狠,我們應(yīng)該知道java是需要glibc的,所以基礎(chǔ)鏡像使用的是alpine-glibc而非alpine疾层,alpine-glibc大概是11.1M将饺。
jre基礎(chǔ)鏡像
- 首先恬涧,需要下載jre,下載地址是https://www.java.com/en/download/manual.jsp棘街,大概是77M槐秧。
- 然后,刪除jre包中的不是必須的東西
#解壓
tar xvcf jre1.8.0_191.tar.gz
#進入目錄
cd jre1.8.0_191/
#刪除文本文件
rm -rf COPYRIGHT LICENSE README release THIRDPARTYLICENSEREADME-JAVAFX.txtTHIRDPARTYLICENSEREADME.txt Welcome.html
#刪除其他無用文件
rm -rf lib/plugin.jar \
lib/ext/jfxrt.jar \
bin/javaws \
lib/javaws.jar \
lib/desktop \
plugin \
lib/deploy* \
lib/*javafx* \
lib/*jfx* \
lib/amd64/libdecora_sse.so \
lib/amd64/libprism_*.so \
lib/amd64/libfxplugins.so \
lib/amd64/libglass.so \
lib/amd64/libgstreamer-lite.so \
lib/amd64/libjavafx*.so \
lib/amd64/libjfx*.so
- jre重新打包
tar -zcvf jre1.8.0_191.tar.gz jre1.8.0_191
基礎(chǔ)鏡像的Dockerfile的編寫
????新建一個jre目錄掖蛤,將剛才處理過的jre1.8.0_191.tar.gz包放入到j(luò)re目錄中杀捻。并在jre目錄中,新建一個Dockerfile文件蚓庭,將以下內(nèi)容復制到Dockerfile文件中
#使用alpine-glibc作為基礎(chǔ)鏡像
FROM docker.io/jeanblanchard/alpine-glibc
#編寫人/維護人,這里可以寫自己的信息
MAINTAINER caochuanhong@sbr-info.com
#定義jre安裝到路徑致讥,可以在run 指令中,附帶 -e JREDIR=/x/x/x來配置jre的安裝路徑
ENV JREDIR /opt/sbr/jre
#添加gz包到鏡像內(nèi)器赞,gz包會自動解壓
ADD jre1.8.0_191.tar.gz ${JREDIR}
#設(shè)置環(huán)境變量
ENV JAVA_HOME ${JREDIR}/jre1.8.0_191
ENV PATH ${PATH}:${JAVA_HOME}/bin
構(gòu)建jre基礎(chǔ)鏡像
將命令行定位到j(luò)re目錄中拄踪,輸入以下命令來構(gòu)建我們自己的鏡像
輸入
docker image ls
查看當前鏡像列表,如圖所示:
輸入
docker build -t sbr/jre8 .
來開始進行jre基礎(chǔ)鏡像的構(gòu)建
說明:
- -t:給要構(gòu)建的鏡像定義一個名稱拳魁,也可以附帶鏡像的版本號,比如:sbr/jre8:1.0.0
- . 這個.代表著惶桐,讓docker去讀取當前目錄下的Dockerfile文件來構(gòu)建鏡像
此時,jre基礎(chǔ)鏡像已經(jīng)制作完成潘懊,我們可以通過該鏡像姚糊,創(chuàng)建一個容器,進入內(nèi)容內(nèi)部執(zhí)行java -version來驗證授舟。
首先救恨,我們先復制該鏡像的id:b3adba0789cd
然后,輸入以下內(nèi)容释树,創(chuàng)建并進入容器內(nèi)部:
docker run -it --name myjre8 b3adba0789cd /bin/sh
說明:
- -i: 以交互模式運行容器肠槽,通常與 -t 同時使用;
- -t: 為容器重新分配一個偽輸入終端奢啥,通常與 -i 同時使用秸仙;
- --name: 為創(chuàng)建的容器設(shè)置一個名稱
- /bin/sh: 容器啟動后,執(zhí)行的腳本
最終效果如圖所示:
通過輸入exit來退出容器
至此桩盲,jre基礎(chǔ)鏡像的制作已經(jīng)完畢寂纪,