赞
踩
设计并运行一个兼顾可扩展性、可移植性和健壮性的应用是一件很有挑战的事情,尤其是当系统复杂度在不断增长时。应用或系统本身的架构极大的影响着其运行方式、对环境的依赖性,以及与相关组件的耦合强弱。当应用在一个高度分布式的环境中运行时,如果能在设计阶段遵循特定模式,在运维阶段恪守特定实践,就可以帮助我们更好的应对那些最常出现的问题。
当开发软件时,你所选用的模式与架构会被很多需求所影响。对于 Kubernetes 来说,它最重要的特征之一就是要求应用拥有水平扩展能力——通过调整应用副本数来分担负载以及提升可用性。这与垂直扩展不同,垂直扩展尝试使用同样的参数将应用部署到性能更强或更弱的服务器上。
基准代码(Codebase):将你的所有代码都放在版本控制系统中(比如 Git 或者 Mercurial)。被部署的内容完全由基准代码决定。
依赖(Dependencies):应用依赖应该由基准代码全部显式管理起来,无论是用 vendor(指依赖代码和应用代码保存在一起),还是通过可由包管理软件解析安装的依赖配置文件的方式。
配置(Config):把应用配置参数与应用本身分开来,配置应该在部署环境中定义,而不是被嵌入到应用本身。
后端服务(Backing Services):本地或远程的依赖服务都应该被抽象为可通过网络访问的资源,连接细节应该在配置中定义。
构建、发布、运行(Build, release, run):应用的构建阶段应该完全与发布、运维阶段区分开来。构建阶段从应用源码创建出一个可执行包,发布阶段负责把可执行包和配置组合起来,然后在运行阶段执行这个发布版本。
进程(Processes):应用应该由不依赖任何本地状态存储的进程实现。状态应该被存储在第 4 个法则描述的后端服务中。
端口绑定(Port binding):应用应该原生绑定端口和监听连接。所有的路由和请求转发工作应该由外部处理。
并发(Concurrency):应用应该依赖于进程模型扩展。只需同时运行多份应用(可能分布在不同服务器上),就能实现不调整应用代码扩展的目的。
易处理(Disposability):进程应该可以被快速启动、优雅停止,而不产生任何严重的副作用。
开发环境与线上环境等价(Dev/prod parity):你的测试、预发布以及线上环境应该尽可能一致而且保持同步。环境间的差异有可能会导致兼容性问题和未经测试的配置突然出现。
日志(Logs):应用应该将日志输出到标准输出(stdout),然后由外部服务来决定最佳的处理方式。
管理进程(Admin processes):一次性管理进程应该和主进程代码一起发布,基于某个特定的发布版本运行。
Kubernetes 使用容器在集群节点上运行隔离的打包应用程序。要在 Kubernetes 上运行,你的应用必须被封装在一个或者多个容器镜像中,并使用 Docker 这样的容器运行时执行。尽管容器化你的组件是 Kubernetes 的要求之一,但其实这个过程也帮助强化了刚刚谈到的“12法则应用”里的很多准则,从而让我们可以简单的扩展和管理应用。
虽然你的应用必须被“容器”化后才能在 Kubernetes 上跑起来,但 pods(译注:因为 pod、service、ingress 这类资源名称不适合翻译为中文,此处及后面均使用英文原文) 才是 Kubernetes 能直接管理的最小抽象单位。pod 是由一个或更多紧密关联的容器组合在一起的 Kubernetes 对象。同一个 pod 里的所有容器共享同一生命周期且作为一个独立单位被管理。比如,这些容器总是被调度到同一个节点上、一起被启动或停止,同时共享 IP 和文件系统这类资源。
Sidecar(边车模式):在这个模式中,次要容器扩展和增强了主容器的核心功能。这个模式涉及在一个独立容器里执行非标准或工具功能。举例来说,某个转发日志或者监听配置值改动的容器可以扩展某个 pod 的功能,而不会改动它的主要关注点。
Ambassador(大使模式):Ambassador 模式使用一个支援性容器来为主容器完成远程资源的抽象。主容器直接连接到 Ambassador 容器,而 Ambassador 容器反过来连接到可能很复杂的外部资源池 - 比如说一个分布式 Redis 集群 - 并完成资源抽象。主容器可以完成连接外部服务,而不必知道或者关心它们实际的部署环境。
Adaptor(适配器模式):Adaptor 模式被用来翻译主容器的数据、协议或是所使用的接口,来与外部用户的期望标准对齐。Adaptor 容器也可以统一化中心服务的访问入口,即便它们服务的用户原本只支持互不兼容的接口规范。
尽管应用配置可以被一起打包进容器镜像里,但是让你的组件在运行时保持可被配置能更好支持多环境部署以及提供更多管理灵活性。为了管理运行时的配置参数,Kubernetes 提供了两个对象:ConfigMaps 与 Secrets。
Kubernetes 包含了非常多用来管理组件生命周期的开箱即用功能,它们可以确保你的应用始终保持健康和可用状态。不过,为了利用好这些特性,Kubernetes 必须要理解它应该如何监控和解释你的应用健康情况。为此,Kubernetes 允许你定义“就绪检测探针(Readiness Probe)”与“存活检测探针(Liveness Probe)”。
在早些时候讨论 Pod 设计基础时,我们提到其他 Kubernetes 对象会建立在 Pod 的基础上来提供更高级的功能。而 deployment 这个复合对象,可能是被定义和操作的最多次的 Kubernetes 对象。
Deployment 允许你配置和管理可互换的 Pod 集合,以扩展应用以及满足用户需求。但是,如何将请求流量路由到这些 pods 则是例外一码事了。鉴于 pods 会在滚动升级的过程中被换出、重启,或者因为机器故障发生转移,之前被分配给这个运行组的网络地址也会发生变化。Kubernetes services 通过维护动态 pods 资源池以及管理各基础设施层的访问权限,来帮助你管理这部分复杂性。
Kubernetes 在定义和管理部署到集群的资源方面提供了很大灵活性。使用 kubectl 这样的工具,你可以命令式的定义一次性资源并将其快速部署到集群中。虽然在学习 Kubernetes 阶段,这个方法对于快速部署资源可能很有用,但这种方式也存在很多缺点,不适合长周期的生产环境管理。
管理运行应用的基础设施,并学习如何最好的利用这些现代化编排系统提供的特性,这些事情可能会令人望而生畏。但是,只有当你的开发与运维过程与这些工具的构建概念一致时,Kubernetes 系统、容器技术提供的优势才能更好的体现出来。遵循 Kubernetes 最擅长的那些模式来架构你的系统,以及了解特定功能如何能缓解由高度复杂的部署带来的挑战,可以帮助改善你运行平台时的体验。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。