文章目录
Docker Compose
Compose 编排基础
Docker Compose 非常适合组合使用多个容器部署
架构
以前
使用 docker run 等命令来完成容器的管理,一旦参数过多,就比较费时费力,容易出错
Docker Compose 将所有容器参数通过精简的配置文件(Compose 文件)来定义,通过命令 docker-compose
命令管理配置文件,完成容器的部署,从而解决复杂应用程序的问题
三个层次
管理的对象从上到下依次:
- 项目(Project):又称为工程,代表实现的一个应用程序,由一组关联的容器组成一个完整的业务单元,可以包含一个或者多个服务
- 服务(Service):代表着需要实现的一个子应用程序,以容器形式来完成任务,一个服务运行一个镜像
- 容器(Container):每个服务又以多个容器实列的形式运行,多个容器实例指的是服务的副本,可以通过修改副本数量来扩展服务
docker-py 是一个使用 python 语言开发并调用 DockerAPI 的软件包,不管前面如何,最终都会落实到 docker 引擎对容器的管理与部署上
使用步骤
- Dockerfile 定义应用程序环境
- docker-compose.yml 文件定义组成应用程序的各个服务(默认配置文件,一个文件作为一个单独的项目,会创建一个独立的网络,让其中的若干容器在隔离的环境中一起运行)
- 启动整个应用程序:
docker-compose up
特性
- 单主机上建立多个隔离环境,它会使用项目名称来隔离彼此的环境,默认项目名称是项目目录的基本名称,也可以使用命令行 -p 或者环境变量 COMPOSE_PROJECT_NAME 来设置自定义的项目名称
- 创建容器的时候保留卷数据,它会保留服务所使用的所有卷
- 仅重建已更改的容器
- 不同环境定制编排
场景
- 开发环境
- 自动化测试环境
- 单主机部署
安装
- 依赖 docker 引擎才能正常工作,所以需要先安装 docker 引擎
官方安装参考地址:安装 Compose 独立版 |Docker 文档
### 插件方式安装的查看方式
docker compose version
示例
- 创建项目目录:
mkdir project-demo ; cd project-demo
- 创建源码文件
cat >app.py <<EOF
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
EOF
- 创建依赖文件
cat >requirements.txt <<EOF
flask
redis
EOF
- 创建 Dockerfile 文件
cat >Dockerfile <<EOF
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
EOF
- 定义 docker-compose.yml 文件
cat >docker-compose.yml <<EOF
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
EOF
- 使用 docker compose up 构建并运行应用
docker compose up
过程
- 命令行访问8000验证程序
Compose 文件详解
Compose 文件是 Docker Compose 项目的主配置文件,又称 Compose 模板文件
- 定义整个应用程序:服务、网络、卷
- 文本文件或者 YAML 格式,后缀可以是 .yml 或者 .yaml
- 默认文件名:docker-compose.yml
文件格式版本
三个版本
传统格式
版本2.x:文件的首部来表示(version: ‘2’)
版本3.x:文件的首部来表示(version: '3)
- 现在多用 3.x 版本,要求docker 1.13.0 以上
- 差异性表现:可用配置项、docker 引擎最低版本、网络有关的行为
文件结构
标准文件的4个顶级部分
- version:定义版本号,没有下级字段
- services:定义服务,由下级字段定义
- networks:定义网络,由下级字段定义
- volumes:定义存储和卷,由下级字段定义
示例文件
version: '3' ## 定义版本号
services: ## 定义服务的部分
web: ## 定义第一个服务名称
build: . ## 定义服务构建方法
ports: ## 定义端口映射
- "8000:5000"
redis: ## 定义第二个服务名称
image: "redis:alpine" ## 定义使用的镜像
networks: ## 定义网络
frontend:
volumes: ## 定义存储
logvolumes01: {}
简单格式说明
- 缩进只能空格,不能 TAB
- 冒号与后面的参数之间需要一个空格
services 定义
- 定义若干服务,每个服务就是一个容器,容器是基于镜像运行的,所以必须使用
image
或者build
字段来提供镜像,其他字段可选
image
指定用于启动容器的镜像,可以是镜像名称或者镜像ID,如果镜像本地不存在,就会根据镜像的信息从远程注册中心进行拉取
build
定义构建镜像的配置,可以定义包括构建上下文路径的字符,如果同时指定 image,那么就会根据 build 构建镜像并且构建出来的镜像命名为定义的 image 名称
build: ./dir
###
build:
context: ./dir ### 定义构建上下文,可以是包含dockerfile的目录,或者访问仓库的URL
dockerfile: xxxxx ### 定义 Dockerfile 文件
args: ### 指定构建参数,构建阶段访问的环境变量
name: whale
command
覆盖容器启动后默认执行的命令
depends_on
定义服务之间的依赖,解决容器的依赖、启动的先后顺序问题
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: mysql
docker compose up
会按照依赖顺序启动服务
docker compose up web
启动web,会一同启动依赖
docker compose stop
先停止web,后停止依赖
entrypoint
覆盖容器的默认入口设置,清除镜像上的任何默认命令,也包括 CMD
env_file
从文件中加载环境变量
env_file: .env
###
env_file:
- ./xxx.env
- ./yyy.env
- ./zzz.env
environment
添加环境变量,数组或者字典形式,布尔值或者逻辑值需要使用引号
environment:
name: whale
age: 18
###
environment:
- name=whale
- age=18
expose
定义用于暴露没有发布到主机的端口,只允许被连接的服务访问,仅可以指定内部端口
expose:
- "9090"
external_links
用来连接未在 docker-compose.yml 文件中定义,甚至非compose管理的容器
external_links:
- redis
- mysql
- db2
network_mode
指定网络模式,与–network 选项类似
network_mode: "bridage"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
networks
指定要加入的网络(networks 部分定义的网络)
networks:
- mynet
ports
指定要暴露的端口
ports:
- "9090"
- "9090:22"
### 多个字段定义端口
ports:
- target: 80
published: 8080
protocol: tcp
mode: host
volumes
与 volumes 部分定义卷存储不同的是,这个地方是用来定义挂载的主机路径或命名卷
- 挂载主机路径作为单个服务定义的一部分,不用再后续的部分中定义这个卷
- 如果多个服务之间重用一个卷,后续的部分中要定义这个卷,然后再这里引用
version: "3"
services:
web:
image: myweb
volumes:
- type: volume
source: mydata
targetL /data
volume:
nocopy: "true"
- type: bind
source: /static
target: /opt/static
db:
image: mysql
volumes:
- "/data/mysql:/var/lib/mysql"
volumes:
mydata
restart
定义容器重启策略,默认设置是 no,任何情况不会重启容器
- akways:总是重新启动
- no-failure:退出代码指示故障错误,将重启容器
volumes 定义
不同于 services 下面的 volumes,这里是单独创建命名卷,能在多个服务之间重用
### 条目可以为空,就会使用 Docker 配置的默认存储驱动
volumes:
mydata:
### 也可以进行字段配置
driver: local ### 定义卷的卷驱动,多数情况下 local 本地
driver_opts: ### 传递给卷的驱动,取决于卷驱动的本身
foo:
baz:
### 外部创建,如果为true,docker compose 不会去尝试创建它,如果不存在就会报错
volumes:
data:
external: true
networks 定义
1.0 版本不支持网络配置,只有 2.0以上才支持
默认网络配置
root@VM-16-4-ubuntu:~/project-demo# cat docker-compose.yml
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
- 创建为名 目录名_default 的网络
- 创建使用 web 的容器,并加入在 web 名下的【目录名_default】网络
- 创建使用 redis的容器,并加入在 redis名下的【目录名_default】网络
更改默认网络的配置
networks:
default:
driver: xxxxx ### 使用自定义驱动
指定自定义网络
- 可以创建更复杂的拓扑
- 自定义网络驱动和选项
- 将服务连接到不由 compose 管理的外部创建的网络中
services:
web:
build: .
ports:
- "8000:5000"
networks:
- frontend
networks:
frontend:
driver: xxxxxxxxx
使用现有网络
networks:
default:
external:
name: xxxxxxxxx
Compose 命令行
命令行格式
docker compose [-f <arg>...] [options] [conmand] [args...]
-
-f 指定多个文件,会按照顺序组合到一个单一的配置中,后面的 compose 文件将覆盖和追加到前面的 compose 文件中(感觉不太好用,比喜欢用)
-
其他选项
- -p :指定项目名称,默认当前目录作为项目名称
- –verbose:输出更多调试信息
- –log-level:设置日志级别
- -v:显示版本信息
- -h:帮助
- –project-directory:指定项目名称,默认是Compose文件所在路径
常见命令
dockers compose build
构建或重新构建服务并设置标签,(不太习惯这种使用方法)
- –no-cache:不使用缓存
- –pull 总是拉取最新版本镜像
- –build-arg key=value 构建时的变量
docker compose start
启动运行指定服务的已存在的容器
docker compose stop
停止指定服务的所有容器
docker compose pause
暂停指定服务的容器
docker compose unpause
恢复指定服务已处于暂停状态的容器
docker compose kill
通过发送SIGKILL信号来强制终止正在运行的容器,也可以 -s SIGINT
发送其他信号
docker compose up
最常用,用于构建、创建、启动和连接指定的服务容器,所有连接的服务都会启动,除非他们已经运行
- -d:后台运行,输出容器名称
- –quiet-pull:拉取镜像不会输出进程信息
- –no-start:创建服务后不启动他们
- –build:启动容器之间构建镜像
docker compose run
为服务运行一次性的命令
docker compose ps
查看服务中当前运行的容器,如果不指定 -p ,会以当前目录作为项目名称去查询
docker compose down
停止容器并删除由它创建的容器、网络、卷和镜像
docker compose rm
删除所有处于停止状态的服务容器,可以使用 -f 进行强制删除
docker compose config
验证和查看 Compose 文件
Compose 环境变量
多种使用方法
- 替换文件中的环境变量:shell 环境中的变量会被找到并替换
- 设置容器中的环境变量:
environment
字段 - shell 环境变量也可传递给容器,不赋值即可将 shell 中的环境变量传递给服务的容器
env_file
字段传递docker compose run -e
设置- …
环境变量优先级
- 优先级最高:compose 文件中定义
- 当前 shell 中的环境变量值(可使用 export 定义)
- 环境文件
- Dockerfile
Compose 编排示例
负载均衡示例
示例由4个容器组成,1个haproxy容器充当负载均衡服务,另外3个nginx充当web页面
cd /opt/software
mkdir test ; cd test
mkdir haproxy web1 web2 web3
### haproxy.cfg
cat >./haproxy/haproxy.cfg <<EOF
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
log global
mode http
option httplog
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
stats uri /status
frontend balancer
bind 0.0.0.0:80
default_backend web_backends
backend web_backends
balance roundrobin
server web1 web1:80 check
server web2 web2:80 check
server web3 web3:80 check
EOF
### web1的index.html
cat >./web1/index.html <<EOF
web1
EOF
### web2的index.html
cat >./web2/index.html <<EOF
web2
EOF
### web33的index.html
cat >./web3/index.html <<EOF
web3
EOF
定义 compose 文件
cat >docker-compose.yml <<EOF
version: "3.5"
services:
web1:
image: nginx
expose:
- "80"
volumes:
- ./web1/index.html:/usr/share/nginx/html/index.html
web2:
image: nginx
expose:
- "80"
volumes:
- ./web2/index.html:/usr/share/nginx/html/index.html
web3:
image: nginx
expose:
- "80"
volumes:
- ./web3/index.html:/usr/share/nginx/html/index.html
haproxy:
image: haproxy
ports:
- "80:80"
volumes:
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
networks:
default:
external:
name: mynet
EOF
运行
验证