目录
- 概述
- 语法
- 命令用法速查
- 实例
-
- [使用当前目录的 Dockerfile 创建镜像](#使用当前目录的 Dockerfile 创建镜像)
- 使用指定URL的Dockerfile创建镜像
- 使用指定目录的Dockerfile创建镜像
- [各选项详解,使用场景, 实例](#各选项详解,使用场景, 实例)
-
- --build-arg=[]
- --cpu-shares
- --cpu-period
- --cpu-quota
- --cpuset-cpus
- --cpuset-mems
- --disable-content-trust
- --disable-content-trust
- -f
- --isolation
- --label=[]
- -m
- --memory-swap
- --no-cache
- --pull
- [--quiet, -q](#--quiet, -q)
- --rm
- --shm-size
- --ulimit
- --squash
- [--tag, -t](#--tag, -t)
- --network
- 扩展部分
-
- 构建时的中间容器会保留在系统中吗?
- 缓存的层会自行清理吗?
- [缓存层的管理策略是什么? 可以自行查看吗?](#缓存层的管理策略是什么? 可以自行查看吗?)
用于学习记录,内容来自于网络,chatgpt3.5,实际操作等。
概述
docker build
命令用于使用 Dockerfile
创建镜像。
语法
docker build [OPTIONS] PATH | URL | -
命令用法速查
OPTIONS说明:
--build-arg=[]
:设置镜像创建时的变量;--cpu-shares
:设置cpu 使用权重
;--cpu-period
:限制CPU CFS周期
;--cpu-quota
:限制CPU CFS配额
;--cpuset-cpus
:指定使用的CPU id
;--cpuset-mems
:指定使用的内存 id;--disable-content-trust
:忽略校验,默认开启;-f
:指定要使用的Dockerfile路径;--force-rm
:设置镜像过程中删除中间容器;--isolation
:使用容器隔离技术;--label=[]
:设置镜像使用的元数据;-m
:设置内存最大值;--memory-swap
:设置Swap
的最大值为内存+swap
,"-1"表示不限swap
;--no-cache
:创建镜像的过程不使用缓存;--pull
:尝试去更新镜像的新版本;--quiet
,-q
:安静模式,成功后只输出镜像 ID;--rm
:设置镜像编译成功后删除中间容器;--shm-size
:设置/dev/shm的大小,默认值是64M;--ulimit
:Ulimit配置。--squash
:将 Dockerfile 中所有的操作压缩为一层。--tag
,-t
: 镜像的名字及标签,通常name:tag
或者name
格式;可以在一次构建中为一个镜像设置多个标签。--network
: 默认default
。在构建期间设置RUN指令
的网络模式
实例
使用当前目录的 Dockerfile 创建镜像
使用当前目录的 Dockerfile 创建镜像,标签为 runoob/ubuntu:v1。
docker build -t runoob/ubuntu:v1 .
使用指定URL的Dockerfile创建镜像
使用URL
github.com/creack/docker-firefox
的 Dockerfile
创建镜像。
docker build github.com/creack/docker-firefox
使用指定目录的Dockerfile创建镜像
也可以通过-f Dockerfile
文件的位置:
docker build -f /path/to/a/Dockerfile
注意:
在执行Dockerfile 中的指令前进行语法检查
在 Docker 守护进程执行 Dockerfile 中的指令前,首先会对 Dockerfile 进行语法检查,
docker build -t test/myapp .
有语法错误时会返回:
Sending build context to Docker daemon 2.048 kB
Error response from daemon: Unknown instruction: RUNCMD
各选项详解,使用场景, 实例
--build-arg=[]
该选项用于在构建镜像时设置镜像创建时的变量 。这个选项允许你在 Dockerfile
中使用 ARG 指令
定义的变量,并且在构建时动态地向这些变量传递值。
使用场景:
当你的 Dockerfile
中使用了 ARG 指令
定义了一些变量,并且你希望在构建镜像时为这些变量传递特定的值,就可以使用--build-arg
选项。
实例:
假设在 Dockerfile 中定义了一个变量 VERSION:
ARG VERSION
然后你可以通过--build-arg
选项在构建镜像时为这个变量传递值:
docker build --build-arg VERSION=1.0 -t my-image:latest .
这个命令中,--build-arg VERSION=1.0
表示为 VERSION 变量
传递了值 1.0
,这样在构建镜像时就会使用这个值作为 VERSION 变量的取值。
这些选项用于设置容器的 CPU 相关参数,具体含义如下:
--cpu-shares
设置 CPU 使用权重。这个选项允许你为容器指定 CPU 使用的相对权重,即分配给容器的 CPU 资源份额。默认情况下,所有容器的 CPU 权重相同。这可以用于在共享 CPU 时优先分配资源给特定的容器。值越高,分配的 CPU 资源越多。
--cpu-period
限制 CPU CFS (Completely Fair Scheduler) 周期
。这个选项用于限制容器可以使用 CPU 的周期。CPU周期单位为微秒,默认为 100000(即100毫秒)。
--cpu-quota
限制 CPU CFS 配额
。这个选项用于限制容器的 CPU 使用配额。配额的单位也是微秒,默认为 -1,表示无限制。
--cpuset-cpus
指定使用的 CPU id。允许你限制容器所能使用的 CPU 核心,以逗号分隔的 CPU 核心 id。
--cpuset-mems
指定使用的内存 id。允许你限制容器所能使用的内存节点,以逗号分隔的内存节点 id。
这些参数可以在运行容器时使用 docker run
命令传递参数。
举个例子:
docker run --cpu-shares=512 --cpuset-cpus=0-3 -d my-container
这个命令表示为容器分配相对权重为512的 CPU 资源,并且限制容器只能使用 CPU id 0 到 3 的核心。
--disable-content-trust
忽略校验,默认开启;
--disable-content-trust
用于在执行 Docker 镜像相关操作时禁用内容信任(Content Trust)。默认情况下,Docker 开启了内容信任,即在拉取、推送和构建镜像时会进行数字签名和验证,以确保镜像的完整性和来源的可信性。
如果你使用 --disable-content-trust
选项,Docker 将忽略内容信任,这意味着在拉取、推送和构建镜像过程中不会对镜像进行数字签名和验证。这可能会降低对镜像完整性和来源验证的安全性。
举个例子:
docker pull --disable-content-trust my-image:latest
这个命令表示拉取镜像时禁用内容信任。
需要注意的是 ,尽管 --disable-content-trust
可能会降低验证安全性,但有时在某些测试和开发环境下可能需要临时禁用内容信任。在生产环境下,建议始终保持内容信任功能开启,以确保安全性。
-f
用于指定要使用的 Dockerfile 路径。通常情况下,Docker 将在当前目录下寻找名为 Dockerfile 的文件来构建镜像,但是如果你的 Dockerfile 不在当前目录中,你可以使用 -f
选项来指定其路径。
使用场景:
当你拥有多个 Dockerfile 或者 Dockerfile 不在当前目录时,你可以使用 -f
选项来明确告诉 Docker 使用特定路径下的 Dockerfile 进行构建。
实例:
docker build -f /path/to/Dockerfile -t my-image:latest .
在这个例子中,-f /path/to/Dockerfile
指定了 Dockerfile 的路径为 /path/to/Dockerfile
,-t my-image:latest
指定了构建的镜像标签,.
表示构建上下文的路径为当前目录。
这样,Docker 将会使用指定路径下的 Dockerfile 来构建镜像。通常情况下,只有在以下情况下才会需要指定多个 Dockerfile:
- 项目包含多个组件或服务:如果你的项目包含多个组件或服务,每个组件可能有自己独立的 Dockerfile,这时你可能会需要在构建镜像时指定不同的 Dockerfile。
- 多阶段构建(Multi-stage builds):在多阶段构建中,一个 Dockerfile 中会定义多个构建阶段。例如,你可能会有一个阶段来编译应用程序,然后另一个阶段来打包最终的可执行文件。在这种情况下,你可能需要使用不同的 Dockerfile 来定义不同阶段的构建过程。
- 多个环境配置:有时候,你可能会希望使用不同的 Dockerfile 来构建不同环境下的镜像,比如生产环境和开发环境可能需要不同的配置。
在这些情况下,你可以使用 -f
选项来指定不同路径下的不同 Dockerfile 来满足项目的需求。
假设一个项目包含一个 Web 应用和一个数据库服务,并且在两个不同的目录中分别有它们各自的 Dockerfile,那么你可以使用 -f 选项来分别指定不同的 Dockerfile 构建两个镜像。
假设项目结构如下所示:
project/
├── webapp/
│ ├── Dockerfile
│ └── ...
└── database/
├── Dockerfile
└── ...
在这种情况下,你可以使用如下命令来构建两个镜像:
命令1:
docker build -f /path/to/project/webapp/Dockerfile -t webapp-image:latest /path/to/project/webapp
这将使用 webapp
目录下的 Dockerfile
构建名为webapp-image
的镜像。
命令2:
docker build -f /path/to/project/database/Dockerfile -t database-image:latest /path/to/project/database
这将使用database
目录下的 Dockerfile
构建名为 database-image
的镜像。
这样就能方便地对项目中的不同组件使用不同的 Dockerfile 进行构建。当使用多阶段构建时,通常会在一个 Dockerfile 中定义多个阶段来实现不同的构建任务,比如编译应用程序、收集依赖和生成最终的可执行文件。
多阶段构建的 Dockerfile 的简单示例
下面是一个使用多阶段构建的 Dockerfile 的简单示例:
-
第一个阶段:编译应用程序
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp -
第二个阶段:生成最终镜像
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]
这个 Dockerfile 包含了两个阶段:
- 第一个阶段使用
golang:1.16
镜像作为基础镜像,将项目文件复制到容器中,然后进行编译生成可执行文件myapp
。 - 第二个阶段使用
alpine:latest
镜像作为基础镜像,将前一个阶段生成的可执行文件复制到容器中,并设置启动命令为./myapp
。
一旦 Dockerfile 中包含了多个阶段,你可以使用-f
选项来指定要构建的 Dockerfile,例如:
docker build -f /path/to/Dockerfile -t myapp-image:latest .
这将使用指定路径下的 Dockerfile
来构建名为myapp-image
的镜像,其中 Dockerfile 包含了多个阶段来构建项目的不同部分。
--isolation
--isolation
参数用于指定容器的隔离技术。
在 Docker 中,容器的隔离技术决定了容器内的进程如何与宿主机以及其他容器隔离。
常见的容器隔离技术包括:
- default:默认值,使用默认的隔离技术。
- process:使用传统的 Linux 进程隔离,该选项会在一个共享的内核中运行容器。
- hyperv:在 Windows 平台上使用 Hyper-V 隔离。
- vm:在 Windows 平台上使用虚拟机隔离。
例如,要在运行容器时指定使用 Hyperv 隔离技术
,可以使用以下命令:
docker run --isolation=hyperv <image>
通过指定不同的隔离技术,可以更灵活地管理容器的运行环境,满足特定的安全性和性能需求。
这些隔离技术各有什么应用场景和优缺点,请举例说明
不同的隔离技术适用于不同的场景,每种隔离技术都有其优点和限制。
下面是一些常见的容器隔离技术的应用场景和优缺点:
- 默认隔离技术(默认值):
○ 应用场景:适用于大多数常规的容器化工作负载。
○ 优点:性能较好,资源消耗低。
○ 缺点:可能存在一定程度的安全风险,因为容器共享宿主机的内核。 - 进程隔离技术(process):
○ 应用场景:对于轻量级应用或者无需高额外隔离的场景。
○ 优点:资源消耗低,适用于短生命周期的任务。
○ 缺点:较缺乏隔离性,容器之间的安全性较低,不适合多租户环境。 - Hyper-V 隔离技术(hyperv):
○ 应用场景:在 Windows 平台上使用。
○ 优点:提供了更加强大的隔离性和安全性,适合需要更高度隔离的工作负载。
○ 缺点:相对于默认隔离技术,性能消耗可能更高。 - 虚拟机隔离技术(vm):
○ 应用场景:在 Windows 平台上使用,需要完全隔离且额外的安全性。
○ 优点:提供最高级别的隔离,可以确保容器之间的完全隔离。
○ 缺点:性能消耗更高,占用更多的资源,适用于安全性要求非常高的场景。
在选择隔离技术时,需要综合考虑安全性、性能以及资源消耗等因素。根据具体的应用需求,选择合适的隔离技术来保证容器的安全和性能。
--label=[]
--label
选项用于为 Docker 镜像添加自定义的元数据标签 。这些标签可以帮助你对镜像进行组织、分类,并且能在管理和使用镜像的过程中提供更多信息。
使用--label
参数可以在构建镜像时为镜像添加元数据标签。例如,你可以将构建者的联系方式、镜像的版本信息、构建日期或者其他相关信息添加为元数据标签。这样可以帮助你更好地管理和跟踪镜像的信息。
以下是使用 --label 选项添加元数据标签的示例:
docker build --label "version=1.0" --label "maintainer=yourname@example.com" -t myimage .
上面的命令会为构建的镜像添加version
和 maintainer
的元数据标签,分别指定镜像的版本和维护者的联系方式。
添加元数据标签可以让你在后续使用镜像时更方便地识别和管理镜像,也可以让其他用户更容易地理解和使用这些镜像。
-m
设置内存最大值
--memory-swap
设置Swap的最大值为内存+swap,"-1"表示不限swap;
-m
和 --memory-swap
选项用于限制容器能够使用的内存以及 Swap 的最大值。这两个参数用于控制容器可以消耗的系统资源,能够帮助你更好地管理容器的资源利用情况。
下面是对这两个选项的详细说明:
-m
:设置容器能够使用的内存最大值。可以用 -m 选项来限制容器能够使用的内存量。例如,使用 -m 1g 可以将容器的内存上限设置为 1GB。
示例:
docker run -m 1g myimage
--memory-swap
:设置容器能够使用的Swap
的最大值。可以用--memory-swap
选项来设置 Swap 的最大值,其默认值为内存 + swap。如果设置为 -1,表示不限制 Swap。
示例:
docker run --memory-swap 2g myimage
这些参数在构建容器时非常有用,可以帮助你限制容器的资源使用,防止容器占用过多的内存或者 Swap,从而导致系统资源的耗尽。通过限制内存和 Swap 的使用,你可以更好地控制容器的资源消耗,防止因为容器内存占用过多而影响其他应用程序的正常运行。
一般设置为多少?
设置内存和Swap的值取决于你的应用程序的性能需求和系统资源的可用情况。通常情况下,建议根据以下几点来设置内存和Swap的值:
- 应用程序的性能需求:首先要考虑你的应用程序对内存的需求。如果你的应用程序需要大量内存才能正常运行,则需要分配足够的内存给容器。
- 宿主机的物理内存大小:不要分配超过宿主机物理内存容量的内存给容器,这可能会导致系统出现内存压力。
- Swap的设置:Swap的大小一般设置为内存的两倍。但需要注意的是,Swap的大小设置过大可能会导致性能下降,因为过分依赖Swap会导致频繁的磁盘交换。
例如,如果你的应用程序对内存的需求较高,但是宿主机的物理内存有限,可以考虑设置较小的内存限制,并留一部分Swap供容器使用。具体的数值设置需要根据你的应用程序和系统资源情况来调整和优化。
最佳实践是在生产环境中进行测试并进行性能优化,以确定最适合你的应用程序和系统的内存和Swap设置。另外,如果你使用的是容器编排工具,如Kubernetes 或 Docker Swarm,也可以根据制定的策略来设置容器的资源限制。
举例
假设你的宿主机拥有16GB的内存,对于一个容器应用来说,下面是一种可能的内存和Swap设置。建议:
-
内存限制:你可以根据应用程序的需求和宿主机资源情况来设置内存的限制。可以考虑设置为宿主机内存的一半,即8GB,或者根据实际情况进行适度调整。
docker run -m 8g myimage
-
Swap限制:通常情况下,可以将Swap的大小设置为内存的两倍。这意味着可以设置为16GB,但需要根据实际情况进行评估和调整。
docker run --memory-swap 16g myimage
这个设置将允许容器使用8GB的内存和16GB的Swap。当然,具体的设置还需要根据你的应用程序的需求、系统资源状况以及性能表现来做出调整。在实际应用中,你可能需要根据具体情况进行测试和优化,以找到最合适的内存和Swap设置。
--no-cache
创建镜像的过程不使用缓存;
--pull
尝试去更新镜像的新版本;
--quiet, -q
安静模式,成功后只输出镜像 ID;
--rm
设置镜像成功后删除中间容器;
--shm-size
设置/dev/shm的大小,默认值是64M;
--ulimit
ulimit配置。
--squash
将 Dockerfile 中所有的操作压缩为一层。
--tag, -t
镜像的名字及标签,通常 name:tag
或者 name
格式;可以在一次构建中为一个镜像设置多个标签。
--network
默认 default。在构建期间设置RUN指令的网络模式
扩展部分
构建时的中间容器会保留在系统中吗?
当使用 docker build
命令构建镜像时,Docker 会根据 Dockerfile 中的指令逐步创建镜像的各个层。在每一步,Docker 会创建临时的容器来执行相应的命令。这些临时容器在命令执行完毕后会被自动清理,不会保留在系统中。因此,在构建过程结束后,不会产生中间容器保留在系统中。这些临时容器的存在对于构建过程的快速性能具有重要意义,但它们并不会占用多余的资源或空间,也不会对正在运行的容器产生影响。
在 Docker 构建镜像的过程中,每个指令在构建镜像的特定层中创建一个存储位置。这些存储位置实际上就是 Docker 镜像的各层。当你重新构建镜像时,如果某个指令的参数、指令本身或者基础镜像没有改变,Docker 会尝试重用之前构建好的层。这意味着,只有在 Dockerfile 的某个步骤发生改变时,Docker 才会重新执行该步骤并创建新的层。
当 Docker 检测到某个步骤的参数和指令都没有改变时,它会直接使用缓存的层,而不是重新运行相同的步骤,这样可以节省时间并提高构建效率。这也意味着,即使之前的临时容器不再存在,Docker 仍然可以重用之前构建好的层,从而避免重新执行相同的步骤。 因此,即使之前的临时容器已经被清理,Docker 仍然可以利用缓存的层,在下一次构建时提供类似的步骤,以提高构建速度和效率。
缓存的层会自行清理吗?
Docker 默认会对构建镜像时生成的缓存层进行管理。当执行 docker build
命令时,Docker 会检查每个步骤的缓存情况,并尝试复用之前构建好的层,以加快构建速度。 对于缓存层的清理,Docker 会根据一些条件来确定是否需要重新构建和清理缓存。如果在 Dockerfile 中的某个步骤发生了变化,比如更改了命令或者参数,Docker 会丢弃该步骤之后的缓存层,并重新构建。另外,你也可以通过在构建时使用 --no-cache
参数来禁用缓存,强制 Docker 重新构建镜像。 总的来说,Docker 会根据需要自动管理缓存的层,确保在构建镜像时能够最大程度地复用之前构建好的层,并在需要时进行清理。
缓存层的管理策略是什么? 可以自行查看吗?
在 Docker 中,缓存层的管理
是由 Docker 引擎
自动进行的,而且并没有提供直接查看缓存层的命令或工具。
Docker 引擎会根据构建过程中的指令和层之间的依赖关系,进行适当的缓存管理 。它会尝试重用之前构建好的层,并在必要时进行清理。这种管理策略是隐含的,通常不需要用户直接干预。 虽然没有直接查看缓存层的命令,但你可以通过查看镜像的历史记录来了解构建镜像时各步骤的情况,以及层的复用情况。可以使用 docker history
命令来查看镜像的历史记录,这可以让你了解每个步骤都对应了哪些层,以及它们是否被缓存和复用。