containerd+runC
,更加轻量,容易管理。Containerd和Docker是容器生态系统中相关但不同的组件。
Docker:
Docker是一种流行的平台,彻底改变了软件开发、发布和运行的方式。它提供了用户友好的界面和工具,用于创建、管理和部署容器。Docker允许开发人员将应用程序及其依赖项打包成容器,确保在不同环境中具有一致性。它提供了命令行界面(CLI)和图形用户界面(GUI),用于管理容器和镜像。
Containerd:
Containerd是一个业界标准的容器运行时,最初是Docker项目的一部分,但后来作为一个独立项目属于Cloud Native Computing Foundation(CNCF)。Containerd作为核心容器运行时负责在主机系统上运行和管理容器。它处理低层次的容器操作,比如容器的执行、镜像传输和存储,并支持containerd API以进行容器管理。
Containerd和Docker之间的关系:
Docker使用containerd作为其容器运行时。在Docker早期阶段,它拥有自己的容器运行时引擎,但随着容器生态系统的发展,决定将Docker模块化,并利用containerd作为底层运行时。这使得Docker能够更专注于高级别的功能和工具,同时利用containerd强大的容器运行时功能。
简而言之,Docker是一个全功能平台,包括CLI、GUI和其他用于容器管理的工具,而它依赖containerd作为容器运行时,在系统上执行和管理容器。Containerd是一个独立的、轻量级且高性能的容器运行时,被Docker和其他容器平台用于管理容器执行。
runC是一个开源的容器运行时工具,用于执行符合Open Container Initiative (OCI) 标准的容器。OCI是一个由Docker、CoreOS和其他公司共同推动的开放标准,旨在定义容器格式和运行时的规范,以促进容器生态系统的互操作性和可移植性。
runC是containerd项目的核心组件之一,它负责实际运行和管理容器。具体来说,当你使用Docker或其他容器平台创建和启动容器时,它们会使用runC来实际创建和运行容器实例。
runC的设计理念是简单和模块化,它只关注容器的运行时生命周期,不处理高级别的容器管理任务,比如镜像构建、网络配置等。因此,runC通常与容器管理工具(比如containerd、Docker、cri-o等)一起使用,这些工具提供了更全面的容器管理功能。
通过使用OCI标准,runC可以保证在支持OCI规范的任何容器运行时中都可以运行容器,这有助于避免了锁定到特定的容器平台。这种开放标准化的方法有助于加强容器生态系统的稳定性和互操作性。
功能范围:
复杂性:
使用场景:
虽然runC和containerd有不同的功能范围和复杂性,但它们通常会在一起使用。containerd使用runC来执行容器,这使得它可以利用runC的简单性和符合OCI标准的优势,并在此基础上提供更多的高级容器管理功能。
OCI(Open Container Initiative)是一个由Linux基金会支持的开放性项目,旨在为容器生态系统建立开放的行业标准。OCI的目标是定义容器格式和运行时的规范,以促进容器技术的互操作性和可移植性。
OCI项目涵盖了两个关键规范:
OCI Image Specification(OCI镜像规范):
这个规范定义了容器镜像的结构和内容。容器镜像是一个轻量级的、可移植的软件包,它包含了应用程序的代码、运行时所需的库文件、配置数据和其他依赖项。OCI Image Specification规定了镜像的存储格式、元数据和文件系统布局等,确保了不同容器运行时都能正确加载和执行这些镜像。
OCI Runtime Specification(OCI运行时规范):
这个规范定义了容器运行时的行为和接口。容器运行时是负责创建和管理容器的组件,它包括容器的生命周期管理、资源隔离、进程管理等功能。OCI Runtime Specification规定了容器配置、标准环境变量、容器状态等,使得不同容器运行时都能遵循统一的行为规范。
采用OCI规范的优势在于它促进了容器技术的标准化和互操作性。不同厂商和项目可以遵循OCI规范,保证其容器和工具在任何支持OCI标准的平台上都能够无缝运行。这种开放标准化的方法有助于加强容器生态系统的稳定性和可持续性,同时也降低了供应商锁定的风险。
目前,许多容器运行时和容器工具,包括Docker、containerd、cri-o等,都支持OCI规范,使得OCI成为了业界公认的容器标准。
Docker 的⼝号是 Build,Ship,and Run Any App,Anywhere,在我们使⽤ Docker 的⼤部分时候,的确能感觉到其优越性,但是往往在我们 Build ⼀个应⽤的时候,是将我们的源代码也构建进去的,这对于类似于 golang 这样的编译型语⾔肯定是不⾏的,因为实际运⾏的时候我只需要把最终构建的⼆进制包给你就⾏,把源码也⼀起打包在镜像中,需要承担很多⻛险,即使是脚本语⾔,在构建的时候也可能需要使⽤到⼀些上线的⼯具,这样⽆疑也增⼤了我们的镜像体积。
⽐如我们现在有⼀个最简单的 golang 服务,需要构建⼀个最⼩的 Docker 镜像,源码如下:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.String(http.StatusOK, "PONG")
})
router.Run(":8080")
}
我们最终的⽬的都是将最终的可执⾏⽂件放到⼀个最⼩的镜像(⽐如 alpine )中去执⾏,怎样得到最终的编译好的⽂件呢?基于 Docker 的指导思想,我们需要在⼀个标准的容器中编译,⽐如在⼀个Ubuntu 镜像中先安装编译的环境,然后编译,最后也在该容器中执⾏即可。但是如果我们想把编译后的⽂件放置到 alpine 镜像中执⾏呢?我们就得通过上⾯的 Ubuntu 镜像将编译完成的⽂件通过 volume 挂载到我们的主机上,然后我们再将这个⽂件挂载到 alpine 镜像中去。
这种解决⽅案理论上肯定是可⾏的,但是这样的话在构建镜像的时候我们就得定义两步了,第⼀步是先⽤⼀个通⽤的镜像编译镜像,第⼆步是将编译后的⽂件复制到 alpine 镜像中执⾏,⽽且通⽤镜像编译后的⽂件在 alpine 镜像中不⼀定能执⾏。
定义编译阶段的 Dockerfile :(保存为Dockerfile.build)
FROM golang
WORKDIR /go/src/app
ADD . /go/src/app
RUN go get -u -v github.com/kardianos/govendor
RUN govendor sync
RUN GOOS=linux GOARCH=386 go build -v -o /go/src/app/app-server
定义 alpine 镜像:(保存为Dockerfile.old)
FROM alpine:latest
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR /root/
COPY app-server .
CMD ["./app-server"]
根据我们的执⾏步骤,我们还可以简单定义成⼀个脚本:(保存为build.sh)
#!/bin/sh
echo Building cnych/docker-multi-stage-demo:build
docker build -t cnych/docker-multi-stage-demo:build . -f Dockerfile.build
docker create --name extract cnych/docker-multi-stage-demo:build
docker cp extract:/go/src/app/app-server ./app-server
docker rm -f extract
echo Building cnych/docker-multi-stage-demo:old
docker build --no-cache -t cnych/docker-multi-stage-demo:old . -f Dockerfile.old
rm ./app-server
`docker create`命令用于创建一个新的容器,但不会自动启动它。这个命令会返回一个容器的ID,可以将其用于后续操作,比如启动容器、进入容器等。
命令格式:
```
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
```
参数说明:
- `OPTIONS`: 可选参数,用于配置容器的各种选项,比如端口映射、数据卷挂载、环境变量等。
- `IMAGE`: 必需参数,指定要使用的镜像名称或ID来创建容器。
- `COMMAND`: 可选参数,可以指定容器启动后要执行的命令。
- `ARG...`: 可选参数,命令的参数,用于传递给容器中运行的命令。
使用示例:
```
docker create -p 8080:80 --name my_container nginx
```
上面的命令创建了一个名为`my_container`的容器,基于`nginx`镜像,将容器的80端口映射到主机的8080端口。
注意:`docker create`只是创建容器,容器并未运行。要启动容器,需要使用`docker start`命令。同时,如果想在容器内部执行命令,可以使用`docker exec`命令。
当我们执⾏完上⾯的构建脚本后,就实现了我们的⽬标。
Docker 17.05版本以后,官⽅就提供了⼀个新的特性: Multi-stage builds (多阶段构建)。 使⽤多阶段构建,你可以在⼀个 Dockerfile中使⽤多个 FROM 语句。每个 FROM 指令都可以使⽤不同的基础镜像,并表示开始⼀个新的构建阶段。你可以很⽅便的将⼀个阶段的⽂件复制到另外⼀个阶段,在最终的镜像中保留下你需要的内容即
可。
FROM golang AS build-env
ADD . /go/src/app
WORKDIR /go/src/app
RUN go get -u -v github.com/kardianos/govendor
RUN govendor sync
RUN GOOS=linux GOARCH=386 go build -v -o /go/src/app/app-server
FROM alpine
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build-env /go/src/app/app-server /usr/local/bin/app-server
EXPOSE 8080
CMD [ "app-server" ]
现在我们只需要⼀个 Dockerfile ⽂件即可,也不需要拆分构建脚本了,只需要执⾏ build 命令即可:
docker build -t cnych/docker-multi-stage-demo:latest .
默认情况下,构建阶段是没有命令的,我们可以通过它们的索引来引⽤它们,第⼀个 FROM 指令从 0 开始,我们也可以⽤ AS 指令为阶段命令,⽐如我们这⾥的将第⼀阶段命名为 build-env ,然后在其他阶段需要引⽤的时候使⽤ --from=build-env 参数即可。
选择最小的基础镜像
合并RUN环节的所有指令,少生成一些层
RUN期间可能安装其他程序会生成临时缓存,要自行删除。如:
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion \
&& rm -rf /var/lib/apt/lists/*
使用 .dockerignore 文件,排除上下文中无需参与构建的资源
使用多阶段构建
合理使用构建缓存加 速构建。(官方的例子:docker build --no-cache -f Dockerfile --target stage2 .
)
.dockerignore
是一个用于告诉Docker在构建镜像时忽略哪些文件和目录的配置文件。它类似于.gitignore
文件,用于指定哪些文件不应包含在构建的Docker镜像中。
当使用docker build
命令构建镜像时,Docker会将当前目录及其子目录中的所有文件发送给Docker引擎,以用于构建镜像。然而,并不是所有文件都应该包含在镜像中,比如一些临时文件、日志、不必要的依赖项等。通过使用.dockerignore
文件,可以指定哪些文件和目录应该被忽略,不包含在构建的镜像中。
.dockerignore
文件的格式和.gitignore
类似,可以使用通配符和目录匹配规则。当Docker构建镜像时,会根据.dockerignore
中的规则来过滤文件,并仅将未被忽略的文件包含在镜像中。
常见的.dockerignore
示例:
# 忽略所有的日志文件
*.log
# 忽略node_modules目录
node_modules/
# 忽略临时文件
temp*
# 忽略配置文件
config.json
secrets.ini
使用.dockerignore
可以帮助减小Docker镜像的大小,避免将不必要的文件包含在镜像中,从而提高镜像构建的效率和镜像的推送下载速度。
Docker Compose 是 Docker 官⽅编排(Orchestration)项⽬之⼀,负责快速的部署分布式应⽤。其代码⽬前在https://github.com/docker/compose上开源。Compose 定位是 「定义和运⾏多个 Docker 容器的应⽤(Defining and running multi-container Docker applications)」,其前身是开源项⽬ Fig 。
在⽇常⼯作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现⼀个 Web 项⽬,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器或者缓存服务容器,甚⾄还包括负载均衡容器等。Compose 恰好满⾜了这样的需求。它允许⽤户通过⼀个单独的 dockercompose.yml 模板⽂件(YAML 格式)来定义⼀组相关联的应⽤容器为⼀个项⽬(project)。
Compose 中有两个重要的概念:
Compose 的默认管理对象是项⽬,通过⼦命令对项⽬中的⼀组容器进⾏便捷地⽣命周期管理。
Compose 项⽬由 Python 编写,实现上调⽤了 Docker 服务提供的 API 来对容器进⾏管理。所以只要所操作的平台⽀持 Docker API,就可以在其上利⽤ Compose 来进⾏编排管理。
目前 Docker 官方用 GO 语言 重写 了 Docker Compose,并将其作为了 docker cli 的子命令,称为 Compose V2。你可以参照官方文档安装,然后将熟悉的 docker-compose 命令替换为 docker compose,即可使用 Docker Compose。
Using Docker Compose is a three-step process:
A Compose file looks like this:
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: redis
Compose 常用命令
docker-compose -h # 查看帮助
docker-compose up # 启动所有 docker-compose服务
docker-compose up -d # 启动所有 docker-compose服务 并后台运行
docker-compose down # 停止并删除容器、网络、卷、镜像。
docker-compose exec yml里面的服务id # 进入容器实例内部 docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
docker-compose ps # 展示当前docker-compose编排过的运行的所有容器
docker-compose top # 展示当前docker-compose编排过的容器进程
docker-compose logs yml里面的服务id # 查看容器输出日志
docker-compose config # 检查配置
docker-compose config -q # 检查配置,有问题才有输出
docker-compose restart # 重启服务
docker-compose start # 启动服务
docker-compose stop # 停止服务
模板文件是使用 Compose 的核心,涉及到的指令关键字也比较多。但这里面大部分指令跟 docker run 相关参数的含义都是类似的。
默认的模板文件名称为 docker-compose.yml,格式为 YAML 格式。
version: "3"
services:
webapp:
image: examples/web
ports:
- "80:80"
volumes:
- "/data"
注意每个服务都必须通过 image 指令指定镜像或 build 指令(需要 Dockerfile)等来自动构建生成镜像。
如果使用 build 指令,在 Dockerfile 中设置的选项(例如:CMD, EXPOSE, VOLUME, ENV 等) 将会自动被获取,无需在 docker-compose.yml 中重复设置。
下面分别介绍各个指令的用法。
指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。
version: '3'
services:
webapp:
build: ./dir
你也可以使用 context 指令指定 Dockerfile 所在文件夹的路径。
使用 dockerfile 指令指定 Dockerfile 文件名。
使用 arg 指令指定构建镜像时的变量。
version: '3'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
使用 cache_from 指定构建镜像的缓存
build:
context: .
cache_from:
- alpine:latest
- corp/web_app:3.14
在Docker Compose文件中,build
关键字用于指定如何构建镜像。它允许您在使用docker-compose up
命令启动服务之前,在本地根据Dockerfile构建自定义镜像。这样您可以对镜像进行自定义配置或添加额外的依赖项。
build
关键字可以有两种用法:
构建一个Dockerfile指定的镜像:
version: '3'
services:
service_name:
build: ./path/to/Dockerfile
在这个例子中,build
关键字告诉Docker Compose在./path/to/Dockerfile
路径下查找Dockerfile并构建一个镜像。Docker Compose将在构建过程中执行Dockerfile中的指令,并使用该镜像来运行服务。
构建一个具有自定义名称的镜像:
version: '3'
services:
service_name:
build:
context: ./path/to/build_context
dockerfile: Dockerfile.custom
args:
ARG_NAME: value
labels:
- "key=value"
image: custom_image_name:tag
在这个例子中,我们使用了更多的构建选项:
context
: 指定构建上下文的路径。构建上下文是Docker构建过程中的当前工作目录,Docker将从该目录中获取所需的构建文件。通常,这是一个包含Dockerfile和构建所需文件的目录。dockerfile
: 指定要使用的Dockerfile名称。如果您的Dockerfile不是标准的Dockerfile
文件名,可以在这里指定它。args
: 定义构建过程中的构建参数(build-time arguments)。这些参数可以在Dockerfile中使用,类似于ARG
指令。例如,您可以在Dockerfile中使用${ARG_NAME}
来引用这里定义的值。labels
: 向构建的镜像添加标签。这些标签可以提供有关镜像的元数据。请注意,如果使用了image
关键字,Docker Compose将在指定的名称下查找镜像。如果没有找到该镜像,它会尝试使用build
关键字指定的Dockerfile进行构建。
指定容器的内核能力(capacity)分配。
例如,让容器拥有所有能力可以指定为:
cap_add:
- ALL
去掉 NET_ADMIN 能力可以指定为:
cap_drop:
- NET_ADMIN
在Docker Compose文件中,cap_add
和cap_drop
关键字用于管理Docker容器的Linux内核能力(Linux capabilities)。Linux内核能力是一种细粒度的权限控制,允许容器在安全的情况下访问一些特定的内核功能,而无需完全暴露主机的全部功能。
cap_add
关键字:
cap_add
关键字用于向容器添加额外的Linux内核能力。您可以通过在cap_add
中列出需要添加的能力名称,让容器获得这些额外的权限。
例如:
version: '3'
services:
my_service:
image: my_image:latest
cap_add:
- NET_ADMIN
- SYS_PTRACE
在这个例子中,my_service
容器将获得NET_ADMIN
和SYS_PTRACE
两个额外的Linux内核能力。
cap_drop
关键字:
相反地,cap_drop
关键字用于从容器中删除一些Linux内核能力。您可以通过在cap_drop
中列出需要删除的能力名称,限制容器的权限。
例如:
version: '3'
services:
my_service:
image: my_image:latest
cap_drop:
- SETUID
- SETGID
在这个例子中,my_service
容器将不具有SETUID
和SETGID
两个Linux内核能力。
通过使用这两个关键字,可以更精细地控制Docker容器的权限,以增强容器的安全性。在实际应用中,您应该根据应用程序的需求仔细选择要添加或删除的Linux内核能力,以确保容器在运行时具有必要的权限而不会导致安全问题。
覆盖容器启动后默认执行的命令,没什么卵用。
在Docker Compose文件中,command
关键字用于指定容器启动时要执行的命令。这个命令会覆盖Docker镜像中默认的启动命令。使用command
关键字可以为容器提供自定义的启动命令或传递参数给应用程序。
command
关键字有两种用法:
单个命令:
version: '3'
services:
my_service:
image: my_image:latest
command: "python app.py"
在这个例子中,my_service
容器将使用python app.py
作为启动命令,而不是Docker镜像中默认的启动命令。这将导致容器在启动时执行Python应用程序。
命令和参数列表:
version: '3'
services:
my_service:
image: my_image:latest
command: ["sh", "-c", "echo Hello, Docker!"]
在这个例子中,my_service
容器将使用sh -c "echo Hello, Docker!"
作为启动命令。这里的启动命令是由一个命令(sh
)和参数列表(-c
和echo Hello, Docker!
)组成的。
请注意,如果Docker镜像中的CMD
指令已经定义了默认的启动命令,command
关键字将覆盖该默认命令。
使用command
关键字的一个常见用例是在容器启动时传递环境变量或应用程序参数。例如,如果应用程序依赖于某些环境变量,您可以通过command
关键字将这些环境变量传递给容器。
version: '3'
services:
my_service:
image: my_image:latest
command: ["sh", "-c", "python app.py $ENV_VARIABLE"]
environment:
- ENV_VARIABLE=value
在上面的例子中,my_service
容器将通过command
关键字执行sh -c "python app.py $ENV_VARIABLE"
命令,并通过environment
关键字设置ENV_VARIABLE
环境变量的值为value
。
总之,command
关键字是一个有用的工具,可以在Docker Compose中定义容器启动时要执行的命令,并允许您为应用程序提供自定义的启动行为。
指定父 cgroup 组,意味着将继承该组的资源限制。
例如,创建了一个 cgroup 组名称为 cgroups_1。
cgroup_parent: cgroups_1
container_name
是Docker Compose文件中用于指定容器的自定义名称的关键字。使用container_name
关键字,您可以为容器指定一个人类可读的名称,而不是由Docker自动生成的默认容器名称。
在Docker Compose文件中,container_name
关键字用于为服务中的容器指定自定义名称。这样做的好处是,容器的名称变得更具有可读性和可理解性,特别是当您有多个服务或容器时,可以更容易地识别和管理它们。
以下是一个使用container_name
关键字的示例:
version: '3'
services:
web_server:
image: nginx:latest
container_name: my_nginx_server
ports:
- "80:80"
在这个例子中,web_server
服务的容器将被命名为my_nginx_server
。当您使用docker ps
命令查看正在运行的容器时,您将看到它的名称是my_nginx_server
,而不是由Docker随机生成的默认名称。
请注意,container_name
关键字在整个Docker Compose文件中必须是唯一的。如果您在同一个Compose文件中的多个服务中使用相同的container_name
,将会导致Compose启动失败。
总结:container_name
关键字是Docker Compose中的一个有用选项,用于为容器指定自定义名称,提高容器的可读性和可管理性。
注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。
在Docker Compose文件中,devices
关键字用于将主机设备映射到容器中。这样,容器就可以直接访问并使用指定的设备,而无需在容器内部进行额外的配置或权限设置。
devices
关键字的使用场景通常涉及需要访问主机设备的特定应用程序或服务。这样的应用程序可能需要与硬件设备(如USB设备、GPU、串口设备等)交互,或者需要通过容器访问主机上的特定设备驱动程序。
下面是一个使用devices
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
- /dev/nvidia0:/dev/nvidia0
在这个例子中,my_service
容器将主机上的/dev/ttyUSB0
和/dev/nvidia0
两个设备映射到容器内部的相同路径。这样,容器中的应用程序就可以直接访问这些设备。
需要注意的是,为了允许容器访问主机设备,通常需要在启动容器时添加特定的权限。如果使用docker run
命令而不是Docker Compose来启动容器,可能需要添加--privileged
参数或设置--device
参数来实现设备映射和访问权限。而在Docker Compose中使用devices
关键字,会自动处理这些权限设置,使设备映射更为便捷。
请注意,使用devices
关键字需要谨慎,因为直接访问主机设备可能带来安全风险。在使用该关键字时,请确保了解容器将访问的设备,并仅授予应用程序实际所需的最低权限。不正确的设备映射可能会导致安全漏洞或操作系统故障。
总结:devices
关键字允许您在Docker Compose中将主机设备映射到容器,以便容器可以直接访问并使用这些设备。使用时需要注意安全性和权限设置。
在Docker Compose版本2及之前的版本中,links
关键字用于定义服务之间的链接(连接)。它允许您在一个服务中访问另一个服务的容器,使得在不同的容器之间建立网络连接变得更加便捷。
然而,需要注意的是,自Docker Compose版本3开始,links
关键字已经被废弃。在版本3及更高版本中,Docker Compose推荐使用Docker网络(Docker networks)来实现容器之间的通信,而不再使用links
关键字。
以下是在Docker Compose版本2及之前如何使用links
关键字的示例:
version: '2'
services:
web_app:
image: my_web_app_image:latest
links:
- db_server
db_server:
image: my_db_server_image:latest
在这个例子中,web_app
服务链接到了db_server
服务。这意味着web_app
容器可以通过db_server
容器的名称来访问db_server
容器,而不需要进行IP地址配置。
然而,使用links
关键字存在一些限制和缺点,因此在Docker Compose版本3及更高版本中,推荐使用Docker网络来替代它。
在Docker Compose版本3及更高版本中,可以通过创建自定义的Docker网络来实现服务之间的通信。这样的网络提供了更好的灵活性和可定制性,并且允许容器之间使用服务名称进行通信,而无需使用links
关键字。
以下是在Docker Compose版本3及更高版本中使用Docker网络的示例:
version: '3'
services:
web_app:
image: my_web_app_image:latest
networks:
- my_network
db_server:
image: my_db_server_image:latest
networks:
- my_network
networks:
my_network:
在这个例子中,我们创建了一个名为my_network
的自定义Docker网络,并将web_app
和db_server
服务连接到了该网络。现在,web_app
服务和db_server
服务可以使用彼此的服务名称进行通信,而无需使用links
关键字。
总结:links
关键字在Docker Compose版本2及之前用于定义服务之间的链接。然而,自Docker Compose版本3开始,推荐使用Docker网络来实现容器之间的通信,而不再使用links
关键字。
解决容器的依赖、启动先后的问题。以下例子中会先启动 redis db 再启动 web
version: '3'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
在Docker Compose文件中,depends_on
关键字用于定义服务之间的依赖关系。它允许您指定一个或多个服务,告知Docker Compose在启动当前服务之前先启动它们所依赖的服务。
然而,需要注意的是,depends_on
关键字并不会等待依赖的服务完全启动和运行才启动当前的服务。它只负责在启动服务的过程中按照指定的顺序来启动依赖的服务,但不会检查这些依赖的服务是否真正处于可用状态。
以下是一个使用depends_on
关键字的示例:
version: '3'
services:
db_server:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=mysecretpassword
web_app:
image: my_web_app_image:latest
depends_on:
- db_server
在这个例子中,web_app
服务依赖于db_server
服务。当您使用docker-compose up
命令启动服务时,Docker Compose会在启动web_app
服务之前先启动db_server
服务。
虽然depends_on
关键字确保服务启动的顺序,但它并不能保证依赖的服务在启动后立即处于可用状态。在现实情况中,某些服务可能需要更多的时间来完成初始化或配置,而另一些服务可能会在启动后立即准备好接受请求。
因此,如果您的服务之间有依赖关系,并且需要等待特定服务完全可用后再启动其他服务,您可能需要使用一些其他的方法来实现服务之间的等待和健康检查。在Docker Compose版本3及以上,可以使用healthcheck
关键字来定义健康检查,以确保服务在启动后处于健康状态。
总结:depends_on
关键字用于定义Docker Compose服务之间的启动顺序和依赖关系。它可以确保在启动服务时,指定的依赖服务先于当前服务启动。但它不能保证依赖的服务在启动后立即处于可用状态,因此在实际应用中,可能需要结合其他方法来实现更复杂的服务之间的等待和健康检查。
自定义 DNS 服务器。可以是一个值,也可以是一个列表。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 114.114.114.114
在Docker Compose文件中,dns
关键字用于为容器指定自定义的DNS服务器。DNS(Domain Name System)是用于将域名解析为IP地址的网络系统。
通过使用dns
关键字,您可以指定容器使用特定的DNS服务器来解析域名,而不是使用默认的DNS服务器。
以下是一个使用dns
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
dns:
- 8.8.8.8
- 8.8.4.4
在这个例子中,my_service
容器将使用Google的公共DNS服务器(8.8.8.8和8.8.4.4)来解析域名。
需要注意的是,使用dns
关键字可以帮助您解决在容器中访问互联网时可能遇到的DNS问题。有时候,特定的网络环境可能导致默认的DNS服务器无法正常工作,或者您希望指定特定的DNS服务器来满足特定需求。
但是,请谨慎使用dns
关键字。在实际使用中,使用自定义DNS服务器可能会导致容器的DNS解析行为与宿主机或其他容器不一致,可能引发一些问题。在大多数情况下,不需要显式指定DNS服务器,Docker容器会默认使用宿主机的DNS设置。
如果您在特定情况下需要自定义DNS服务器,请确保您了解其对网络访问和容器间通信可能带来的影响,并进行充分测试。
总结:dns
关键字用于为Docker Compose中的容器指定自定义的DNS服务器。它允许您解决在容器中访问互联网时可能遇到的DNS问题,但需要谨慎使用,确保了解其影响并进行适当的测试。
在Docker Compose文件中,dns_search
关键字用于为容器指定自定义的DNS搜索域(DNS search domains)。DNS搜索域是一组域名后缀列表,当容器尝试解析不带域名后缀的主机名时,它会自动尝试添加这些搜索域后缀,以尝试解析完整的域名。
使用dns_search
关键字,您可以为容器指定一个或多个DNS搜索域,以便在进行域名解析时自动添加这些搜索域后缀。
以下是一个使用dns_search
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
dns_search:
- example.com
- subdomain.example.com
在这个例子中,my_service
容器将自动尝试使用example.com
和subdomain.example.com
这两个DNS搜索域后缀,以尝试解析不带域名后缀的主机名。
使用dns_search
关键字可以方便地为容器提供统一的域名解析策略,特别是在跨多个域名后缀的网络环境中。它允许容器在解析主机名时自动尝试添加指定的域名后缀,以增加解析成功的几率。
需要注意的是,dns_search
关键字仅影响容器内部的域名解析。它并不会改变宿主机或其他容器的域名解析行为。
总结:dns_search
关键字用于为Docker Compose中的容器指定自定义的DNS搜索域。它允许容器在解析主机名时自动尝试添加指定的域名后缀,以增加解析成功的几率。
挂载一个 tmpfs 文件系统到容器。
tmpfs: /run
tmpfs:
- /run
- /tmp
在Docker Compose文件中,tmpfs
关键字用于将临时文件系统(tmpfs)挂载到容器的指定目录,以在容器中创建一个临时的内存文件系统。
临时文件系统是一种基于内存的文件系统,它将文件存储在内存中而不是硬盘上。因为存储在内存中,所以读写速度非常快,但是数据不会持久化保存,一旦容器停止或重新启动,临时文件系统中的数据都会被清空。
使用tmpfs
关键字,您可以将临时文件系统挂载到容器中的某个目录,使得容器内的应用程序可以使用这个临时文件系统进行快速读写操作,适用于需要临时存储数据或临时工作的场景。
以下是一个使用tmpfs
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
tmpfs:
- /tmp
在这个例子中,my_service
容器将在启动时在容器内的/tmp
目录下挂载一个临时文件系统。这样,在容器内部对/tmp
目录的读写操作都将直接在内存中进行,从而获得更高的读写性能。
需要注意的是,使用tmpfs
关键字时,您可以指定多个目录来挂载多个临时文件系统。每个目录都将挂载一个单独的临时文件系统,但请注意,内存是有限的资源,因此在使用tmpfs
时要谨慎使用,并避免在内存中存储过多的数据。
另外,请注意,tmpfs
关键字仅在Docker版本17.06及更高版本中受支持。
总结:tmpfs
关键字用于在Docker Compose中将临时文件系统挂载到容器的指定目录,以实现在内存中进行快速读写操作的临时存储。这对于需要临时存储数据或临时工作的场景非常有用。请确保谨慎使用,并了解内存资源的限制。
从文件中获取环境变量,可以为单独的文件路径或列表。
如果通过 docker-compose -f FILE 方式来指定 Compose 模板文件,则 env_file 中变量的路径会基于模板文件路径。
如果有变量名称与 environment 指令冲突,则按照惯例,以后者为准。
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
环境变量文件中每一行必须符合格式,支持 # 开头的注释行。
# common.env: Set development environment
PROG_ENV=development
在Docker Compose文件中,env_file
关键字用于从指定的文件中加载环境变量,并将这些环境变量添加到服务的容器中。这样,您可以轻松地将环境变量从文件导入到Docker容器,而不需要在Compose文件中直接硬编码环境变量。
env_file
关键字可以接受一个或多个文件路径作为参数,每个文件中包含了一组环境变量定义。这些文件可以是普通文本文件,每行一个环境变量定义,格式为KEY=VALUE
。注释行以#
开头。
以下是一个使用env_file
关键字的示例:
假设我们有一个名为.env
的文件,其内容如下:
DB_HOST=db_server
DB_PORT=5432
DB_USER=myuser
DB_PASS=mypassword
然后,在Docker Compose文件中,我们可以这样使用env_file
关键字:
version: '3'
services:
my_service:
image: my_image:latest
env_file:
- .env
在这个例子中,my_service
服务的容器将从.env
文件中加载环境变量,并将这些环境变量添加到容器中。这样,容器内的应用程序可以使用这些环境变量来配置其行为,而不需要直接在Compose文件中指定这些环境变量。
使用env_file
关键字的好处是,它使得在不同环境中部署应用程序更加方便。您可以在不同的环境中创建不同的.env文件,从而轻松地配置应用程序所需的环境变量,而不需要更改Compose文件本身。
请注意,使用env_file
关键字加载的环境变量将会覆盖Compose文件中直接定义的同名环境变量。因此,在.env文件中定义的环境变量将优先生效。
总结:env_file
关键字用于从指定的文件中加载环境变量,并将这些环境变量添加到Docker Compose服务的容器中。它使得配置应用程序所需的环境变量更加方便和灵活,可以根据不同的环境创建不同的.env文件,而不需要更改Compose文件本身。
设置环境变量。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据。
environment:
RACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
如果变量名称或者值中用到 true|false,yes|no 等表达 布尔 含义的词汇,最好放到引号里,避免 YAML 自动解析某些内容为对应的布尔语义。这些特定词汇,包括
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
在Docker Compose文件中,environment
关键字用于为服务指定环境变量。环境变量是用于在容器中传递配置信息和参数的常见方式,使得容器的行为可以根据所设置的环境变量值来动态地调整。
environment
关键字允许您为服务定义一个或多个环境变量,每个环境变量由键值对表示,即KEY=VALUE
的形式。在容器启动时,这些环境变量将被传递给容器内部的应用程序或进程。
以下是一个使用environment
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
environment:
- DB_HOST=db_server
- DB_PORT=5432
- DB_USER=myuser
- DB_PASS=mypassword
在这个例子中,my_service
服务的容器将有四个环境变量:DB_HOST
、DB_PORT
、DB_USER
和DB_PASS
。这些环境变量的值将在容器内部的应用程序中可用,可以用来配置应用程序连接数据库等行为。
使用environment
关键字的好处是,它使得在Docker Compose文件中配置容器的环境变量非常简单。您可以轻松地为不同的服务指定不同的环境变量,而无需修改应用程序代码。
需要注意的是,environment
关键字定义的环境变量是在Compose文件中硬编码的。如果需要更灵活的环境变量配置,您可以考虑使用env_file
关键字来从外部文件加载环境变量。
总结:environment
关键字用于在Docker Compose文件中为服务指定环境变量。它使得在Compose文件中配置容器的环境变量变得非常简单,可以根据需要为不同的服务设置不同的环境变量。
在Docker Compose文件中,expose
关键字用于声明服务容器暴露的网络端口,但是并不实际映射到宿主机的端口。这个关键字是为了方便定义容器内部的网络端口,以便其他服务或容器可以直接访问该端口,但并不会在宿主机上创建端口映射。
expose
关键字通常用于在多个服务或容器之间进行内部通信,而不希望将这些端口直接暴露到宿主机的外部网络。
以下是一个使用expose
关键字的示例:
version: '3'
services:
backend:
image: my_backend_image:latest
expose:
- 8080
frontend:
image: my_frontend_image:latest
expose:
- 80
在这个例子中,backend
服务容器将暴露其内部的8080
端口,而frontend
服务容器将暴露其内部的80
端口。这样,这两个服务之间可以通过相应的端口进行内部通信,但这些端口并不会直接映射到宿主机的网络。
需要注意的是,使用expose
关键字仅声明了容器内部的端口,而并没有实际进行端口映射。如果您需要在宿主机上访问这些端口,您仍然需要使用ports
关键字或docker run
命令来进行端口映射。
总结:expose
关键字用于在Docker Compose文件中声明服务容器暴露的网络端口,以便其他服务或容器可以直接访问该端口,但并不会在宿主机上创建端口映射。它通常用于服务之间的内部通信,而不直接暴露端口到外部网络。要在宿主机上访问这些端口,仍然需要使用ports
关键字或docker run
命令进行端口映射。
external_links
是Docker Compose文件中的一个关键字,用于在Compose项目中连接到其他已经存在的外部容器。它允许您将Compose服务与在Compose项目之外或者在另一个Compose项目中定义的容器建立连接,使得这些服务可以进行通信。
通常情况下,您可以通过在Compose文件中使用links
关键字来声明服务之间的连接。但是,external_links
关键字提供了一种更灵活的方式,允许您连接到不在当前Compose项目中的容器。
以下是使用external_links
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
external_links:
- external_db:db_server
- another_container
在这个例子中,my_service
服务将连接到两个外部容器。第一个连接是将名为external_db
的外部容器连接到my_service
服务的db_server
主机名。第二个连接没有指定别名,因此它将使用外部容器的名称作为默认别名。
需要注意的是,external_links
关键字用于连接到已经存在的外部容器,而不是在当前Compose文件中定义的服务。这些外部容器可以是在同一个主机上运行的容器,也可以是在不同主机上运行的容器。
另外,需要注意的是,external_links
关键字在Docker Compose版本3及以上版本中已被标记为废弃。在较新的版本中,建议使用自定义的Docker网络(networks
关键字)来实现容器之间的通信,而不是使用external_links
。
总结:external_links
关键字用于在Docker Compose项目中连接到其他已经存在的外部容器,允许Compose服务与不在当前Compose项目中定义的容器进行通信。然而,在Docker Compose版本3及以上版本中,external_links
关键字已被标记为废弃,推荐使用自定义的Docker网络(networks
关键字)来实现容器之间的通信。
类似 Docker 中的 --add-host 参数,指定额外的 host 名称映射信息。
extra_hosts:
- "googledns:8.8.8.8"
- "dockerhub:52.1.157.61"
会在启动后的服务容器中 /etc/hosts 文件中添加如下两条条目。
8.8.8.8 googledns
52.1.157.61 dockerhub
在Docker Compose文件中,extra_hosts
关键字用于为服务添加额外的主机名解析。它允许您在容器内部手动指定一组主机名与对应的IP地址映射关系,从而可以在容器中使用这些自定义主机名来访问其他计算机或容器。
extra_hosts
关键字的格式是一个列表,每个列表项都包含一个主机名和对应的IP地址,以空格分隔。例如:
version: '3'
services:
my_service:
image: my_image:latest
extra_hosts:
- "host1:192.168.1.100"
- "host2:192.168.1.101"
在这个例子中,my_service
服务的容器将会添加两个额外的主机名解析:host1
将解析为192.168.1.100
,host2
将解析为192.168.1.101
。
使用extra_hosts
关键字的场景通常是当您需要在容器内部访问一些不在Docker网络内部的计算机或容器时,或者需要手动指定主机名解析时,可以使用它来实现这些需求。
需要注意的是,extra_hosts
关键字仅在当前服务的容器内部有效,不会影响其他服务的容器。对于整个Compose项目的所有服务,您可以使用/etc/hosts
文件来添加全局的主机名解析规则,但这将应用于整个项目的所有容器。
总结:extra_hosts
关键字用于为Docker Compose中的服务添加额外的主机名解析,允许容器内部手动指定一组主机名与对应的IP地址映射关系。这在需要在容器内部访问不在Docker网络内部的计算机或容器时非常有用。请注意,extra_hosts
仅在当前服务的容器内部有效,不会影响其他服务的容器。
healthcheck
是Docker和Docker Compose中的一个重要功能,用于检查容器内部应用程序或服务的健康状态。通过设置healthcheck
,Docker可以定期检查容器的运行状况,如果健康检查失败,Docker将认为容器不健康,并可能触发一些自定义的行为。
在Docker Compose文件中,healthcheck
关键字用于定义服务容器的健康检查设置。健康检查可以通过三种方式进行:命令、Shell脚本和HTTP请求。
下面是这三种方式的示例:
version: '3'
services:
my_service:
image: my_image:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
在这个例子中,my_service
服务容器的健康检查使用了命令方式。它将每30秒运行一次curl -f http://localhost/health
命令来检查服务的健康状态,如果命令返回状态码不为0(即请求失败),Docker将认为容器不健康。
version: '3'
services:
my_service:
image: my_image:latest
healthcheck:
test: ["CMD-SHELL", "python3 health_check.py"]
interval: 1m
timeout: 10s
retries: 3
在这个例子中,my_service
服务容器的健康检查使用了Shell脚本方式。它将每1分钟运行一次python3 health_check.py
命令来检查服务的健康状态,如果命令的输出不为空,并且返回状态码为0,Docker将认为容器是健康的。
version: '3'
services:
my_service:
image: my_image:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 5s
timeout: 3s
retries: 5
start_period: 10s
在这个例子中,my_service
服务容器的健康检查使用了HTTP请求方式。它将每5秒运行一次curl -f http://localhost/health
命令来检查服务的健康状态,如果请求失败,Docker将认为容器不健康。此外,start_period
设置为10秒,表示在容器启动后的前10秒内,不会执行健康检查,以避免在容器启动过程中产生误报。
无论使用哪种方式,健康检查可以帮助您更好地监控和维护容器的运行状况,确保服务在运行期间始终保持健康状态。通过合理配置healthcheck
,您可以更好地处理容器故障和自动容器恢复等情况。
总结:healthcheck
关键字用于在Docker Compose文件中定义服务容器的健康检查设置。健康检查可以通过命令、Shell脚本或HTTP请求进行。通过合理配置healthcheck
,可以更好地监控和维护容器的运行状况,确保服务在运行期间始终保持健康状态。
在Docker Compose文件中,image
关键字用于指定服务所使用的容器镜像。容器镜像是一个包含了应用程序和其依赖的文件系统快照,它是用于创建容器的基础。
image
关键字的值通常是一个字符串,表示要使用的容器镜像的名称和版本标签。您可以使用Docker Hub上的公共镜像,也可以使用私有镜像或者自己构建的镜像。
以下是一个使用image
关键字的示例:
version: '3'
services:
my_service:
image: nginx:latest
在这个例子中,my_service
服务将使用名为nginx
的公共Docker镜像,并指定使用其最新版本(latest
标签)。
如果您使用的是私有镜像,或者希望将Docker Compose文件与镜像构建过程解耦,可以将镜像的名称和版本标签留空,然后通过其他方式指定镜像。例如,可以在使用docker-compose up
命令时通过--build
参数构建镜像,或者使用docker-compose pull
命令拉取最新版本的镜像。
需要注意的是,如果没有指定版本标签,Docker将默认使用latest
标签。但是,建议在生产环境中显式指定镜像的版本标签,以确保在部署时使用特定的稳定版本,避免意外地使用了不稳定的最新版本。
总结:image
关键字用于在Docker Compose文件中指定服务所使用的容器镜像。容器镜像是创建容器的基础,可以是公共镜像、私有镜像或者自己构建的镜像。建议在生产环境中显式指定镜像的版本标签,避免使用不稳定的最新版本。
在Docker Compose文件中,labels
关键字用于为服务添加一组自定义标签(Labels)。标签是键值对的元数据,用于为Docker容器或服务添加额外的信息。这些信息可以用于管理、识别和分类容器,也可以在其他工具或平台上进行查询和展示。
labels
关键字的值是一个字典(或映射),其中每个键值对表示一个标签。键表示标签的名称,而值表示标签的内容。标签的名称和内容可以是任意字符串,通常采用键=值
的形式。
以下是一个使用labels
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
labels:
- "com.example.vendor=MyCompany"
- "com.example.version=1.0"
- "com.example.release-date=2023-07-30"
在这个例子中,my_service
服务将被添加三个自定义标签:com.example.vendor
、com.example.version
和com.example.release-date
。这些标签可以用于识别和查询服务,也可以在Docker Compose集成的其他工具或平台上进行展示或过滤。
使用labels
关键字可以为服务或容器添加自定义元数据,帮助您更好地管理和组织容器。例如,您可以使用标签来标识服务的版本信息、制造商信息、发布日期等等。
另外,Docker官方和第三方的一些工具和平台也会使用标签来提供额外的功能或集成。因此,在适当的情况下,使用labels
关键字可以为您的容器提供更多的灵活性和可扩展性。
总结:labels
关键字用于在Docker Compose文件中为服务添加自定义标签,标签是键值对的元数据,用于为容器或服务添加额外的信息。这些信息可以用于管理、识别和分类容器,也可以在其他工具或平台上进行查询和展示。使用labels
关键字可以提供更多的灵活性和可扩展性,帮助更好地管理和组织容器。
在Docker Compose文件中,logging
关键字用于配置服务容器的日志记录选项。通过logging
关键字,您可以指定服务容器日志的驱动程序和相应的配置,以及定义日志的其他属性。
logging
关键字的值是一个字典,其中包含用于配置日志记录的各种选项。以下是常用的一些配置选项:
driver
:指定用于记录日志的驱动程序。可以是json-file
、syslog
、journald
、gelf
、fluentd
等。默认为json-file
。
options
:指定用于配置日志驱动程序的附加选项。每个驱动程序都可以有不同的配置选项,具体取决于所选的驱动程序。例如,对于gelf
驱动程序,您可以指定GELF服务器的地址和端口。
max-size
:指定日志文件的最大大小。当日志文件大小达到这个值时,Docker将自动进行日志轮转。可以使用10m
(表示10兆字节)或者50k
(表示50千字节)等格式。
max-file
:指定日志文件的最大数量。当日志文件数量达到这个值时,Docker将删除最旧的日志文件。
以下是一个使用logging
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
在这个例子中,my_service
服务容器的日志记录将使用json-file
驱动程序,并设置日志文件的最大大小为10兆字节,最大文件数量为3。
通过适当配置logging
关键字,您可以更好地管理和控制服务容器的日志记录,确保日志信息的保存和轮转满足您的需求。
需要注意的是,logging
关键字仅在Docker Compose版本3及以上版本中受支持。在较旧的版本中,日志记录是通过log_driver
和log_opt
等关键字进行配置的。
总结:logging
关键字用于在Docker Compose文件中配置服务容器的日志记录选项。通过指定驱动程序、配置选项、最大文件大小等参数,可以更好地管理和控制容器的日志记录。请注意,logging
关键字仅在Docker Compose版本3及以上版本中受支持。
日志的保存位置取决于您在Docker Compose文件中配置的日志记录驱动程序。不同的驱动程序会将日志保存在不同的位置。
在默认情况下,当您没有显式指定日志记录驱动程序时,Docker将使用json-file
驱动程序。对于json-file
驱动程序,默认情况下,容器的日志将保存在宿主机上的/var/lib/docker/containers/
文件中。其中,
是容器的ID,每个容器有唯一的ID,用于标识容器。
例如,假设您有一个名为my_service
的服务容器,其ID为abcd1234efgh
,那么它的日志文件路径将类似于:
/var/lib/docker/containers/abcd1234efgh/abcd1234efgh-json.log
这是在默认情况下,使用json-file
驱动程序时,容器的日志保存的位置。
如果您配置了其他日志记录驱动程序,比如syslog
、journald
、gelf
等,那么日志可能保存在不同的位置或通过不同的方式进行记录。例如,使用syslog
驱动程序将把日志发送到宿主机上的syslog服务,而不会将日志保存在文件中。
要查看日志的确切保存位置,您可以通过以下方式之一来查找:
使用docker inspect
命令来查看容器的详细信息,包括日志的路径:
docker inspect
在Docker Compose项目的目录下,进入./logs
子目录,其中可能会保存Docker Compose中配置的某些服务的日志。
请注意,日志的保存位置和配置可能因您的系统、Docker版本和具体配置而有所不同。因此,建议在配置日志记录时,查看相关文档或使用docker inspect
命令来获取准确的日志保存位置。
设置网络模式。使用和 docker run 的 --network 参数一样的值。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
在Docker Compose文件中,network_mode
关键字用于指定服务容器所使用的网络模式。网络模式决定了容器与宿主机以及其他容器之间的网络通信方式。
network_mode
关键字可以设置为以下几种值:
bridge
(默认值):使用Docker默认的网络模式。每个容器都拥有自己的网络栈,可以通过映射端口或使用Docker网络进行通信。
host
:容器与宿主机共享网络栈。这意味着容器将与宿主机拥有相同的网络接口,从而使容器能够直接使用宿主机的网络接口,无需额外的端口映射。但这也意味着容器的网络隔离性较差。
none
:容器不使用任何网络栈。在这种模式下,容器将不具有网络连接,将无法访问外部网络,也无法被其他容器或宿主机访问。
service:
:将容器连接到Docker Compose项目中指定的服务的网络栈。这样,容器将与指定的服务共享网络,使它们之间可以直接进行通信,无需进行端口映射。
:将容器连接到指定名称的自定义Docker网络。这样,容器将与自定义网络中的其他容器进行通信。
以下是一个使用network_mode
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
network_mode: host
在这个例子中,my_service
服务容器将使用host
网络模式,与宿主机共享网络栈,使得容器可以直接使用宿主机的网络接口。
需要注意的是,network_mode
关键字可以用于更改容器的网络模式,但可能会影响到容器的网络隔离性和与其他服务或容器的通信方式。因此,在设置network_mode
时,请谨慎考虑容器的网络需求和安全性要求。
总结:network_mode
关键字用于在Docker Compose文件中指定服务容器所使用的网络模式。可以设置为bridge
(默认值)、host
、none
、service:
或
等值。每种模式都决定了容器与宿主机以及其他容器之间的网络通信方式。在设置network_mode
时,请谨慎考虑容器的网络需求和安全性要求。
配置容器连接的网络。
version: "3"
services:
some-service:
networks:
- some-network
- other-network
networks:
some-network:
other-network:
在Docker Compose文件中,networks
关键字用于定义自定义网络,以便在Compose项目中创建具有特定配置的网络。通过networks
关键字,您可以在Compose文件中定义多个网络,并将服务容器连接到这些网络中的一个或多个,以实现容器之间的通信。
networks
关键字的值是一个字典,其中每个键值对表示一个自定义网络的配置。每个自定义网络都可以具有以下配置选项:
driver
:指定网络的驱动程序。可以是bridge
、overlay
、macvlan
、ipvlan
等,也可以是其他第三方网络驱动程序。
driver_opts
:指定用于配置网络驱动程序的附加选项。每个网络驱动程序都可以有不同的配置选项,具体取决于所选的驱动程序。
external
:指定是否为外部网络。如果设置为true
,则表示这是一个由Compose项目之外创建的外部网络,Compose将不会创建该网络,而是连接到已经存在的网络。
以下是一个使用networks
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
networks:
- my_network
- other_network
networks:
my_network:
driver: bridge
other_network:
driver: overlay
driver_opts:
encrypted: true
在这个例子中,my_service
服务容器将连接到两个自定义网络:my_network
和other_network
。my_network
是一个使用bridge
驱动程序的自定义网络,而other_network
是一个使用overlay
驱动程序的自定义网络,并设置了额外的驱动选项encrypted: true
。
通过自定义网络,您可以更好地管理容器的网络通信,实现容器之间的隔离,或者将Compose项目与其他Docker项目的网络连接起来。如果网络设置较为复杂,建议使用自定义网络来更好地组织和管理容器的网络配置。
总结:networks
关键字用于在Docker Compose文件中定义自定义网络,用于创建具有特定配置的网络。通过自定义网络,可以更好地管理容器的网络通信,实现容器之间的隔离,或者将Compose项目与其他Docker项目的网络连接起来。每个自定义网络可以配置驱动程序、驱动选项以及是否为外部网络。
在Docker Compose文件中,pid
关键字用于设置服务容器的PID(进程标识符)命名空间配置。PID命名空间是Linux内核提供的一种隔离机制,它允许每个进程拥有独立的PID空间,即每个进程都有自己的PID号,从而实现进程之间的隔离。
pid
关键字的值可以是以下两种设置:
pid: "host"
:使用宿主机的PID命名空间。这意味着容器内部的进程将与宿主机共享相同的PID空间,即它们具有相同的PID号。这种模式下,容器内的进程可以看到宿主机上所有的进程,并且可以对宿主机上的进程进行操作。
pid:
:将容器连接到另一个容器的PID命名空间。这意味着容器内的进程将与另一个容器共享相同的PID空间,即它们具有相同的PID号。这样,两个容器内的进程可以相互看到和操作。
以下是使用pid
关键字的示例:
version: '3'
services:
service1:
image: my_image:latest
service2:
image: my_image:latest
pid: "host"
在这个例子中,service1
服务容器没有配置pid
关键字,因此使用默认的PID命名空间隔离。而service2
服务容器使用了pid: "host"
,使其与宿主机共享PID命名空间。
需要注意的是,使用pid
关键字将进程隔离性进行调整,可能会影响容器内进程与宿主机或其他容器的交互。因此,在设置pid
关键字时,请谨慎考虑容器的需求和安全性要求。
总结:pid
关键字用于在Docker Compose文件中设置服务容器的PID(进程标识符)命名空间配置。它可以设置为host
表示使用宿主机的PID命名空间,或者指定另一个容器的名称或ID,使容器连接到另一个容器的PID命名空间。使用pid
关键字可以调整进程之间的隔离性,但请注意在设置时谨慎考虑容器的需求和安全性要求。
在Docker Compose文件中,ports
关键字用于将容器内部的端口映射到宿主机上的端口,以便可以通过宿主机的IP地址和映射的端口来访问容器内的服务。
ports
关键字的值是一个列表,其中每个列表项表示一个端口映射规则。每个映射规则可以采用两种形式:
HOST:CONTAINER
:将容器内的端口映射到宿主机上的指定端口。HOST
表示宿主机上的端口,CONTAINER
表示容器内部的端口。例如,80:8080
表示将容器内的8080
端口映射到宿主机上的80
端口。
CONTAINER
:只指定容器内部的端口,Docker将会随机选择一个宿主机端口进行映射。例如,8080
表示将容器内的8080
端口映射到宿主机上的一个随机端口。
以下是一个使用ports
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
ports:
- "80:8080"
- "443:8443"
- "8080"
在这个例子中,my_service
服务容器将进行三个端口映射。80:8080
表示将容器内的8080
端口映射到宿主机上的80
端口,443:8443
表示将容器内的8443
端口映射到宿主机上的443
端口,而8080
表示将容器内的8080
端口映射到宿主机上的一个随机端口。
通过配置ports
关键字,您可以将容器内的服务暴露给宿主机和外部网络,使得可以通过宿主机的IP地址和映射的端口来访问容器内的服务。
需要注意的是,映射的端口号必须是宿主机未被占用的端口,否则会导致映射失败。在指定映射规则时,请确保宿主机的端口可用。
总结:ports
关键字用于在Docker Compose文件中将容器内部的端口映射到宿主机上的端口,以便可以通过宿主机的IP地址和映射的端口来访问容器内的服务。映射规则可以采用HOST:CONTAINER
或者CONTAINER
的形式。通过配置ports
关键字,可以将容器内的服务暴露给宿主机和外部网络。
注意:当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML 会自动解析 xx:yy 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。
在Docker Compose文件中,secrets
关键字用于定义和管理容器内部的敏感信息,如密码、密钥等。通过使用secrets
关键字,您可以将敏感数据安全地传递给容器,而无需明文暴露这些信息在Compose文件中。
secrets
关键字的值是一个字典,其中每个键值对表示一个密钥(secret)的配置。每个密钥配置可以包含以下属性:
file
:指定包含密钥内容的文件。这个文件可以是Docker Swarm或Docker Compose项目的秘密管理器中的一个已存在的密钥。
external
:指定是否为外部密钥。如果设置为true
,则表示这是一个由Compose项目之外创建的外部密钥,Compose将不会创建该密钥,而是使用已经存在的外部密钥。
以下是一个使用secrets
关键字的示例:
version: '3.1'
services:
my_service:
image: my_image:latest
secrets:
- my_secret
secrets:
my_secret:
file: ./secrets/my_secret.txt
在这个例子中,my_service
服务容器将使用名为my_secret
的密钥,并将密钥内容从./secrets/my_secret.txt
文件中提取。该文件包含了实际的敏感信息,比如密码或密钥。
通过使用secrets
关键字,可以将敏感信息与Compose文件解耦,从而更好地保护敏感数据,并避免将明文密码等信息暴露在版本控制系统中。
需要注意的是,secrets
关键字仅在Docker Swarm模式下支持。在Docker Compose的标准模式下(非Swarm),secrets
关键字将不起作用。
总结:secrets
关键字用于在Docker Compose文件中定义和管理容器内部的敏感信息。通过使用secrets
关键字,可以将敏感数据安全地传递给容器,而无需明文暴露这些信息在Compose文件中。请注意,secrets
关键字仅在Docker Swarm模式下支持,不适用于标准的Docker Compose模式。
指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等)。例如配置标签的用户名和角色名。
security_opt:
- label:user:USER
- label:role:ROLE
在Docker Compose文件中,security_opt
关键字用于设置容器的安全选项。通过security_opt
关键字,您可以指定一系列安全选项来增加容器的安全性,并对容器的权限进行更精细的控制。
security_opt
关键字的值是一个列表,其中每个列表项表示一个安全选项。这些选项通常是Docker守护程序支持的一些安全性配置选项,用于限制容器的特定行为。
以下是一些常用的安全选项示例:
no-new-privileges
:禁止容器内的进程获取额外的权限。这可以防止容器内的进程以root权限运行,提高容器的安全性。
apparmor=
:为容器指定AppArmor配置文件的名称,用于加强对容器内进程的访问控制。
seccomp=
:为容器指定Seccomp配置文件的名称,用于限制容器内进程可以使用的系统调用。
以下是一个使用security_opt
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
security_opt:
- "no-new-privileges"
- "apparmor=my_apparmor_profile"
- "seccomp=my_seccomp_profile"
在这个例子中,my_service
服务容器将使用三个安全选项:禁止获取额外的权限,应用名为my_apparmor_profile
的AppArmor配置文件,以及名为my_seccomp_profile
的Seccomp配置文件。
通过配置security_opt
关键字,可以增强容器的安全性,限制容器的特定行为,并提供更细粒度的权限控制。
需要注意的是,security_opt
关键字可能在某些情况下与特定的容器镜像或Docker守护程序配置有关。在使用安全选项之前,请确保了解所使用镜像的安全性要求,并根据需要进行适当的配置。
总结:security_opt
关键字用于在Docker Compose文件中设置容器的安全选项。通过指定一系列安全选项,可以增加容器的安全性,限制容器的特定行为,并提供更细粒度的权限控制。请注意在使用安全选项之前了解所使用镜像的安全性要求,并根据需要进行适当的配置。
在Docker Compose文件中,stop_signal
关键字用于指定停止(停用)容器时要使用的信号。当使用docker-compose stop
或docker-compose down
命令停止服务容器时,Compose将向容器发送指定的信号来请求容器正常停止。
stop_signal
关键字的值是一个信号名称或者信号编号,用于指定要使用的停止信号。信号名称可以是字符串,如SIGINT
、SIGTERM
等,也可以是信号编号,如2
(SIGINT)或15
(SIGTERM)。
默认情况下,Docker Compose会使用SIGTERM
信号请求容器停止。这是一个优雅的停止信号,它允许容器在收到信号后进行清理和关闭工作。如果容器没有在一定时间内响应SIGTERM
信号,Compose会发送一个SIGKILL
信号来强制终止容器。
通过stop_signal
关键字,您可以根据容器内应用程序的需要,选择不同的信号进行停止请求。例如,有些应用程序可能在接收到SIGINT
信号后能够优雅地停止,而其他应用程序可能需要使用特定的自定义信号来进行停止操作。
以下是一个使用stop_signal
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
stop_signal: SIGUSR1
在这个例子中,my_service
服务容器将在停止时使用SIGUSR1
信号来请求容器正常停止。
请注意,不是所有应用程序都支持所有信号,并且某些信号可能会导致应用程序的异常行为。在选择停止信号时,请确保了解应用程序的信号处理机制,并选择适合的信号来实现优雅的停止过程。
总结:stop_signal
关键字用于在Docker Compose文件中指定停止容器时要使用的信号。默认为SIGTERM
信号。通过设置不同的信号名称或信号编号,可以选择适合应用程序的信号来实现优雅的停止过程。在选择停止信号时,请确保了解应用程序的信号处理机制,并选择适合的信号来请求容器正常停止。
配置容器内核参数。
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
在Docker Compose文件中,sysctls
关键字用于设置容器的内核参数。通过sysctls
关键字,您可以自定义容器内部的Linux内核参数,以便优化容器的性能或调整内核行为。
sysctls
关键字的值是一个字典,其中每个键值对表示一个内核参数的配置。键表示要设置的内核参数名称,值表示该参数的值。
以下是一个使用sysctls
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
sysctls:
net.core.somaxconn: "1024"
net.ipv4.ip_forward: "1"
在这个例子中,my_service
服务容器将设置两个内核参数:net.core.somaxconn
和net.ipv4.ip_forward
。net.core.somaxconn
参数用于设置Linux内核中的net.core.somaxconn
参数,net.ipv4.ip_forward
参数用于设置net.ipv4.ip_forward
参数。这样,可以调整容器内核的连接数限制和IP转发行为。
通过使用sysctls
关键字,您可以根据容器的需求,对内核参数进行适当的调整和优化,以获得更好的性能和行为。
需要注意的是,设置不当的内核参数可能会导致系统不稳定或不安全。在使用sysctls
关键字时,请确保了解所设置的内核参数的含义和影响,并根据实际需求进行配置。
另外,sysctls
关键字在Docker Compose版本3.4及以上版本中受支持。
总结:sysctls
关键字用于在Docker Compose文件中设置容器的内核参数。通过指定内核参数名称和值,可以自定义容器内部的Linux内核参数,以便优化容器的性能或调整内核行为。在使用sysctls
关键字时,请确保了解所设置的内核参数的含义和影响,并根据实际需求进行配置。
在Docker Compose文件中,ulimits
关键字用于设置容器的资源限制(ulimits)。通过ulimits
关键字,您可以限制容器内部进程的资源使用,以确保容器在运行时不会过度消耗系统资源,提高容器的稳定性和安全性。
ulimits
关键字的值是一个列表,其中每个列表项表示一个资源限制规则。每个资源限制规则可以包含以下属性:
name
:指定要限制的资源名称。例如,core
表示核心转储文件大小,nofile
表示打开文件描述符的数量。
soft
:指定软限制,即资源的软限制值。这是一个软限制值,容器的进程可以超过软限制,但超过时会产生警告。软限制通常是硬限制的下限。
hard
:指定硬限制,即资源的硬限制值。这是一个硬限制值,容器的进程不能超过硬限制。超过硬限制时,会产生错误。
以下是一个使用ulimits
关键字的示例:
version: '3'
services:
my_service:
image: my_image:latest
ulimits:
nofile:
soft: 1024
hard: 2048
在这个例子中,my_service
服务容器将设置一个资源限制规则,限制容器内部进程打开的文件描述符数量。软限制(soft limit)为1024,硬限制(hard limit)为2048。这意味着容器的进程可以打开最多1024个文件描述符,但在超过1024之前会产生警告;并且容器的进程不能超过2048个文件描述符。
通过使用ulimits
关键字,您可以根据容器的需求,限制容器内部进程的资源使用,确保容器不会过度消耗系统资源,提高容器的稳定性和安全性。
需要注意的是,设置不当的资源限制可能会影响容器的运行。在使用ulimits
关键字时,请确保了解所设置的资源限制的含义和影响,并根据实际需求进行配置。
总结:ulimits
关键字用于在Docker Compose文件中设置容器的资源限制(ulimits)。通过设置软限制和硬限制,可以限制容器内部进程的资源使用,确保容器在运行时不会过度消耗系统资源,提高容器的稳定性和安全性。在使用ulimits
关键字时,请确保了解所设置的资源限制的含义和影响,并根据实际需求进行配置。
在Docker Compose文件中,ulimits
关键字无法直接用于限制容器的CPU和内存使用。ulimits
关键字只能用于设置容器内部进程的资源限制,如打开文件描述符数量等,而不能直接用于限制容器的CPU和内存。
要限制容器的CPU和内存使用,您可以使用Docker Compose中的其他相关配置选项。具体取决于您使用的Docker版本和Compose文件的版本,以下是一些可能的配置选项:
对于Docker Compose版本3及以上:
cpus
:用于指定容器的CPU配额。您可以将其设置为一个浮点数,表示容器能够使用的CPU核心数的最大百分比。例如,cpus: 0.5
表示容器最多使用50%的一个CPU核心。
mem_limit
:用于指定容器的内存限制。您可以将其设置为一个字符串,表示容器能够使用的最大内存量。例如,mem_limit: 512m
表示容器最多可以使用512 MB的内存。
mem_reservation
:用于指定容器的内存保留值。您可以将其设置为一个字符串,表示容器启动时分配给容器的最小内存量。容器实际使用的内存可以超过此值,但保留此内存供容器使用。
对于Docker Compose版本2及以下:
cpu_shares
:用于指定容器的CPU份额。您可以将其设置为一个整数,表示容器使用CPU资源的相对权重。较高的值表示容器在竞争CPU资源时有更高的优先级。
mem_limit
:与上述相同,用于指定容器的内存限制。
mem_reservation
:与上述相同,用于指定容器的内存保留值。
以下是一个示例,展示如何在Docker Compose文件中使用上述配置选项来限制CPU和内存使用:
version: '3'
services:
my_service:
image: my_image:latest
cpus: 0.5
mem_limit: 512m
mem_reservation: 256m
在这个例子中,my_service
服务容器将被限制为最多使用50%的一个CPU核心,最多使用512 MB的内存,并且在启动时分配了256 MB的内存。
数据卷所挂载路径设置。可以设置为宿主机路径(HOST:CONTAINER)或者数据卷名称(VOLUME:CONTAINER),并且可以设置访问模式 (HOST:CONTAINER:ro)。
该指令中路径支持相对路径。
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
如果路径为数据卷名称,必须在文件中配置数据卷。
version: "3"
services:
my_src:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
在Docker Compose文件中,volumes
关键字用于定义数据卷的配置,以便在容器和宿主机之间共享数据或持久化数据。数据卷是用于在容器之间共享数据或将数据持久化到宿主机文件系统的一种机制。
volumes
关键字的值是一个字典,其中每个键值对表示一个数据卷的配置。数据卷可以具有多种形式,包括命名卷、绑定挂载和临时数据卷。
version: '3'
services:
my_service:
image: my_image:latest
volumes:
- my_data_volume:/data
volumes:
my_data_volume:
在这个例子中,my_service
服务容器将使用一个命名卷my_data_volume
,将容器内的/data
目录与该命名卷关联起来。
version: '3'
services:
my_service:
image: my_image:latest
volumes:
- /path/on/host:/data
在这个例子中,my_service
服务容器将宿主机上的/path/on/host
目录挂载到容器内的/data
目录。
version: '3'
services:
my_service:
image: my_image:latest
volumes:
- /data
在这个例子中,my_service
服务容器将使用一个临时数据卷,用于存储容器内的/data
目录数据。
通过使用volumes
关键字,您可以将数据卷与服务容器关联起来,实现数据在容器和宿主机之间的共享和持久化。数据卷是Docker中重要的概念之一,它允许容器之间共享数据,并将数据持久化到宿主机的文件系统中,以便在容器重启后数据仍然保留。
总结:volumes
关键字用于在Docker Compose文件中定义数据卷的配置,以便在容器和宿主机之间共享数据或持久化数据。数据卷可以是命名卷、绑定挂载或临时数据卷。通过使用volumes
关键字,可以将数据卷与服务容器关联起来,实现数据在容器和宿主机之间的共享和持久化。
此外,还有包括 domainname, entrypoint, hostname, ipc, mac_address, privileged, read_only, shm_size, restart, stdin_open, tty, user, working_dir 等指令,基本跟 docker run 中对应参数的功能一致。
指定服务容器启动后执行的入口文件。
entrypoint: /code/entrypoint.sh
指定容器中运行应用的用户名。
user: nginx
指定容器中工作目录。
working_dir: /code
指定容器中搜索域名、主机名、mac 地址等。
domainname: your_website.com
hostname: test
mac_address: 08-00-27-00-0C-0A
允许容器中运行一些特权命令。
privileged: true
指定容器退出后的重启策略为始终重启。该命令对保持服务始终运行十分有效,在生产环境中推荐配置为 always 或者 unless-stopped。
restart: always
以只读模式挂载容器的 root 文件系统,意味着不能对容器内容进行修改。
read_only: true
打开标准输入,可以接受外部输入。
stdin_open: true
模拟一个伪终端。
tty: true
docker stats命令的结果
通过docker stats命令可以很方便的看到当前宿主机上所有容器的CPU,内存以及网络流量等数据, 一般小公司够用了。。。。
但是
docker stats统计结果只能是当前宿主机的全部容器,数据资料是实时的,没有地方存储、没有健康指标过线预警等功能
version: '3.1'
volumes:
grafana_data: {}
services:
influxdb:
image: tutum/influxdb:0.9
restart: always
environment:
- PRE_CREATE_DB=cadvisor
ports:
- "8083:8083"
- "8086:8086"
volumes:
- ./data/influxdb:/data
cadvisor:
image: google/cadvisor
links:
- influxdb:influxsrv
command: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086
restart: always
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
grafana:
user: "104"
image: grafana/grafana
user: "104"
restart: always
links:
- influxdb:influxsrv
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- HTTP_USER=admin
- HTTP_PASS=admin
- INFLUXDB_HOST=influxsrv
- INFLUXDB_PORT=8086
- INFLUXDB_NAME=cadvisor
- INFLUXDB_USER=root
- INFLUXDB_PASS=root
启动docker-compose文件:
docker compose up
查看三个服务容器是否启动
docker compose ps