Docker已经成熟,并且正在从主要使用在构建/测试阶段扩展到生产开发。同样的,微服务正在从主要使用在green field web服务扩展到在企业内使用——作为组织分解他们庞大的应用,支持更快的发布周期的探索方式。
作为组织努力扩展他们的应用开发和发布,实现持续交付,虽然有挑战性,但是微服务和容器越来越多的被企业考虑。虽然这两者都会带来好处,但是他们并不是“一刀切”,并且我们看到企业为了他们特定的用例和环境仍然通过这些技术和设计模式进行试验。
为什么用Microservices?为什么用容器?
微服务是一个吸引人的DevOps模式,因为它可以实现快速推向市场。随着每个微服务被开发、部署和独立运行(通常使用不同语言、技术堆栈和工具),微服务允许组织“分而治之”,并且更有效率的扩展团队和应用。当管道不受限于整体的配置,任一工具箱,组件依赖关系,发布进程,或者基础设施——有独特的能力来改善扩展开发和操作。为了优化资源利用率,它还帮助组织更简单的决定什么服务不需要扩展。
容器提供一个良好的明确的、隔离的运行时环境。代替人工发布和所有的变量,容器支持将所有东西打包到一个Docker-type文件中,通过管道提升为一致的环境中的一个单独容器。除了隔离和一致的环境,容器运行一个容器进程开销也非常低。这支持了环境的一致性从开发到生产,和极快的准备,适应调整,与扩展,加速和简化了开发与操作。
为什么在容器中运行微服务?
在容器化的环境中运行基于微服务的应用很有意义。Docker和微服务是天然的伙伴,形成现代应用交付的基础。
在一个较高的水平,微服务和Docker一起是DevOps的PB&J是因为:
- 它们的目的都在于把一件事做好,并且都是免费的。
- 你需要学会把擅长的转化到另一个上。
更具体的说:
目标
微服务(通常)是一个单独的进程,集中于应用的一个方面,尽可能在隔离环境中操作。
Docker容器在一个边界清晰的环境中运行一个单独的进程。
复杂性
通过微服务,你现在需要知道部署,协调,和运行多重服务(几十到几百个),然而在这之前你可能有一个更为传统的三层/整体架构。当微服务支持敏捷开发——特别是在开发方面——他们会遇到许多技术挑战,主要是在操作方面。
容器对这些复杂性有帮助,因为容器可以使它们变得简单并且在容器中快速部署服务,这主要对于开发人员来说。
扩展
微服务让扩展变得更为简便,因为每个服务可以独立于其他服务进行扩展。
原生容器集群编排工具,例如Kubernetes,和云环境,例如Amazon ECS和Google Container Engine(GKE),提供容易的扩展容器机制,基于加载和业务规则。
系统理解
微服务和容器本质上都促使你更好的理解系统——如果你不能彻底的理解你的架构、拓扑、功能、操作和性能,你不会在这些技术上取得成功。
挑战
管理微服务和大规模Docker部署,给IT企业造成了独特的挑战。因为非常多的重叠部分,为了成功部署和更改微服务和容器,组织必须熟练运用,在挑战和实施容器最佳实践和微服务扩展的方面有相当多的重复。
- 增加管道变化。随着更多的迁移部分,操作交付管道变得更为复杂。当你分离一个整体,变成若干个微服务,管道的数量也许会从1跳到50(或者然而你已经建立很多微服务)。你需要考虑将来需要多少不同的团队,是否有足够的人员来支持每个微服务/管道。
- 测试变得更复杂。有大量的测试需要考虑——集成测试,API契约测试,静态分析等等。
- 增加部署复杂性。当扩展容器化的应用相当简单的时候,有许多活动需要先设置。在发布到生产环境之前,必须多次部署开发和测试,贯穿管道。如此多的不同的服务独立开发,部署量急剧增加。
- 监控、日志和修复变得非常重要并且日益困难,因为有更多的迁移部分和不同的分布式服务,包含整体的用户体验和应用性能。
- 有许多不同的工具链、架构和环境需要管理。
- 需要考虑到目前的应用程序,并且如何协调这些新服务和容器功能–或者基于微服务的应用。
- 随着如此大量的分布式环境,和组织需要同时支持容器和微服务,与传统的发布和整体的应用程序,管理和审计(特别是在企业层面)变的更为复杂。
除了这些常见的挑战,微服务和容器还有它们自己独有的挑战。如果你正在考虑微服务,最好知道下面这些:
- 分布式系统是困难的,并要求很强大的系统理解。
- 服务组装是一个棘手的问题,而且改变很昂贵。以整体作为开始,避免过早分解,直到你彻底理解应用行为。需要描述进程间失效模式,虽然抽象在纸上看着不错,但是易于遇到瓶颈。
- 注意事物边界和外键关系,它们将会很难分解。
- 考虑基于事件的技术,来减少进一步的耦合。
- 为了API和服务SLA:“自己保守的做,宽大的接受别人所做的。”
- 状态管理是难处理的,缓存和其他有趣的事……
- 测试(特别是在服务间的集成测试)和监控(因为服务数量的增长)变得更为复杂。
- 服务虚拟化,服务发现,和API集成点的合理设计和反向兼容是必不可少的。
- 故障排除失败:“每次断电都是一起神秘谋杀。”
- 即便一个服务很小,部署路径仍然要考虑到。
- 一切你都要依靠互联网——需要考虑宽带,延迟和可靠性。
- 当前应用该怎么处理:重写?忽略?还是混合?
容器挑战
安全是一个关键的挑战——因为它还是一个相对较新的技术,由于关注安全问题,因此下载一个镜像。对OpSes来讲容器是一个黑匣子:更少的控制,容器内更少的可见性,和现有的工具无法理解容器。一定要签署和扫描镜像,验证库等;加强容器环境;早点放弃权限分配,并且使用细粒度的访问控制,因此它不是所有的root。了解认证信息(容器服务可以帮你)。
监控是很棘手的,因为容器实例可能连续下降或者span-up。需要考虑用记录和监控来解除失效的容器或者保存日志和业务数据,定位数据,合规数据,日志,来自其他(时间)实例的diagnostics-from。
知道在哪运行,并且为什么运行,避免镜像臃肿和容器蔓延。
由于容器托管和集群编排市场仍然是新兴市场,我们看到用户尝试很多跨环境运行容器,或者使用不同的集群编排工具和APIs。这些早期的采用者需要管理容器,在锁定特定的云厂商或point-tool时最小化风险,或者在重写复杂的脚本上投入更大的工作量(并且学习路线曲折),为了重新决定他们的部署和发布进程,一个新容器环境或者工具。
微服务和容器的最佳实践
然而,公认的,当谈到部署微服务和容器会有相当多的挑战,最终结果将是减少管理成本并更快的投入市场。如果微服务和容器对你的应用程序用例很有意义,有大量的计划需要在把应用分解成成上百组不同的服务前实现,或是迁移你的数据中心到一个容器环境。没有精细的计划和紧跟产业最佳实践,很容易失去微服务和容器带来的优势。
为了成功的运行微服务和大规模容器,有一些技能,组织需要在整个软件交付周期中运用:
- 建立相关领域知识。部署微服务之前理解相关领域是至关重要的,在做困难决定前,在哪把问题分割到不同的服务中去的。先保持一个整体。保持模块化和优质代码。
- 每个服务需要独立CI和部署管道,所以你可以独立的创建,验证和部署每个服务,无需考虑其他服务的交付状态。
- 管道自动化:票务系统没有自动化。随着大量增加的管道和管道复杂性,你必须会编排端到端的进程,包括所有的point-tools,环境,和配置。需要自动全部的进程——从CI,测试,配置,基础设施配置,开发,应用发布进程,和生产反馈循环。
- 测试自动化:如果不首先建立自动化测试,微服务和容器将变成噩梦。一个自动化测试框架将会检查在管道最终所有准备好的一切,并且增加生产团队的信心。
- 为容器使用企业注册表。知道数据在哪储存并且重视安全,通过在软件管道中增加模块化安全工具。
- 知道什么在运行,在哪和为什么。理解平台限制,避免镜像臃肿。
- 管道必须与工具/环境无关的,因此可以支持每个工作流和工具链,无论他们是什么,你可以方便的在服务和容器环境之间转移。
- 一致的日志和监控贯穿所有的服务,规定循环反馈到管道。确保管道自动化插入到监控以便警报触发自动进程,例如回滚一个服务,在蓝/绿部署间调动,扩展等等。监控/性能测试工具需要允许追踪一个请求,穿过系统,即使它在不同服务间弹跳。
- 处理失败要更加仔细(考虑使用Hystrix)。
- 为微服务灵活的配置人员和组织设计。考虑每个服务每个团队是否有足够的人员。
对微服务和容器兴趣不断增加,并且有很好的理由。无论如何,企业需要确保他们有技巧和知识来克服挑战,可靠的管理大规模技术。计划和软件交付模型是关键,运用正确的技术和工具,微服务和容器就可以实现更快的发布和减少开销。
更多DevOps精华内容
关于实现明确的代码需求,持续交付反面模式,微服务和容器的最佳实践的更多的思考,让你免费的新DZone DevOps指南!(52页的免费ebook:https://dzone.com/guides/devops-continuous-delivery-and-automation)