对于不同的团队,生产环境意味着不同的东西。在本书中,我们所说的生产环境是指真实客户用于运行代码的环境。这是相对于开发环境、预演环境及测试环境而言的,后者的停机时间不会被客户感知到。
在生产环境中,Docker有时是用于接收公共网络流量的容器,有时则是用于处理来自队列负荷的异步的后台作业。不管哪种用途,在生产环境中运行Docker与在其他环境中运行相比,最主要的差异都是需要在其安全性与稳定性上投入较多的注意力。
编写本书的动力之一是,与Docker相关的文档和博客文章中缺乏对实际生产环境与其他环境的明确区分。我们认为,80%的Docker博客文章中的建议在尝试在生产环境中运行6个月之后会被放弃(或至少修改)。为什么?因为大多数博客文章中举的都是理想化的例子,使用了最新、最好用的工具,一旦某个极端的情况变成了致命缺陷,这些工具将被遗弃(或延期),被更简单的方法所取代。这是Docker技术生态系统现状的一个反映,而非技术博客的缺陷。
总的来说,生产环境很难管理。Docker简化了从开发到生产的工作流程,但同时增加了安全和编排的复杂度(更多关于编排的内容参见第4章)。
为了节省时间,下面给出本书的重点综述。
所有在生产环境中运行Docker的团队,都会在传统的安全最佳实践上做出一项或多项妥协。如果无法完全信任容器内运行的代码,那么就只得选用容器与虚拟机一对一的拓扑方式。对于很多团队而言,在生产环境中运行Docker的优势远远大于其带来的安全与编排问题。如果遇到工具方面的问题,请等待一到两个月,以便Docker社区对其进行修复,不要浪费时间去修补其他人的工具。保持Docker设置最小化。让一切自动化。最后,对成熟的编排工具(如Mesos、Kubernates等)的需求远比想象的要少得多。
### 功能内置与组合工具
Docker社区一个常见的口头禅是“电池内置但可移除”,指的是将很多功能捆绑在一起的单体二进制文件,这有别于传统Unix哲学下相对较小、功能单一、管道化的二进制文件。
这种单体式的做法是由两个主要因素决定的:(1)使Docker易于开箱即用;(2)Golang缺少动态链接。Docker及多数相关工具都是用Google的[Go编程语言](https://golang.org/)编写的,该语言可以简化高并发代码的编写与部署。虽然Go是一门出色的编程语言,但用它来构建的Docker生态系统中也因此迟迟无法实现一个可插拔的架构,在这种架构中可以很容易用替代品对工具进行更换。
如果读者有Unix系统背景,最好是编译自己的精简版Docker守护进程,以符合生产环境的需求。如果读者有开发背景,预计到2015年下半年,Docker插件将成为现实[\[1\]](#anchor001)。在此期间,估计Docker生态系统中的工具将会出现明显的重叠现象,某些情况下甚至是相互排斥的。
换句话说,要让Docker运行于生产环境中,用户的一半工作将是决定哪些工具对自己的技术栈最有意义。与DevOps所有事情一样,先从最简单的解决方案入手,然后在必要时增加其复杂性。
2015年5月,Docker公司发布了[Compose](https://docs.docker.com/compose/)、[Machine](https://docs.docker.com/machine/)及[Swarm](https://docs.docker.com/swarm/),与Docker生态系统内的同类工具进行竞争。所有这些工具都是可选的,请根据实际情况对其进行评估,而不要认为Docker公司提供的工具就一定是最佳解决方案。
探索Docker生态系统时的另一项关键建议是:评估每个开源工具的资金来源及其商业目标。目前,Docker公司和CoreOS经常发布工具,以争夺关注度和市场份额。一个新工具发布后,最好等上几个月,看看社区的反应,不要因为它看起来很酷就切换到最新、最好用的工具上。
- - - - - -
[[1]](#ac001) Docker 1.7版中正式引入了插件系统。——译者注
- 版权信息
- 版权声明
- 内容提要
- 对本书的赞誉
- 译者介绍
- 前言
- 本书面向的读者
- 谁真的在生产环境中使用Docker
- 为什么使用Docker
- 我们所说的“生产环境”
- 哪些东西不要Docker化
- 技术审稿人
- 第1章 入门
- 1.1 术语
- 1.2 从开发环境到生产环境
- 1.3 使用Docker的多种方式
- 1.4 可预期的情况
- 第2章 技术栈
- 2.1 构建系统
- 2.2 镜像仓库
- 2.3 宿主机管理
- 2.4 配置管理
- 2.5 部署
- 2.6 编排
- 第3章 示例:极简环境
- 3.1 保持各部分的简单
- 3.2 保持流程的简单
- 3.3 系统细节
- 3.4 集群范围的配置、通用配置及本地配置
- 3.5 部署服务
- 3.6 支撑服务
- 3.7 讨论
- 3.8 未来
- 3.9 小结
- 第4章 示例:Web环境
- 4.1 编排
- 4.2 连网
- 4.3 数据存储
- 4.4 日志
- 4.5 监控
- 4.6 无须担心新依赖
- 4.7 零停机时间
- 4.8 服务回滚
- 4.9 小结
- 第5章 示例:Beanstalk环境
- 5.1 构建容器的过程
- 5.2 日志
- 5.3 监控
- 5.4 安全
- 5.5 小结
- 第6章 安全
- 6.1 威胁模型
- 6.2 容器与安全性
- 6.3 内核更新
- 6.4 容器更新
- 6.5 suid及guid二进制文件
- 6.6 容器内的root
- 6.7 权能
- 6.8 seccomp
- 6.9 内核安全框架
- 6.10 资源限制及cgroup
- 6.11 ulimit
- 6.12 用户命名空间
- 6.13 镜像验证
- 6.14 安全地运行Docker守护进程
- 6.15 监控
- 6.16 设备
- 6.17 挂载点
- 6.18 ssh
- 6.19 私钥分发
- 6.20 位置
- 第7章 构建镜像
- 7.1 此镜像非彼镜像
- 7.2 镜像构建基本原理
- 7.3 小结
- 第8章 存储Docker镜像
- 8.1 启动并运行存储的Docker镜像
- 8.2 自动化构建
- 8.3 私有仓库
- 8.4 私有registry的扩展
- 8.5 维护
- 8.6 对私有仓库进行加固
- 8.7 保存/载入
- 8.8 最大限度地减小镜像体积
- 8.9 其他镜像仓库方案
- 第9章 CI/CD
- 9.1 让所有人都进行镜像构建与推送
- 9.2 在一个构建系统中构建所有镜像
- 9.3 不要使用或禁止使用非标准做法
- 9.4 使用标准基础镜像
- 9.5 使用Docker进行集成测试
- 9.6 小结
- 第10章 配置管理
- 10.1 配置管理与容器
- 10.2 面向容器的配置管理
- 10.3 小结
- 第11章 Docker存储引擎
- 11.1 AUFS
- 11.2 DeviceMapper
- 11.3 BTRFS
- 11.4 OverlayFS
- 11.5 VFS
- 11.6 小结
- 第12章 Docker 网络实现
- 12.1 网络基础知识
- 12.2 IP地址的分配
- 12.3 域名解析
- 12.4 服务发现
- 12.5 Docker高级网络
- 12.6 IPv6
- 12.7 小结
- 第13章 调度
- 13.1 什么是调度
- 13.2 调度策略
- 13.3 Mesos
- 13.4 Kubernetes
- 13.5 OpenShift
- 第14章 服务发现
- 14.1 DNS服务发现
- 14.2 Zookeeper
- 14.3 基于Zookeeper的服务发现
- 14.4 etcd
- 14.5 consul
- 14.6 Eureka
- 14.7 Smartstack
- 14.8 nsqlookupd
- 14.9 小结
- 第15章 日志和监控
- 15.1 日志
- 15.2 监控
- 15.3 小结
- DockOne社区简介
- 看完了