【51CTO.com原创稿件】本文讨论在多种云服务的模式下,成功部署和运行 Kubernetes 群集的关键操作难点与最佳实践。
根据 2018 年云计算状况报告显示:如今 81% 的企业都使用了多种云服务的模式,他们通过采用公有云服务、现代基础构造平台、以及公/私有云的持续混合,在快速、灵活地调整自身规模和容量的同时,能够更快地给客户提供价值。
实际上,根据 IDC 的最新数据, 2018 年第一季度,全球服务器出货量同比增加了 20.7%,高达 270 万台,整体收入则增长了 38.6% ,这是连续第三个季度达到两位数的增长。
另一个令人振奋的趋势是:容器的出现为应用组件的打包和管理提供了最佳的实现方式。Kubernetes 也已被广泛地接受为部署和操作容器化应用的最佳方案。而且,Kubernetes 的关键价值就在于它能够协助标准化多种云供应商所提供的服务功能。
当然,上述优势也带来了一定的复杂性。容器虽然解决了 DevOps 的相关问题,但同时也引入了一个新的、需要管理的抽象层。
由于 Kubernetes 本身就是一个需要管理的分布式应用,因此它只能解决运营上的部分问题,而非全部。
我们将在本文中讨论多种云服务的模式下,成功部署和运行 Kubernetes 群集的关键操作难点与最佳实践。
总的说来,我们所持的观点是:IT运营团队应当为多个内部其他团队构建出一套企业级的 Kubernetes 整体策略。
使用最佳的基础设施
与传统的内部基础设施供应商相同,所有云服务供应商都能够提供存储和网络等方面的服务。
在考虑多种云服务模式的策略时,我们值得注意的是:到底是使用各个供应商所提供的现有功能?或是要用到一个抽象层。
虽然这两种方法都可行,但是您应当谨慎地尽量最小化抽象层、且使用供应商自己提供的方案。
例如:不要在AWS中运行覆盖网络(overlay network,译者注:是一种面向应用层,而不必或减少考虑网络层与物理层的网络协议),而最好去使用 AWS 提供的 Kubernetes CNI (容器网络接口,Container Network Interface)插件,为 Kubernetes 提供原生的网络功能。
此方法还可以使用诸如安全组和 IAM (译者注:身份识别与访问管理,Identity and Access Management)等其他服务。
管理自己的Kubernetes版本
Kubernetes 是一个快速推进的项目,它每三月都有一个更新版本的发布。因此您需要决定的是:由供应商为您测试和管理 Kubernetes 的各个发布版本,还是希望允许自己的团队直接使用那些版本。
凡事都有利弊两面值得考虑。如果您使用供应商去管理 Kubernetes,那么他们会带来额外的测试和验证方面的帮助。
当然,云原生计算基金会(Cloud Native Computing Foundation,CNCF )的 Kubernetes 社区本身就具有成熟的开发、测试与发布流程。
Kubernetes 项目是由一个特殊兴趣小组(Special Interest Groups,SIGs)所管理, Release SIG (https://github.com/kubernetes/sig-release#mission)负责通过各种流程,来确保每个新版本的质量和稳定性。
CNCF还为各个供应商提供了 Kubernetes 软件一致性(https://www.cncf.io/certification/software-conformance/)计划,以证明他们的软件能与 Kubernetes 的各个 API 实现 100% 兼容。
对于企业内部而言,我们最好将稳定的版本使用到生产环境之中。但是,有些团队可能需要具有 pre-GA (译者注:pre-General Availability, 发布正式版本之前)功能的群集。
因此,最好的办法就是:让团队灵活地选择多种经过验证的 Upstream 版本,或者让他们根据需要去尝试新的版本,但是需要风险自担。
根据策略来规范群集的部署
安装 Kubernetes 群集时,我们需要做出如下重要的决定:
- 版本:要使用的 Kubernetes 组件版本。
- 网络:要使用的网络技术,通过 CNI (Container Networking Interface ,容器网络接口, https://github.com/containernetworking/cni)插件来配置。
- 存储:要使用的存储技术,通过 CSI (Container Storage Interface ,容器存储接口,https://github.com/container-storage-interface/spec)插件来配置。
- 入口:入口控制器(Ingress Controller)可被用于负载平衡器,以及将各种外部请求反向代理到您的不同应用服务上。
- 监控:可用于监控群集中 Kubernetes 组件和工作负载的加载项。
- 日志记录:一种集中式日志方案,可用于从群集的 Kubernetes 组件和应用负载中收集、聚合并转发日志到集中式日志记录系统中。
- 其他加载项:其他需要作为群集的一部分运行的服务,如 DNS 和安全组件。
虽然我们可以对每一次群集的安装执行上述决策,但是如果能将它们作为群集安装的模板或策略录入下来的话,对于我们之后的重用来说则会更为高效。
例如,我们可以用到 Terraform 脚本(https://www.terraform.io/docs/providers/kubernetes/index.html)或 Nirmata 集群策略(http://nirmata-documentation.readthedocs.io/en/latest/Clusters.html)。
一旦群集安装被予以自动化,它就可以作为高级工作流的一部分进行调用。例如:根据服务目录,执行自助服务的调配请求。
提供端对端的安全
对于容器和 Kubernetes 的安全性,我们需要考虑如下方面:
- 镜像扫描:在容器镜像运行之前,我们必须进行各种漏洞的扫描。因此,在允许镜像进入企业的专用存储表之前,该步骤可以作为持续交付(Continuous Delivery)管道的一部分予以实施。
- 镜像来源:除了对镜像进行漏洞扫描之外,我们还应当只允许那些“受信任”的镜像进入正在运行的群集环境之中。
- 主机与群集扫描:除了对镜像实施安全控制,我们也应对群集节点执行扫描。通过运用 CIS(Center for Internet Security)的各种安全基线( https://www.cisecurity.org/benchmark/kubernetes/),对 Kubernetes 进行例行安全加固就是一种最佳的实践。
- 分割与隔离:虽说多租户环境并非是硬性要求,但是通过在多个异构的工作负载之间共享群集,着实能够提高效率并节省成本。Kubernetes 为隔离(如:命名空间和网络策略)和管理资源的开销(如:资源配额)提供了相应的构造。
- 身份管理:在典型的企业部署中,用户标识由一个集中式目录所提供。因此,无论我们在何处部署群集,都应当通过联合用户标识的控制,以方便实现一致性的管控与应用。
- 访问控制:虽然 Kubernetes 并没有用户的概念,但是它对指定的角色和权限能够提供丰富的控制。群集可以用到各种默认的角色、以及指定了权限集的自定义角色。重要的是:同一个企业内部的所有群集都应当使用通用的角色定义,和跨集群的管理方法。
虽然上述每一项安全实践都可以被单独地使用,但是我们还是应该全面地审查和规划那些跨多种云供应商时的安全策略。
我们可以通过使用诸如 AquaSec、Twistlock 等安全解决方案,以及其他与 Nirmata、OpenShift 等平台相结合的措施来实现。
集中应用管理
与安全性相同,在 Kubernetes 的群集上管理各种应用也需要具有集中且一致性的方案。Kubernetes 提供了一整套可用于定义和操作不同应用程序的构造。
由于确实具有一些应用程序的内置理念,因此它能够灵活地支持不同的应用类型,并允许在 Kubernetes 上以不同的方式构建出不同的应用平台。
当然,Kubernetes 的应用管理平台也提供了一些通用的属性和功能。下面列举了对 Kubernetes 工作负载予以集中式应用管理所需要考虑的方面:
应用程序建模与定义
用户需要通过定义其应用的组件,从而在现有组件的基础上撰写出新的应用。用户可以通过 Kubernetes 的声明性,来定义系统的目标状态。
Kubernetes 的工作负载 API 提供了几种构造,来定义所需的资源状态。
例如:我们可以使用部署来建模出无状态的工作负载组件。这些定义通常被写成一组 YAML 或 JSON 的清单。当然,开发人员也可以运用诸如 Git 之类的版本控制系统(Version Control System,VCS)来组织和管理这些清单。
开发人员只需定义和管理应用清单中的一些部分,而其他部分则可以由运营团队来指定操作的策略和特定的运行环境。因此,我们可以将应用清单理解为在部署和更新之前所动态地生成的一个管道。
Helm 是一款辅助 Kubernetes 进行包管理的工具。它能够方便地对应用进行分组、版本控制、部署和更新。
Kubernetes 应用平台必须分别从开发和运营的不同关注点出发,提供简单的方法来建模、组织和构造应用清单、以及 Helm Charts。
而平台还必须提供对不同定义的验证,以便尽早捕获各种常见的错误,同时还能以简单方法重用那些应用的定义。
应用程序运营环境管理
应用程序在完成建模与验证之后,就需要被部署到群集之中。由于我们的最终目标是在不同的工作负载中重用这些群集,以提高效率和节约成本。因此,我们最好将应用程序的运行环境与群集进行解耦,并将通用的策略和控制应用到环境之中。
由于 Kubernetes 允许使用命名空间和网络策略来创建虚拟群集,因此 Kubernetes 的应用平台应当能够方便地利用这些构造,来创建具有逻辑分割与隔离、以及资源控制的环境。
变更管理
在多数情况下,运行环境具有持久性,因此我们需要以可控方式对其进行变更。而这些变更往往源自编译系统或交付管道中的上游环境。
Kubernetes 应用平台需要为 CI/CD(持续集成和持续交付)工具提供各种集成,并监控外部存储库的更改。
一旦检测到变更,它们就应当根据不同环境下变更管理的策略,对其进行验证和处理。当然,用户也可审查变更、接受更改、或完全依赖自动化的更新进程。
应用程序监视
不同的应用程序会被运行在多个环境、和多种群集之中。从监控的角度而言,我们需要设法给传递的消息去噪,从而能聚焦到应用程序的实例之上。
因此,我们需要将应用程序的指标、状态和事件关联到运行环境的构造上。
同时,Kubernetes 应用平台还须将监控与自动化的细粒度标签相集成,以便用户深入地查看到任何环境中的应用实例。
应用程序日志记录
与监控类似,日志数据也需要将应用的定义和运行环境信息相关联,并且能够被任何应用组件所访问到。Kubernetes 应用平台必须能够对不同运行组件上的日志进行流转和聚合。
如果您用到了集中式日志系统,那么就必须对应用予以必要的标记,以便将日志从不同的应用与环境中分离出来,同时也能实现跨团队与用户的访问管理。
警报与通知
为了实现服务级别的管理,我们必须能够根据任何指标数值、状态变更或不同条件,来自定义警报。同样,我们可以根据相关性来区分出需要立即采取行动与可以延迟处置的警报。
例如:如果同一应用程序被部署运行在多个环境(如开发测试、暂存和生产环境)中,我们就必须能定义只在生产工作负载上被触发的警报规则。
Kubernetes 应用平台必须具备环境和应用的感知能力,从而提供对细粒度警报规则的定义和管理。
远程访问
由于云服务环境是动态的,而容器又将这种动态提升到了新的水平。因此,一旦有问题被检测和报告,我们就必须能够快速地访问到系统中那些受到影响的组件。
而 Kubernetes 应用平台则必须提供一种方法,能在运行的容器中启动 shell ,访问容器运行环境的详细信息,而不必通过 VPN 和 SSH 去访问各种云服务的实例。
事件管理
通常在 Kubernetes 的应用中,有可能会出现容器的退出和重启。这种退出可能是正常工作流(如升级)的一部分,也可能是由于内存不足等错误所造成的。
Kubernetes 应用平台必须能够识别故障,并捕获故障的所有详细信息,进而采取离线的分析与排障。
总结
容器和 Kubernetes 使得企业能够利用一组通用的行业最佳实践,来对跨多种云服务的应用程序进行操作和管理。
所有主流的云服务供应商和应用平台,都相继承诺可以支持 Kubernetes 了。
在他们之中,有以“开发人员提供代码工件,平台负责其余部分”为模式的平台即服务(Platform-as-a-Service,PaaS)方案;也有以“开发人员提供容器镜像,平台负责其余部分”为模式的容器即服务(Container-as-a-Service,CaaS)方案;还有以“开发人员只需提供功能函数,平台负责其余部分”为模式的功能即服务(Functions-as-a-Service,FaaS)方案。可以说,Kubernetes 已成为了新的云原生操作系统。
因此,在开发多种云服务模式的 Kubernetes 策略时,企业必须周全地考虑到:他们希望如何去使用基础架构服务、如何管理 Kubernetes 的组件版本、如何设计与管理Kubernetes群集、如何定义公共安全层、以及如何管理好应用。
原文标题:Best Practices for Multi-Cloud Kubernetes作者:Jim Bugwadia
【51CTO原创稿件,合作站点转载请注明原文作者和出处为51CTO.com】