简述Kubernetes Metric Service?

需要注意的是端口和镜像地址。

查看默认空间pod资源:

到此这篇关于kubernetes(k8s)安装metrics-server实现资源使用情况监控的文章就介绍到这了,更多相关kubernetes安装metrics-server资源监控内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

作者/讲师:杨朝乐/才云科技软件工程师

才云基础设施部分运维开发工程师,专注于 Kubernetes 部署及运维。

大家好,我叫杨朝乐,来自才云科技基础设施部门。今天给大家分享一个平时可能接触得较少的话题:关于 Kubernetes 的稳定性和可用性。

下面是今天分享以下 5 个主题:

Kubernetes 集群的稳定性和众多因素相关。比如我们有一个集群,上面会有很多应用,这些应用可能是无状态的,通过 来管理;也可能是有状态的应用,通过 StatefulSet 来管理。Kubernetes 集群之上,通过多种 Controller 来管理我们的应用。而在集群之下,比如集群节点的存储、网络、资源等,比如物理硬件的好坏,都是影响集群稳定性的重要一环。

就像有一个叫做 “Jenga” 这个游戏,某些元素的单个故障不会导致集群不可用,一旦某些关键元素或者多个元素故障,超过了集群的自恢复能力,集群便不再可用了。

那么,Kubernetes 为我们提供了哪些提高集群可用性的利器呢?下面分享几个使用较多的特性:Replica,Qos,HPA,Health Check。

我们先来看一个一切正常的 Kubernetes 集群,包含 3 个节点,每个节点上跑了一些应用。可以注意到,有些应用有多个实例,有些只有一个实例。下面,如果第一个节点的 Console 和第二个节点的 Api 故障了,集群服务的可用性会怎样呢?

我们可以联想到,对于 Console 的故障,当 Console 不可用时,Console 对应的服务也不可用;而 Kubernetes 会保证应用的副本时,所以 Console 这个应用会重新的创建出来,并正常提供服务。但在重新调度和创建起来之前,服务是会中断的。作为对比,Api 服务因为使用了多个副本,在图中的故障情况下,服务是仍然可用的。所以这里我们推荐使用多个副本。

下面再看一张图,图中应用的大小对应应用的资源占用,这里以占用的内存为例。比如在节点 3 上,Db 因为资源不足,无法正常运行。

这里列出了几个可能的场景:

  • 应用(节点 1 上的 Db)使用了过多的内存,会发生什么呢?Db 自己可能会因为内存不足或超限而被 kill 掉;Db 可能会导致其他优先级低的应用被 kill 掉。
  • 应用(节点 3 上的 App)申请了过多的内存,导致原先想调度到这个节点上的应用无法调度上来

这些场景会在配置不同的 QoS classes 策略下有所不同,Kubernetes 提供了三种资源使用策略,根据应用的资源申请(request)和资源限额(limit)的不同、对于到 Guaranteed Burstable 和 BestEffort 三种模式。实际场景下,应该合理分配资源,避免资源的浪费和服务的不稳定。

和 Qos 类似的,HPA 是应用水平自动扩容。切换到这样场景:集群的 Db 服务负载很低,多个副本显得浪费;或者,集群的 Api 服务,突然流量剧增,当前的副本数已经不够了。这个时候,通过配置 HPA,可以使应用在负载高的时候,自动的添加副本数来减小单个实例的压力;也可以在压力小的时候,降低副本数,释放资源。

说到这里,可以提一下这里的负载,目前 Kubernetes HPA 实现上是通过衡量 CPU 的负载来评估服务负载的,实际使用中可能不能满足我们的需求。不过 Kubernetes 还提供了 Custom metric 让我们来自定义负载的指标。而与 HPA 类似的,还有集群的自动扩缩容(Cluster Autoscaler)和应用的垂直扩容(VPA)。

下面讲讲健康检测(Health Check)。比如应用 Api 出现了问题,我们实际访问 Api 服务时发现这个服务确实不可用了,但我们查询到的 Api pod 运行的状态的 Running,也就是正常在跑,Kubernetes 不会知道这个应用不工作了。默认情况下,如果应用没有异常退出,Kubernetes 会认为这个应用是正常的,不会做特殊处理。

但我们或许会遇到以下 2 种情况:

  1. 应用还在初始化阶段等导致服务不可用,我们可以借助健康检测来让 Kubernetes 发现和处理这类异常。

对于状况 1,我们可以配置存活性检测(Liveness Probes),如果存活性检测没有通过,Kubernetes 会自动来重启这个应用。

对于状态 2,我们可以配置可用性检测(Readiness Probes),这样在服务初始化完成前,通过 Service 不能访问到这个服务,避免造成意想不到的后果。

提高集群的稳定性,Kubernetes 还提供了许多高级功能,这些功能可能没有前面提到的那几个常见,但却也是十分有用的。下面分享两个功能特性:资源预留和关键组件调度保证。

实际场景下的资源使用,除开用户运行的实际业务,操作系统本身也会占有一定的资源,比如系统内核,比如系统服务(sshd udev 等)。如果用户业务使用了过多的资源,以至于系统的资源得不到保障,导致系统不稳定,集群服务就也得不到保障了。这个时候,我们可以通过配置 System-reserved 来给系统预留部分的资源。

但是这样就够了么?我们知道,Kubernetes 集群本身也有许多控制组件,这些组件如果因为资源不足出现故障,整个集群也没法保障稳定了。这个时候,我们可以类似配置 System-reserved 一样,配置 Kube-reserved,来预留资源给 Kubernetes 相关的组件,比如 Kubelet 和 Docker daemon。这样一来,哪怕用户业务负载很高,也可一定程度上通过保证系统核心组件的稳定来提高集群的稳定性。

除了 Kubernetes 的系统组件,还有一些组件,这些组件如果没有跑起来,整个集群都可能不可用,比如 dns 服务,比如网络插件等。这些关键的应用(Critical Add-On),Kubernetes 提供了一种机制,来保证这些关键应用的存活。

比如这样一种情况,DNS 调度到了一个节点,这个节点存在一些问题,导致 DNS 一直不停的出错重启。默认情况下,除非 Kubernetes 认为这个节点不可用,进而重新调度 DNS,DNS 服务是不会重新调度的,这样会导致集群不可用,并且不能自动修复。这个时候,如果配置了 Rescheduler 组件,并且把 DNS 配置成了关键应用,DNS 会被重新调度到另外一个节点。这样,集群的服务一定程度下,可以自动的修复。

讲了许多的提高集群稳定性的方法,下面谈谈集群使用中可能遇到的异常。回到最初的那个图,图上每一个节点,都可能出现异常,比如:应用没有跑起来;节点挂掉了;网络故障;Docker 卡死等。下面以电力故障为例,来谈谈出现异常时候,对集群服务的影响。

下面三张图中三个节点上分别跑着一些服务,假设故障分别出现在这三个节点上,会发生什么呢?前面提到了 Replica,我们知道如果 Replica 为 1,服务是会中断的。这个中断时间可能没有大家想象的那么短。

默认情况下,从节点状态变为不可用,到 重新调度到其他可用节点,可能需要几分钟的时间。我们可以通过配置 pod-eviction-timeout 来调整这个时间,但不建议配的太小,这样可能因为比如网络不稳导致 pod 不停地重新调度,造成抖动。

那是否 Replica 配置成 2 或者更多就可以了呢?我们可以想想节点 1 出现故障,服务 Console 全部跑在了节点 1 上,哪怕 Console 有多个服务,故障还是会造成 Console 服务中断。这个时候,我们可以配置 podAntiAffinity,来保证服务的多个副本不会调度到相同的节点上,以此来进一步提高可用性。

我们继续假设,如果出现电力故障的节点是 Master 呢?如果这是唯一的 Master,那么故障的服务不会重新调度和恢复;通过 Service 方式访问这个应用,有可能访问到故障的后端服务。

K8S 里的高可用方案

如果是有多个 Master 呢?理想的情况下,故障节点上的应用会重新调度,故障的服务也会自动恢复。为什么说理想的情况下呢,这个我们稍后会解释,在此之前,我们先看看高可用在 Kubernetes 是如何实现和工作的。

图中描述了一个典型的 Kubernetes HA 方案架构,包括几个重要的地方:

  • Masters:集群 Master 节点数不再是一个,而是三个,etcd 作为集群的模式工作在三个 Master 节点上,每个节点上都会跑一个 apiserver,并连接这个 etcd 集群;其他有状态的组件比如 controller scheduler 会采用主备的方式,在三个 Master 上都会运行,但是只有一个节点上的会选举为主,提供服务。
  • load balancer:一个负载均衡服务,把流量导入到存活的 Master 节点的 apiserver 服务上。这个负载均衡即可以是一个外部 IaaS 提供的云负载均衡,也可以是自己通过keepalived 和 nginx 搭建出来的内部负载均衡。

社区热门的部署工具 ,也有整合 HA master 的计划,下图是一个目前的完成度情况,可以发现里面还有不少工作要做,预计的发布版本是 v1.10。如果不想等得太久,社区也给出了一个基于 Kubeadm 手动创建一个 HA master 集群的方案和操作流程。这里给出了相关文档的链接,感兴趣的同学可以自己选择阅读。

回到刚才说的理想的情况,HA 方案可以保证集群高可用。但实际情况呢?

目前的 HA 集群,在实际使用上,会有一些坑,虽然某些可能在最新的上游版本修复了,但如果没有更新版本,这些问题还会存在。

  • etcd client 问题:当三台 Master 节点挂掉一台时,apiserver 可能仍然连接的是停止服务的那台 Master 节点上的 etcd ,这样 apiserver 无法获取和更新最新的集群状态,导致可能通过 kubectl get node 查询集群的状态,在一个节点上查询到的是三个节点全正常,另外一个节点显示有一台 not ready。
  • 规则来实现的。目前的 kubernetes svc 会根据 client IP 做会话保持,这样如果访问的恰好是坏掉的 Master 节点 IP,这个节点上的 kubernetes svc 就会一直不可用了。如果去掉会话保持,会有三分之一的概率服务不可用。

抛开上面提到的两个问题,还是电力故障的情况,这次情况比较糟糕,所有节点都受到了影响。但运气比较好,电力很快就恢复了,这个时候,集群服务会怎样呢?

场景一:负载均衡服务没有恢复,Master 节点很快恢复正常了。因为负载均衡还未恢复,所有 Node 节点都会认为是不可用的,导致的一个可能后果是,所有 Node 上的服务都重新调度并在 Master 节点创建,Master 节点负载会非常高。哪怕后面 LB 恢复了,master 节点的任务也不会自己迁出,集群的负载会极度不均衡。

场景二:负载均衡服务正常,Master 节点和 Node 节点都在快速的启动服务中。这个时候,如果 Node 节点规模很大,apiserver 和 etcd 的请求会非常的多。比较糟糕的情况是,Master 节点的 etcd 因为负载太高不能正常提供服务,导致 Node 节点注册失败,然后不断尝试重新注册 Node;哪怕负载降下来后,Node 节点全部注册成功,大量应用重新调度,产生大量的事件,etcd 很可能马上又坏掉了。这个时候,就需要对 apiserver 做限流了,防止突发的压力增长导致集群不可用。

谈了很多异常的状态,那么有什么好的办法来处理这些异常呢?限于时间关系,以下图为例给大家简单讲讲如何处理异常。

  • Symptom:通常发现异常时,是因为发现了一些不寻常的征状,比如某个服务不可用了,某个 pod 卡在了 terminating 状态;某个创建的 deployment 没有看到运行的 pod。根据这些征状,我们对于出现的异常有了一个初步的了解,便于借助工具做进一步的诊断。
  • Tools:诊断问题时,我们可以借助许多工具。比如 kubectl describe 来查看事件,kubectl logs 来查看日志,nsenter 进入容器的命名空间诊断问题,tcpdump 抓包来诊断网络问题等。借助这些工具,和诊断的一些结论,我们可以猜测可能的原因
  • Root Cause:导致异常的原因多种多样,异常的直接原因,借助工具可以快速发现,比如创建了 deployment 没有创建出 pod 原因是节点资源不足。我们可以继续追踪这个异常,为什么会突然资源不足了呢,借助工具可以发现是有一个节点不可用了。继续追查,可能是这个节点的 kubelet 异常退出了。通过一步步,找到了根本原因,才能从根源上解决这个问题。

上图中列出了一些有趣的 Root Cause,比如内核的 panic,dockerd 卡死,错误的挂载目录,配置了错误的网络策略等。

这里给大家分享一下经验:

  • 借助日志系统和监控系统发现和诊断异常
  • 优先查看节点的负载情况,确保不是资源不足,磁盘写满导致的
  • 诊断问题不仅限于 Kubernetes 本身,相关的存储、网络、容器运行时等都可能出问题
  • 不要忽略硬件本身的问题,比如磁盘本身有故障

今天的分享到这里,感谢大家!

校对:(才云)、(才云)

如果想要监控 Kubernetes,包括基础架构平台和正在运行的工作负载,传统的监控工具和流程可能还不够用。就目前而言,监控 Kubernetes 并不是件容易的事。

Kubernetes 已经席卷了整个容器生态系统,它充当着容器分布式部署的大脑,旨在使用跨主机集群分布的容器来管理面向服务的应用程序。Kubernetes 提供了用于应用程序部署、调度、更新、服务发现和扩展的机制,但是监控 Kubernetes 呢?

虽然 Kubernetes 可以极大地简化将应用程序在容器以及跨云的部署过程,但它会为日常任务、应用程序性能管理、服务可见性以及典型的“监控->警报->故障排除”工作流程增加了复杂性。

旧版监控工具从静态目标中收集指标,用于监控服务器和服务,这些工具过去工作良好,但现在无法正常工作。下面就是这些工具现在无法监控 Kubernetes 的原因:

为了简化应用程序部署,基础架构增加了新的复杂性层:动态配置的 IaaS、自动配置的配置管理工具以及编排平台(如 Kubernetes),它们都位于裸机或虚拟基础架构与支持应用程序的服务之间,因此在控制平面上监控 Kubernetes 安全也是工作的一部分。

除了增加基础架构的复杂性之外,微服务还被设计了新的应用程序,其中相互通信的组件数量也会按数量级增加。每个服务分布在多个实例中,并且容器可以根据需要在基础结构中移动。这就是监控 Kubernetes 编排状态对于了解 Kubernetes 执行工作至关重要的原因。我们要验证服务的所有实例都已启动并运行。

我们需要监控系统,这样能为高水平的服务目标发出警报,另外我们也要保留粒度以根据需要检查各个组件。当采用云原生架构时,它们带来了变化也带走了越来越多的小组件。这就影响了 Kubernetes 监控方法和工具。

随着指标数量的激增,传统的监控系统已无法跟上。虽然过去我们能知道每个服务组件有多少个实例以及它们位于何处,但现在情况已不再如此。现在指标通常具有一定的基数,Kubernetes 会有一些多维级别,例如集群、节点、命名空间、Service 等。许多标签的代表属性来自于微服务的逻辑、应用程序版本、API 端点、特定资源或操作等。

另外,容器不会永远运行下去。据一份容器使用情况报告显示,22% 的容器寿命不超过 10 秒,54% 的容器寿命不到 5 分钟。这会造成很大的变动,容器 ID、Pod 名称之类的标签始终在变化,这也是我们在处理新标签时却再也看不到它们的原因。

现在,我们如果将度量标准的名称、标签与实际值、时间戳一起使用,在短时间内,就将拥有成千上万个数据点,即使是在小型 Kubernetes 集群中,也将生成数十万个时间序列,如果是中型基础架构,可能就是数百万个。这就是为什么 Kubernetes 监控工具需要准备好扩展成千上万个指标。

容器的生命周期是短暂的,它一旦死亡,内部的所有东西都将消失,我们无法使用 SSH 或查看日志。容器非常适合操作,我们可以打包、隔离应用程序,在任何地方以一致的方式部署它们,但是同时,它们同样会成为难以排除故障的黑盒。监控工具可以通过系统调用跟踪从而提供详尽的可见性,这样我们可以查看容器内发生的每个进程、文件或网络连接,从而更快地对问题进行故障排除。

考虑到这些因素,我们可以更好地理解为什么监控 Kubernetes 与监控服务器、VM 甚至是云实例有很大不同。

Kubernetes 集群具有多个组件和层,在每个组件和层中,我们需要监控不同的故障点。以下是 Kubernetes 监控的一些典型用例:

通过监控集群,您可以全面了解整个平台的运行状况和容量。具体的用例如下:

  • 集群资源使用情况:集群基础架构充分利用了吗?还是产能过剩?
  • 项目和团队分摊资源:每个项目或团队的资源使用量是多少?
  • 节点可用性和运行状况:是否有足够的节点可用于复制我们的应用程序?我们会耗尽资源吗?
  • Pod 丢失(Missing)和失败:Pod 是否在我们的应用程序中运行?多少 Pod 快死亡了?
  • 正在运行的实例与所需的实例:每个 Service 实际准备了多少个实例?我们需要多少个?
  • 请求和限制的 Pod 资源使用情况:是否设置了 CPU 和内存的请求和限制?它们的实际作用是什么?

归根结底,应用的监控才是最重要的。下面是应用监控的一部分:

  • 应用程序可用性:应用程序是否响应?
  • 应用程序运行状况和性能:我们有多少个请求?多少响应能力或延迟时间?我们有没有出错?

与大多数平台一样,Kubernetes 具有一组基本工具,可以监控平台,包括基于物理基础架构之上的 Kubernetes 构造。由于 Kubernetes 具有可扩展性,它会添加其他组件以获得 Kubernetes 可见性。让我们来看一下 Kubernetes 监控设置的部分:

cAdvisor 是一个开源容器资源使用收集器。它专为容器而构建,支持本地 Docker 容器。cAdisor 会自动发现给定节点中的所有容器,并收集CPU、内存、文件系统和网络使用情况统计信息,不过它仅会收集基本资源利用率。仅当容器具有 X%CPU 利用率时,cAdvisor 才能告诉我们应用程序的实际性能。cAdvisor 本身并不提供任何长期存储或分析功能。

为了进一步处理这些数据,我们需要一些东西来整合整个集群中的数据。最受欢迎的选择是 Heapster。就像任何应用程序一样,Heapster 在集群中作为 Pod 运行。Heapster Pod 从 kubelet 获取有用数据,而 kubelet 本身的数据则是从 cAdvisor 得到,然后 Heapster 按窗格将信息分组,其中也包括相关标签。

Heapster 是一个收集者,而不是采集者,它只是让我们收集整个集群中的 cAdvisor 数据。我们需要将这些数据推送到可配置的后端进行存储和可视化。我们可以添加可视化层(例如 Grafana)查看数据。

Kubernetes 仪表板提供了一种简单的方式,让我们通过 Kubernetes 命名空间和工作量查看环境。它提供了一种一致的方式来可视化基本数据,包括基本的 CPU、内存数据。另外,我们还可以从仪表板进行管理并采取措施,不过这就涉及到了多租户集群上的安全问题,需要设置适当的 RBAC 特权。

  • 现在计划了多少个副本?目前有多少可用?
  • 有多少个 Pod 正在运行、已停止、已终止?
  • 此 Pod 已重启多少次?

我们现在对在 Kubernetes 环境中构建合理的监控有了一定了解,虽然仍然没有详细的应用程序监控(例如:我的数据库服务的响应时间是多少?),但至少可以看到基础主机、Kubernetes 节点以及 Kubernetes 状态的一些监控。

Kubernetes 探针发挥了定期监控 Pod 的运行状况和可用性的重要作用。它可以让我们通过针对端点的请求和运行命令来任意定义“活动性”。以下是基于运行 cat 命令的 liveness 探针的简单示例:

Prometheus 是一个是开源的时间序列数据库,它和 Kubernetes 一样是 CNCF 项目。Prometheus 监控是围绕 Prometheus 服务器的整个监控堆栈,该服务器会收集并存储度量,另外还有用于仪表板的 Grafana。

尽管一开始使用 Prometheus 监控 Kubernetes 真的很简单,但是以后 DevOps 团队会很快意识到 Prometheus 也有一些使用障碍,例如规模、RBAC 以及一些团队合规性问题。

我要回帖

更多关于 service in 的文章

 

随机推荐