由于之前写了一篇文章,主要是关于docker 基础的东西。这里说一下,容器编排的事情,因为后面 k8s 会用到这个。
参考 下面这个, 文档特别清晰
Docker Compose gitbook
Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速的部署分布式应用
注意 docker compose 有两个版本 一个是 python 编写的 ( docker-compose ),一个是 go 重写的 叫 compose v2 ( docker compose )命令几乎没有区别,只是 go 的少了 -
, 我们用python 版的就行。没什么差别
Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速的部署分布式应用
本章将介绍 Compose 项目情况以及安装和使用。
1.Compose 的简介
目标: 定义和运行多个 Docker 容器的应用, 针对多个容器组,进行一键启动和停止。
具体实现: docker-compose.yml 来定义一组相关联的应用容器为一个项目(project) docker-compose.yml 就相当于 dockerfile 的 dockfile
概念
service 服务 , 包含多个运行的容器
project 项目, docker compose 管理的单元
2. 安装
$ curl -L https://raw.githubusercontent.com/docker/compose/1.27.4/contrib/completion/bash/d
ocker-compose > /etc/bash_completion.d/docker-compose
3 使用
自己跑了一便文档上的例子,确实比较好用哟
-
在 任意文件夹 内穿件下面三个文件
-bash-4.2# pwd
/home/yangxuelei/docker_compose
-bash-4.2# ls
app.py docker-compose.yml Dockerfile
内容分别如下:
app.py
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
count = redis.incr('hits')
return 'Hello World! 该页面已被访问 {} 次。\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
Dockerfile
FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]
docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
-
运行
docker-compose up -d # -d 指定 后台运行,和 docker run -d 类似
运行过程
-bash-4.2# docker-compose up
------------------------------------------------------------------------------
单独创建一个网络 ( 确保容器名能在容器内部作为域名链接,打通网络)
Creating network "docker_compose_default" with the default driver
----------------------------------------------------------------------------------
生成镜像 默认为 (当前目录名_serversname:latest)
Building web
Sending build context to Docker daemon 4.096kB
Step 1/5 : FROM python:3.6-alpine
3.6-alpine: Pulling from library/python
...
Digest: sha256:f6bbda8e3f379c148c8ce45f7e017373158d0b725305b82c3f41d65ec4d18969
Status: Downloaded newer image for python:3.6-alpine
---> ac438c122d19
Step 2/5 : ADD . /code
---> 0e90ba41919e
......
Successfully tagged docker_compose_web:latest
Pulling redis (redis:alpine)...
alpine: Pulling from library/redis
540db60ca938: Already exists
( redis 镜像已经存在,所以不重新构建了 )
-----------------------------------------------------------------------------
从构建好的镜像 运行运行容器
Creating docker_compose_web_1 ... done
Creating docker_compose_redis_1 ... done
Attaching to docker_compose_web_1, docker_compose_redis_1
看一下刚刚启动的容器:
docker ps 查看启动的容器
上述命令会自动 帮你构建镜像,并按照配置启动容器组。已经存在镜像,则不会成重新构建,除非 使用 docker-compose build 重新构建服务
docker-compose build [options] [SERVICE...]
-
停止
docker-compose down
停止过程
Stopping docker_compose_web_1 ... done
Stopping docker_compose_redis_1 ... done
Removing docker_compose_web_1 ... done
Removing docker_compose_redis_1 ... done
Removing network docker_compose_default
可以看出,是先停掉容器,然后再删除容器的,也会删除网络。所以必要的数据一定要 挂载到外面做持久化
-
再次运行
-bash-4.2# docker-compose up -d
Creating network "docker_compose_default" with the default driver
Creating docker_compose_redis_1 ... done
Creating docker_compose_web_1 ... done
可以看到不会重复构建镜像,只会创建新的网络和容器
-
查看生成的镜像 (服务运行的时候才能显示, 因为是根据容器显示的)
-bash-4.2# docker-compose images
Container Repository Tag Image Id Size
------------------------------------------------------------------------------
docker_compose_redis_1 redis alpine 1690b63e207f 32.32 MB
docker_compose_web_1 docker_compose_web latest d14fc1d5217b 53.59 MB
4 docker-compose 相关命令
docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]
可选的 参数
-f, --file FILE 指定使用的 Compose 模板文件,默认为 docker-compose.yml
-p, --project-name NAME 指定项目名称,默认将使用所在目录名称作为项目名
(up 的时候可以,使用 -p 参数修改 默认的 目录名的项目名)
docker-compose -p compose_test up -d
# Creating compose_test_redis_1 ... done
# Creating compose_test_web_1 ... done
build (仅针对写了 build 的services)
config
检查 Compose 文件是不是对的,错误的话会有错误信息
down
停止容器组,依次删除容器和清楚创建的网络
exec
进入指定的容器 ( services 里定义的服务名) 或者直接 docker exec
ps
查看容器组 (只包含 compose 启动的容器)
images
列出 compose 文件中的镜像
kill (通过发送 SIGKILL 信号来强制停止服务容器)
logs
默认会 用不同的颜色 显示 服务组的控制台日志
pause
暂停一个服务容器,和 docker pause 一样的
pull
拉取服务依赖的镜像
push
推送服务依赖的镜像到 Docker 镜像仓库
restart
重启项目中的服务
rm
run
docker-compose run ubuntu ping docker.com
所有关联的服务将会自动被启动
scale
这个还是挺有用的,设置服务容器的个数
docker-compose scale web=3 db=2
start
启动服务
stop
关闭容器
up
这个命令是最常用的
它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作
docker-compose up 将会尝试停止容器,然后重新创建(保持使用 volumes-from 挂载的卷),以保证新启动的服务匹配 docker-compose.yml 文件的最新内容
docker compose 模板文件
格式
ymal
一个基本模板
version: "3"
services:
webapp:
image: examples/web
ports:
- "80:80"
volumes:
- "/data"
一些可用的配置项 (只说一下,常用的吧)
每个服务都必须通过 image 或者 build ( 使用 Dockerfile) 指令 指定镜像生成的方式
build
指定dockerfile 路径,相对于 docker-compose.ymal 文件 相对路径 或者 绝对路径
build: ./dir
或者
build:
context: ./dir # Dockerfile 所在文件夹的路径
dockerfile: Dockerfile-alternate # Dockerfile 文件名
args: # arg 指令指定构建镜像时的变量
buildno: 1
command
command: echo "hello world"
默认为 dockerfile 的入口命令,你可以用这个覆盖
container_name
container_name: docker-web-container
覆盖默认的规则 : 项目名称服务名称序号
如果指定了 这个容器名,就没办法使用 docker-compose scale 命令了,因为多个容器名不能一样
depends_on
指定当前容器 依赖那个容器(需要先启动)
下面的启动 顺序依次是 redis db web
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
web 服务不会等待 redis db 「完全启动」之后才启动
expose
暴露端口,但不映射到宿主机
expose:
- "3000"
- "8000"
healthcheck
容器健康检查配置
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
image
和build 目的一样,指定某个镜像的生成方式
如果本地不存在 会尝试 pull
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd
labels
添加容器描述信息, 和 dockerfile 里面的 labels 一样
labels:
com.startupteam.description: "webapp for a startup team"
com.startupteam.department: "devops department"
com.startupteam.release: "rc3 for v1.0"
network_mode
和 docker run --network 的一样
networks
设置容器使用的网络
ports
和 docker run -p 一样
HOST:CONTAINER 前面是 宿主机,后面是容器,单个 的话就是暴露容器端口
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
volumes
设置挂在目录
HOST:CONTAINER 宿主机路径/数据卷 : 容器路径
支持相对路径
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
以及其他命令
domainname, entrypoint, hostname, ipc, mac_address, privileged, read_only, shm_size, restart, stdin_open, tty, user, working_dir
关于 compose 容器间的通信 (使用 服务名 即可)
https://michael728.github.io/2019/06/15/docker-compose-networks/
下面关于我的 docker-compose.yml
version: '3' # 最新的是3, Compose配置文件格式声明
services: # 定义服务
model_server: # 某个服务
labels: # 同 dockerfile labels 描述信息
author: "yangxuelei@airia.cn"
useage: "airia stream model server"
lanuage: "golang 1.15.5"
run_mode: "go mod"
frame: "gin"
build: model_server_install # 指定一个打包的相对目录(或绝对目录)
container_name: model_server # 定死容器名, 将不能使用 docker-compose
scale 命令,因为容器名字不能重复
ports: # 端口映射,同dockerfile
- 8080:8080
volumes: # 数据挂载,同 dockerfile
- /home/yangxuelei/airia_stream_mount/model_server:/home/root/media
depends_on: # 容器依赖,会在他们之后启动当前的 service
- redis
- mysql
monitor_server:
labels:
useage: "airia stream monitor server"
language: "python3.6"
frame: "django 2.2"
build: monitor_server_install
container_name: monitor_server
depends_on:
- redis
- mysql
ports:
- 8086:8086
- 8505:8505
- 8506:8506
volumes:
- /home/yangxuelei/airia_stream_mount/monitor_server:/home/RESOURCES/monitor
/alert/images
mysql:
image: mysql # 直接使用官方镜像
expose: # 暴露端口,服务之间,而不是暴露到宿主机
- 3306
environment: # 设置一些环境变量
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: abcd@1234
MYSQL_USER: root
MYSQL_PASS: abcd@1234
MYSQL_DATABASE: model_server
volumes:
- /home/yangxuelei/airia_stream_mount/mysql-data:/var/lib/mysql # 数据持久
化到外面/初始化数据库结构
# 我是直接弄一个空的数据库,执行完吧 /var/lib/mysql放到外面的挂在目录,然后模拟初始化
- /home/yangxuelei/airia_stream_mount/init.sh:/var/init.sh # 挂载外部初始化
数据脚本, 这个后面不需要了,直接用上面的数据挂载初始化
# command: /bin/sh /var/init.sh # 指定这个初始化文件,传给 mysql的
entrypoint 命令
container_name: aistream_mysql
labels:
useage: "model_server and monitor server data stoage"
redis:
image: redis
expose:
- 6379
container_name: aistream_redis
labels:
useage: "for websocket"
# 启动
# docker-compose -p haha up -d 后台启动, 有打包好的镜像会直接运行
# docker-compose -p haha build 重新打包生成镜像
# docker-compose -p haha down 停止服务并移除容器和网络
# docker-compose -p haha logs 查看所有的启动日志
网友评论