kuberntes Events事件处理

2023年 7月 15日 63.3k 0

应用程序并不总是在稳定状态下运行。会根据日期、时间或特定事件而波动。CPU 需求各不相同,运行时内存和网络需求也各不相同。而应用程序不断变化的需求,由Kubernetes来调度程序分配计算或内存资源,这些可能会导致Kubernetes上的node或者pod处于不可用状态的原因之一,而这些pod最终是关联到应用程序上,只有将这些资源被分配给其他应用程序或暂停,直到一切结束。

这种重新分配可能有意或意外地发生。突然的性能波动可能导致集群内的节点故障——或其他由pod 驱逐、内核恐慌,内存溢出,或 VM 意外停机引起的中断。

OOMKilled

OOMKilled是为了保证vm的健康状态,在后台,OOM Killer 为每个正在运行的进程分配一个分数。分数越高,进程被杀死的可能性就越大, Kubernetes 会利用该分数来帮助决定要杀死哪些 pod。

VM 上运行的 kubelet 监控内存消耗。如果 VM 上的资源变得稀缺,kubelet 将开始杀死 pod。从本质上讲,这个想法是为了保持 VM 的健康状况,以便在其上运行的所有 pod 都不会失败。多数的需求超过了少数的需求,少数被干掉。两种方式

  • OOMKilled:限制过度使用
  • OOMKilled:已达到容器限制

限制过度使用

当pod 限制的总和大于节点上的可用内存时,可能会发生OOMKilled: Limit Overcommit错误。例如,如果有一个具有 8 GB 可用内存的节点,可能会得到 8 个 pod,每个 pod 都需要 1 gig 内存。但是,即使其中一个 Pod 配置了 1.5 gigs 的限制,也会面临内存不足的风险。只需要一个 pod 出现流量峰值或未知的内存泄漏,Kubernetes 将被迫开始杀死 pod。

达到容器限制

虽然Limit Overcommit错误与节点上的内存总量有关,但Container Limit Reached通常归结为单个 pod。当 Kubernetes 检测到一个 pod 使用的内存超过了设置的限制时,它会杀死该 pod,并显示错误OOMKilled—Container Limit Reached。

发生这种情况时,检查应用程序日志以尝试了解 pod 使用的内存超过设置限制的原因。可能有多种原因,例如流量激增或长时间运行的Kubernetes 作业导致它使用比平时更多的内存。

如果在期间发现应用程序按预期运行并且它只需要更多内存来运行,可能会考虑增加 request 和 limit 的值。

有效应对这些事件至关重要。但是,了解特定应用程序如何以及为何表现出此类行为同样重要。K8s 事件对象可以帮助提供一些上下文,但是默认的手段能到的东西有限

事件

事件在Kubernetes框架中是一个对象,它会自动生成以响应其他资源(如节点、Pod 或容器)的变化

状态变化是最关键的部分。例如,pod 生命周期中的各个阶段——比如从pending到running的转换,或者成功或失败,或重启等状态可能会触发 K8s 事件。正如之前提到的,重新分配和调度也是如此。

事件实际上是 K8s 领域的。它们可以深入了解基础架构的运行方式,同时为任何令人不安的行为提供信息。但是Kubernetes 中的事件日志记录并不完美。

由于事件对象不被视为常规日志,因此默认情况下它们不包含在Kubernetes 日志中。此外,事件可能不会按预期显示以响应某些行为,例如由错误镜像引起的容器启动失败(例如[ImagePullBackoff)。我们可能希望某个事件在某些资源(ReplicaSet、StatefulSet等)上可见,但它们在 pod 本身上却是模糊可见的。因此,管理员需要执行调试时手动提取

事件分类

Kubernetes 部署中可能有多种类型的事件。当 Kubernetes 执行核心操作时,可能会出现许多状态转换

Failed Events

容器创建失败非常常见,因此创建失败或者更新的失败会因为很多原因导致,如镜像名称错误,权限等都会导致失败

此外,节点本身可能会失败。当这些故障发生时,应用程序应该回退到正常的剩余节点

Evicted Events

驱逐事件相当普遍,因为 Kubernetes 可以在工作节点终止其各种 pod。某些 pod 可能会占用计算和内存资源,或者相对于它们各自的运行时消耗不成比例的数量。Kubernetes 通过驱逐 pod 并在别处分配磁盘、内存或 CPU 空间来解决这个问题。

这并不总是一个问题,如果未能对他们的 pod 设置适当的限制,因此未能在容器级别限制资源消耗。如果没有定义的请求或限制参数,资源很可能会失控。

被驱逐的事件可以揭示这些次优配置,当数百个容器同时运行时,这些配置很容易在一次新的洗牌中丢失。驱逐事件还可以告诉我们pod 何时被分配到新节点。

Kubernetes Scheduling Events

称为FailedScheduling事件,当 Kubernetes 调度程序无法找到合适的节点时发生。这个事件的介绍非常具有描述性。记录的消息准确地解释了为什么新节点没有获得必要的资源。内存或 CPU 不足也会触发此事件。

Node-Specific Events

节点上的事件可能指向系统内某处的不稳定或不健康行为。首先,NodeNotReady事件表示没有准备好进行 pod 调度的节点。相反,健康节点将被描述为“就绪”,而“unknown”节点无法轮询状态和响应。

同时,Rebooted事件的含义很简单。由于特定操作或不可预见的崩溃,可能必须重新启动节点。

最后,当集群无法访问时会触发HostPortConflict事件。这可能意味着选择的 nodePort 不正确。此外,DaemonSets可能与 hostPorts 冲突并导致此问题。

过滤和监控事件

Kubernetes 事件并非所有事件都是关键任务。就像确认消息一样,其中许多可以简单地应用于按设计或预期运行的系统。K8s 将这些表示为Normal。

因此,所有事件都被分配了一个类型——Normal, Information, Warning。对于典型的集群,正常事件是无聊且不那么有用的;在故障排除过程中,它们不会透露任何内在价值。还为事件分配了一个简短的原因(触发此事件的原因)、一个Age、一个From(或起源)和一个提供更多上下文的Message 。这些本质上是与所有事件相关的“属性”或字段。它们还提供了一种从更大的集合中过滤某些事件的方法。

过滤非常简单。在kubectl中,可以输入以下内容以过滤掉正常事件,--field-selector type!=Normal

# kubectl -n preh5   get events --field-selector type!=Normal 
LAST SEEN   TYPE      REASON   OBJECT                                     MESSAGE
14m         Warning   Failed   pod/gv-service-857fc678f8-wwtpv   Error: ImagePullBackOff

也可以根据最新的时间选项来匹配--sort-by='.lastTimestamp'

#  kubectl -n preh5   get events --field-selector type!=Normal --sort-by='.lastTimestamp' 
LAST SEEN   TYPE      REASON   OBJECT                                     MESSAGE
8m33s       Warning   Failed   pod/gv-service-857fc678f8-wwtpv   Error: ImagePullBackOff

使用-o json查看json格式的信息

#  kubectl -n pre-veh5   get events --field-selector type!=Normal --sort-by='.lastTimestamp'  -o json
{
    "apiVersion": "v1",
    "items": [
        {
            "apiVersion": "v1",
            "count": 1150,
            "eventTime": null,
            "firstTimestamp": "2022-03-16T03:18:45Z",
            "involvedObject": {
                "apiVersion": "v1",
                "fieldPath": "spec.containers{gis-vehicle-service}",
...
        "resourceVersion": "",
        "selfLink": ""
    }
}

同时可以使用kubectl get events --watch开持续观察日志

由于使用的是kubectl,因此可以从 Kubernetes 组件日志或集成的第三方日志工具中提取这些事件。后者很常见,因为 K8s 事件通常不存储在默认的 Kubernetes 日志中

可观测Sloop

Sloop 监控 Kubernetes,记录事件和资源状态变化的历史,并提供可视化来帮助调试过去的事件。

主要特征:

  • 允许查找和检查不再存在的资源(例如:发现之前部署中的 pod 正在使用的主机)。
  • 提供时间线显示,显示部署、ReplicaSet 和 StatefulSet 更新中相关资源。
  • 帮助调试瞬态和间歇性错误。
  • 允许查看 Kubernetes 应用程序中随时间的变化。
  • 是一个独立的服务,不依赖于分布式存储。
  • 我们安装sloop,通过docker run起来

    docker run --rm -it -p 28080:8080 -v ~/.kube/:/kube/ -v /etc/localtime:/etc/localtime -e KUBECONFIG=/kube/config sloopimage/sloop:latest

    docker-compose

    version: '2.2'
    services:
      sloopimage:
        image: sloopimage/sloop:latest
        container_name: sloopimage
        restart: always
        hostname: "sloopimage"
        #network_mode: "host"
        environment:
        - KUBECONFIG=/kube/config
        volumes:
        - /root/.kube/:/kube/
        - /etc/localtime:/etc/localtime
        - /data:/some_path_on_host
        mem_limit: 2048m
        ports:
        - 28080:8080

    image-20220316182722724.png

    kube-eventer

    kube-eventer是阿里云的开源项目,他可以捕捉一些事件,配合钉钉发送报警, 但是他的频率非常高

    image-20220316154255223.png

    类似这样

    TestPlan
    Level:Warning 
    Kind:Pod 
    Namespace:test-test 
    Name:vecial-96b6765cf-6zst5.16d65799bf506486 
    Reason:BackOff 
    Timestamp:2022-03-16 15:42:14 
    Message:Back-off restarting failed container

    参考

    https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/在 Linux OOM Killer 中幸存

    相关文章

    LeaferJS 1.0 重磅发布:强悍的前端 Canvas 渲染引擎
    10分钟搞定支持通配符的永久有效免费HTTPS证书
    300 多个 Microsoft Excel 快捷方式
    一步步配置基于kubeadmin的kubevip高可用
    istio全链路传递cookie和header灰度
    REST Web 服务版本控制

    发布评论