在上一篇文章中介紹了如何在Docker中部署單獨(dú)的Spring Boot應(yīng)用线召。使用Docker命令和Dockerfile文件特別適合創(chuàng)建單獨(dú)的容器。但如果你想在相互孤立的應(yīng)用中建立網(wǎng)絡(luò)通信互相調(diào)用赤炒,容器管理將很快變得非常混亂亏较。為解決這個(gè)問(wèn)題莺褒,Docker提供了一個(gè)名為Docker Compose的工具。
Compose 是一個(gè)用戶定義和運(yùn)行多個(gè)容器的 Docker 應(yīng)用程序雪情。在 Compose 中你可以使用 YAML 文件來(lái)配置你的應(yīng)用服務(wù)遵岩。然后,只需要一個(gè)簡(jiǎn)單的命令,就可以創(chuàng)建并啟動(dòng)你配置的所有服務(wù)尘执。 例如舍哄,它能夠在一個(gè)命令中啟動(dòng)或停止一個(gè)復(fù)合服務(wù),或者將多個(gè)服務(wù)的日志記錄輸出合并到一個(gè)虛擬終端機(jī)誊锭。
這里我們創(chuàng)建一個(gè)例子表悬,讓運(yùn)行在兩個(gè)不同Docker容器里的應(yīng)用互相通信,并作為“一體”呈現(xiàn)給主機(jī)系統(tǒng)丧靡。我們將使用之前教程——使用Spring-Cloud-Config創(chuàng)建配置中心蟆沫,這里包含了兩個(gè)應(yīng)用:spring-cloud-config/server,spring-cloud-config/client温治。
安裝docker-compose
1.從github上下載docker-compose二進(jìn)制文件安裝
#安裝前建議去 https://github.com/docker/compose/releases 這里檢查一下最新版本
curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
#給docker-compose執(zhí)行權(quán)限
chmod +x /usr/local/bin/docker-compose
#測(cè)試
docker-compose --version
顯示docker-compose version 1.21.0, build 1719ceb表示安裝成功
2.pip安裝
$pip install docker-compose
注意
Windows版的Docker Toolbox是不帶Docker Compose的饭庞,需要另裝。裝compose需要先安裝python, 再裝pip, 才能pip install compose熬荆。
一個(gè)比較偷懶的的方案是使用一個(gè)docker compose的image:dduportal/docker-compose, 通過(guò)它就可以運(yùn)行docker compose而不用在boot2docker中安裝舟山。官網(wǎng)地址https://hub.docker.com/r/dduportal/docker-compose/
準(zhǔn)備工作
1.工程打包
在spring-cloud-config/server和spring-cloud-config/client應(yīng)用工程目錄下執(zhí)行mvn 打包命令:
mvn package spring-boot:repackage
在工程的target目錄里找到生成的jar包。將jar包更名為config-server.jar卤恳、config-client.jar上傳到Docker環(huán)境里累盗。
2.通用的基礎(chǔ)鏡像
創(chuàng)建一個(gè)帶有java環(huán)境,運(yùn)行Alpine linux的輕量級(jí)基礎(chǔ)鏡像纬黎。
FROM alpine:edge
MAINTAINER peterwanghao.com
RUN apk add --no-cache openjdk8
COPY files/UnlimitedJCEPolicyJDK8/* /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/
注意:本例中使用了一些安全加解密算法幅骄,因此需要下載加密算法強(qiáng)度不受限的JCE包。將其拷貝到相應(yīng)目錄下本今。
創(chuàng)建鏡像
docker build --tag=alpine-java:base --rm=true .
Config Server 容器
新建文件Dockerfile.server:
FROM alpine-java:base
MAINTAINER peterwanghao.com
COPY files/config-server.jar /opt/spring-cloud/lib/
ENV SPRING_APPLICATION_JSON='{"spring": {"cloud": {"config": {"server": \
{"git": {"uri": "http://admin@192.168.16.70/r/Test.git", "clone-on-start": true}}}}}}'
ENTRYPOINT ["/usr/bin/java"]
CMD ["-jar", "/opt/spring-cloud/lib/config-server.jar"]
VOLUME /var/lib/spring-cloud/config-repo
EXPOSE 8888
Config Client容器
新建文件Dockerfile.client:
FROM alpine-java:base
MAINTAINER peterwanghao.com
RUN apk --no-cache add netcat-openbsd
COPY files/config-client.jar /opt/spring-cloud/lib/
COPY files/config-client-entrypoint.sh /opt/spring-cloud/bin/
RUN chmod 755 /opt/spring-cloud/bin/config-client-entrypoint.sh
在啟動(dòng)時(shí)運(yùn)行一個(gè)啟動(dòng)腳本config-client-entrypoint.sh拆座,判斷下config-server是否已經(jīng)啟動(dòng)。
#!/bin/sh
while ! nc -z config-server 8888 ; do
echo "Waiting for upcoming Config Server"
sleep 2
done
java -jar /opt/spring-cloud/lib/config-client.jar
Docker Compose
創(chuàng)建一個(gè)docker-compose.yml文件:
version: '2'
services:
config-server:
container_name: config-server
build:
context: .
dockerfile: Dockerfile.server
image: config-server:latest
expose:
- 8888
networks:
- spring-cloud-network
volumes:
- /var/lib/spring-cloud/config-repo:/var/lib/spring-cloud/config-repo
logging:
driver: json-file
config-client:
container_name: config-client
build:
context: .
dockerfile: Dockerfile.client
image: config-client:latest
entrypoint: /opt/spring-cloud/bin/config-client-entrypoint.sh
environment:
SPRING_APPLICATION_JSON: '{"spring": {"cloud": {"config": {"uri": "http://config-server:8888"}}}}'
expose:
- 8000
ports:
- 8080:8000
networks:
- spring-cloud-network
links:
- config-server:config-server
depends_on:
- config-server
logging:
driver: json-file
networks:
spring-cloud-network:
driver: bridge
volumes:
spring-cloud-config-repo:
external: true
version:版本號(hào)是必填項(xiàng)冠息,這里我們使用新的版本號(hào)挪凑,沒(méi)有聲明的話默認(rèn)版本為“1”。
services:每個(gè)對(duì)象都定義為一個(gè)服務(wù)逛艰,即容器躏碳。
??build:從Dockerfile創(chuàng)建一個(gè)鏡像
????context:Dockerfile的路徑
????dockerfile:Dockerfile的文件名
??image:當(dāng)構(gòu)造時(shí)鏡像的命名,或者去庫(kù)里搜索此鏡像
??expose:供container之間的端口訪問(wèn)
??ports:用于暴露的端口散怖,主機(jī)的端口映射到容器的端口
??networks:要使用的命名網(wǎng)絡(luò)的標(biāo)識(shí)符菇绵。給定的名稱值必須在networks部分中列出。
??volumes:標(biāo)識(shí)要使用的命名卷和將卷裝入的安裝點(diǎn)镇眷,由冒號(hào)分隔咬最。同樣,必須在單獨(dú)的volumes段中定義卷名欠动。
??links:這將在該服務(wù)與所列出的服務(wù)之間創(chuàng)建內(nèi)部網(wǎng)絡(luò)鏈接永乌。此服務(wù)將能夠連接到所列出的服務(wù)惑申,冒號(hào)之前的部分指定服務(wù)名稱,冒號(hào)之后的部分指定服務(wù)在偵聽(tīng)端口上的主機(jī)名翅雏。
??depends_on:告訴Docker圈驼,啟動(dòng)之前需要先成功啟動(dòng)的服務(wù)。注意:此操作只是容器級(jí)的望几。
??logging:在這里绩脆,我們使用的是“JSON文件”驅(qū)動(dòng)程序,它是默認(rèn)的驅(qū)動(dòng)程序橄妆。
networks:在這一節(jié)中衙伶,我們指定了服務(wù)可用的網(wǎng)絡(luò)。在這個(gè)例子中害碾,我們讓DOCKER創(chuàng)建一個(gè)名為“橋”的網(wǎng)絡(luò)。
volumes:類似于networks赦拘。如果將external選項(xiàng)設(shè)置為true慌随,則將使用給定的現(xiàn)有名稱。
運(yùn)行
docker-compose up --build
使用docker ps命令可以看到config-srver與config-client一起啟動(dòng)運(yùn)行
docker@default:~/spring-cloud-config$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
09107b735b63 config-client:latest "/opt/spring-cloud/b 3 hours ago Up 3 hours 0.0.0.0:8080->8000/tcp config-client
05313481589e config-server:latest "/usr/bin/java -jar 3 hours ago Up 3 hours 8888/tcp config-server
334300d10399 dduportal/docker-compose:latest "/usr/local/bin/dock 3 hours ago Up 3 hours vibrant_heisenberg
測(cè)試
在瀏覽器中訪問(wèn)http://192.168.99.100:8080/whoami/Peter 返回了正確的配置信息
Hello Peter! You are a(n) Developer and your password is 'mysecret'.