多容器编排与管理 Docker Compose简介

上篇回顾
设定档格式 YAML

Docker太多文章介绍了, 小弟我K8S也没那麽熟稔
就介绍自己熟的Compose吧

Docker的相关入门能参考
30 天与鲸鱼先生做好朋友
30天与 Docker 做好朋友:跟鲸鱼先生一同探索开发者的大平台(iT邦帮忙铁人赛系列书)

docker compose

Docker Compose

Github
常常一个专案内, 主要的业务服务会有一些依赖的服务一起搭配, 进而完成工作.
常见的其他服务有NginxDB(MySQL, Postgre...)NoSQL(Redis、Mongo...)SMTP...etc
至於这compose需要什麽服务, 就看各业务服务需要哪些了.

利用DockerCompose来管理容器, 或者配置各容器需要挂载到哪个network、volume...,
都能透过开发者定义的docker-compose.yml文件, 来定义一组相关连的容器为一个Project.
所以上篇才介绍一下YAML

Docker-compose的图, 也正好说明,
一只章鱼?鱿鱼?有好几只手, 每个触手上管理着一个container, 任章鱼把玩

跟Dockfile的差异

其实只是管理便利性地差异,
Docker-compose还是要先安装好Docker, 当然Compose也能来编译原本写好的Dockerfile
如果自己是喜欢写Makefile或Shell快速管理的高手, 当然也是可以不需要Compose.

Compose中两个重要概念

  • Service
    • 一个应用的容器
  • Project
    • 由一组关联的应用容器组成的一个完整业务单元, 在docker-compose.yml中定义.

Compose默认管理的对象是Project, 透过命令对Project中的容器进行生命周期管里

以下只是范例, 并不真能跑, 因为我没放web专案的代码

version: "3"
services:
  web:
    ports:
      - 80:80
    environment:
      PRODUCTION: 'true'
  backgroundservice:
    build: 
      context: ../
      dockerfile: docker/CrawlerDockerfile
  db:
    image: mysql:8.0
    ports:
      - "3306:3306"
    command: [
      "--server-id=1",
      "--default-authentication-plugin=mysql_native_password"
    ]
    volumes:
      - ./db.cnf:/etc/mysql/conf.d/mysqld.cnf
      - ./sql:/docker-entrypoint-initdb.d

每个service都需要透过image指令来指定image名称与版本(如web和db)
又或者透过build指令来编译Dockfile, 建构出image(如backgroundservice)

build

context
args
指定Dockfile所在的文件位置, 可以是绝对位置或相对位置),
Compose会自动利用这路径下的Dockfile来自动构建出image, 然後使用该image进行容器的设定

---
version: "3.9"
services:
  webapp:
    build: ./dir #直接指定路径, 前提要dockfile档名刚好是Dockerfile
...

---
version: "3.9"
services:
  webapp:
    build:
      context: ./dir #透过context来指定路径
      dockerfile: Dockerfile-alternate #说明要执行编译的Dockfile档名
      args: # 指定编译image时, 所需要的arguments
        buildno: 1
...

image

指定image名称, 版本, 甚至能直接指定image ID(但我不推荐,, 没阅读性)

command

用来覆盖容器启动後默认执行的动作, 跟dockerfile的CMD类似的
在推荐的书本里Chap5也有提到

expose

开放port给container连线, 但没有映射到host上

expose:
  - "3000"
  - "8000"

ports

将port绑定在host上, 然後就能在host的环境, 与容器做交互

depends_on

当使用docker-compose up时, 依照依赖顺序, 以范例来说会先启动db和redis,再来启动web
docker-compose stop时, 一样反序的关闭容器.

Control startup and shutdown order in Compose
但! 只是启动顺序, 不代表web被启动完成时, db已经启动完成.
以下是官网的说明, 就只有启动, 并不会等待容器的状态到Ready

However, for startup Compose does not wait until a container is “ready” (whatever that means for your particular application) - only until it’s running. There’s a good reason for this.

官网推荐的作法是在透过一只wait-for-it.sh,
在依赖方执行透过docker-compose的command或直接写在dockerfile的CMD去执行;
vishnubob/wait-for-it
eficode/wait-for

或是被依赖方透过healthcheck去执行CMD, DockerLibrary有提供一些服务的HealthCheck脚本
透过healthcheck的话, 请别用until-do-done,
透过命令提供的options: interval, timeout, start-period retries来做循环
直接执行一次成功回应exit 0, 失败回应exit 1
ps 这方法有版本限制问题

version: "3.9"
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

docker-compose太多config options了, 大家能自己到官网学习

docker-compose 常见命令

docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]

options:

  • -f compose文件名称, 预设是docker-compose.yml
  • -p 指定project name, 预设用所在目录名称当专案名称, 建议指定, 方便管理
  • --verbose 输出详细的debug资讯

commands:

  • build
    • docker-compose build [options] [SERVICE...]
    • 重新build该项目所有service的image
      • --force-rm 删除临时容器
      • --no-cache 就不用cache
      • --pull 尝试拉取最新的image版本
  • config
    • 验证compose档案格式, 错误会显示错误原因
    • 好用! YAML格式太吃indent了XD
  • up
    • docker-compose up [options] [SERVICE...]
    • 等於一整组的动作, 重新create container, start container, link each
    • -d 将在後台运行
    • --scale SERVICE_NAME=NUM, 用来水平伸缩指定service的数量
  • stop
    • docker-compose stop [options] [SERVICE...]
    • 停止状态是running的容器
  • rm
    • docker-compose rm [options] [SERVICE...]
    • 会删除所有状态是stopped的容器, 所以建议事先使用上面的stop来停止容器後再进行删除
  • ps
    • docker-compose ps [options] [SERVICE...]
    • 列出容器清单
  • logs
    • docker-compose logs [options] [SERVICE...]
    • 如果没指定service name, 则把所有service的log都输出

Podman-Compose

关於Docker desktop的替代方案之一的Podman, 也支持compose, 所以转换上挺方便的

本日小结

Docker-compose对於一个专案内有多个容器的需求时, 管理容器的生命周期以及设定档的撰写非常便利.
且由於是一个专案内要设定多个service, 所以上一篇学到的anchor&alias*, 应该能在很多开源专案内的yml常看到.

虽然Docker渐渐地被冷漠?
但为了方便开发者与运维人员便利管理容器, 且Docker真的太夯,
基本替代方案出来, 还是兼容Dockerfile与Docker-compose.

相关说明能参考
30天分享那些年我怎麽理解 kubernetes 的运作

ps

Dokcker-compose V2最近刚释出,
V1是用Python开发的, V2则是用Go
使用指令上, V1如文章是docker-compose, V2则是docker compose
详情能看Compose Github连结


<<:  抓取资料库数据 - SQL进阶语法

>>:  【第二十天 - Flutter 与 Android、iOS 沟通方式 - 官方范例讲解】

JSON介绍

今天要先介绍JSON的写法,明天的实作会取用今天建置好的JSON档介绍Methods和Compute...

Day29 Lab 2 - Object storage数据压缩

资料的压缩最好是能做在前端,因为网路最慢的地方就是前後端的沟通了,现在的压缩演算法有很多,举凡gzi...

第18天 - 来试着做一个简易购物系统(2)_购买後,减少商品数量

考虑了一下,还是把价格给加上去好了(因为他跟商品数量的处理应该是差不多麻烦) 新建立一个 s_buy...

《征服》魔术师是万无一失

解读《征服》这本书,很有意思的是其中的时间管理,注意力管理,还有风险管理的维度展开。 把我们对魔术师...

【Aspose系列】Aspose.Cells (1) - 建立/读取Workbook、WorksheetCollection

这个系列旨在介绍 Aspose 的几类常用 API,有兴趣的话就一起往下看吧!此系列中不会包含 As...