Docker Compose介紹
使用微服務架構的應用系統一般包含若干個微服務,每個微服務一般都會部署多個實例。如果每個微服務都要手動啟停,那么效率之低、維護量之大可想而知。本節課將討論如何使用 Docker Compose來輕松、高效地管理容器。為了簡單起見將 Docker Compose簡稱為 Compose。
Compose 是一個用于定義和運行多容器的Docker應用的工具。使用Compose,你可以在一個配置文件(yaml格式)中配置你應用的服務,然后使用一個命令,即可創建并啟動配置中引用的所有服務。下面我們進入Compose的實戰吧
Docker Compose的安裝
Compose的安裝有多種方式,例如通過shell安裝、通過pip安裝、以及將compose作為容器安裝等等。本文講解通過pip安裝的方式。其他安裝方式如有興趣,可以查看Docker的官方文檔:https://docs.docker.com/compose/install/
1、安裝python-pip
# yum -y install epel-release
# yum -y install python-pip
2、安裝docker-compose
# pip install docker-compose
3、待安裝完成后,執行查詢版本的命令
# docker-compose version
Docker Compose入門示例
Compose的使用非常簡單,只需要編寫一個docker-compose.yml,然后使用docker-compose 命令操作即可。docker-compose.yml描述了容器的配置,而docker-compose 命令描述了對容器的操作。我們首先通過一個示例快速入門:
還記得上節課,我們使用Dockerfile為項目microservice-eureka-server構建Docker鏡像嗎?我們還以此項目為例測試
- 我們在microservice-eureka-server-0.0.1-SNAPSHOT.jar所在目錄的上一級目錄,創建docker-compose.yml 文件。
目錄樹結構如下:
├── docker-compose.yml
└── eureka
├───── Dockerfile
└───── microservice-eureka-server-0.0.1-SNAPSHOT.jar
- 然后在docker-compose.yml 中添加內容如下:
eureka: #指定服務名
build: ./eureka #指定Dockfile所在路勁
ports:
- "8761:8761" #指定端口映射
expose:
- 8761 #容器提供服務端口
- 在docker-compose.yml 所在路徑執行:
# docker-compose up
Compose就會自動構建鏡像并使用鏡像啟動容器。也可使用 docker-compose up -d后臺啟動并運行這些容器
- 訪問:
http://宿主機IP:8761/
,發現可以正常啟動。
Docker Compose管理容器的結構
- Docker Compose將所管理的容器分為三層,分別是工程( project),服務(service)以及容器( container)。
- Docker Compose運行目錄下的所有文件( docker-compose.yml、 extends文件或環境變量文件等)組成一個工程(默認為 docker-compose.yml所在目錄的目錄名稱)。一個工程可包含多個服務,每個服務中定義了容器運行的鏡像、參數和依賴,一個服務可包括多個容器實例。
- 上節示例里工程名稱是 docker-compose.yml所在的目錄名。該工程包含了1個服務,服務名稱是 eureka,執行 docker-compose up時,啟動了eureka服務的1個容器實例
docker-compose.yml常用指令
image
指定鏡像名稱或者鏡像id,如果該鏡像在本地不存在,Compose會嘗試pull下來。
示例:
image: java
build
指定Dockerfile文件的路徑。可以是一個路徑,例如:
build: ./dir
也可以是一個對象,用以指定Dockerfile和參數,例如:
build: context: ./dir dockerfile: Dockerfile-alternate args: buildno: 1
command
覆蓋容器啟動后默認執行的命令。
示例:
command: bundle exec thin -p 3000
也可以是一個list,類似于Dockerfile總的CMD指令,格式如下:
command: [bundle, exec, thin, -p, 3000]
links
鏈接到其他服務中的容器。可以指定服務名稱和鏈接的別名使用SERVICE:ALIAS 的形式,或者只指定服務名稱,示例:
web: links: - db - db:database - redis
external_links
表示鏈接到docker-compose.yml外部的容器,甚至并非Compose管理的容器,特別是對于那些提供共享容器或共同服務。格式跟links類似,示例:
external_links: - redis_1 - project_db_1:mysql - project_db_1:postgresql
ports
暴露端口信息。使用宿主端口:容器端口的格式,或者僅僅指定容器的端口(此時宿主機將會隨機指定端口),類似于docker run -p ,示例:
ports: - "3000" - "3000-3005" - "8000:8000" - "9090-9091:8080-8081" - "49100:22" - "127.0.0.1:8001:8001" - "127.0.0.1:5000-5010:5000-5010"
expose
暴露端口,只將端口暴露給連接的服務,而不暴露給宿主機,示例:
expose: - "3000" - "8000"
volumes
卷掛載路徑設置。可以設置宿主機路徑 (HOST:CONTAINER) 或加上訪問模式 (HOST:CONTAINER:ro)。示例:
volumes: # Just specify a path and let the Engine create a volume - /var/lib/mysql # Specify an absolute path mapping - /opt/data:/var/lib/mysql # Path on the host, relative to the Compose file - ./cache:/tmp/cache # User-relative path - ~/configs:/etc/configs/:ro # Named volume - datavolume:/var/lib/mysql
volumes_from
從另一個服務或者容器掛載卷。可以指定只讀或者可讀寫,如果訪問模式沒有指定,則默認是可讀寫。示例:
volumes_from: - service_name - service_name:ro - container:container_name - container:container_name:rw
environment
設置環境變量。可以使用數組或者字典兩種方式。只有一個key的環境變量可以在運行Compose的機器上找到對應的值,這有助于加密的或者特殊主機的值。示例:
environment: RACK_ENV: development SHOW: 'true' SESSION_SECRET: environment: - RACK_ENV=development - SHOW=true - SESSION_SECRET
env_file
從文件中獲取環境變量,可以為單獨的文件路徑或列表。如果通過 docker-compose -f FILE 指定了模板文件,則 env_file 中路徑會基于模板文件路徑。如果有變量名稱與 environment 指令沖突,則以envirment 為準。示例:
env_file: .env env_file: - ./common.env - ./apps/web.env - /opt/secrets.env
extends
繼承另一個服務,基于已有的服務進行擴展。
net
設置網絡模式。示例:
net: "bridge" net: "host" net: "none" net: "container:[service name or container name/id]"
dns
配置dns服務器。可以是一個值,也可以是一個列表。示例:
dns: 8.8.8.8 dns: - 8.8.8.8 - 9.9.9.9
dns_search
配置DNS的搜索域,可以是一個值,也可以是一個列表,示例:
dns_search: example.com dns_search: - dc1.example.com - dc2.example.com
其他
docker-compose.yml 還有很多其他命令,本文僅挑選常用命令進行講解,其他不不作贅述。如果感興趣的,可以參考docker-compose.yml文件官方文檔:https://docs.docker.com/compose/compose-file/
用Docker Compose編排Spring Cloud微服務
如果微服務較多,則可以用docker compose來統一編排,我們打算用docker compose來統一編排三個微服務:eureka服務(項目05-ms-eureka-server),user服務(項目05-ms-provider-user),order服務(項目05-ms-consumer-order-ribbon)
編排微服務
1、在根目錄創建文件夾/app
2、在app目錄下新建docker-compose.yml文件和三個文件夾eureka,user,order
3、在eureka,user,order三個文件夾下分別構建eureka服務鏡像,user服務鏡像,order服務鏡像,以構建eureka服務鏡像為例,在eureka文件夾下新建dockerfile文件并且將eureka服務的可運行jar包上傳到該目錄(注意:需要將配置eureka.client.serviceUrl.defaultZone的值改為http://eureka:8761/eureka/
,默認情況下Compose以服務名稱作為hostname被其他容器訪問),dockerfile文件內容如下
# 基于哪個鏡像
From java:8
# 將本地文件夾掛載到當前容器
VOLUME /tmp
# 復制文件到容器
ADD microservice-eureka-server-0.0.1-SNAPSHOT.jar /app.jar
# 聲明需要暴露的端口
EXPOSE 8761
# 配置容器啟動后執行的命令
ENTRYPOINT ["java","-jar","/app.jar"]
4、docker-compose.yml內容如下
version: '2' #docker的文件格式版本
services:
eureka: #docker服務名
image: eureka #docker鏡像
ports:
- "8761:8761"
user:
image: user
ports:
- "8000:8000"
order:
image: order
ports:
- "8010:8010"
5、啟動所有微服務,在命令后面加-d可以后臺啟動:
# docker-compose up
6、訪問三個微服務是否正常
編排高可用微服務
1、在根目錄創建文件夾/app-ha
2、在app-ha目錄下新建docker-compose.yml文件和三個文件夾eureka-ha,user-ha,order-ha
3、在eureka-ha,user-ha,order-ha三個文件夾下分別構建eureka-ha服務鏡像,user-ha服務鏡像,order-ha服務鏡像,eureka-ha服務參考項目08-ms-eureka-server-ha,(注意:需要修改user服務和order服務配置文件eureka.client.serviceUrl.defaultZone的值為http://peer1:8761/eureka/,http://peer2:8762/eureka/
)
4、docker-compose.yml內容如下
version: '2' #docker的文件格式版本
services:
peer1: #docker微服務名稱
image: eureka-ha #docker鏡像
ports:
- "8761:8761"
environment:
- spring.profiles.active=peer1
peer2:
image: eureka-ha
ports:
- "8762:8762"
environment:
- spring.profiles.active=peer2
user:
image: user-ha
ports:
- "8000:8000"
order:
image: order-ha
ports:
- "8010:8010"
5、啟動所有微服務,在命令后面加-d可以后臺啟動:
# docker-compose up
6、訪問三個微服務是否正常
動態擴容微服務
有時我們需要擴容微服務,比如我們想把用戶和訂單微服務各部署兩個微服務,則docker-compose.yml文件應該如下配置
docker-compose.yml內容如下
version: '2' #docker的文件格式版本
services:
peer1: #docker微服務名稱
image: eureka-ha #docker鏡像
ports:
- "8761:8761"
environment:
- spring.profiles.active=peer1
peer2:
image: eureka-ha
ports:
- "8762:8762"
environment:
- spring.profiles.active=peer2
user:
image: user-ha
order:
image: order-ha
執行如下擴容命令:
# docker-compose up #必須先正常編排微服務,然后才能動態擴容
# docker-compose scale user=2 order=2
注意:如果是在同一臺物理機上做動態擴容,則需要在docker-compose.yml里去掉除了eureka其它微服務ports端口映射
運行完查看eureka注冊中心如下圖所示: