云计算
本文以公众号EAWorld翻译发表,转载须注明出处。
作者: Michael D. Elder
译者:白茫茫
原题: Kubernetes 12-factor apps
原文: http://t.cn/EoBns1o
12原则的详情请阅读《全网首发:逐一解读云原生应用开发“12-Factors”》
如果您使用容器构建APP展示,您应该听说过什么是“12要素原则”。 “十二要素”为微服务的开发提供了明确的指引。 我们相信,只有遵循这些原则,APP应用和服务才能更容易地运行、扩展和部署。
在谈到“十二要素原则”时,笔者习惯于按普遍场景对这些原则进行分组。 对我来说,12个要素最终是关于如何编码、部署和运营的原则。 这些是软件分发生命周期中最常见的场景,为许多开发人员和DevOps集成团队所熟知。
那么,在使用Kubernetes的过程中,在构建微服务器时如何应用12要素原则呢? 事实上,12因素原则对Kubernetes的发展和发展过程产生了深远的影响。 以下内容逐一分析Kubernetes的容器组织模式如何直接支持各组的12要素原则。
一.与编码有关的因素
源代码管理需要考虑的因素包括基准代码、生成和部署生命周期以及如何最终保持生产和开发环境的一致性。
基本软件分发周期图
Sourcecontrolallthethings
源代码控制一切
要素1 :一个基准代码,多个部署
Kubernetes中使用了很多声明性的结构。 所有APP应用程序信息都通过YAML或JSON实现基于文本的表示。 容器本身描述为dockerfile等源形式,在构建过程中,可以反复将文本形式的dockerfile转换为容器镜像。 从镜像到容器部署都封装在文本格式中,所以很容易实现所有东西的源代码控制。 最常见的工具是Git。
在Kubernetes中,很多东西可以用声明来记述。 《Kubernetes in the Enterprise》这本书记录了很多完整的例子,相关的代码都在Github上。
当APP应用程序需要跨不同的环境(如开发、用户接受和生产)运行时,最常见的方法是使用GitOps交付模型来实现多个分支的管理,并区分不同环境之间的差异。
要素5 :严格隔离构建、发布和操作
如标题所示,为了遵循这一原则,必须将环境的建立、公开和执行严格分开。 最常见的实现方法是工件管理。 提交代码后,将开始构建,生成容器镜像并将其发布到镜像库。 如果使用Helm(Kubernetes的包管理器,类似于Ubuntu的apt-get ),kubernetes APP应用程序将同时打包并发布到Helm库。 通过重建二进制或镜像文件,所有这些发布都可以在不同的环境中重用和部署,从而确保此过程不会引入未知的更改。
要素10 :开发环境与生产环境等价
通过遵循这个等价原则,可以避免“在我这里可以,为什么在你这里不行”的麻烦对话。 容器(或Kubernetes )意味着可以标准化APP应用的提供和执行依赖,并以相同的方式将任何东西部署到任何地方。 因此,如果在生产环境中使用高可用性mysql配置,则可以在开发群集上部署相同的体系结构。 在预开发环境中构建与生产环境等效的体系结构通常可以避免意外差异。 这些差异可能会对APP应用程序的正常运行,甚至失败产生重要影响。
二.与部署有关的因素
只有当部署成功时,构建的价值才能发挥。 12个要素中,描述相关最佳做法的原则非常多,如应该如何部署微服务、如何处理依赖关系、如何分析其他微服务的细节等。
微服务的可靠性取决于其最不可靠的依赖。
如何理解这句话,答案在下面的Kubernetes体系结构图中:
Pod和相关的Kubernetes对象
元素2 :显式声明依赖关系
对于以上词语的理解,首先需要考虑依存关系的构筑,12个要素中的依存关系的记述参照了构筑管理的原则。 但是,由于对其他API和数据存储的依赖会广泛影响微服务器的可靠性,所以倾向于将依赖元素放在部署相关的组中。 Kubernetes引入了readiness和liveness的探测机制,可以执行运行时的依赖检查。 readiness探测器验证在某个时间点或时间段是否存在健康的后端服务来响应请求。 另一方面,活跃度探测器可以确认服务器本身的健康性。 如果在指定的时间范围内,两个指标中的任何一个导致失败阈值,Pod将重新启动。
译注:
这里作者对liveness和readiness的理解存在误解。 “liveness”指标实际上指示了容器正常工作的下划线,只有在超过该下划线时,容器才会重新启动。 另一方面,readiness指标表示容器可以正常工作的联机状态,如果不满足readiness要求,容器将不会重新启动,只会显示为“异常”状态。 例如,Tomcat的APP应用程序成功启动后为liveness,但只有在spring容器初始化、数据库连接等相关进程完成后才为readiness。
详情请参照http://t.cn/EorvPAh
建议您阅读《Release It!》这本书,体验书中的智慧,并使用书中描述的体系结构模型(如保险丝、Fail Fast、Timeouts等)来提高APP应用的可靠性。
在环境中保存配置
根据此元素的请求,开发人员需要将配置源代码存储在诸如ENV VARs等进程的环境变量表中。 通过配置和代码分离,微服务器可以完全独立于环境,并移植到其他环境中,而无需进行源代码级别的更改。 Kubernetes提供ConfigMaps和Secrets对象来配置源代码管理。 实际上,Secrets不应该在没有额外加密的情况下包含在源代码管理中。 容器可以在运行时获取配置详细信息。 将配置信息保存为环境变量有助于系统的扩展和满足不断增长的服务需求。
元素6 :在无状态流程中执行APP表示
在Kubernetes中,容器镜像作为Pod中的进程运行。 根据从12个要素的观察,Linux内核通过以过程模型为中心的资源共享实现了很多优化。 Kubernetes或容器只能提供接口以实现更好的隔离,不能并行不一致地处理同一主机上的容器进程。 流程模型的应用使系统更易于扩展和故障恢复管理。 一般来说,过程必须是无状态的。 然后,可以将工作负载作为副本进行横向扩展。 但是,Kubernetes也有具有数据库/高速缓存等状态的工作负载。
必须使用永久数据存储库按需保存APP应用程序的状态。 可以从配置文件中发现应用进程的所有实例。 在基于Kubernetes的APP应用程序中,微服务器无法期待粘性会话,因为它会同时执行Pod的多个副本,并将请求路由到其中一个副本。 这意味着用户可以始终将一个会话周期内的所有请求转发到同一特定对象。
得益于流程模型的机制,所有服务都可以通过创建更多的流程实例轻松扩展。 Kubernetes提供了许多控制器,包括复制、部署、状态集和复制控制器。
有关副本的部分,请参见以下代码片段的第2行到第7行:
wtson-conversation.yamlhostedwith? by GitHub
Kubernetes部署文件列出了所需副本数量的声明(如第7行所示)。
要素4 :将后端服务作为额外资源
我们通常将类似网络环境的依赖定义为“后端服务”。 正确的做法是独立于微服务器本身的生命周期来考虑这些上游服务的生命周期。 无论是添加还是剥离后端服务,都不应该影响微服务器本身正常响应的能力。
例如,如果APP应用程序需要与数据库进行交互,则需要设置某些连接细节,以隔离APP应用程序与数据库之间的交互行为。 这可以通过动态服务发现或Kubernetes Secret的Config配置来实现。 其次,必须考虑网络请求是否实现了容错,以确保在后端服务器出现运行时故障时不会出现微服务器级联故障。 在“《Release It!》”中有详细说明。 相关的后端服务必须在独立容器中或群集以外的任何位置运行。 微服务不应关注交互细节,与数据库的交互操作都是通过API进行的。
元素7 :通过端口绑定提供服务
在生产环境中,多个微服务器提供不同的功能,服务器之间的通信需要通过良好定义的协议来达成。 可以使用Kubernetes Service对象声明和解析群集内部和外部相关服务的网络端点。
如果在容器出现之前需要部署新服务器或更新现有服务器的版本,则需要花费大量时间来解决主机上的端口冲突问题。 容器隔离机制和Linux内核网络命名空间机制允许在单个主机的同一端口上运行多个进程或同一微服务器的多个版本。 这样,Kubernetes的Service对象就可以向所有主机公开微服务池,以实现入站请求的基本负载平衡。
在Kubernetes中,Service对象是声明的,它会自动平衡路由到Pod的相关请求的负载。
处理对Pod的相关请求的负载平衡的服务声明示例:
wtson-conversation-service.yamlhostedwith? by GitHub
三.运营相关因素
要素八(合并)、要素九)可处置性)、要素十一)日志)和要素十二)任务管理)关于如何简化微服务器的运营。
Kubernetes专注于如何根据需要创建和销毁多个Pod的简单部署单元,单个Pod本身毫无价值。
要素8 :通过流程模型进行扩展
要素6所述的过程模型对同时机制的实现做出了很大的贡献。 如上所述,Kubernetes通过各种类型的生命周期控制器可以实现无状态APP化的运行时扩展。 所需副本的数量由声明的模型定义,并且可以在运行时更改。 同样,Kubernetes提供了许多用于管理并发的行,包括复制控制器、复制集、部署、状态集、作业和延迟集
以下动画演示了添加副本的过程。
ReplicaSet可用于添加更多的Pod。 新创建的Pod将自动响应来自服务对象的入站请求。
基于对CPU、内存等相关计算资源及其他外部指标的阈值监测,Kubernetes引入了自动扩展机制。 horizontalPodautoscaler(HPA )可以在一个部署或复制中自动扩展pod的数量。
HPA基于指标的观测添加Pod
自动扩展应关注Pod的纵向扩展和集群扩展。 纵向Pod扩展适合有状态的APP应用。 Kubernetes触发CPU和内存,向Pod添加更多的计算资源。 也可以使用自定义指针而不是HPA来触发自动扩展。
Vertical Pod Autoscaler扩展了容器的可用内存
要素9 )快速启动和优雅结束
12要素原则中的可处置性,考虑使用Linux内核的信号机制与运行中的进程进行对话的方法。 根据可丢弃性原则,微服务器可以快速启动,并随时消失,而不影响用户体验。 对于无状态的微服务器来说,实现部署原则有助于达到可丢弃性。 实际上,藉由上述livenessProbes和readinessProbes探测器机制,Kubernetes将在指定时间段丢弃变得不健康的Pod。
元素11 :将日志作为事件流
对于容器,所有日志通常记录在stdout或stderr文件描述符中。 其中重要的设计原则是,容器不应该管理日志输出的内部文件,而应该提交给容器组织系统以收集日志并进行分析和归档。 在Kubernetes中,日志收集一般作为公共服务存在。 以我自己的经验,我可以使用Elasticsearch-Logstash-Kibana的组合顺利地实现它。
要素12 :将后台管理任务作为一次性流程执行
数据库迁移、备份、恢复和日常维护等管理任务必须与微服务的基本运行时在逻辑上分离,并解除绑定。 在Kubernetes中,Job控制器可以创建一次执行的Pod,也可以根据计划创建执行不同活动的Pod。 作业控制器可用于实现业务逻辑。 Kubernetes将API令牌加载到Pod中,因此还可以使用作业控制器与Kubernetes组织系统进行交互。
通过隔离这样的管理任务,将来可以简化微服务器的动作,减少潜在的失败。
四.结语
如果读者对这个话题感兴趣,我建议通过点赞转发和朋友分享本文的观点。 如果你有机会加入KubeCon Europe,欢迎加入我和Brad Topol的脸书。 另外,请详细讨论这个话题。 分享更多关于Kubernetes能力的演示。
除了构建微服务器的12条原则外,我和另一位作者,Shikha Srivastava也识别了从生产环境中遗漏的7条原则,Shikha将很快就此发表文章。 敬请期待。
了解EAWorld :微服务、DevOps、数据治理、移动架构原创技术共享
详情请访问云服务器、域名注册、虚拟主机的问题,请访问西部数码代理商官方网站: www.chenqinet.cn