docker-compose下载慢_编写Docker Compose时要注意的五大常见错误

859e365e5c9df5cdef51c4777e581699.gif

508b88313d753a19b5431bc87c5f5ae2.png

在构建容器化的应用时,开发人员往往需要某种方法来引导启动目标容器,以对其进行代码级别的测试。尽管业界有许多方法可以实现该目的,但Docker Compose是目前最受欢迎的一种方法。它能够让如下两个方面变得容易实现:
  • 指定在开发过程中需要启动的容器。
  • 设置一套快速的代码测试调试(code-test-debug),以方便开发循环。
通常情况下,团队事先编写一个docker-compose.yml文件,指定开发所需的所有内容,并将其提交给存储库。然后,每个开发人员只需运行docker-compose up,即可启动测试其代码所需的所有容器。不过,要让docker-compose的设置能够达到最佳性能状态,例如:在不到一分钟之内启动开发环境,并且在几秒钟内完成对每个更改的测试,这些都需要团队花费大量的工作。在这些准备过程中,由于各个开发人员每天花费在测试其代码上的时间各不相同,而且任何细微的改动,都可能会对整个开发团队的生产力产生巨大的影响。因此,我们有必要在此讨论他们在编写Docker Compose时常见的五大错误,及其对应的解决方法。

错误1:频繁地进行容器重建

Docker的构建往往比较耗时,特别是每次针对代码的变更开展测试的时候。如果能够节省此方面的时间,那么对于加快开发周期来说是十分有益的。过去,对于非容器化的应用,我们通常会采取如下传统的工作流程:
  • 编写代码
  • 构建
  • 运行
多年来,业界持续优化该流程,并提出了诸如:针对编译语言的增量构建和热重载(hot reloading)等实用技巧。随着容器技术的出现,我们在现有的工作流程中增加了docker构建的步骤,如下图所示。
  • 编写代码
  • 构建
  • Docker构建
  • 运行
当然,如果构建得不好,那么docker构建步骤也可能会带来额外的时间开销。例如:使用apt-get进行依赖项的重载步骤。有时候,这些步骤可能会让整个测试过程比添加Docker之前还要慢。解决方案:在Docker外部运行代码第一种解决方法是在Docker Compose中启动所有的依赖项,然后在本地运行测试代码。此举模仿了非容器化应用开发的工作流程。您只需向localhost公布依赖关系,然后将正在使用的服务指向所有的localhost:地址即可。但是,该方法并非永远可行,如果您正在使用的是代码依赖容器镜像中的内置元素时,那么用户电脑就不一定能够访问到具体内容。解决方案:最大化缓存,以优化Dockerfile如果必须构建Docker镜像,那么我们可以编写Dockerfile,通过最大化缓存,将Docker的构建时间从原来的10分钟压缩至1分钟。在生产环境中,Dockerfile的典型模式是通过将单个命令链接到一条RUN语句中,来减少层级的数量。毕竟,在开发过程中镜像的大小并不重要,重要的是层级的数量。下面展示的是在生产环境中的一个Dockerfile文件:
RUN \ 
go get -d -v \
&& go install -v \
&& go build
不过,该命令在每次被重新运行时,Docker都会重新下载所有的依赖项,并重新安装它们。我们可以通过增量构建(incremental build)来提供效率。同时,您可以将开发专用的Dockerfile其分成几个短小的步骤,从而使得那些经常更改的代码步骤被排到最后,而将鲜少更改的步骤(例如拉式依赖关系)被放在首位。因此,在重建Dockerfile时,您不必构建整个项目,而只需构建那些被已更改的少量末尾块即可。有关此方面的案例,您可以参阅以下用于Blimp(请参见--https://kelda.io/blimp)开发的Dockerfile。通过遵循上述方法,您可以将繁琐的构建过程缩减到了几秒钟之内完成。
FROM golang:1.13-alpine as builder 
RUN apk add busybox-static
WORKDIR /go/src/github.com/kelda-inc/blimp
ADD ./go.mod ./go.mod
ADD ./go.sum ./go.sum
ADD ./pkg ./pkg
ARG COMPILE_FLAGS
RUN CGO_ENABLED=0 go install -i -ldflags "${COMPILE_FLAGS}" ./pkg/...
ADD ./login-proxy ./login-proxy
RUN CGO_ENABLED=0 go install -i -ldflags "${COMPILE_FLAGS}" ./login-proxy/...
ADD ./registry ./registry
RUN CGO_ENABLED=0 go install -i -ldflags "${COMPILE_FLAGS}" ./registry/...
ADD ./sandbox ./sandbox
RUN CGO_ENABLED=0 go install -i -ldflags "${COMPILE_FLAGS}" ./sandbox/...
ADD ./cluster-controller ./cluster-controller
RUN CGO_ENABLED=0 go install -i -ldflags "${COMPILE_FLAGS}" ./cluster-controller/...
RUN mkdir /gobin
RUN cp /go/bin/cluster-controller /gobin/blimp-cluster-controller
RUN cp /go/bin/syncthing /gobin/blimp-syncthing
RUN cp /go/bin/init /gobin/blimp-init
RUN cp /go/bin/sbctl /gobin/blimp-sbctl
RUN cp /go/bin/registry /gobin/blimp-auth
RUN cp /go/bin/vcp /gobin/blimp-vcp
RUN cp /go/bin/login-proxy /gobin/login-proxy
FROM alpine
COPY --from=builder /bin/busybox.static /bin/busybox.static
COPY --from=builder /gobin/* /bin/
最后值得一提的是:随着多阶段构建(multi-stage builds,请参见--https://docs.docker.com/develop/develop-images/multistmuage-build/)的引入,我们如今可以创建各种具有良好分层和较小镜像的Dockerfile。不过,我们在此并不会展开详细的讨论。解决方案:使用主机卷(host volumes)大多数语言都会提供一种方法来监视程序代码,并在代码发生更改时自动重新运行。例如,nodemon就是JavaScript语言的一种Node自动重启工具(请参见--https://www.npmjs.com/package/nodemon)。由于主机卷可以将您电脑上的目录,镜像到正在运行的容器之中,因此您在使用文本编辑器来编辑文件时,各种更改将会被自动同步到容器中,并在容器内被立即执行。最初,您可能需要花点时间进行前期准备,之后在Docker中,您可以在1-2秒内马上看到代码的更改结果。因此,我们会选择使用主机卷将代码直接挂载到容器中,以便以原生的方式,在包含其了运行时依赖项的Docker容器中运行自己的代码。

错误2:缓慢的主机卷

如果您使用过主机卷,那么是否已经注意到:在Windows和Mac上读写文件的速度可能会非常缓慢?其实,对于诸如Node.js和具有复杂依赖性的PHP应用程序之类,需要读写大量文件的命令而言,这是一个已知的问题。其背后的原因是:Docker主要运行在Windows和Mac上的VM中。而我们在进行主机卷的挂载时,它必须经过大量的转换,才能使文件夹进入容器,这有点类似于网络文件系统。而此类额外的开销,在Linux本地运行Docker时,则不会出现。解决方案:放宽强一致性该问题的一个关键原因是:文件系统在默认挂载时,需要保持强一致性。也就是说:所有特定文件的读写进程都必须统一对于文件修改的顺序,以便让文件的内容达成最终的一致。可是,强一致性的代价非常昂贵,它需要所有文件的写入进程之间持续保持协调,以确保它们不会干扰或破坏彼此的更改。虽然在生产环境中的数据库需要保持强一致性。但是在开发过程中,由于写入进程就是代码文件本身,目标就是我们的存储库,因此强一致性就不那么必需了。那么,我们就可以考虑Docker在挂载卷时,放宽强一致性。例如:在Docker Compose中,我们可以简单地将此cached关键字添加到卷挂载中,以获得显著的性能保证。对应的代码如下:
volumes: 
- "./app:/usr/src/app/app:cached"
注意:此举仅适合开发环境,不适合生产环境。解决方案:代码同步另一种处置方法是设置代码的同步。您可以使用工具侦测主机和容器之间的变化,通过复制文件来解决差异(类似于rsync),而不是挂载卷。Docker在最新的版本中内置了用来替代卷的缓存模式--Mutagen(请参见--https://mutagen.io/)。此外,上文提到的Blimp则使用Syncthing(请参见--https://http//syncthing.net/)实现了类似的功能。解决方案:不要挂载软件包Node之类的语言通常会把大部分文件操作放在packages目录中(如node_modules)。那么,我们可以试着从卷中去除此类目录,以显著提高性能。下列示例是一个将代码挂载到容器中的专属卷,它覆盖了node_modules目录。
volumes:  
- ".:/usr/src/app"
- "/usr/src/app/node_modules"
该挂载操作会告诉Docker去使用node_modules目录下的标准卷,以使得在npm install运行时,不再使用慢速的主机挂载方式。为了使该工作能够正常进行,我们应该在容器首次启动时,在entrypoint中执行npm install,以安装依赖项,并更新node_modules目录。具体代码如下:
entrypoint: 
- "sh"
- "-c"
- "npm install && ./node_modules/.bin/nodemon server.js"
如果您想查看并运行上述完整的示例,请参考--https://kelda.io/blimp/docs/examples/#nodejs。

错误3:脆弱的配置

如果您曾深入研究过代码,您可能会发现Docker Compose中也充斥着各种大量复制和粘贴而来的代码。显然,我们需要干净整洁的Docker Compose文件,以方便轻松地按需做出修改。解决方案:使用各种env文件Env文件能够将环境变量与Docker Compose主配置分开,以实现:
  • 避免将代码泄露到git的历史记录中。
  • 开发人员都能按需自定义设置。例如,每个开发人员都可以持有一个唯一的访问密钥。他们通过将配置保存在.env文件中,以实现不必修改已提交的docker-compose.yml文件,也不必在文件更新时处理各种冲突问题。
如果您想使用环境文件,只需添加一个.env文件,或设置带有env_file字段的显式路径即可(请参见--https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option)。

解决方案:使用替代文件

替换文件(请参见--https://docs.docker.com/compose/extends/)可以方便您在具有基本配置的基础上,在其他文件中指定各项修改。该功能非常适合Docker Swarm及其YAML文件。您可以将生产环境的配置存储在docker-compose.yml中,然后在替代文件中,指定开发所需的任何修改(例如:使用主机卷)。解决方案:使用extends如果您使用的是Docker Compose v2,那么就可以使用extends关键字,在多个位置导入YAML片段。例如,您可能会定义:公司里所有的服务都需要在开发的Docker Compose文件中带有某五个特定的配置。然后您可以使用extends关键字将其放置到任何需要的地方,以实现模块化。当然,如果仅在YAML中执行此项操作可能比较繁琐,我们完全可以通过编程来实现。虽然Compose v3删除了对于extends关键字的支持。但是,您仍然可以使用YAML anchors(请参见--https://support.atlassian.com/bitbucket-cloud/docs/yaml-anchors/)来实现类似的结果。

错误4:乱序启动(Flaky Boots)

如果docker-compose出现了崩溃,我们能够仅使用docker-compose restart来重启服务吗?其实此类问题主要与服务错误的启动顺序有关。例如,您的Web应用可能依赖于数据库,那么在Web应用启动时,如果数据库尚未准备就绪,就会出现崩溃。解决方案:使用depends_ondepends_on使您可以控制启动的顺序。默认情况下,depends_on仅判断依赖项是否已经创建,而不会判断依赖项是否“健康”。虽然Docker Compose v2能够支持将depends_on与运行状况的检查相结合。不过,该功能也在Docker Compose v3中被去除了。当然,您可以使用诸如wait-for-it.sh之类的脚本,来手动实现类似的功能。和上面提到的放宽强一致性相同,虽然Docker文档不建议在生产环境中使用depends_on和wait-for-it.sh,来为容器指定特定的启动顺序。但是对于开发而言,我们完全可以用到depends_on。

错误5:资源管理不善

如果您碰到开发流程受阻,Docker无法全速运行,或是无法平稳地获取运行所需的资源,那么您可以考虑以下几个方面:解决方案:更改Docker Desktop的分配Docker Desktop需要大量的RAM和CPU,尤其是在Mac和Windows的VM上。Docker Desktop的默认配置往往不会分配足够的RAM和CPU,因此我们通常需要调整相关的设置。在开发时,我经验是:为Docker分配大约8GB的RAM和4个CPU,并且在不使用Docker Desktop时,及时关闭之。解决方案:删除未使用的资源人们在使用Docker时经常会出现数百个卷与旧的容器镜像。这在无形中浪费了各种资源。为了释放这些资源,我们建议通过间或运行docker system prune的方式,以删除当前未使用到的所有卷、容器和网络。

总结

总的说来,为了改善开发人员在使用Docker Compose时的体验,我建议您做到如下五点:
  • 最小化容器的重建。
  • 使用主机卷。
  • 像对待代码那样,认真配置文件,以便于维护。
  • 让启动更加可靠。
  • 认真分配管理资源。
此外,您还可以通过链接--https://kelda.io/blog/docker-volumes-for-development/,以获悉如何设置主机卷,并加快Docker开发。

Java帮帮

非盈利学习社区

官网:www.javahelp.com.cn

27387fe793450b273dd087b5a3c57137.png

职涯宝

帮助职业者成功

分享优质内容

官网:zhiya360.com

0d9e8da5d2eeb33afe0f2674f4dafd3d.png

九点编程

深夜学习,未来可期

c952be1c148f7e588fe4ba93ea89d87f.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457804.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端测试利器--Browser-Sync启动命令

使用browser-sync启动命令cmd切换到项目的根目录下**1.browser-sync start --server --files "css/*.css"----------**使用两个*检测所有的目录**转载于:https://blog.51cto.com/1888512/1862054

VMware实现Android x86 8.1 从安装到使用

VMware实现Android x86 8.1 从安装到使用 虚拟机--Android 安装 Android系统配置 安装软件 个性化设计 托坑指南 一些终端模拟器的指令 虚拟机–Android 发现现在安卓虚拟机已经到了8.1,我就试试能不能安装并正常使用。由于版本过新,网上也没有一些系统的…

frame越过另一个frame_拥抱swoole(三)之用php实现一个混合服务器

混合服务器,就是可以同时支持http,websocket,tcp等的服务器,用swoole就是这么简单,分分钟,就可以愉快地搞物联网开发了,啥都支持,我采用官方的例子,创建一个混合服务器&a…

Hibernate学习系列————注解一对多单向实例

2019独角兽企业重金招聘Python工程师标准>>> 开发环境:MysqlEclipse 一对多单向的列子原理:一个班级,多个学生,学生端为多的一端,他们拥有一个外键指向相同的班级。 项目结构 需要的jar包 hibernate.cfg.xm…

Spring学习笔记--自动装配Bean属性

Spring提供了四种类型的自动装配策略: byName – 把与Bean的属性具有相同名字(或者ID)的其他Bean自动装配到Bean的对应属性中。byType – 把与Bean的属性具有相同类型的其他Bean自动装配到Bean的对应属性中。constructor – 把与Bean的构造器入参具有相同类型的其他…

sudo apt-get nmap 报错锁占用

在Ubuntu中用apt-get命令安装软件是出现如下错误: 网上搜了一下原因,说是有另外一个程序在运行,导致锁不可用,原因可能是赏析运行更新或安装没有正常完成。这是因为上次更新或者安装没有正常完成。 网上的两种解决方法&#xff1…

python逐行读取txt写入excel_用python从符合一定格式的txt文档中逐行读取数据并按一定规则写入excel(openpyxl支持Excel 2007 .xlsx格式)...

前几天接到一个任务,从gerrit上通过ssh命令获取一些commit相关的数据到文本文档中,随后将这些数据存入Excel中。数据格式如下图所示观察上图可知,存在文本文档中的数据符合一定的格式,通过python读取、正则表达式处理并写入Excel文…

筋斗云newcloud错误码列表

响应码信息备注440Ip Error客户送IP错误441Callee Number Error被叫号码位数错误(标准11位正确,错误加前缀0,或其他前缀)442Called Operator Error被叫运营商错误(支持移动,不支持联通电信)443N…

Extjs 之 initComponent 和 constructor的区别(转)

在创建自定义类时,先构造(constructor)后初始化(initComponent)。如:(在旧的Extjs 版本中使用 Ext.extend 实现扩展) Ext.define(Btn,{ extend:Ext.button.Button, init…

hive遍历_从Hive中的stored as file_foramt看hive调优

一、行式数据库和列式数据库的对比1、存储比较行式数据库存储在hdfs上式按行进行存储的,一个block存储一或多行数据。而列式数据库在hdfs上则是按照列进行存储,一个block可能有一列或多列数据。2、压缩比较对于行式数据库,必然按行压缩&#…

oracle sql语句 从指定条数查询

现有表A 查询从第10行之后的数据 select a from ( select a, rownum r from A ) where r > 10 order by r; 实际工作中例子 select account,acct_name from ( select account, acct_name, rownum r from pmctl_nonsleep_acct ) where r > 10 order by

帮助孩子学会感恩_页数204_出版日期2015.03_完整版PDF电子书下载

帮助孩子学会感恩_页数204_出版日期2015.03_完整版PDF电子书下载 带索引书签目录高清版_13813212 下载链接http://pan.baidu.com/s/1geEmUeZ 【作 者】(英)蒂姆惠特尼(TimWhitney)著【丛书名】陪孩子成长系列丛书【形态项】 204 …

xwpftablecell设置字体样式_HTML的文字样式

font 属性可以用来作为 font-style, font-variant, font-weight, font-size, line-height 和 font-family 属性的简写,或将元素的字体设置为系统字体。字体修改font-family 属性:设置HTML页面中的字体font-size 属性:设置字体大小font-weight…

将中文标点符号替换成英文标点符号

/// 转全角的函数(SBC case) /// ///任意字符串 /// 全角字符串 /// ///全角空格为12288,半角空格为32 ///其他字符半角(33-126)与全角(65281-65374)的对应关系是:均相差65248 ///public string ToSBC(string input) { //半角转全角:char[] cinput.ToCh…

Centos6.5升级GCC

由于CentOS自带的gcc实在是老掉牙了,所以决定升级一下gcc,下面介绍如何进行源码编译,升级gcc。 从GNU网站下载你想要的gcc版本,链接:ftp://ftp.gnu.org/gnu/gcc/,选择合适的gcc版本,然后下载&am…

oracle sql语句 exists

exists 这个关键字只是个查询条件 用来判断后面跟的查询语句是否查找到记录 查找到为真 反之为假 例子 select * from ammst_corp a where account 999999999999999999 and exists ( select 1 from pmrgt_unit where unit_code a.open_unit ) 查找 9999999999999999…

python金字塔_高斯金字塔与拉普拉斯金字塔的原理与python构建

高斯金字塔和拉普拉斯金字塔【1】在图像相关领域应用广泛,尤其是图像融合和图像分割方面。本文从理论和opencv实现两个方面对两种金字塔进行了介绍,并给出了二者的视觉效果。1、高斯金字塔在计算机视觉与图像处理相关任务中,经常需要使用同一…

mongodb在32位机的连接

Windows 32bit版本安装Mongodb时,会发生的下面问题 2016-05-09T00:09:45.1240800 I STORAGE [initandlisten] exception in initAndListen: 28663 Cannot start server. The default storage engine wiredTiger is not available with this build of mongod. Pleas…

oracle sql 语句 start with ...... connect by prior .......

这个查询条件可以理解为递归查询 select up_unit_code from pmctl_nuit START WITH unit_code 1188899Q CONNECT BY PRIOR up_unit_code unit_code 语句理解: 首先根据条件 START WITH unit_code 查询到 up_unit_code 显示 然后 CONNECT BY P…

cnetos7安装zabbix3.0.3安装手册

亲测可用呀。学习好几天 最好用的文档详见附件http://down.51cto.com/data/2251232转载于:https://blog.51cto.com/11802086/1863554