一、Docker编配和服务发现
- 编配(orchestration)是一个没有严格定义的概念。这个概念概念大概描述了自动配置、协作和管理服务的过程。在Docker的世界里,编配用来描述一组时间过程,这个过程会管理运行在多个Docker容器里的引用,而这些Docker容器有可能运行在多个宿主机上。Docker对编配的原生支持非常弱,不过整个社区围绕编配开发和集成了很多很棒的工具
- 在现在的生态环境里,已经围绕Docker构建和继承了很多工具。一些工具只是简单地将多个容器快捷地“连”在一起,使用简单的组合来构建引用程序栈。另外一些工具提供了在更大规模多个Docker宿主机上进行协作的能力,以及复杂的调度和执行能力
- 刚才提到的这些领域,每个领域都值得写一本书,不过我们下面三篇文章只介绍如何简单使用这些工具
- 在最近的3篇文章中,我们会介绍:
- 简单的容器编配:
- 这部分内容介绍Docker Compose。Docker Compose(之前的Fig)是由Orchard团队开发的开源DOcker编配工具,后来2014年被Docker公司收购。这个工具用Python编写,遵循Apache 2.0许可
- 本文介绍的
- 分布式服务发现:
- Docker的编配和集群:
其他编配工具和组件
- Compose和Consul不是Docker编配工具这个家族里唯一的选择。编配工具是一个快速发展的生态环境,没有办法列出这个领域中的所有可用的工具,这些工具的功能不尽相同,不过大部分属于以下两个类型:
- 下面是一些其他的编配工具和组件
二、Docker Compose介绍
- 使用Docker Compose,可以用一个YAML文件定义一组要启动的容器,以及容器运行时的属性
- Docker Compose称这些容器为“服务”,定义为:容器通过某些方法并制定一些运行时的属性来和其他容器产生交互
- 本文下面介绍如何使用Docker Compose构建一个简单的多容器引用程序栈
- 官方文档:https://docs.docker.com/compose/
本文的代码、文件链接
三、Docker Compose的安装
- 目前Docker Compose可以运行在Linux、Windows和OS X上。可以通过直接安装可执行包来安装,或者通过Docker Toolbox安装,也可以通过Python Pip包来安装
Linux下的安装
- 目前Docker Compose只能安装在64位的Linux上
- 第一步:可安装Pip工具
sudo apt install python-pip
- 第二步:然使用Pip安装Docker Compose
sudo pip install -U docker-compose
- 第三步:然后直接就可以使用这个程序了,例如下面查看docker-compose的版本(前面输出的警告信息忽略,是因为我系统Python没搞好的原因,下面输入docker-compose命令都会带有,不影响使用)
docker-compose --version
OS X下的安装
- 如果OS X已经下载了Docker Toolbox,那么Docker Toolbox已经包含了Docker Compose
- 如果没有下载Docker Toolbox,那么可以像上面Linux一样安装,步骤都是一样的
Windows下的安装
- 如果Windows已经下载了Docker Toolbox,那么Docker Toolbox已经包含了Docker Compose
- 当然安装Docker Compose的方法很多,可以自行百度
四、编写测试用例
- 为了演示Compose是如何工作的,下面我们使用一个Python Flask引用作为例子,这个例子使用了以下两个容器
- 应用容器:运行Python示例程序
- Redis容器:运行Redis数据库
- 第一步:创建一个composeapp目录,用来存放本文实践的所有文件
mkdir composeapp
cd composeapp
- 第二步:创建引用程序的源代码,名为app.py,代码如下:
- 这个简单的Flask应用程序追踪保存在Redis里的计数器
- 每次访问根路径/时,计数器会自增
vim app.py
from flask import Flask
from redis import Redis
import os
app = Flask(__name__)
redis = Redis(host="redis", port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return 'Hello Docker Book reader! I have been seen {0} times'.format(redis.get('hits'))
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
- 第三步:创建一个requirements.txt文件来保存应用程序的依赖关系,下面Dockerfile会用到。文件的内容如下:
vim requirements.txt
flask
redis
- 第四步:创建Dockerfile文件,用于构建镜像,文件的内容如下:
- FROM指令:基于Python 2.7镜像构建
- LABEL指令:镜像的元数据,此处随意设置
- ENV指令:与Dockerfile有有关
- ADD指令:将宿主机当前路径下的app.py和requirements.txt文件加入到镜像的/composeapp目录下
- WORKDIR指令:将镜像的/composeapp目录设置为工作目录
- RUN指令:执行pip命令来安装应用的依赖:flask和redis
vim Dockerfile
FROM python:2.7
LABEL maintainer="https://blog.csdn.net/qq_41453285/"
ENV REFRESHED_AT 2020-07-27
ADD . /composeapp
WORKDIR /composeapp
RUN pip install -r requirements.txt
- 第五步:基于上面的Dockerfile创建镜像,镜像的名字为“dongshao/composeapp”
sudo docker build -t dongshao/composeapp .
sudo docker images
- 现在我们有一个镜像了,这个镜像包含了实例应用和应用需要的依赖,下面我们可以使用Docker Compose来部署应用了
- 之后会从Docker Hub上的默认Redis镜像直接创建Redis容器,这样就不需要重新构建或者定制Redis容器了
五、编写docker-compose.yml文件
- 上面我们的镜像已经创建好了,现在可以配置Compose来创建需要的服务了
- Docker Compose运行的原理大致如下:
- 在Compose中,我们定义了一组要启动的服务(以Docker容器的形式表现),我们还定义了我们希望这些服务要启动的运行时的属性,这些属性和docker run命令需要的参数类似
- 将所有与服务有关的属性都定义在一个YAML文件里
- 之后执行docker-compose up命令,Compose会启动这些容器,使用指定的参数来执行,并将所有的日志输出合并到一起
- 创建一个docker-compose.yml文件,内容如下:
vim docker-compose.yml
version: '3'
services:
web:
image: jamtur01/composeapp
command: python app.py
ports:
- "5000:5000"
volumes:
- .:/composeapp
links:
- redis
redis:
image: redis
docker-compose.yml解析
- 整个文件使用了一个YAML的散列键定义:web和redis
- 对于web服务,指定了一些运行时参数:
- image:指定了要使用的镜像(jamtur01/composeapp)
- command:指定服务启动时要执行的命令,此处我们为启动app.py程序
- ports:指定了运行容器时,宿主机与容器之间的端口映射,此处我们把宿主机的5000端口映射到容器的5000端口上
- volumes:创建容器的卷,此处容器的/composeapp目录挂载到了宿主机的当前路径.下
- 对于Redis服务:
- 比较简单,直接让其运行一个redis容器,该容器运行时没有指定任何配置,因为这个镜像会默认在标准端口上启动一个Redis数据库
- 上面的web服务相关参数就像相当于执行了下面的命令:
sudo docker run -d -p 5000:5000 -v .:/composeapp --link redis:redis --name jamtur01/composeapp python app.py
- 上面的Redis服务相关参数就像相当于执行了下面的命令:
sudo docker run redis
六、运行Compose
- 上面我们已经编写好了docker-compose.yml文件,并且在其中指定了服务,现在可以来执行这些服务了
- 在上面我们的composeapp目录下输入下面的命令即可
sudo docker-compose up
- 上面输出了大量的信息,内容为:
- 从最前面的信息可以看出,Compose创建了两个新的服务:
- composeapp_redis_1、composeapp_web_1
- 命名是有规范的,为了保证服务的唯一性,Compose将docker-compose.yml文件中指定的服务名字加上了目录名作为前缀,并使用数字作为后缀
- 由于我们的服务是在前台运行的,因此每个服务的日志都会输出:
- 输出的日志每一行都是用缩短的服务名字作为前缀,并交替输出在一起
- 因为我们的Python应用程序是映射到宿主机的5000端口上的,因此我们可以输入下面的URL来访问这个程序:
- 页面显示了当前计数器的值
- 如果你刷新网页,那么这个计数器的值会增加,每次刷新都增加保存在Redis里的值
- Redis更新是通过由Compose控制的Docker容器之间的链接实现的
备注:-d选项
- 上面我们启动服务时,没有指定-d选项,服务和Compose的信息都显示在了前台
- 你可以输出Ctrl+C来停止运行Compose运行,但是由于Redis等服务和Compose交替运行,所以如果你输入Ctrl+C,那么Redis服务也停止了
- 所以你可以在启动服务的时候使用-d选项,让Compose以守护进程的方式在后台运行
sudo docker-compose up -d
- 提示:在默认情况下,Compose会试图连接到本地的Docker守护进程,不过会受到DOCKER_HOST环境变量的影响,去连接一个远程的Docker宿主机
七、Compose的其它命令使用
help命令
- compose通过了很多命令,可以使用help命令来查看帮助文档
# 查看所有的帮助
sudo docker-compose help
# 查看单个命令的帮助, 例如查看ps命令的
sudo docker-compose help ps
-d选项
- 接着上面的演示案例,我们现在按下Ctrl+C来关闭在宿主机前台运行的Compose服务
- 然后输入下面的命令重新运行这些服务,不过我们指定-d选项,让这些服务以守护进程的方式在后台运行
sudo docker-compose up -d
ps命令
- 功能:该选项可以查看这些服务的运行状态
- 例如,下面查看我们那两个服务的状态,显示了Compose服务的一些基本信息,例如有:每个服务的名字、启动服务的命令以及每个服务映射到的端口
sudo docker-compose ps
logs命令
- 功能:可以查看服务的日志事件
- 例如,下面查看Compose服务的日志:
sudo docker-compose logs
stop命令、start命令、restart命令
- stop命令:用来停止compose服务
- start命令:用来启动compose服务
- restart命令:重启compose服务
- 演示案例:下面我们尝试停止运行的compose服务,停止之后再去查看可以看到任务停止了
sudo docker-compose stop
sudo docker-compose ps
kill命令
- 该命令与stop命令一样,都是用来停止Compose服务的
rm命令
- 功能:该功能可以同来删除服务
- 演示案例:下面来删除创建的两个服务,输入之后会让你输入y或N来选择是否删除。删除之后可以看到服务已经不存在了
sudo docker-compose rm
sudo docker-compose ps
八、总结
- 本文我们使用一个文件就可以构建一个简单的Python-Redis栈了。可以看出这种方法能够非常简单地构建一个需要多个Docker容器的应用程序
- 而这个例子,只展现了Compose最表层的能力,在Compose官网还有很多更高级的例子,比如使用: