前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Elastic Observability和OpenAI来深入了解Kubernetes的错误日志

使用Elastic Observability和OpenAI来深入了解Kubernetes的错误日志

原创
作者头像
点火三周
发布2023-05-24 10:03:50
1.8K0
发布2023-05-24 10:03:50
举报
文章被收录于专栏:Elastic Stack专栏Elastic Stack专栏

正如我们在之前的博客中展示的那样,Elastic® 提供了一种从 Kubernetes 集群和运行在其上的应用程序中采集和管理遥测数据的方式。Elastic 提供了开箱即用的仪表板来帮助跟踪指标、提供日志管理和分析APM (也支持原生 OpenTelemetry),以及使用 AIOps 功能和机器学习(ML)分析所有内容的能力。虽然您可以在 Elastic 中使用预置的 ML 模型开箱即用的 AIOps 功能或自己的 ML 模型来主动发现和定位异常,但仍然需要深入挖掘问题的根本原因。Elastic 的解决方案有效降低了运维的操作工作并提升了高效运营,但用户仍然需要一种方式来调查和理解从特定错误消息的含义到问题的根本原因的所有内容。作为一个操作用户,如果您以前没有遇到过特定的错误或它是一些运行脚本的一部分,您可能会去google并开始搜索信息。

OpenAI 的 ChatGPT 正变得越来越有趣,它是一个生成式的 AI 工具,可以其背后的模型为我们提供更多信息。如果您希望使用 OpenAI 来获取生产或开发环境中错误的更深入洞察力(甚至是简单的语义),那该怎么办呢?您可以轻松地将 Elastic 与 OpenAI 的 API 相连接以实现这一点。

Kubernetes是大多数部署(本地或云服务提供商)中的主要组件,但即使是管理像GKE、EKS或AKS这样的服务,也需要相当的专业知识。

在本博客中,我将介绍如何使用 Elastic 的 watcher 功能将 Elastic 连接到 OpenAI,并询问它有关从 Kubernetes 集群中摄取的错误日志的更多信息。更具体地说,我们将使用 Azure 的 OpenAI 服务。Azure OpenAI 是 Microsoft 和 OpenAI 之间的合作伙伴关系,因此 OpenAI 的相同模型在 Microsoft 版本中也可用。

虽然这篇博客讲述了一个具体的例子,但它可以针对Elastic在日志中收到的其他类型的错误进行修改。无论是来自云厂商、应用程序、数据库等,本博客中描述的配置和脚本都可以轻松修改。

先决条件和配置

如果您打算跟着本文做一次尝试,以下是我们用于设置配置的一些组件和详细信息:

  • 确保您有一个已部署的Elastasticsearch集群。
  • 我们使用了 GCP GKE Kubernetes 集群,但您可以使用您选择的任何 Kubernetes 集群服务(本地或云服务)。
  • 我们还运行了一个版本的 OpenTelemetry Demo。将 Elastic 与 OpenTelemetry demo结合使用的说明在此处。 
  • 我们还配置了 Azure 帐户和Azure OpenAI 服务。您需要从 Azure 获取适当的令牌,并从 Azure 的 OpenAI 服务获取适当的 URL 端点。
  • 我们将使用Elastic 的开发工具,具体来说是控制台,来加载和运行脚本,这是一个Elastic watcher
  • 我们还将添加一个新索引来存储 OpenAI 查询的结果。

这是我们将在此博客中设置的配置:

一切就绪

在接下来的几个步骤中,我将介绍:

  • 获得 Azure OpenAI 授权(OpenAI 的替代选项)
  • 识别 Kubernetes 错误日志
  • 使用正确的脚本配置观察者
  • 比较 Azure OpenAI/OpenAI 与 ChatGPT UI 的输出

第一步:Azure OpenAI 服务和授权

当您登录到您的 Azure 订阅并设置 Azure OpenAI 服务实例时,您将能够在“管理密钥”下获取您的密钥.

您的 OpenAI 实例有两个密钥,但您只需要KEY 1 .

经 Microsoft 许可使用
经 Microsoft 许可使用

此外,您还需要获取服务 URL。请参阅上图,以了解从何处获取KEY 1 和URL。

如果你不使用 Azure OpenAI 服务而是选择标准的 OpenAI 服务,那么你可以在以下位置获取密钥:

代码语言:javascript
复制
https://platform.openai.com/account/api-keys 

您将需要创建一个密钥并保存它。获得密钥后,您可以转到第 2 步。

第 2 步:识别 Elastic 日志中的 Kubernetes 错误

当您的 Kubernetes 集群运行时,Elastic的Kubernetes集成通过在集群上运行的Elastic agent daemon set发送日志和指标数据到Elastic。这些数据被采集、处理和索引。Kubernetes日志存储在一个名为.ds-logs-kubernetes.container_logs-default-*的索引中(*代表日期),并且还预加载了一个名为logs-kubernetes.container_logs的数据流(data stream)。因此,既可以使用现成的仪表板来研究指标数据,也可以在Elastic Discover中查看所有日志。

虽然来自 Kubernetes 的任何错误都可能令人生畏,但更微妙的问题是来自运行在kube-system 命名空间中的 pod 的错误。拿pod konnectivity agent来举例,它本质上是一个运行在节点上帮助建立隧道的网络代理,是 Kubernetes 中至关重要的组件。其任何错误都会导致集群出现连接问题并导致一连串问题,因此了解和解决这些错误非常重要。当我们从konnectivity 代理中过滤出错误日志时,我们看到了很多错误。

但不幸的是,我们仍然无法理解这些错误的含义。 

输入 OpenAI 以帮助我们更好地理解问题。通常,您会从 Discover 中获取错误消息并向 ChatGPT 提问(或通过 Google 来找到答案)。

以下是一个难以理解的错误日志的示例:

代码语言:javascript
复制
E0510 02:51:47.138292       1 client.go:388] could not read stream err=rpc error: code = Unavailable desc = error reading from server: read tcp 10.120.0.8:46156->35.230.74.219:8132: read: connection timed out serverID=632d489f-9306-4851-b96b-9204b48f5587 agentID=e305f823-5b03-47d3-a898-70031d9f4768

OpenAI 输出如下:

ChatGPT 为我们提供了一套相当不错的想法,说明为什么我们的konnectivity-agent会发生此 rpc 错误.

那么,当这些错误发生时,我们如何自动的获得相关的洞见呢?

第 3 步:使用正确的脚本配置Watcher

什么是 Elastic Watcher?Watcher 是 Elasticsearch 的一个功能,您可以使用它来根据条件创建操作,周期性的查询你的数据并判断是否需要执行操作。Watcher 对于分析任务关键型和业务关键型的数据非常有帮助。例如,您可以监视应用程序日志以查找可能导致更大操作问题的错误。

关于Watcher你可以选择使用 UI 或脚本创建,并决定是手动触发或定期运行。

在本例中,我们将使用脚本,因为我们可以轻松修改它并根据需要运行它。这里,我们使用 DevTools 控制台输入脚本并对其进行测试:

该脚本列在博客末尾的附录。也可以在这里下载。 

该脚本执行以下操作:

1、每五分钟运行一次 2. 在日志中搜索来自容器konnectivity-agent的错误 3. 获取第一个错误消息,对其进行转换(重新格式化和清理),并将其放入变量first_hit.

代码语言:javascript
复制
"script": "return ['first_hit': ctx.payload.first.hits.hits.0._source.message.replace('\"', \"\")]"

4. 错误消息通过以下prompt发送到 OpenAI:

代码语言:javascript
复制
 What are the potential reasons for the following kubernetes error: {{ctx.payload.second.first_hit}}

5.如果搜索找到错误,它将继续创建索引并放置error messagepod.nameOpenAI 的解释到一个名为chatgpt_k8_analyzed的新索引中。 为了查看结果,我们 针对新创建的索引创建了一个名为chatgpt_k8_analyzed的新数据视图:

在 Discover 中,数据视图上的输出为我们提供了错误分析。

对于脚本在五分钟间隔内发现的每个错误,它都会进行错误。我们也可以根据需要,使用range来分析特定时间范围内的情况。您指需要按需修改该脚本。

步骤 4. 对比Azure OpenAI/OpenAI 与 ChatGPT UI 的输出

正如您在上面注意到的那样,我们从 Azure OpenAI API 调用获得的结果与我们在 ChatGPT UI 中测试我们的查询所获得的结果相对相同。这是因为我们将 API 调用配置为使用与 ChatGPT UI 相同/相似的模型。

对于 Azure OpenAI API 的调用,我们使用了以下参数:

代码语言:javascript
复制
"request": {
             "method" : "POST",
             "Url": "https://XXX.openai.azure.com/openai/deployments/pme-gpt-35-turbo/chat/completions?api-version=2023-03-15-preview",
             "headers": {"api-key" : "XXXXXXX",
                         "content-type" : "application/json"
                        },
             "body" : "{ \"messages\": [ { \"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, { \"role\": \"user\", \"content\": \"What are the potential reasons for the following kubernetes error: {{ctx.payload.second.first_hit}}\"}], \"temperature\": 0.5, \"max_tokens\": 2048}" ,
              "connection_timeout": "60s",
               "read_timeout": "60s"
                            }

通过将system的角色设置为You are a helpful assistant,并使用 gpt-35-turbo url 部分,我们实际上是在设置 API 以使用davinci 模型,这与默认设置的 ChatGPT UI 模型相同。

而对于 Azure OpenAI 服务,您需要将 URL 设置为类似于以下内容:

代码语言:javascript
复制
https://YOURSERVICENAME.openai.azure.com/openai/deployments/pme-gpt-35-turbo/chat/completions?api-version=2023-03-15-preview

如果您使用 OpenAI(相对于 Azure OpenAI 服务),请求调用(针对https://api.openai.com/v1/completions)将是这样的:

代码语言:javascript
复制
"request": {
            "scheme": "https",
            "host": "api.openai.com",
            "port": 443,
            "method": "post",
            "path": "\/v1\/completions",
            "params": {},
            "headers": {
               "content-type": "application\/json",
               "authorization": "Bearer YOUR_ACCESS_TOKEN"
                        },
            "body": "{ \"model\": \"text-davinci-003\",  \"prompt\": \"What are the potential reasons for the following kubernetes error: {{ctx.payload.second.first_hit}}\",  \"temperature\": 1,  \"max_tokens\": 512,     \"top_p\": 1.0,      \"frequency_penalty\": 0.0,   \"presence_penalty\": 0.0 }",
            "connection_timeout_in_millis": 60000,
            "read_timeout_millis": 60000
          }

如果您有兴趣创建一个更基于 OpenAI 的版本,您可以下载替代脚本并查看Elastic 社区成员的另一篇博客

不仅仅 Kubernetes 日志之外的其他见解

你可以对脚本的不同部分进行修改:

  • Inputs
  • Conditions
  • Actions
  • Transforms

在此处了解有关如何修改的更多信息。一些修改示例可能包括:

  1. 从应用程序组件(例如,来自 OTel demo的 cartService、frontEnd)、云服务提供商(例如,AWS/Azure/GCP 日志)甚至来自 Kafka、数据库等组件的日志中查找错误日志。
  2. 改变时间范围,从连续运行到在特定范围内运行。 
  3. 在日志中查找特定错误。
  4. 分析一组错误,而非我们演示中的仅分析第一个错误。

修改是无止境的,当然你可以使用 OpenAI 而不是 Azure OpenAI 服务来运行它。

结论

我希望您已经了解 Elastic Observability 如何帮助您连接到 OpenAI 服务(如我们展示的 Azure OpenAI,甚至 OpenAI)以更好地分析错误日志消息,而不必运行多个 Google 搜索并寻找可能的见解。

以下是我们所涵盖内容的快速回顾:

  • 开发可用于查找 Kubernetes 错误并将其发送到 OpenAI 并将其插入到新索引中的 Elastic watcher 脚本
  • 使用正确的授权和请求参数配置 Azure OpenAI 服务或 OpenAI

准备好开始了吗?部署一个Elasticsearch集群,并尝试我在上面概述的特性和功能,以从您的 OpenTelemetry 数据中获得最大价值和可见性。

附录

Watcher 脚本

代码语言:javascript
复制
PUT _watcher/watch/chatgpt_analysis
{
    "trigger": {
      "schedule": {
        "interval": "5m"
      }
    },
    "input": {
      "chain": {
          "inputs": [
              {
                  "first": {
                      "search": {
                          "request": {
                              "search_type": "query_then_fetch",
                              "indices": [
                                "logs-kubernetes*"
                              ],
                              "rest_total_hits_as_int": true,
                              "body": {
                                "query": {
                                  "bool": {
                                    "must": [
                                      {
                                        "match": {
                                          "kubernetes.container.name": "konnectivity-agent"
                                        }
                                      },
                                      {
                                        "match" : {
                                          "message":"error"
                                        }
                                      }
                                    ]
                                  }
                                },
                                "size": "1"
                              }
                            }
                        }
                    }
                },
                {
                    "second": {   
                        "transform": {
                            "script": "return ['first_hit': ctx.payload.first.hits.hits.0._source.message.replace('\"', \"\")]"
                        }
                    }
                },
                {
                    "third": {
                        "http": {
                            "request": {
                                "method" : "POST",
                                "url": "https://XXX.openai.azure.com/openai/deployments/pme-gpt-35-turbo/chat/completions?api-version=2023-03-15-preview",
                                "headers": {
                                    "api-key" : "XXX",
                                    "content-type" : "application/json"
                                },
                                "body" : "{ \"messages\": [ { \"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, { \"role\": \"user\", \"content\": \"What are the potential reasons for the following kubernetes error: {{ctx.payload.second.first_hit}}\"}], \"temperature\": 0.5, \"max_tokens\": 2048}" ,
                                "connection_timeout": "60s",
                                "read_timeout": "60s"
                            }
                        }
                    }
                }
            ]
        }
    },
    "condition": {
      "compare": {
        "ctx.payload.first.hits.total": {
          "gt": 0
        }
      }
    },
    "actions": {
        "index_payload" : {
            "transform": {
                "script": {
                    "source": """
                        def payload = [:];
                        payload.timestamp = new Date();
                        payload.pod_name = ctx.payload.first.hits.hits[0]._source.kubernetes.pod.name;
                        payload.error_message = ctx.payload.second.first_hit;
                        payload.chatgpt_analysis = ctx.payload.third.choices[0].message.content;
                        return payload;
                    """
                }
            },
            "index" : {
                "index" : "chatgpt_k8s_analyzed"
            }
        }
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 先决条件和配置
  • 一切就绪
    • 第一步:Azure OpenAI 服务和授权
      • 第 2 步:识别 Elastic 日志中的 Kubernetes 错误
        • 第 3 步:使用正确的脚本配置Watcher
          • 步骤 4. 对比Azure OpenAI/OpenAI 与 ChatGPT UI 的输出
          • 不仅仅 Kubernetes 日志之外的其他见解
          • 结论
          • 附录
          相关产品与服务
          Elasticsearch Service
          腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档