一、概述
Docker Compose 的前身是 Fig,它是一个定义及运行多个 Docker 容器的工具。可以使用YAML文件来配置应用程序的服务。然后,使用单个命令,您可以创建并启动配置中的所有服务。Docker Compose 会通过解析容器间的依赖关系(link, 网络容器 -net-from 或数据容器 -volume-from)按先后顺序启动所定义的容器。
Compose 是 Docker 的服务编排工具,主要用来构建基于 Docker 的复杂应用,Compose 通过一个配置文件来管理多个 Docker 容器,非常适合组合使用多个容器进行开发的场景。
Compose适用于所有环境:生产,开发,测试以及CI工作流程。使用Compose基本上是一个三步过程:
1、使用Dockerfile定义应用程序的环境,以便在任何地方进行复制。
2、在docker-compose.yml中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。
3、运行docker-compose开始并运行整个应用程序。
docker-compose官方文档:Docker Compose overview | Docker Documentation
docker-compose 是用来做docker 的多容器控制,有了 docker-compose 你可以把所有繁复的 docker 操作全都用一条命令自动化完成。从上图可以看到,这位compose非常开心的把N多个容器抓在一起,根据自己的心情来编排部署。
Docker对于运维或开发者来说,Docker最大的优点在于它提供了一种全新的发布机制。这种发布机制,指的是我们使用Docker镜像作为统一的软件制品载体,使用Docker容器提供独立的软件运行上下文环境,使用Docker Hub提供镜像统一协作,最重要的是该机制使用Dockerfile定义容器内部行为和容器关键属性来支撑软件运行。
Dockerfile作为整个机制的核心。在Dockerfile中不但能够定义使用者在容器中需要进行的操作,而且能够定义容器中运行软件需要的配置,于是软件开发和运维终于能够在一个配置文件上达成统一。运维人员使用同一个Dockerfile能在不同的场合下"重现"与开发者环境中一模一样的运行单元(Docker容器)出来。
二、Compose 的优点
先来了解一下我们平时是怎么样使用docker的?把它进行拆分一下:
1、docker search 镜像,是不是先查找一个镜像;
2、docker run -itd 镜像名称 ,然后在运行这个镜像;
3、然后如果你要在运行第二个镜像、第三个镜像.....等等,你是不是又要docker search、docker run运行。
上面" docker run -itd 镜像名称 "这只是最小的动作,如果你要映射硬盘,设置nat网络或者映射端口等等。就要做更多的 docker 操作,这显然是非常没有效率的,况且如果你要大规模部署,是不是觉得就很麻烦了。
但是我们写在docker-compose里面就很好了。你只需要写好后只运行一句:
docker-compose up -d
三、原理
docker-compose的调用过程扁平的像一张纸,仅用一张简单的模块图就足够解释明白,如下图所示:
首先,用户执行的docker-compose up -d指令调用了命令行中的启动方法。功能很简单明了,一个docker-compose.yml定义了一个docker-compose的project,docker-compose操作提供的命令行参数则作为这个project的启动参数交由project模块去处理。
其次,如果当前宿主机已经存在与该应用对应的容器,docker-compose将进行行为逻辑判断。如果用户指定可以重新启动已有服务,docker-compose就会执行service模块的容器重启方法,否则就将直接启动已有容器。这两种操作的区别在于前者会停止旧的容器,创建启动新的容器,并把旧容器移除掉。在这个过程中创建容器的各项定义参数都是从docker-compose up 指令和docker-compose.yml中传入的。
接下来,启动容器的方法也很简洁,这个方法中完成了一个Docker容器启动所需的主要参数的封装,并在container模块执行启动。该方法所支持的参数我想大多数朋友过是有所了解的。
最后,container模块会调用docker-py客户端执行向Docker daemon发起创建容器的POST请求,再往后就是Docker处理的范畴了,相信看过我这篇文章 Docker:架构拆解请的朋友就明白了。
为了能够说明compose如何实现上述编排与部署的原理,下面和大家分享一个通过compose来编排部署LNMP服务来更好的理解它。
四、编排部署 (需要安装docker-ce)
curl -L \ https://github.com/docker/compose/releases/download/1.21.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
mkdir compose_lnmp/
cd compose_lnmp/
需要提前准备配置文件tar包
tree
vim docker-compose.yml 编写yml文件
version: '3'
services:
nginx:
hostname: nginx
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- 80:80
networks:
- lnmp
volumes:
- ./wwwroot:/usr/local/nginx/html
php:
hostname: php
build:
context: ./php
dockerfile: Dockerfile
ports:
- 9000:9000
networks:
- lnmp
volumes:
- ./wwwroot:/usr/local/nginx/html
mysql:
hostname: mysql
image: mysql:5.6
ports:
- 3306:3306
networks:
- lnmp
volumes:
- ./mysql/conf:/etc/mysql/conf.d
- ./mysql/data:/var/lib/mysql
command: --character-set-server=utf8
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wordpress
MYSQL_USER: user
MYSQL_PASSWORD: user123
networks:
lnmp:
version: '3' 这是定义compose的版本号为version 3,可以参考官方文档详细了解具体有哪些版本 Overview | Docker Documentation
services:
nginx:这是services下面的二级标签,名字用户自己定义,它将是服务运行后的名称;
hostname: nginx 这是定义容器的主机名,将写入到/etc/hostname中;
build:
context: ./nginx 指定nginx服务的上下文路径;
dockerfile:Dockerfile 指定通过上面指定路径中的Dockerilfe来构建;
ports:
- 80:80 端口映射没什么好说的;
networks:
-lnmp 指定的网络环境
volumes:把宿主机的/wwwroot目录绑定到容器中的/usr/local/nginx/html目录;
php:这个二级标签服务和下面的内容跟nginx差不多;
mysql:这个二级标签服务也和nginx、php差不多,唯一不同的是多了个images标签、还有定义了些环境变量。
image: mysql:5.6 它是通过mysql:5.6镜像来构建mysql服务器,前面nginx、php都指定了上下文通过Dockerfile来构建的。
environment:
MYSQL_ROOT_PASSWORD:定义root用户密码变量为123456;
MYSQL_DATABASE:定义了数据变量为wordpress;
MYSQL_USER:定义了普通用户变量为user;
MYSQL_PASSWORD:定义了普通用户密码变量为user123;
3、networks:
lnmp: 相当于执行docker network create lnmp命令了;
docker-compose -f docker-compose.yml up -d
docker-compose ps