Posted on:
Last modified:
2022-04 更新:k8s 已经取得了绝对优势,我现在实在找不到再使用 docker-compose 的理由了,在 本地搭建测试环境可以参考这篇:使用 multipass+autok3s 快速搭建本地 k3s 集群
------正文的分隔线------
使用 docker run 运行容器的时候经常需要加很多的参数,每次都输入这么多参数很容易出错。另外 我们经常需要同时运行若干个容器来构成一个服务,此时还是涉及到网络的联通等操作。
docker-compose 可以把 docker 执行时的参数写成 yaml 文件,运行的时候只需要
docker-compose up -d
一下就可以了。
话不多说,下面通过一个例子来学习一下 docker-compose.yml
文件的语法。
version: "3" # 版本号,目前最新版是 3,不同版本的语法是不太兼容的
services: # 定义的服务,注意是一个字典
web:
build: .
environment: # 定义环境变量
- ENV=prod
depends_on: # 该服务依赖下面的两个服务,也就是指定了
- db
- redis
command: python app.py
redis:
image: redis # 使用 dockerhub 上的 redis 镜像,这里也可以填自己的私有地址
network_mode: host|none
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"
db:
image: postgres
volumes:
- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
- "dbdata:/var/lib/postgresql/data" # 挂载的库,为了和 yaml 语法兼容,必须用引号
volumes: # 定义的卷
dbdata:
depends_on
指定当前的服务依赖的服务,从而确定启动顺序0.0.0.0
docker-compose 有以下 3 个常用命令:
docker-compose up [-d] [SERVICE]
启动服务,-d 表示以 daemon 形式后台运行,并且会在
重启后自动启动。docker-compose run
docker-compose stop
默认情况下,一个文件中的所有服务会绑定到同一个网络,互相可以通过服务的名字作为域名访问。
不过要注意,依赖其他容器提供服务的容器要使用 depends_on
表明依赖关系,否则可能在启动
过程中发现找不到服务,进而启动失败。
docker-compose 提供了 --scale
选项来实现横向伸缩。
--scale SERVICE=NUM Scale SERVICE to NUM instances. Overrides the
`scale` setting in the Compose file if present.
但是前提是不能在宿主机上绑定了同一个端口。比如说这样是不行的:
services:
web:
ports:
- "5000:5000"
那么改成 ports: ["5000"]
行吗?实际上这还是在宿主机上暴露了一个随机端口,其实没有必要。
在接下来的方法中,我们使用 expose
指令。
我们使用 expose
指令,只在容器网络内部暴露端口而不绑定宿主机任何端口,只有 container
网络内部才能访问。另外需要注意的是 Dockerfile 中的 EXPOSE
命令现在已经变成空指令了,
加不加没有任何区别。
expose:
- "5000"
那么这时候怎么在外部访问服务呢?我们可以加一个 load balancer, 比如 nginx
user nginx;
events {
worker_connections 1000;
}
http {
server {
listen 4000;
location / {
proxy_pass http://web:5000;
}
}
}
docker-compose.yaml
services:
web:
expose:
- "5000"
nginx:
image: nginx:latest
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- web
ports:
- "4000:4000"
这样就可以起多个副本啦:
docker-compose up --scale web=5
另外,还可以使用这两个镜像:
docker-compose 中默认的 project name 就是目录的名字,而 volume 的名字会添加上 project 的
前缀,也就是 <project>_<volume>
. 这就带来了一个问题,当我们把 docker-compose.yml 移动
路径的时候,原来的 volume name 就和新的对应不上了,简直神坑。
docker volume create --name <new_volume>
docker run --rm -it \
-v <old_volume>:/from \
-v <new_volume>:/to \
alpine ash -c "cd /from ; cp -av . /to"
docker volume rm <old_volume>
所以,最好使用 --project-name
来指定项目的名字,而不要让 docker-compose 自己生成。
如果要挂载目录或者文件到 docker 中的话,默认是以 docker-compose.yml
文件的路径为依据的,
简直奇葩。
volumes:
- ./deploy/prom.yml:/etc/prometheus/prometheus.yml
要改成 $PWD
才以运行命令的目录为根目录查找文件:
volumes:
- $PWD/deploy/prom.yml:/etc/prometheus/prometheus.yml
© 2016-2022 Yifei Kong. Powered by ynotes
All contents are under the CC-BY-NC-SA license, if not otherwise specified.
Opinions expressed here are solely my own and do not express the views or opinions of my employer.
友情链接: MySQL 教程站