1. 聚能聊>
  2. 话题详情

如何在生产环境中使用Docker:你需要知道的各种问题

Docker引起了交付方式的变革,从交付代码和文档变成交付Docker镜像乃至交付编排模板。容器服务让我们可以专注应用本身功能的开发,而无需关注基础设施、应用部署、管理等等一大堆棘手的问题。

越来越多的公司开始考虑使用Docker的方式部署和管理应用,以降低运维的成本。说易行难,真正开始的时候又不知道具体该做什么,会遇到哪些坑。今天我们聊一聊怎么样一步步迁移到容器服务上,如何解决整个过程可能遇到的各种问题。

参与话题

奖品区域 活动规则 已 结束

  • 奖品一

    淘公仔 x 1

  • 奖品二

    优酷VIP季卡 x 1

  • 奖品三

    聆听专属T恤衫 x 2

59个回答

0

rg小桓 已获得聆听专属T恤衫 复制链接去分享

1.docker的方便我觉得是敏捷交付以及持续集成,在对集群宿主机的资源利用上比虚拟主机方便一些,譬如容器迁移比vm迁移方便,我想问一下容器对于资源利用比直接跑在vm上是不是要好一些。
2.假如我的应用是基于tomcat的,挂载volume是用宿主机的磁盘好一些还是用nas,发布新版本(譬如更换war包)有什么好的方法,是我手动去替换volume里边的war包还是触发自动构建重新起一个tomcat容器,如果我只是想替换tomcat应用容器中的某些jsp文件呢
3.用阿云的容器服务的时候,集群默认会有etcd容器还是需要自己起一个
4.容器的监控是用阿云的监控即可还是需要自己另寻他路,譬如用谷歌的cadvisor等
期望解答

太公 回复

更细粒度的资源管理可以提高资源利用率,从物理机到虚拟机再到容器,资源的粒度在不断细化。一台VM上启动多个容器能更充分的利用VM的资源,配合云服务和自动调度等手段,可以进一步提供资源利用率和降低资源成本。

docker推崇的做法是不可变基础架构,变更的是镜像而不是容器内的文件,所以每次发布,要用新的war包构建一个新镜像,再用新镜像启动应用。即使不说容器,在Java Web开发里也不建议在生产环境里热更新JSP,生产环境要求的是可靠和高性能,替换jsp这种方式只能用在开发测试环境。

容器服务有etcd服务,但主要用于docker daemon以及容器服务自身的agent,如果是您自己的业务上用到etcd,可以自己起一个。

监控方面,容器服务默认就支持了。您可以在控制台页面上查看每个容器的实时监控信息,这些数据也会自动同步到云监控,不需要额外配置。另外如果您自己有监控系统,也可以通过配置把所有的监控数据发送到您的监控系统里。可以参考监控的文档:https://help.aliyun.com/document_detail/32471.html?spm=5176.product25972.6.172.6KGKjv

rg小桓 回复

嗯,好的,谢谢戒空师傅的解答,java web热替换jsp文件或者class文件您觉得是会有风险的么,我们下一个项目准备上容器服务了,您的意思是只要发布一次新的变更,最好是重新生成新的镜像么,用新的war包生成镜像,是不是在dockerfile里面用add或者copy指令把war包路径添加到镜像里边么

太公 回复

倒不是说热替换这种方式不好,在开发测试环境可以提高效率,改了代码马上就能看到效果。但是在生产环境,需要的更多是稳定可靠,在生产环境用替换的方式,一方面不便于自动化,我见过的自动部署系统都是部署完整的应用。另一方面,很容易出现只替换了部分文件的情形,而且很难排查哪些文件是新的,哪些是老的。最后,tomcat/jetty这些服服务器在开启热部署功能之后会有性能下降,毕竟需要不断的扫描系统上文件的变化。

所以每次变更都应该是变更整个应用,用docker的话,就是一个完整的新的镜像。dockerfile用add或者copy把war放进去。关于做镜像的一些最佳实践可以参考上面的一个问题。

评论
1

混合左右拳 已获得淘公仔 复制链接去分享

有没有镜像制作的最佳实践可以参考?

火蓝云 回复

简单的说,镜像制作遵循下面几条原则

  1. 选择合适的基础镜像,ubuntu, centos工具丰富,很多人也比较熟悉,但是制作的镜像较大。如果要精简镜像体积,可以使用busyboxy、alpine作为基础镜像。
  2. 分离应用构建和镜像制作。先构建出应用的二进制文件,再制作镜像,不要再Dockerfile里直接构建应用。
  3. 适当的声明Env、Volume
太公 回复

赞楼上,我补充几点

  1. 使用Dockerfile制作镜像,不要用docker commit
  2. Dockerfile放在一个专门的目录里,其中只包含制作镜像所需的文件(如果分离构建和镜像制作,这里只放构建后的包,不要放源码)。
  3. 必要的时候可以使用.dockerignore
  4. 减少层数量,Dockerfile里用RUN的时候,一个RUN后面跟多个命令,命令之间用&&分割
  5. 经常变化的内容放在Dockerfile的后面,前面不变的部分可以直接用Cache,降低Build镜像的时间。
麦垛 回复

在dockerfile中减少执行的构建指令可以减少镜像的层数。
对于已经构建好的镜像则可以通过docker save/load的方式将镜像多层压缩至一层。

评论
2

hyper_x 已获得聆听专属T恤衫 复制链接去分享

如何平滑迁移到docker
合适的容器调度管理平台
多主机跨容器通信及性能问题
容器的监控及故障迁移恢复

太公 回复

迁移docker的时候,建议“慢慢来”,先把一些边缘的、无状态的应用放在容器里运行,核心服务先不动,稳定之后再逐渐开始迁移重要应用。迁移过程中,可能会涉及到对应用访问模式的改造,在条件允许的情况下,比如业务压力不是这么大,可以做一些改造。比如两个应用原来是部署在一台机器上,通过unix domain socket通信,切换到Docker之后,推荐每个容器只跑一个应用,但是在过渡期,做一个大镜像,里面放两个应用也不是不可以。

容器管理方面,目前主要三个方面:k8s, swarm和mesos,很难说哪个更好,您可以都尝试下。阿里云的容器服务采用的是swarm的模式,集成了阿里云的一些基础服务:日志、监控、存储等,在调度等方面做了很多优化,你也可以使用看看。

容器跨主机通信,docker本身提供了overlay network,也有一些开源的软件Flannel calico,按照底层网络模式分,overlay flannel weave等是vxlan的方式,需要对packet封装和解封,性能上差一些,calico使用BGP协议直接路由,但是对底层的网络模型要求较高。容器服务提供了针对阿里云的VPC的Docker插件,容器之间的数据包不需要封装操作,性能几乎和VPC内两台ecs通信性能一样。

故障迁移和恢复,这个在容器服务中是原生支持的。监控方面可以参考下我们的帮助文档 https://help.aliyun.com/document_detail/32471.html?spm=5176.product25972.6.172.6KGKjv

评论
1

1277376506016181 已获得优酷VIP季卡 复制链接去分享

个人理解:具体到Docker技术在测试领域的应用,可以体现在:

1)快速搭建兼容性测试环境

从Docker的镜像与容器技术特点可以预见,当被测应用要求在各类Web服务器、中间件、数据库的组合环境中得到充分验证时,可以快速地利用基础Docker镜像创建各类容器,装载相应的技术组件并快速启动运行,测试人员省去了大量花在测试环境搭建上的时间。

2)快速搭建复杂分布式测试环境

Docker的轻量虚拟化特点决定了它可以在一台机器上(甚至是测试人员的一台笔记本电脑上)轻松搭建出成百上千个分布式节点的容器环境,从而模拟以前需要耗费大量时间和机器资源才能搭建出来的分布式复杂测试环境。

3)持续集成

Docker可以快速创建和撤销容器,在持续集成的环境中,可以频繁和快速地进行部署和验证工作。

太公 回复

👍这个理解很到位,很多公司就是这样在测试环境中使用Docker的。

评论
1

西秦说云 复制链接去分享

在Docker部署下,你认为docker swarm mesos 和 k8s 选哪个会好点?

太公 回复

很难说哪个更好,各有特点。但是在生产环境直接使用,还是有不少事情要做的,怎么利用oss nas实现存储卷功能,怎么收集日志,监控数据要怎么采集、存储和展示,这些都是实践中会遇到的问题。

云衣裳 回复
回复@太公:

请问阿里容器有没有集成K8s的计划?K8s被OpenStack采纳,俨然已是业界标准,阿里应该有所动作吧?

太公 回复

我们正在开发一些工具,帮用户更方便的在阿里云上部署k8s,同时也会提供一些k8s和阿里云基础服务(日志、监控等)的集成,敬请期待

评论
1

huolanyun 复制链接去分享

应用怎么访问依赖的另外一个应用?

火蓝云 回复

最简单的方式是两个应用在同一个compose文件里,直接用links就可以了。如果不在一个compose文件里,用external link也是可以的。

太公 回复

首先要确定网络结构。在容器服务里,如果没指定用host模式启动容器,那么容器有一个独立的ip地址,通过这个ip地址可以访问容器内的服务。如果应用有多个实例,就要考虑采用负载均衡的方式,把请求分散到后端的多个实例上。

应用之间的服务发现和互访,可以从这个文档开始了解 https://help.aliyun.com/document_detail/44517.html

除了文档所列举的方式外,还可以考虑使用专门的注册/发现服务,比如eureka

评论
1

sakuragi 复制链接去分享

一个vm中部署多个容器,占用的ip是否相同,port是否可以共用?
编排模板是否可以嵌套?
soa架构中的编排最佳实践有吗?

太公 回复
    1. 不同的网络模型不一样,简单来说,同一个VM上多个容器的IP“可以”不相同,这是默认的行为,每个容器都有自己的网络栈,一个容器监听了端口,对其他容器没有影响。
    1. 目前还不支持嵌套
  1. 3.《微服务架构》这本书还不错,可以参考。
sakuragi 回复
回复@太公:

thx!

评论
1

贺贺呵呵 复制链接去分享

大家好,我是个大四学生,对这方面比较感兴趣,想问一下,选择迁移微服务需要做什么样的准备,一般生产环境下一台宿主机能跑多少容器,容器的安全性到底如何。

太公 回复

Docker本身占用的资源很少,你可以把这个问题理解成:一台机器能跑多少进程。显然跟机器规格和每个进程本身占用的资源有关。

安全上,Docker提供了容器级别的隔离机制,相对于Hypervisor会弱一些,但是比直接运行在宿主机上要安全的多。所以如果你的程序原来运行在宿主机上,改成运行在容器里,安全性是增强的。

评论
1

好的顶顶顶 复制链接去分享

docker 和微服务如何结合?

太公 回复

Docker和微服务可谓天生一对。容器服务提供了对大量微服务部署和运维的的支撑,微服务提供了一种更适合在容器服务里运行的架构模式。阿里云容器服务针对微服务架构提供了很多功能:各种方式的服务发现、复杂均衡、routing等。您可以了解下。

评论
0

韩国人 复制链接去分享

什么样的应用或者说用业务场景适合迁移到docker?

太公 回复

https://oss.aliyuncs.com/yqfiles/5c0b0fcc425d9e9718bd56c776bef798fa99c714.png
这张图里给了一个简单的分类方式,按照生命周期和状态两个维度进行分类。除了数据库这种有状态长生命周期的应用,其他类型都可以放在容器服务里。容器服务最大的价值在于自动部署、自动运维(应用恢复,自动迁移,自动伸缩等),在这个场景里,应用必须具备能动态发现,不强依赖本地状态,迁移过程不影响服务等特性,具备这些特性的应用都适合运行在容器服务里。

dreamsong 回复

悄悄的看各位大神的发言

评论
1

游讯 复制链接去分享

Docker的前生今世与未来,时间精力有限是否要全部压注Docker,对于一个网络开发的小白来说,开始很难也很重要!

太公 回复

很多企业开始使用Docker,可以预见将来越来越多的场景会使用Docker。全部押注这个词太重了,如果实际工作中能用到Docker,学学也没有坏处。

评论
1

lu9523 复制链接去分享

如何才能更好的实现资源的隔离和管控,譬如不同的container之间抢夺cpu,抢夺io,甚至写满磁盘导致其他container全挂掉,有什么需要特别注意的地方?

太公 回复

在Linux系统上,Docker的资源用的是Linux的CGroup机制,我们可以设置每个group的cpu配额,io配额等等,有些重要的应用,多分配点,不那么重要的,少分配点。或者更彻底的方式:不同的group绑定到不同的cpu core上,例如你系统是4core的,第一个应用绑定到core0和core1,第二个应用绑定core2,第三个应用和其他应用共享core3,这都是可以的。

lu9523 回复
回复@太公:

谢谢,受教了,感觉docker这个玩意儿,上手很容易,想要掌握比较难,最简单的地方的是他很容易就可以跑起来,最难的地方也是怎么让他又快又容易而且不出问题的跑起来,感觉资源编排这玩意才是的核心和最有价值的东西,哎,现在也只有在自己的机器上玩玩,但是把这个用到公司的生产环境上去还不太现实,有太多问题有待解决了,首先迁移现有的应用到docker就是一个让人绝望的事,看来也只能游说老板能不能批准把新上线的东西扔docker里,比较一下效果。。。。

评论
1

HDD 复制链接去分享

docker技术确实是一个很新的技术,但是它使得开发和实施或者是部署,没有任何差别,但是假如果说,当利用docker做好了一个镜像之后,又对原来的一些内容做了一些修改,无论是环境或者项目相关,又必须重新再镜像一次,这样会不会有点麻烦,所以,有没有一种方法,或是技术,就像git一样,直接可以检测不同,然后进行一个增量的更新或者修改~

太公 回复

Docker的镜像是分层的,重新构建镜像时,如果底层内容在Dockerfile没有变化,Docker可以直接使用已经存在的层,不需要重复构建。利用这个特性,我们可以把稳定的内容放在Dockerfile前面,变化的内容放在后面。这样可以减少每次构建镜像的时间。这也算是一种增量构建的方式。

评论
1

bluenochange 复制链接去分享

一些大数据平台例如hadoop,hbase等是否适合容器话管理?
是否应该保证一个容器一个应用?但如果容器内部支持ssh又违反了这点,不支持又太不方便。

太公 回复

hadoop能不能用Docker?答案是肯定可以的,Hadoop现在就支持用Docker的方式执行Job。这里主要是把Docker当成一个执行环境。

一个容器内尽量单个应用,如果用登录到容器里操作,用docker exec container sh就好了,没必要安装ssh

评论
1

1939681048751431 复制链接去分享

问题:阿里云服务器上可以装多个docker吗,怎么管理多个docker?

太公 回复

容器服务的每个集群包含多台VM,每台VM上运行一个Docker Daemon。Docker Daemon负责管理机器上运行的多个Docker容器。也就是说,每台机器上天生就是可以启动多个Docker容器的。

评论
1

纯郁e817 复制链接去分享

请问我们可以采取什么样的预防措施,来规避今后不慎(或不得不)升级Docker主程序版本后所产生的可能的后向兼容(运维/侦错脚本无法使用)甚至容器内资料丢失的风险?

太公 回复

容器服务本身提供了自动升级Docker版本的功能,每个版本都是在经过多轮测试之后才推出。由于Docker本身的原因,现在升级过程中,机器上所有的容器会重启,所以升级操作需要您自己选择合适的时间升级,升级过程也是一台升级成功才继续升级下一台。

对于重要的需要持久化的数据,不要放在容器里,通过挂载宿主机目录或者容器服务的数据卷功能,把数据存储在分布式存储上。

评论
1

asdasdaq123123 复制链接去分享

docker宿主机的快速扩展

太公 回复

容器服务支持宿主机的自动扩容(测试版),不过和容器的扩容速度比起来,宿主机启动+配置完成的时间会慢上不少。对于能预料到的流量高峰,可以提前准备好宿主机。

评论
0

lihe嘿嘿 复制链接去分享

在进行docker部署的过程中遇到最大的问题时多主机网络互连的问题,虽然在最新的版本1.12中集成了swarm集群的overlay网络,但是测试过程中感觉不太稳定,会出现网络连接不上,节点僵死的情况,不得不初始化节点。如果不使用docker service集群的方式的话,docker run的方式又需要额外搭建overlay网络,比较麻烦。

太公 回复

swarmkit毕竟刚推出不久,还需要时间成熟,现阶段不建议用在生产环境里。

肖俊charles 回复

看看学学

评论
1

方糖科技 复制链接去分享

一个应用里能接入几个网站,我试了很多次都无法存放很多网站 volume 是永久储存的

太公 回复

容器服务内置了一个routing服务,所有的请求通过routing转发给后端的网站。理论上支持的网站数量无上限,但实际上会受限与集群内机器的数量以及网站的负载情况。

评论
1

西秦说云 复制链接去分享

如何把现行的soa架构的应用迁移到docker容器呢?

太公 回复

这个话题比较大,只能给一些参考,还是要根据具体的场景采用合适的办法。

总的来说有这样几个大的原则

  1. 首先要看哪些应用运行在容器服务里,通常一些无状态的web应用和服务都比较适合放在容器服务里运行。
  2. 尽可能不需改应用,先Docker化,用Docker的方式跑起来,以降低迁移的风险。
  3. 先边缘应用,再核心应用。

具体操作的时候,可以先在容器服务起一个测试环境,这个环境可以包括所有的业务系统,确认没有问题之后再迁移。

评论
3