1 简介
对于某个应用可能会有多个容器,比如一个django项目,用到了mysql、django、redis、nginx这些容器,每个容器都有自己独特的配置,启动这些容器至少需要四条语句。为简化应用配置,docker开发了compose项目,这个东西实在太好了,只有一个可执行文件,可以随意迁移,但目前仅支持x86_64的Linux机器,docker-compose。
原则上所有的生产型应用,必须使用compose,即不再依赖从命令行运行容器,即docker run,所有的应用都必须使用docker-compose,启动、停止、查看日志。
安装非常简单,直接复制一个docker-compose即可,但目前仅支持 x86_64的Linux机器
2 输入
docker-compose需要一个输入文件,文件格式是yml,默认文件名是docker-compose.yml,yml文件格式非常类似json,但是以缩进代替内容级别,这点又和python类似。请务必使用智能编辑器,确保格式正确。
2.1 框架
version: "2"
services:
registry:
#registry配置
nginx:
# nginx配置
以version开头,目前compose配置文件版本号为2。后面为定义的services,其中可以定义多个容器,每个容器可以自行配置。事实上每个容器的配置与docker run参数一一对应。
2.2 示例
version: "2"
services:
registry:
restart: always
image: registry:2
expose:
- "5000"
environment:
REGISTRY_HTTP_TLS_CERTIFICATE:/certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
REGISTRY_STORAGE_DELETE_ENABLED: 'True'
volumes:
- ./certs:/certs
- ./data:/var/lib/registry
nginx:
restart: always
image:dockerreg.maxnetsys.com:5000/maxnet-nginx
ports:
- "5000:5000"
links:
- registry
volumes:
- ./auth:/etc/nginx/conf.d/:ro
-./auth/nginx.conf:/etc/nginx/nginx.conf:ro
- ./log:/var/log/nginx
上述是一个私有仓库应用的compose示例,其中使用了两个容器。
l registry
仓库容器,使用当前目录下的certs目录作为ssl证书的存储位置,data目录作为所有镜像的存储位置。
定义两个ssl证书相关的环境变量,供ssl证书使用;同时定义此仓库删除标志为True,表明此仓库可以接受镜像删除,详细查看仓库相关文档。
restart标志为always,表示此容器异常退出后会自动重启,此标志在生产环境中必须存在,防止应用容器异常时可以自动启动。
image,指明镜像名称。
expose,对内导出端口,当前为端口5000,仅供本机其他容器使用。
l nginx
nginx容器,实现用户认证功能,即客户端pull时无需认证,push时必须认证。
ports,表示此容器对外部开发端口,外部端口在冒号左边,内部端口在冒号右边。
links,表示此容器会连接到registry,此处nginx容器会将客户端的请求转发到docker容器。
该容器定义了三个数据卷,其中的nginx.conf为文件数据卷,只读;log为存储nginx日志的数据卷;auth为nginx使用到的ssl证书和用户名密码等数据,只读。
3 运行
l 启动
在当前目录下使用命令docker-compose up,此终端会挂住并打印所有终端日志,如果使用-d参数则会后台运行。
l 结束
在当前目录下使用命令docker-compose down。
l 查看
在当前目录下使用命令docker-compose ps。
l 停止、重启服务
在当前目录下使用命令docker-compose stop service_name仅停止某个服务,在产品版本升级时需要使用。首先下载最新版本的镜像,然后停止此镜像对应的服务,再启动此服务就可以完成版本升级工作了。
4 原理
4.1 容器名称
compose大大简化了docker容器的部署和升级,可以看到每个容器的名称默认如下格式:
目录名称_服务名称_number
其中的number一般都是1。
4.2 网络
使用命令docker network ls查看,可以发现有很多网络设备,再使用ifconfig可以发现出现了很多接口,其实docker内部实现时,每个容器都有一个网络接口,这些接口再和主机上的接口桥接成一个网络。
欲知网络详情,详细请参考docker 相关内容https://docs.docker.com/compose/networking/