当前位置: 首页 > 科技观察

重构:保持Dockerfile清洁的5个技巧

时间:2023-03-21 10:32:58 科技观察

当Dockerfile无故增长时,会出现以下问题:难以理解和维护-我们需要阅读数百行才能理解这么多行之间的所有依赖关系可能会被忽略An明显的安全问题当每个人都在更改同一个文件时,Git会引起更多冲突如果我们不清理每个依赖项,图像大小可能会很重最好的解决方案是将Dockerfile拆分为多个Dockerfile,以使我们的Dockerfile更小,更容易理解和维护。这里有一些减少Dockerfile大小的技巧。重构1:从其官方镜像获取依赖项以避免创建从官方镜像复制的工件。比如:我需要用terraform,不需要重新安装apt-get,直接用terraform官方镜像就可以了。来自golang的原始Dockerfile:1.12RUNapt-getupdate&&\apt-getupgrade-y&&\apt-getinstall-ygitopenssh-clientzipWORKDIR$GOPATH/src/github.com/hashicorp/terraformRUNgitclonehttps://github.com/hashicorp/terraform.git./&&\gitcheckoutv0.12.9&&\./scripts/build.shWORKDIR/my-configCOPY./my-config/CMD["terraforminit"]重构后DockerfileFROMhashicorp/terraform:0.12.9ASterraformFROMgolang:1.12COPY--from=terraform/go/bin/terraform/usr/bin/terraformWORKDIR/my-configCOPY./my-config/CMD["terraforminit"]重构2:将依赖提取到另一个Dockefile如果没有可以从中提取工件的官方镜像,则应将其构建被分离到另一个Dockefile中。然后将工件复制到原始Dockerfile中。原始Dockerfile:FROMgolang:1.12RUNapt-getupdate&&\apt-getupgrade-y&&\apt-getinstall-ygitopenssh-clientWORKDIR/go/src/gitlab.com/sahilm/RUNgitclonehttps://github.com/sahilm/yamldiff.gitRUNcdyamldiff&&\goget-ugithub.com/golang/dep/cmd/dep&&\dependence&&\GOOS=linuxgobuild-o/usr/local/yamldiffWORKDIR/my-appCOPY./my-app/CMD["./run.sh"]重构:forDockerfileforyamldiff。来自golang:1.12RUNapt-getupdate&&\apt-getupgrade-y&&\apt-getinstall-ygitopenssh-clientWORKDIR/go/src/gitlab.com/sahilm/RUNgitclonehttps://github.com/sahilm/yamldiff.gitRUNcdyamldiff&&\goget-ugithub。com/golang/dep/cmd/dep&&\dependence&&\GOOS=linuxgobuild-o/usr/local/yamldiffCMD["bash"]重构:应用程序的Dockerfile。FROMMarvalero/yamldiff:latestASyamldiffFROMgolang:1.12COPY--from=yamldiff/usr/bin/yamldiff/usr/bin/yamldiffWORKDIR/my-appCOPY./my-app/CMD["./run.sh"]重构3:放置图像被分成阶段Docker有一个多阶段的特性,当你的Dockerfile有不同的部分时,它会派上用场。最常见的用例是进行构建,然后复制主映像中的工件。具有不同的阶段使您的Dockerfile更清晰、更安全。来自golang:1.12RUNapt-getupdate&&\apt-getupgrade-y&&\apt-getinstall-ygitopenssh-clientWORKDIR/go/src/gitlab.com/sahilm/RUNgitclonehttps://github.com/sahilm/yamldiff.gitRUNcdyamldiff&&\goget-ugithub。com/golang/dep/cmd/dep&&\dependence&&\GOOS=linuxgobuild-o/usr/local/yamldiffCMD["bash"]重构Dockerfile:FROMgolang:1.12asB??uilderRUNapt-getupdate&&\apt-getupgrade-y&&\apt-getinstall-ygitopenssh-clientWORKDIR/go/src/gitlab.com/sahilm/RUNgitclonehttps://github.com/sahilm/yamldiff.gitRUNcdyamldiff&&\goget-ugithub.com/golang/dep/cmd/dep&&\dependensure&&\GOOS=linuxgobuild-o/usr/local/yamldiffFROMubuntu:18.04COPY--from=Builder/usr/local/yamldiff/usr/local/yamldiffCMD["bash"]重构4:对多行参数进行排序尽可能对多行参数进行排序。这有助于仔细检查是否没有重复的包。FROMubuntu:18.04RUNapt-get-yqqinstall\ca-certificates\bash\jq\wget\curl\openssh-client\build-essential\libpng-dev\python\zipCDM["bash"]重构Dockerfile:FROMubuntu:18.04RUNapt-get-yqqinstall\bash\build-essential\ca-certificates\curl\jq\libpng-dev\openssh-client\python\wget\zipCDM["bash"]重构5:标签使用Docker镜像时保持标签整洁同样至关重要。我一直发现拥有三种类型的标签非常有用:分支名称:标识特定分支的镜像的最新版本注意:为什么不是最新的?使用最新时,我永远不知道它是指最新的稳定版本还是整个存储库中的最新版本。使用分支名(如master、feature/new-class等)指向某个分支的最新版本会更直观。版本:需要区分修补程序和重大更改。我建议使用语义版本控制(major.minor.patch)。提交:我一直想知道标记指向哪个提交。您现在可以通过在存储库中创建版本标签来执行此操作。然而,当这不可能时,只需使用CommitSHA标记图像。