如果Docker中的一个服务需要依赖多个应用进程(比如一个web服务由java、tomcat、mysql、nginx等多个应用进程组成),需要在Docker中运行多个容器,容器之间有交互和关联,docker run
提供--link
选项来建立容器间的依赖关联。
但是容器的依赖必须保证被依赖的容器正在运行,如果一个服务中容器的依赖关系比较复杂、繁琐,还可能容易出现差错。Docker提供了Docker Compose
来解决此问题。
Docker Compose
是Docker官方提供的容器编排工具,它使用YAML格式模板文件定义容器的依赖关系,这些容器会根据配置模板中的“--link”等参数,对启动的优先级自动排序,简单执行一条“docker-compose up”,就可以把同一个服务中的多个容器依次创建、启动。
1.安装Docker Compose
官方指引:https://docs.docker.com/compose/install/#install-compose
Step 1:下载最新版Docker Compose
$ sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 617 0 617 0 0 541 0 --:--:-- 0:00:01 --:--:-- 541
100 8280k 100 8280k 0 0 101k 0 0:01:21 0:01:21 --:--:-- 106k
Step 2:添加可执行权限
$ chmod +x /usr/local/bin/docker-compose
Step 3:测试是否安装成功
$ docker-compose --version
docker-compose version 1.18.0, build 8dd22a9
2.使用Docker Compose创建、启动、停止容器
这里使用之前提到的WordPress的例子来做演示
Step 1:查询原来WordPress应用启动的容器
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
26a266da188a wordpress "docker-entrypoint.s…" 11 minutes ago Up 11 minutes 0.0.0.0:8080->80/tcp MyWordPress
05305331681f mariadb "docker-entrypoint.s…" 11 minutes ago Up 11 minutes 3306/tcp db
Step 2:停止这两个容器
[root@localhost ~]# docker stop MyWordPress && docker stop db
MyWordPress
db
Step 3:创建docker-compose配置文件~/wordpress/docker-compose.yml
[root@localhost ~]# cat << EOF > ~/wordpress/docker-compose.yml
> wordpress:
> image: wordpress
> links:
> - db:mysql
> ports:
> - 8080:80
> db:
> image: mariadb
> environment:
> MYSQL_ROOT_PASSWORD: example
> EOF
Step 4:进入配置文件所在目录,使用docker-compose以后台方式创建并启动容器
[root@localhost ~]# cd ~/wordpress/ && docker-compose up -d
Creating wordpress_db_1 ... done
Creating wordpress_db_1 ...
Creating wordpress_wordpress_1 ... done
Step 5:容器启动成功后再次查看运行中的容器,使用了新的CONTAINER ID创建了新的容器,并且已自动命名
[root@localhost wordpress]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06a518aaae16 wordpress "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp wordpress_wordpress_1
e429a99ad973 mariadb "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp wordpress_db_1
3.Docker Compose相关命令
3.1 创建并启动一组容器
# 当前所在目录为默认配置文件docker-compose.yml所在目录
docker-compose up -d
# 使用指定配置文件作为Docker Compose配置文件
docker-compose -f xxx.yml up -d
3.2 停止一组容器
docker-compose -f xxx.yml stop
3.3 启动一组容器
docker-compose -f xxx.yml start
3.4 查看指定项目的所有容器状态
docker-compose -f xxx.yml ps
3.5 删除项目
docker-compose -f xxx.yml down
4.Docker Compose配置文件
Docker Compose默认使用docker-compose.yml作为配置文件,执行docker-compose命令时,当前所在目录需要与docker-compose.yml所在目录一致;
如果自定义配置文件,则不需要在配置文件所在目录下执行docker-compose命令,但是需要使用-f xxx.yml
指定配置文件。
Docker Compose配置文件使用YMAL语法定义了一组关联的应用容器,详细的参数和属性与运行docker run
命令时的选项和参数基本一致,只是以不同的形式描述而已。
5.Docker Compose实现水平扩展和负载均衡
这里以一个简单的flask应用为例,请求/将返回当前运行flask应用的容器的hostname。
1.使用Pipenv创建虚拟环境,并创建一个最简单的flask应用。
app.py
from flask import Flask
import socket
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, my hostname is {}\n'.format(socket.gethostname())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=80, debug=False)
2.编写构建应用镜像的Dockerfile
FROM python:3.7
ADD flask-demo /app/flask-demo
WORKDIR /app/flask-demo/
ENV FLASK_APP="app.py"
RUN pip install pipenv
RUN pipenv install
EXPOSE 80
CMD pipenv run python app.py
3.编写docker-compose配置文件,其中lb为haproxy,用于处理请求转发
docker-compose.yml
version: "3"
services:
web:
build:
context: .
dockerfile: Dockerfile
lb:
image: dockercloud/haproxy
links:
- web
ports:
- 9090:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
4.使用docker-compose启动应用
docker-compose up -d
使用curl访问http://localhost:80,返回结果如下
$ curl http://localhost:9090
Hello, my hostname is c4374b73e405
5.使用docker-compose的--scale选项指定容器的数量
$ docker-compose up --scale web=3 -d
Starting docker-compose-scale_web_1 ... done
Creating docker-compose-scale_web_2 ... done
Creating docker-compose-scale_web_3 ... done
docker-compose-scale_lb_1 is up-to-date
多次请求将被转发轮询到各个应用容器中
$ curl http://localhost:9090
Hello, my hostname is c4374b73e405
$ curl http://localhost:9090
Hello, my hostname is e9b3416512f3
$ curl http://localhost:9090
Hello, my hostname is 130939b91e36
并且后续可以继续通过--scale增减应用的容器数量实现扩容或缩容。
网友评论