文章目录
- 一、introduce
- 二、安装compose
- 三、compose 初探
- 四、compose yml细看
- 五、docker-compose命令
一、introduce
- docker compose 和 docker 是docker 公司的两个项目
- why docker compose?
docker compose定位:定义和运行多个容器应用。典型场景:一个 web项目,除了web应用本身,还需要 数据库、缓存LB 的配合(依赖项)。如果一个个起,实际很费事。Docker compose 允许用户通过一个docker compose yaml
模板定义一组相关联的容器共同构成一个项目。但要注意,资源的调度compose是搞不定的,要靠K8S
Compose中的两个概念:
- 服务 service:就是一组由相同镜像拉起来的容器
- 项目 project:一组关联应用组成的一个完整业务单元,可在docker-compose.yml 文件中定义
Compose的管理对象是项目,通过命令对一组容器进行生命周期管理。不过还要注意Compose的项目和我们说的一套代码的项目(工程)是两个东西。
Compose由Python写就,本质上是调用了 docker API。只要平台支持 Docker API,就能利用Compose编排管理。
二、安装compose
下面描述基于Linux(centos7)安装:
[root@localhost helloapp]# sudo curl -L "https://github.com/docker/compose/releases/download/1.28.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 633 100 633 0 0 406 0 0:00:01 0:00:01 --:--:-- 406
100 11.6M 100 11.6M 0 0 1849k 0 0:00:06 0:00:06 --:--:-- 2652k
[root@localhost helloapp]# sudo chmod +x /usr/local/bin/docker-compose
[root@localhost helloapp]# docker compose -v
Docker version 20.10.3, build 48d30b5
为啥要放到 usr/local/bin
? 主要是这样会自动配置环境变量。
三、compose 初探
创建测试目录,创建docker-compose.yml
文件(内容如下),并启动docker-compose up
;宿主机测试 curl localhost:8081
;宿主机测试docker ps -a
发现有新起的服务。
version: "3.9"
services:
tomcat-service:
image: "tomcat:9.0"
ports:
- "8080:8080"
tomcat-service-1:
image: "tomcat:9.0"
ports:
- "8081:8080"
四、compose yml细看
第一步:以下面这段 yml
作为说明材料
version: "3.9"
services:
tomcat-service:
image: "tomcat:8.0"
ports:
- "8080:8080"
volumes:
# 【数据卷挂载的第一种方式: 指定路径 挂载】
# - /home/hello:/usr/local/tomcat/webapps
# 【第二种方式: 具名挂载】
- tomcatapps:/usr/local/tomcat/webapps
volumes:
tomcatapps: # 【使用具名挂载时一定要 声明 这个 名字;也可以使用 external 指定,但感觉也没啥必要】
先说明一下【volumes】:
- 使用 具名挂载 时一定要声明 卷名
- 使用具名挂载的容器,产生的卷名为 项目名_卷名, 而非卷名
使用docker inspect ContainerID
,查看挂载信息:
进入到宿主机挂载目录,可见已形成映射:
下面我们制作了一个几乎囊括了所有常用 模板指令的 docker-compose.yml
文件。
version: "3.9"
services:
# ########################## 在docker-compose 之前 build 一个镜像,并直接拉起容器#######
mywebapp:
build:
context: ./mywebapp # 【docker build 上下文,其实就是 一个目录(相对于本 docker-compose.yml文件)】
dockerfile: Dockerfile #【指定 DockerFile,如果是 默认的,不写也成】
container_name: hello
ports:
- "8082:8080"
networks:
- hello
depends_on:
- tomcat01 #【我们就 假如 tomcat01 是一个 被依赖的服务】
# ##########################下方使用的都是现成 的docker images##########################
tomcat01: #【服务 id ,id当然是必须 唯一 的 】
container_name: tomcat01 # 【指定容器启动的名字,否则就是 项目名_tomcat01】
image: "tomcat:8.0"
ports: #【类似 这种 格式,在yml 中是一个 数组 ; 有的指令支持 KV 对】
- "8080:8080"
volumes:
# 【数据卷挂载的第一种方式: 指定路径 挂载】
# - /home/hello:/usr/local/tomcat/webapps
# 【第二种方式: 具名挂载】
- tomcatapps01:/usr/local/tomcat/webapps
networks: # 【指定Tomcat01 所在的网络,注意 指定的网络并不会自动创建,需要首先手动创建】
- hello
# 【真正能体现 编排 作用的指令,表示 tomcat01 这个服务依赖了 mysql01 redis01两个服务,不过,"依赖" 不代表
# mysql01 redis01 启动完成后才会启动 Tomcat01. docker-compose 会 在两者启动到一定程度(?)时就会启动tomcat01】
depends_on:
- mysql01 # 【这里是 服务名 ,不是 容器名】
- redis01
#【 健康检查 ;这里 只定义了健康检查,但是并没有 指明 假如不健康会怎么处理。hc 不是必须的】
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
# 【内核参数修改: 非必须的。少数 应用需要改内核配合】
# sysctls:
# - net.core.somaxconn=1024
# - net.ipv4.tcp_syncookies=0
# 【Override the default ulimits for a container; 其实就是Linux的 ulimit 参数】
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
tomcat02:
container_name: tomcat02
image: "tomcat:8.0"
ports:
- "8081:8080"
volumes:
- tomcatapps02:/usr/local/tomcat/webapps
networks:
- hello
mysql01:
container_name: mysql01
image: "mysql:5.7"
ports:
- "3306:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
networks:
- hello
# environment:
# - MYSQL_ROOT_PASSWORD=root
# 使用 environment 和 env_file 都能实现环境变量的set,但是 通过 environment 指令会将一些敏感信息暴露到
# 环境变量里,而 env_file 会相对安全(当然到底是否安全还是要看如何使用env_file.
# env_file 中的格式,推荐写成 K=V ,文件 以 .env 结尾; 支持相对和绝对路径
env_file:
- ./mysql.env
redis01: # 起一个单实例的redis容器
container_name: redis01
image: "redis:5.0.10"
ports:
- "6379:6379"
volumes:
- redisdata:/data
# 默认是 不开启持久化,通过【override】掉默认命令来开启持久化
command: "redis-server --appendonly yes"
networks:
- hello
volumes:
tomcatapps01: # 【使用具名挂载时一定要 声明 这个 名字】
tomcatapps02:
mysqldata:
mysqlconf:
redisdata:
networks: # 定义网桥
hello: # 【定义服务用到的网桥名称,默认创建的 是 bridge 】
external:
true # 【指定外部网桥,当然前提是 网桥 必须存在】
上述docker-compose.yml
中指定的docker build
的Dockerfile 如下:
FROM java:8
WORKDIR /home/hello
ADD hello-world-0.0.1-SNAPSHOT.jar mywebapp.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar"]
CMD ["mywebapp.jar"]
对应的文件目录(这个十分重要,目录就是docker build 上下文):
五、docker-compose命令
最常用、最强大的是 docker-compose up
docker-compose up [options] [--scale SERVICE=NUM...] [--] [SERVICE...]
-
--scale SERVICE=NUM Scale SERVICE to NUM instances. Overrides the "scale" setting in the Compose file if present.
【居然可以 扩容的!!!】 - 默认 docker-compose 起的项目跑在前台,如果
-d
(生产推荐)表示后台跑
另外还有:
-
docker-compose --verbose
方便调试 -
docker-compose -v
显示版本 -
docker-compose -p ProjectName
再取个项目名字 -
docker-compose ps
【只显示项目中的容器】 docker-compose exec
docker-compose down
docker-compose restart
docker-compose start
docker-compose stop
-
docker-compose top
【执行项目中所有服务的 top】 docker-compose unpause
docker-compose pause
docker-compose rm
【删除某个项目中的服务】
- -v [干掉数据卷]
- -f
-
docker-compose logs
【看日志,方便调试】
注意: 上面所有的命令都 针对 service 的。