一、容器编排
1. 容器编排的作用
当要使用一个容器时,大概会经历如下 Docker 命令:
- 拉取镜像
- 创建容器(指定网络、指定数据卷、指定环境变量等)
- 启动容器
- 停止容器
- 重启容器
如果需要用到很多容器,就需要分别对每个容器执行这些 Docker 命令,非常繁琐。
容器编排就是把要使用的容器全部定义到一个文件中,然后通过容器编排命令 docker-compose 统一管理这些容器、网络、挂载以及容器间的依赖关系。
2. 容器编排文件的结构
容器编排文件的扩展名是 yaml 或 yml,常见命名为 docker-compose.yaml 或 compose.yaml
文件的内容涉及基础 Docker 命令知识( 容器、网络、数据卷),当掌握这些命令后再学习容器编排文件的结构就很简单了,一看就懂(基本都是 docker create 的参数),以添加 mysql 和 redis 容器为例,文件结构如下(其中 service-mysql 和 service-redis 是服务名,自定义的):
# 挂载
volumes:
ougaii-data:
# 网络
networks:
ougaii-net:
# 容器集合
services:
# mysql 部分
service-mysql:
container_name: ougaii-mysql
image: mysql:9.4.0
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=123456
volumes:
- ougaii-data:/var/lib/mysql
networks:
- ougaii-net
# redis 部分
service-redis:
container_name: ougaii-redis
image: redis:8.2.1
ports:
- 6379:6379
environment:
- REDIS_PASSWORD=123456
volumes:
- ougaii-data:/bitnami/redis/data
- ougaii-data:/opt/bitnami/redis/mounted-etc
networks:
- ougaii-net
当容器编排文件内的容器之间有先后启动顺序,则在设置容器的部分,还可以通过 depends_on 属性指定依赖关系,被 depends_on 指定的容器会先行启动。
3. 容器编排命令
容器编排的核心命令是 docker-compose,本节记录的是 启动、重启、停止相关命令。其他的比如查看日志之类的,虽然 docker-compose 也提供了对应的命令, 但是我感觉没必要记忆,因为容器启动后,可以通过 Docker 的基础命令查看。
还有一个地方必须要提一下,就是本节后面部分的命令中,都会出现一个 -f 参数。这个参数用来指定 容器编排文件的路径,但是当容器编排文件的文件名为 docker-compose.yaml、docker-compose.yml、compose.yaml、compose.yml 时可以省略 -f 参数,docker 会自动在命令行同级目录中找这几个文件。
1. 启动容器
常用的启动命令有两种:
- 适合初次执行容器编排文件时使用,会 拉取镜像、创建 数据卷、网络、容器、并启动容器,比如文件名为 ougaii-compose.yml,则完整命令为
docker-compose -f ougaii-compose.yml up -d - 适合后续使用(既容器已经存在),不会创建各种资源,只会启动容器,比如文件名为 ougaii-compose.yml,则完整命令为
docker-compose -f ougaii-compose.yml start
2. 重启容器
- 重启全部容器:
docker-compose -f ougaii-compose.yml restart - 指定服务名重启容器
docker-compose -f ougaii-compose.yml restart service-mysql - 重启编排文件中变动的容器:
docker-compose -f ougaii-compose.yml up -d
3. 停止容器
- 停止全部容器:
docker-compose -f aaa.yml stop - 停止指定服务名的容器:
docker-compose -f aaa.yml stop service-mysql - 删除全部容器、网络、数据卷:
docker-compose -f aaa.yml down -v
二、制作镜像
1. 制作
制作镜像的需求一般有两种,一种是对已有的容器做修改后,需要生成新的镜像实现复用,这个在 Docker 基础命令文章中有记载。另一种就是把 jar 制作成镜像,这个需要自己写构建文件,文件名为 Dockerfile
下面是一个把 ougaii-generator.jar 制作成镜像的例子,没啥特别需要多说的,贼简单,都有注释:
# Dockerfile
# 基础镜像 java 21
FROM eclipse-temurin:21-jre-alpine-3.22
# 添加作者信息
LABEL author="ougaii <16891544@qq.com>"
# 添加文件描述
LABEL description="ougaii-generator docker file"
# 创建工作目录,后续 linux 命令都在这个目录下执行
WORKDIR /app
# 将宿主机上的 jar 复制到 镜像中工作目录内
COPY ./ougaii-generator-1.0.jar ougaii-generator.jar
# 环境变量,可以在创建容器时覆盖
ENV JAVA_OPTS="-Xms256m -Xmx512m"
ENV SPRING_PROFILES_ACTIVE="dev"
ENV TIME_ZONE="Asia/Shanghai"
# 安装创建用户和组的工具
RUN apk add --no-cache shadow
# 创建非root用户
RUN groupadd ougaii && useradd -m -g ougaii ougaii
# 指定时区
RUN ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_ZONE > /etc/timezone
# 切换用户
USER ougaii
# 提示这个目录有必要持久化,如果在 docker create 时不指定数据卷,则创建一个默认的数据卷来挂载这个目录
VOLUME ["/home/ougaii/generator"]
# 容器监听的端口
EXPOSE 8001
# 容器运行后,执行的命令
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar ougaii-generator.jar --spring.profiles.active=$SPRING_PROFILES_ACTIVE"]
2. 执行构建
构建镜像常见方式有两种,一种是直接用 Docker 命令,另一种是通过 容器编排。
1. 直接用 Docker 命令构建镜像
常规的构建命令格式为: docker build -f 构建文件 -t 自定义镜像名:自定义版本号 .
注意,不要忘了最后的 .,它代表构建上下文目录为当前目录,COPY、ADD 等指令中的路径是相对于该目录的。如果构建上下文目录不是当前目录,可以修改为实际路径。
还有就是 -f 部分,这个是指定构建文件的。docker build 会默认在命令行的所在目录中查找名字为 Dockerfile 的文件,如果构建文件的名字是 Dockerfile,则可以省略 -f 部分。
举例:
假设在命令行所处目录内有名为 Dockerfile 的文件,要将其构建成名字为 generator、版本为 v1 的镜像,则完整命令为:docker build -t generator:v1 .
2. 通过容器编排构建镜像
在容器编排文件中配置构建镜像并启动容器很简单,和配置其他容器完全相同,就是多了一个 build 属性,如下:
# 容器集合
services:
# 自定义服务名
service-generator:
# 构建镜像的属性
build:
# 构建上下文
context: .
# dockerfile 路径
dockerfile: Dockerfile
# 自定义镜像名和版本
image: generator:v1
container_name: ougaii-generator
ports:
- 8001:8001
environment:
- SPRING_PROFILES_ACTIVE=dev
networks:
- ougaii-net
配置完毕后,运行容器编排文件,还是基于 docker-compose up 命令,只是多了一个 --build 选项,例: docker-compose up -d --build
3. 镜像层
一个镜像是由多个镜像层组成的(基础镜像层 + 镜像层1 + 镜像层2 …),在编写构建文件时,Dockerfile 中每有一个构建命令( RUN、COPY、ADD) 就生成一个新的镜像层。
镜像层是可以复用的,比如 镜像1 和 镜像2 中有一个相同的镜像层,则这个镜像层就可以复用,镜像层复用的好处如下:
- 节省网络资源:拉取 镜像1 后,再去拉取 镜像2 时,不会再发送请求去拉取重复的镜像层。
- 节省本地磁盘空间:镜像1 和 镜像2 中相同的镜像层,本地只会存储一份。
- 加快构建速度:当本地有相同的镜像层时,不需要再次构建该镜像层。


被折叠的 条评论
为什么被折叠?



