在Docker容器中部署相互依賴的應用

上一篇文章中介紹瞭如何在Docker中部署單獨的Spring Boot應用。使用Docker命令和Dockerfile文件特別適合創建單獨的容器。但如果你想在相互孤立的應用中建立網絡通信互相調用,容器管理將很快變得非常混亂。爲解決這個問題,Docker提供了一個名爲Docker Compose的工具。

Compose 是一個用戶定義和運行多個容器的 Docker 應用程序。在 Compose 中你可以使用 YAML 文件來配置你的應用服務。然後,只需要一個簡單的命令,就可以創建並啓動你配置的所有服務。 例如,它能夠在一個命令中啓動或停止一個複合服務,或者將多個服務的日誌記錄輸出合併到一個虛擬終端機。

這裏我們創建一個例子,讓運行在兩個不同Docker容器裏的應用互相通信,並作爲“一體”呈現給主機系統。我們將使用之前教程——使用Spring-Cloud-Config創建配置中心,這裏包含了兩個應用:spring-cloud-config/server,spring-cloud-config/client。

安裝docker-compose
1.從github上下載docker-compose二進制文件安裝

#安裝前建議去 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執行權限
chmod +x /usr/local/bin/docker-compose
#測試
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。

一個比較偷懶的的方案是使用一個docker compose的image:dduportal/docker-compose, 通過它就可以運行docker compose而不用在boot2docker中安裝。官網地址https://hub.docker.com/r/dduportal/docker-compose/

準備工作
1.工程打包
在spring-cloud-config/server和spring-cloud-config/client應用工程目錄下執行mvn 打包命令:

mvn package spring-boot:repackage

在工程的target目錄裏找到生成的jar包。將jar包更名爲config-server.jar、config-client.jar上傳到Docker環境裏。

2.通用的基礎鏡像
創建一個帶有java環境,運行Alpine linux的輕量級基礎鏡像。

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/

注意:本例中使用了一些安全加解密算法,因此需要下載加密算法強度不受限的JCE包。將其拷貝到相應目錄下。

創建鏡像

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://[email protected]/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

在啓動時運行一個啓動腳本config-client-entrypoint.sh,判斷下config-server是否已經啓動。

#!/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
創建一個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:版本號是必填項,這裏我們使用新的版本號,沒有聲明的話默認版本爲“1”。
services:每個對象都定義爲一個服務,即容器。
  build:從Dockerfile創建一個鏡像
    context:Dockerfile的路徑
    dockerfile:Dockerfile的文件名
  image:當構造時鏡像的命名,或者去庫裏搜索此鏡像
  expose:供container之間的端口訪問
  ports:用於暴露的端口,主機的端口映射到容器的端口
  networks:要使用的命名網絡的標識符。給定的名稱值必須在networks部分中列出。
  volumes:標識要使用的命名卷和將卷裝入的安裝點,由冒號分隔。同樣,必須在單獨的volumes段中定義卷名。
  links:這將在該服務與所列出的服務之間創建內部網絡鏈接。此服務將能夠連接到所列出的服務,冒號之前的部分指定服務名稱,冒號之後的部分指定服務在偵聽端口上的主機名。
  depends_on:告訴Docker,啓動之前需要先成功啓動的服務。注意:此操作只是容器級的。
  logging:在這裏,我們使用的是“JSON文件”驅動程序,它是默認的驅動程序。
networks:在這一節中,我們指定了服務可用的網絡。在這個例子中,我們讓DOCKER創建一個名爲“橋”的網絡。
volumes:類似於networks。如果將external選項設置爲true,則將使用給定的現有名稱。

運行

docker-compose up --build

使用docker ps命令可以看到config-srver與config-client一起啓動運行

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

測試
在瀏覽器中訪問http://192.168.99.100:8080/whoami/Peter 返回了正確的配置信息

Hello Peter! You are a(n) Developer and your password is 'mysecret'.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章