运维老司机血泪总结:docker build镜像构建的避坑法则

docker build命令用于从Dockerfile构建镜像(新手必看!Dockerfile核心指令详解,让你的镜像更专业)。当运行docker build命令时,将从PATH中指定的目录读取Dockerfile。它还将当前目录中的任何其他文件和目录发送给Docker守护进程。此目录的内容将由Dockerfile中的ADD命令使用。

警告:这将根据当前目录的内容向Docker守护进程发送大量数据。构建是由Docker守护进程运行的,而不是由CLI运行的,因此必须将整个上下文传输到守护进程。当上下文被发送到Docker守护进程时,Docker CLI会报告“Sending build context to Docker daemon”(正在向Docker守护进程发送构建上下文)。

当指定tarball存档或单个Dockerfile的URL时,客户端不会向Docker守护进程发送上下文。在这种情况下,归档根目录下的Dockerfile和归档的其余部分将用作构建的上下文。当Git存储库设置为URL时,存储库将在本地克隆,然后作为上下文发送。

docker build命令的用法如下:

docker build [--add-host[=[]]] [--build-arg[=[]]] [--cache-from[=[]]] [-c|--cpu-shares[=0]] [--cgroup-parent[=CGROUP-PARENT]] [--help] [--iidfile[=IIDFILE]] [-f|--file[=PATH/Dockerfile]] [-squash] Experimental [--force-rm] [--isolation[=default]] [--label[=[]]] [--no-cache] [--pull] [--compress] [-q|--quiet] [--rm[=true]] [-t|--tag[=[]]] [-m|--memory[=MEMORY]] [--memory-swap[=LIMIT]] [--network[="default"]] [--shm-size[=SHM-SIZE]] [--cpu-period[=0]] [--cpu-quota[=0]] [--cpuset-cpus[=CPUSET-CPUS]] [--cpuset-mems[=CPUSET-MEMS]] [--target[=[]]] [--ulimit[=[]]] PATH | URL | -

选项    

-f, --file PATH/Dockerfile

要使用的Dockerfile的路径。如果路径是相对路径,并且您是从本地目录构建的,则路径必须相对于该目录。如果你是从指向tarball或Git存储库的远程URL构建的,那么路径必须相对于远程上下文的根。在所有情况下,文件都必须在构建上下文中。

默认设置为当前路径下的Dockerfile。

--squash true|false

仅限实验用途。

构建镜像后,将新层压缩为具有单个新层的新镜像。压缩不会破坏任何现有镜像,而是使用压缩层的内容创建一个新镜像。这实际上使它看起来像所有的Dockerfile命令都是用一个层创建的。使用此方法保留构建缓存。

注意:使用此选项意味着新镜像将无法利用与其他镜像的层共享,并且可能会使用更多的空间。

注意:使用此选项,您可能会看到由于存储两个镜像副本而使用了更多的空间,一个用于完整包含所有缓存层的构建缓存,另一个用于压缩版本。    

--add-host []

添加自定义主机到IP映射(host=ip,或host:ip)

在/etc/hosts中添加一行。格式为hostname=ip,或hostname:ip。

--add-host选项可以多次设置。

--build-arg variable

buildarg的名称和值。

例如:如果你想为http_proxy传递一个值,请使用:

--build-arg=http_proxy="http://some.proxy.url"

用户在构建时传递这些值。Docker使用buildarg作为通过Dockerfile的RUN指令运行的命令或其他Dockerfile指令中的变量扩展的环境上下文。这不是为了传递密钥值。阅读更多关于buildargs指令⟨https://docs.docker.com/engine/reference/builder/#arg⟩。

--cache-from ""

设置将用作构建缓存源的镜像。

--force-rm true|false

即使在构建失败后,也要始终删除中间容器。默认值为false。

--isolation "default"

Isolation指定了容器使用的隔离技术类型。    

--label label

为镜像设置元数据。

--no-cache true|false

构建镜像时不要使用缓存。默认值为false。

--iidfile ""

将镜像ID写入文件。

--help

打印使用声明。    

--pull true|false

始终尝试拉取镜像的较新版本。默认值为false。    

--compress true|false

使用gzip压缩构建上下文。默认值为false。

-q, --quiet true|false

成功后抑制构建输出并打印镜像ID。默认值为false。

--rm true|false

成功构建后删除中间容器。默认值为true。

-t, --tag ""

如果成功,将存储库名称(以及可选的标签)应用于生成的镜像。有关有效标签名称的更多信息,请参阅docker-tag。

-m, --memory MEMORY

设置内存限额大小。

--memory-swap number[S]

组合内存加swap限额;S是一个可选后缀,可以是b(字节)、k(千字节)、m(兆字节)或g(千兆字节)之一。

此选项只能与--memory一起使用。参数值应该总是大于--memory设置的值。默认值是--memory值的两倍。设置为-1以启用无限制交换。

--network type

在构建过程中为RUN指令设置网络模式。支持的标准值有:none、bridge、host和container:<name|id>。任何其他值都被视为此容器应连接到的自定义网络名称或ID。

在Linux中,默认值是bridge。

--shm-size SHM-SIZE

/dev/shm的大小。格式为<数字><单位>,数字必须大于0,单位是可选的,可以是b(字节)、k(千字节)、m(兆字节)或g(千兆字节)。如果省略单位,系统将使用字节。如果完全省略尺寸,系统将使用64m。

-c, --cpu-shares 0

CPU份额(相对权重)。

默认情况下,所有容器获得相同比例的CPU周期。CPU份额是相对于默认设置1024的“相对权重”。此默认值在此处定义:

cat /sys/fs/cgroup/cpu/cpu.shares1024

您可以通过调整容器的CPU份额权重相对于所有其他正在运行的容器的权重来更改此比例。要修改默认值1024的比例,请使用-c或--cpu-shares标志将权重设置为2或更高。

Container CPU share Flag{C0} 60% of CPU --cpu-shares 614 (614 is 60% of 1024){C1} 40% of CPU --cpu-shares 410 (410 is 40% of 1024)

该比例仅在CPU密集型进程运行时适用。当一个容器中的任务空闲时,其他容器可以使用剩余的CPU时间。实际使用的CPU时间取决于系统上运行的容器数量。

例如,考虑三个容器,其中一个配置--cpu-shares 1024,另外两个配置--cpu-shares 512。当所有三个容器中的进程都试图使用100 %的CPU时,第一个容器将获得总CPU时间的50%。如果添加第四个具有--cpu-shares 1024的容器时,则第一个容器只能获得33%的CPU,其余的容器分别获得16.5%、16.5%和33%的CPU。

Container CPU share Flag CPU time{C0} 100% --cpu-shares 1024 33%{C1} 50% --cpu-shares 512 16.5%{C2} 50% --cpu-shares 512 16.5%{C4} 100% --cpu-shares 1024 33%

在多核系统中,CPU时间的份额分布在多个CPU核上。即使一个容器的CPU时间限制在100%以下,它也可以使用每个单独CPU核的100%。

例如:考虑一个具有三个以上内核的系统。如果你启动一个容器{C0},其中以--cpu-shares 512运行一个进程;而另一个容器{C1},其中以--cpu-shares 1024运行两个进程,这可能会导致CPU份额按照以下划分:

PID container CPU CPU share100 {C0} 0 100% of CPU0101 {C1} 1 100% of CPU1102 {C1} 2 100% of CPU2--cpu-period 0

限制CPU CFS(Completely Fair Scheduler,完全公平调度程序)周期。

限制容器的CPU使用率。此标志使内核将容器的CPU使用限制在您指定的周期内。

--cpu-quota 0

限制CPU CFS(Completely Fair Scheduler,完全公平调度程序)配额。

默认情况下,容器以完整的CPU资源运行。此标志使内核将容器的CPU使用限制在您指定的配额内。

--cpuset-cpus CPUSET-CPUS

允许执行的CPU(0-3,0,1)。

--cpuset-mems CPUSET-MEMS

允许执行的内存节点(MEMs)(0-3,0,1)。仅在NUMA系统上有效。

例如:如果您的系统上有四个内存节点(0-3),请使用--cpuset-mems 0,1来确保Docker容器中的进程只使用前两个内存节点的内存。

--cgroup-parent CGROUP-PARENT

创建容器cgroup的cgroups路径。如果路径不是绝对的,则认为该路径相对于init进程的cgroups路径。如果Cgroups不存在,则会创建它们。    

--target ""

设置目标构建阶段名称。

--ulimit []

Ulimit选项。有关ulimit的更多信息,请参阅在容器中设置ulimit⟨ https://docs.docker.com/engine/reference/commandline/run/#set-ulimits-in-container---ulimit ⟩

示例

使用当前目录中的Dockerfile构建镜像,可以使用build命令和Dockerfile来构建Docker镜像:

docker build .

在构建过程中,Docker会创建中间镜像。为了保留它们,您必须显式设置--rm false。

docker build --rm false .

一个好的做法是创建一个具有相关名称的子目录,并在该目录中创建Dockerfile。例如,一个名为mongo的目录可能包含一个用于创建Docker MongoDB映像的Dockerfile。同样,另一个名为httpd的目录可用于存储Apache web服务器映像的Dockerfiles。    

将镜像所需的文件添加到子目录也是一种很好的做法。然后,这些文件将使用Dockerfile中的COPY或ADD指令指定。

注意:如果你引用一个tar文件(一个好的做法),那么Docker会自动将ADD指令中指定的tar文件的内容提取到指定的目标中。

构建一个镜像并命名该镜像    

一个好的做法是给你正在构建的镜像命名。请注意,出于一致性考虑,只能使用【a-z】、【0-9】、【-】、【_】和【.】。这里没有硬性规定,但最好考虑一下名字。

-t/--tag标志用于重命名镜像。以下是一些示例:

虽然这不是一个好的做法,但镜像名称可以是任意的:

docker build -t myimage .

一种更好的方法是提供一个完全限定且有意义的存储库、名称和标签(在这种情况下,标签是指“:”后面的限定符)。在这个例子中,我们为Fedora存储库构建了一个JBoss镜像,并将其版本设置为1.0:

docker build -t fedora/jboss:1.0 .

下一个例子是“whenry”用户存储库,它使用Fedora和JBoss,并指定了2.1版本:

docker build -t whenry/fedora-jboss:v2.1 .

如果你没有提供版本标签,Docker将分配版本latest:

docker build -t whenry/fedora-jboss .

当您列出镜像时,上面的镜像将具有标签latest。    

您可以将多个标签应用于镜像。例如,您可以将latest标记应用于新构建的镜像,并添加另一个引用特定版本的标记。例如,要将镜像标记为whenry/fedora-jboss:latest和whenry/fedora-jboss:v2.1,请使用以下命令:

docker build -t whenry/fedora-jboss:latest -t whenry/fedora-jboss:v2.1 .

因此,重命名镜像是任意的,但应该考虑一个对消费者有意义的有用约定,也应该考虑Docker社区约定。

使用URL构建镜像    

这将从URL克隆指定的GitHub存储库并将其用作上下文。存储库根目录下的Dockerfile用作Dockerfile。这仅在GitHub存储库是专用存储库的情况下有效。

docker build github.com/scollier/purpletest

注意:您可以通过git://方案设置任意Git存储库。

使用tarball上下文的URL构建镜像    

这将把URL本身发送到Docker守护进程。守护进程将获取tarball存档,解压缩它并将其内容用作构建上下文。存档根目录下的Dockerfile和存档的其余部分将用作构建的上下文。

如果您也传递-f PATH/Dockerfile选项,系统将在tarball的内容中查找该文件。    

docker build -f dev/Dockerfile https://10.10.10.1/docker/context.tar.gz

注意:支持的压缩格式为“xz”、“bzip2”、“gzip”和“identity”(无压缩)。

指定容器的隔离技术(--isolation)    

此选项在Windows上运行Docker容器的情况下很有用。--isolation <value>选项设置容器的隔离技术。在Linux上,唯一支持的是使用Linux命名空间的默认选项。在Microsoft Windows上,您可以指定以下值:

•default:使用Docker守护进程--exec-opt指定的值。如果守护进程没有指定隔离技术,Microsoft Windows将使用process作为其默认值。

•process:仅隔离命名空间。

•hyperv:基于Hyper-V管理程序分区的隔离。

***推荐阅读***

误以为是外国货?这家国产SD-WAN神器竟能免费白嫖,附Panabit免费版体验全记录

零成本自建企业级SD-WAN!用Panabit手搓iWAN实战

iWAN隧道实测:一次握手跑满2.3Gbps,白嫖的SD-WAN真能吊打专线?

Panabit竟能无缝整合Ubuntu?用5MB升级包在Ubuntu极速安装Panabit

从崩溃到3G带宽!Panabit三种部署模式性能实测,这个坑千万别踩

48核+96GB内存!EVE-NG 6.2低配版安装实录,网络工程师必看!

告别重装!Ubuntu 22.04直升24.04教程,零数据丢失的终极方案

小白也能玩转VPP!Ubuntu 24.04使用APT极速部署VPP

CentOS迁移指南:在Ubuntu上从零编译部署VPP+DPDK,解锁Ubuntu网络性能!

从单网卡到全局,3种方法教你精准拿捏Ubuntu的IPv6

IPv6隧道搭建指南:用WireGuard轻松玩转IPv4/IPv6混合网络

基于IPv6配置openVPN实战:告别双栈难题,一步打通IPv6隧道!

无需公网IPv4!手把手教你配置基于IPv6的WireGuard安全隧道

运营商不会告诉你的秘密:企业级路由器能通过多拨叠加带宽,轻松跑满千兆!

目前来看,ollama量化过的DeepSeek模型应该就是最具性价比的选择

哪怕用笔记本的4070显卡运行DeepSeek,都要比128核的CPU快得多!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Danileaf_Guo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值