之前使用Docker,是先定义Dockerfile文件,然后使用docker build
、docker run
等命令操作容器。
但通常来说,一个应用系统不仅仅只包含一个服务,每个服务一般也有多个容器实例。这种情况下如果每个容器都要手动启停,那么效率之低、维护量之大可想而知。
Docker Compose是Docker官方编排(Orchestration)项目之一,负责快速的部署分布式应用。
使用Docker Compose可以轻松、高效的管理容器,它是一个用户定义和运行多个容器的Docker应用程序。在Docker Compose中你可以使用YAML文件来配置你的应用服务,然后只需要一个简单的命令,就可以创建并启动你配置的所有服务。
github地址:https://github.com/docker/compose
服务(service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
项目(project):由一组关联的应用容器组成的一个完成业务单元,在docker-compose.yml中定义。
Compose的默认管理对象是项目(project),通过子命令可以很方便对项目中的一组容器进行生命周期管理。
# curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# docker-compose -v #查看版本
docker-compose
命令:build 构建(重新构建)项目中的服务容器
bundle 从 Compose 文件生成一个docker包
config 验证 Compose 文件格式是否正确,若正确则显示配置,若格式错误显示错误原因
create 创建服务
down 停止并删除up所启动的容器,并移除网络、镜像和数据卷
events 从容器接收实时事件
exec 进入指定的容器
help 获得一个命令的帮助
images 列出 Compose 文件中包含的镜像
kill 强制停止服务容器
logs 查看服务容器的输出
pause 暂停一个服务容器
port 打印某个容器所映射的公共端口
ps 列出项目中目前的所有容器
pull 从镜像仓库拉取服务依赖的镜像
push 推送服务依赖的镜像到镜像仓库
restart 重启项目中的服务
rm 删除所有(停止状态的)服务容器
run 在指定服务上执行一个命令
scale 设置指定服务运行的容器个数
start 启动已经存在的服务容器
stop 停止运行状态中的容器,但不删除
top 查看各个服务容器内运行的进程
unpause 恢复暂停状态中的服务容器
up 包括构建镜像、(重新)创建服务、启动服务,并关联服务相关容器的一系列操作
version 打印版本信息
docker-compose
参数:-f, --file 指定使用的 Compose 模板文件,默认为 docker-compose.yml
-p, --project-name 指定项目名称,默认将使用所在目录名称作为项目名
--log-level 指定日志级别(DEBUG, INFO, WARNING, ERROR, CRITICAL)
--no-ansi 不打印ANSI控制字符
--verbose 打印更多调试信息
-v, --version 打印版本并退出
-H, --host 守护进程socket连接的主机
模板文件是使用Docker Compose的核心,涉及到的指令关键字也比较多。默认的模板文件名称为docker-compose.yml
,格式为YAML格式。
docker-compose.yml
组成:services
一个服务代表一个容器,这个容器的镜像可以由pull或build而来。
服务的启动类似docker run,每个服务都有自己的名字、使用的镜像、挂载的数据卷、所属的网络、依赖哪些其他服务等
volumes
数据卷,可以定义数据卷的名字,然后挂载到不同的服务下去使用
networks
网络,可以定义网络的名字及网络类型等
注意:每个服务都必须通过image指令指定镜像或build指令(需要Dockerfile)等来自动构建生成镜像。如果使用build指令,在Dockefile中设置的选项(例如:CMD、EXPOSE、VOLUME、ENV等)将会自动被获取,无需在docker-compose.yml中再次设置。
build
指令:build,指定Dockerfile所在文件夹的路径。Compose将会利用Dockerfile自动构建镜像,然后使用镜像启动服务容器。
build: /path/to/build/dir
也可以是相对路径,只要上下文确定就可以读取到Dockerfile。
build: ./dir
设定上下文根目录,然后以该目录为准指定Dockerfile。
build:
context: ../
dockerfile: path/of/Dockerfile
cap_add
、cap_drop
指令:cap_add、cap_drop,指定容器的内核能力(capacity)分配。
cap_add:
- ALL #用于所有能力
cap_drop:
- NET_ADMIN #去掉NET_ADMIN能力
command
指令:command,覆盖容器启动后默认执行的命令。
command: echo 'hello world'
container_name
指令:container_name,指定容器名称。Compose默认使用项目名称_服务名称_序号
。指定名称后无法使用扩展(scale)。
container_name: docker-web-container
depends_on
指令:depends_on,指定容器的依赖、启动先后的顺序。
depends_on:
- db
- redis
dns
指令:dns,自定义dns服务器。
dns:
- 8.8.8.8
- 114.114.114.114
dns_search
指令:dns_search,配置dns搜索域。
dns_search:
- domain1.example.com
- domain2.example.com
environment
指令:environment,设置环境变量,可以使用数组和字典两种格式。
environment:
PACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
expose
指令:expose,暴露端口但不映射到宿主机,只被连接的服务访问
expose:
- "3000"
- "8000"
extra_hosts
指令:extra_hosts,添加主机名,会在容器/etc/hosts
文件中添加一些记录。
extra_hosts:
- "googledns:8.8.8.8"
- "dockerhub:52.1.157.61"
healthcheck
指令:healthcheck,检查容器是否健康运行。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
tomeout: 10s
retries: 3
image
指令:image,指定服务的镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取镜像。
image: hello-world
labels
指令:labels,为容器添加Docker元数据(metadata)信息。
labels:
com.startupteam.description: "webapp for a startup team"
com.startupteam.department: "devops department"
com.startupteam.release: "rc3 for v1.0"
logging
指令:logging,配置日志选项。
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
#目前支持三种日志驱动类型
driver: "json-file"
driver: "syslog"
driver: "none"
#options配置日志驱动的相关参数
options:
max-size: "200k"
max-file: "10"
network_mode
指令:network_mode,设置网络模式。
network_mode: "bridge"
networks
指令:networks,配置容器连接的网络。
networks:
- some-network
- other-network
ports
指令:ports,指定映射的端口。
ports:
- "80:80"
- "8080"
restart
指令:restart,指定容器退出后的重启策略。
restart: always
secrets
指令:secrets,存储敏感数据。
mysql:
image:mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
secrets:
- db_root_password
- my_other_secret
secrets:
my_secret:
file: ./my_secret.txt
my_other_secret:
external:true
sysctls
指令:sysctls,配置容器内核参数。
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
ulimits
指令:ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
volumes
指令:volumes,指定数据卷所挂载路径。可以设置宿主机路径或加上访问模式,支持相对路径。
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
注意:以上指令只是常用的指令,并不是所有的指令。
下面使用Docker Compose部署wordpress项目,该项目包含两个service:wordpress和mysql。
docker-compose.yml
:# mkdir /wordpress && cd /wordpress
# vim docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 123456789
MYSQL_DATABASE: wordpress
restart: always
volumes:
- db_data:/var/lib/mysql
networks:
- my-bridge
wordpress:
depends_on:
- db
image: wordpress
ports:
- "80:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: 123456789
networks:
- my-bridge
volumes:
db_data:
networks:
my-bridge:
driver: bridge
# docker-compose up -d
Creating network "wordpress_my-bridge" with driver "bridge"
Creating volume "wordpress_db_data" with default driver
Creating wordpress_db_1 ... done
Creating wordpress_wordpress_1 ... done
# docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------
wordpress_db_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
wordpress_wordpress_1 docker-entrypoint.sh apach ... Up 0.0.0.0:80->80/tcp
查看新建的network和volume
# docker network ls
NETWORK ID NAME DRIVER SCOPE
ff9743715e7f bridge bridge local
cfa3c20aedc7 host host local
6527f05a2b23 none null local
784ff3c3208f wordpress_my-bridge bridge local
# docker volume ls
DRIVER VOLUME NAME
local f3242b47b11ff0ddf6c520df36c8cccc99509421d4d6b19373b60db8304b6c1c
local wordpress_db_data
查看数据库容器
# docker exec -it wordpress_db_1 bash
root@1255075bb1fd:/# mysql -uroot -p123456789
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| wordpress |
+--------------------+
5 rows in set (0.03 sec)
当前部署机器ip为192.168.30.130
,打开浏览器访问192.168.30.130
,
填写信息后直接登录,可以看看wordpress站点
可以看到,使用Docker Compose部署项目十分简单。但因为Docker Compose部署的项目,它所有的容器都在同一台主机上,这在生产环境下是不能接受的,所以Docker Compose仅适用于开发环境。
那么如何在生产环境下部署项目呢,这就需要使用Docker Swarm啦,在此不进行讨论。