Docker的一些思考和实践

前言

2016年的时候,我所在的部门立了一个使用docker实现运维自动化的项目,项目负责人正是我的导师。于是,在导师的带领下,我开始玩docker了。本文主要记录一下当时玩docker的一些心得体会,希望能给大家带来一点启发。😄

被分派任务

对于docker是一个什么东西以及怎么上手,不是本文的重点,详细可以参考这个链接。我当时的任务是构建镜像以及打通代码从svn到镜像里的整个流程。这里面最为复杂的就是构建自定义镜像了。网上大多的做法是直接从公有仓库下载,但是我们发现下载的镜像都挺大,还包含了一些我们不想要的东西。并且如果直接使用,带宽和时间的成本都不低。于是,导师安排我研究自定义镜像。

构建定制化镜像

这里简述一下构建这些定制化镜像的步骤。

  • 首先是准备busybox,这是一个基础的镜像。
  • 编译安装需要的服务组件,找出组件所依赖的库文件。
  • 将前两步的文件打包,使用dockerfile构建镜像。

这里想详细说一下第二点,找出依赖的库文件,当时花了很长时间来研究这个。通过实践发现其实影响镜像大小的主要因素是两个lib目录的大小(/usr/lib64 & /usr/lib)。所以只要严格控制lib目录,镜像的大小就能得到很好的控制。通过使用ldd不断调试,我大致找出了正常运行一些常用的服务组件所需要的库文件的最小子集,做成了excel表分享给大家。(稍后提供github地址)
经过一番折腾后,最终所做出来的镜像大小约等于每个中间件编译后的大小。(比如nginx编译后是6m左右,那么做出来的nginx镜像不会超过10m,其实就是看库文件的大小)
另外,由于当时使用了ceph共享文件系统收集容器的日志,所以还花了不少时间将ceph的客户端都打进了每个镜像里面,方便挂载并输出各种日志。

自定义运行动作

对于某些中间件我们还需要定义一些容器启动后的动作。一般的动作就是在dockerfile里面的ENTRYPOINT写好一条启动命令即可。这里我想记录的是当时我们大规模使用的web容器resin镜像的构建过程。我定义resin镜像的ENTRYPOINT是一个脚本,这个脚本大概做了如下的工作:

  • 创建程序运行的用户
  • 替换resin配置
  • 从cmdb获取数据库配置信息以及ceph挂载信息
  • 将代码放到合适位置
  • 创建log目录并启动resin

总的来说,就是一系列根据实际情况的初始化工作。

一点感悟

从认识docker到自定义镜像,到根据需求自定义初始化容器脚本,虽然过程比较艰苦,但是成功之后还是其乐无穷的。😄 同时深刻体会到根据实际工作情况进行自我创造是一件非常有趣的事情。

Github: thinking-docker

您的支持将鼓励我继续创作!
0%