在生产环境中可遵循的Kubernetes优秀实践

根据Gartner的一项预测:到2022年,全球将有超过75%的组织,会在生产环境中运行容器化的应用(如今该比例不到30%)。而到2025年,该比例将会超过85%。由于云原生应用需要基础架构的高度自动化,目前以Docker和Kubernetes为代表的DevOps实现平台,正在以容器编排工具的形式,让更多的公司能够以更快的速度,构建、发布和交付其软件产品。

总的说来,Kubernetes具有支持自动扩展、零停机时间部署、服务发现、自动部署、以及回滚等出色且丰富的功能,非常适合于大规模的容器部署与管理。虽然Kubernetes能够灵活地分配资源和工作负载,但是具有复杂而陡峭的学习曲线。为了省时省力,您当然可以将其外包给KaaS提供商。不过,如果您需要对生产环境中的Kubernetes具有全面的掌控能力,那么就需要花费一些时间,来掌握Kubernetes的可观察性、日志记录、集群监控、以及安全性配置等方面。

与此同时,由于在生产环境中运行容器往往需要大量的计算资源与能力,因此人们纷纷选用各种基于云的编排平台。不过,这其中也潜在着一些安全问题。例如:Kubernetes Pod虽然可以在所有基础架构中快速启动,但是随着其Pod之间内部流量的增加,Kubernetes的攻击面会逐渐增大,安全隐患随之增多。此外,Kubernetes固有的高度动态、且短暂的运行环境,往往无法与传统的安全工具完美融合。我们亟待开发出一种能够满足存储安全性、网络监控与治理、容器生命周期管理、以及平台选择等需求的Kubernetes配置策略。

下面,我将和您讨论在生产环境中,可遵循的Kubernetes各种优秀实践与探索。

使用就绪且存活的探针(Probes)进行健康检查

对于线上业务而言,保证服务的正常稳定是重中之重。而对于故障服务的及时处理,避免影响业务,以及快速恢复一直是DevOps的难点。在管理大型且分布式的系统时,为了确保应用实例的正常运行,我们需要提前设置好Kubernetes的运行状况检查。

您可以根据目标环境与需求,来创建并定制各种运行状况检查项。例如,我们可以用到WeaveWorks。它能够创建一个虚拟的网络,以网络交换机的方式,连接到部署在多台主机上的Docker容器,便于应用无需逐个配置端口映射和链接等信息。

值得注意的是,那些就绪(Readiness)的探针可以让Kubernetes知晓应用是否已准备好了为流量提供对应的服务。也就是说,在分配服务并将流量发送给Pod之前,Kubernetes需要始终确保拥有正常的就绪探针。

那么,我们又该如何获悉应用的有效性呢?在此,我们需要通过存活(Liveliness)探针,以确保应用一旦失效,Kubernetes会立即删除旧的Pod,并将其替换为新的Pod。

通过上述对于Kubernetes的健康检查,我们可以及时对于检测到的故障服务,采取自动下线,或重启服务的方式,使其自行恢复。

资源管理

通常,我们需要为单个容器指定或限制资源的请求数,将Kubernetes所处的环境分为不同的命名空间(namespace),以供不同的团队、部门、应用、以及客户来使用。

值得一提的是,此处的Kubernetes资源使用情况是指在生产环境中,容器与Kubernetes Pod的资源被使用的数量。据此,我们可以合理地控制好在转化时所需的成本。此外,通常运营团队还需要获悉容器的CPU平均使用率,以及Pod所消耗的资源百分比,进而判定目前的Kubernetes生产环境是否处于已被优化的最佳状态。

启用RBAC

RBAC(基于角色的访问控制)是一种许可或限制用户和应用,对于系统和网络访问的方法。Kubernetes从1.8版开始便引入了RBAC。我们可以通过rbac.authorization.k8s.io API组,来创建各种授权策略,限制能够访问目标生产环境和群集的用户与进程。

可以说,RBAC为Kubernetes集群增加了一个额外的安全层。您可以在Kubernetes中对某些帐户的权限进行添加或删除,以及设置具体的访问规则。

群集配置和负载平衡

要满足生产环境级别,Kubernetes架构需要具备高可用性、multi-master、以及multi-etcd群集等特性。在实际应用中,我们往往会使用诸如Terraform、Ansible之类的工具,来配置群集。

一旦我们设置好了所有的集群,并为正在运行的应用创建了Pod,那么我们就该考虑为这些Pod配备负载平衡器,以便将各种网络流量路由到对应的服务处。不过,开源的Kubernetes项目并不会默认提供负载均衡器。因此,我们需要与诸如NGINX Ingress controller、HAProxy或ELB之类的工具,或是针对Kubernetes的插件,来实现负载平衡的功能。

将标签附加到Kubernetes对象

我们可以将诸如键/值对(key/value pairs)之类的标签,作为某种属性附加到Pod等对象上。在生产环境中,我们可以通过标签,对Kubernetes对象进行识别,分组,批量查询,以及其他操作。例如:我们可以根据容器所属的应用,对容器进行分组。当然,团队可以事先建立好任意数量的标签约定。

设置网络策略

网络策略能够方便我们通过明确的声明,来决定哪些流量适合通过,进而让Kubernetes能够阻止所有不合格(non-conforming)或不需要的流量。例如,作为基本的安全措施,我们可以在群集中定义和限制某些网络流量。

实际上,Kubernetes中的每个网络策略都可以被定义为一个授权连接的列表。根据已创建的网络策略,只有满足条件的Pod才有资格接受既定的连接。简而言之,网络策略会根据白名单,来授权和允许“从”或“向”Pod建立的连接。

集群监控和日志记录

集群监控,对于确保生产环境中Kubernetes的配置、性能和流量等方面的安全性,都是至关重要的。同时,我们有必要在系统架构的每一层上设置日志功能。这些生成的日志将有助于我们通过安全工具,来执行分析和审计功能。可以说,没有日志和监控,我们就不可能诊断出发生的问题,也就无法确保合规性。

从无状态的应用开始

由于运行无状态应用要比有状态的应用容易得多,因此对于刚上手K​​ubernetes的团队而言,他们可以使用无状态的后端,通过避免建立长期运行(long-running)的连接,轻松地根据业务的需求,按需进行灵活的迁移和扩展。此外,通过使用无状态,开发人员还可以在零停机时间状态下,更有效地部署应用程序。

启用自动扩展插件(Auto Scaler)

Kubernetes提供三种用于部署的自动扩展功能,即:水平Pod自动扩展插件(HPA)、垂直Pod自动扩展插件(VPA)、以及群集自动扩展。其中:

水平Pod自动扩展插件,会根据感知到的CPU利用率,自动扩展部署、复制控制器、副本(replica)集、以及状态集的数量。

垂直Pod自动扩展插件,会为CPU和内存的请求数和限定数设置合适的值,并且可以自动更新这些值。

群集自动扩展,可以扩展和收缩Worker节点池的大小,并能够根据当前的利用率,来调整Kubernetes集群的大小。

控制运行时(run times)的各种源头

如果您只允许Pod从公共资源中提取镜像,那么您可能对运行时一无所知。因此,我们需要对群集中的所有容器进行源头控制。通过在注册表上应用策略,我们就可以从受信任的注册表中提取安全、且经过认证的镜像。

持续评估

我们需要不断评估目标应用的状态,以及设置的合理性。例如,我们可以通过查看某个容器的历史内存使用情况,从长远的角度来分配更少、却又更加合理的内存数量,以节省成本。

保护那些重要的服务

通过使用Pod优先级,您可以对不同服务的重要程度进行设置。例如,为了获得更好的稳定性,您可以将RabbitMQ Pod设置得比其他应用Pod更为重要;或者通过把Ingress Controller Pod的重要性设置得优先于数据处理Pod,进而保持那些面对用户的服务的可用性。

零停机时间

说到可用性,我们还可以通过设置群集和服务的HA(高可用性),来确保零宕机时间。例如,使用Pod的反亲和性(Pod anti affinity),我们可以确保在不同节点上,分配一个Pod的多个副本,并通过计划内和计划外的群集节点中断,来确保服务的可用性。

此外,通过使用Pod的中断预算(Pod disruption budgets),我们也能够确保副本数量最少。

小结

综上所述,为了交付出平稳可靠的应用服务,我们从可用性、可扩展性、安全性、负载平衡、资源管理、以及监控等方面,深入讨论了在生产环境中,可以遵循的Kubernetes各种优秀实践。

你可能感兴趣的:(在生产环境中可遵循的Kubernetes优秀实践)