k8s生产实际问题排查(网关,数据库读写等)

1.对于sse请求的网关转发配置

复制代码
annotations:
  higress.io/load-balance: "mcp-sse"

增加sse会话粘性,它确保的是同一个SSE会话 的请求,而不是同一个IP的请求,始终落到最初创建该会话的后端实例 上,当第一次请求的时候,将 Pod-A 的地址(如IP和端口)进行Base64编码 ,然后将这个编码后的字符串作为会话ID 的一部分,通过SSE消息返回给客户端,客户端会在返回中会带上这个包含编码后端地址的会话ID。Higress收到请求后,会直接解码会话ID ,提取出里面绑定的后端地址(Pod-A),然后精准地将请求路由到那个特定的Pod,而不是重新进行负载均衡。

所以设置mcp-sse需要前端同时配合 **在fetchEventSource 请求sse时 在请求头设置x-mcp-session-id 携带返回的sessionid 经实战测试 ,**设置sessionid的时机,应该在onopen的时候,因为onmessage是当服务端主动推送数据时才会触发,如果只在onmessage的时候设置,有可能会造成部分会话丢失,因为没有及时在请求头中携带x-mcp-session-id 具体实现代码如下

javascript 复制代码
 fetchEventSource(import.meta.env.VITE_APP_BASEURL+'/sseConnect', {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${token}`,
            'Accept': 'text/event-stream',
            'x-mcp-session-id': currentSessionId || '', 
          },
        onopen(response){
            console.log('~~~~~~~~~~~~~~~~~sseClient onopen~~~~~~~~~~~~~~~~',response)
 // 检查响应状态
      if (!response.ok) {
        // 响应非 2xx,抛出错误,避免重连
        throw new Error(`SSE 连接失败,状态码: ${response.status}`);
      }
       const sid = response.headers.get('mcp-session-id');
      if (sid) currentSessionId = sid;
      console.log('SSE 连接成功');
          },    
 onmessage(event){
            console.log('Aievent::::::::::::::::;',event)
            let data;
            if(event.data){
               data =JSON.parse(event.data)

            }
            if(data && data.sessionid){
              currentSessionId = data.sessionid
            }
...
}

并且最佳实践是在服务端初次sse实例初始化的时候,连接成功的时候,就先推送一个消息

2. 如果sse 在客户端的onopen都没触发,有可能是网关配置没关闭缓冲配置,同时需要服务端在sse请求的时候,对响应头设置也需要关闭缓冲配置

ingress配置是 proxy_buffering:off

higress和 nginx的配置可能会有所差异,如果当前的网关已经是higress管理的话,使用nginx的方式配置可能不会生效,

nginx.ingress.kubernetes.io/proxy-buffering: "off"

服务端创建sse连接实例时 需要设置关闭缓冲兜底配置x-Accel-buffering防止上面配置因为nginx higress网关没对应没生效的问题

javascript 复制代码
 res.status(200).set({
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      Connection: 'keep-alive',
      'X-Accel-Buffering': 'no' // 重要,绕过网关的缓冲 当proxy_buffering没生效时,否则onopen一直不会触发
      //   'Access-Control-Allow-Origin': '*' // 允许跨域
    });

如果不关闭网关会一直在缓冲,没有返回到客户端数据

3.text-embedding 的 higress网关特殊配置

之前我们在higress网关配置设置的时候对于普通的chat model是配置的/v1 + 模型对应的前缀匹配 具体可见笔者之前的文章

helm 托管 + higress 网关-CSDN博客

对于embedding的模型 由于他请求的路径不是/chat/competations而是/v1/embeddings ,所以需要和之前的/v1到chat的配置单独区分, 根据最长匹配优先,可以在路径匹配 设置/v1/embeddings 这样所有embeddings的请求都会优先打到 /v1/embeddings的网关规则配置,

4.密码环境变量配置的报错 secret 管道修饰符处理错误

如果因为环境变量的问题报错 ,可以进入pod内,执行env | grep '环境变量名' ,在进行secret配置的时候,stringData是为了将数组自动处理base64并添加到data中, | quote 是为了处理成字符串防止yaml解析报错,如果是string则需要手动自己做base64处理 使用,| b64en处理,这次报错就是我已经使用了stringData但是又错误的使用了b64en 然后打印了环境变量发现了报错

5.mongodb数据库写入权限不足报错

排查过程:

在mongodb pod中 mongosh登录后

db.runCommand({ connectionStatus: 1 }) authenticatedUsers 中要包含用户才有权

use admin

db.getUser("admin") 返回的roles里面看 { role: "readWrite", db: "app" } 有没有指定库的写入操作权限

如果没有 db.grantRolesToUser("admin", { role: "readWrite", db: "app" }) 补授权 测试,

后来发现只要每次pod重启请求就会将用户权限刷新,经过科学上网**,发现是在mongoStore部署初始化配置的角色的时候就已经设置固定了,mongodbcommunity 配置,**

javascript 复制代码
users:
  - db: admin
    name: admin
    passwordSecretRef:
      name: mdb-admin-user-password
    roles:
    - db: admin
      name: clusterAdmin
    - db: admin
      name: userAdminAnyDatabase
    - db: admin
      name: readWriteAnyDatabase
    scramCredentialsSecretName: admin-scram

需要给admin用户开启 readWriteAnyDatabase权限,才能有对数据库的读取和使用,

排查技巧:

1.在排查网关请求转发的过程中,可以打印网关日志 即higress-gateway 的logs进行排查 ,重点关注response_code_detail,

如果是route not found则是网关没生效,找不到对应的网关请求路径,根据path能看到实际请求的地址,

kubectl logs -n higress-system -l app=higress-gateway -f --tail=10 | grep -E 'chat/completions'

可以打印过滤指定的higress网关日志

相关推荐
孙克旭_16 分钟前
k8s基础组件与创建资源
运维·docker·容器·kubernetes
孙克旭_43 分钟前
云原生基础之Containerd容器运行时
运维·云原生
分布式存储与RustFS44 分钟前
RustFS 自建对象存储实战目录:110 篇按场景分类(持续更新)
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
无忧_wy1 小时前
MoneyPrinterTurbo 自动化视频生成实战指南
运维·人工智能·自动化·音视频
木头左11 小时前
【Nginx】内网服务源 IP 白名单实战:动态域名解析放行网段 + 端口接管零改造
运维·nginx·白名单·反向代理
禁默12 小时前
启元 Q1 二次开发实践:Ubuntu 部署与仿真验证,从 PrimeConsole 到 ROS 2 Humble + RViz
linux·运维·ubuntu
skywalk816313 小时前
把 去也网站 从 Ubuntu 搬到 FreeBSD:一次 Service Jail + nginx 的部署实录
linux·运维·nginx·ubuntu·freebsd
翔云12345614 小时前
RocksDB中,客户端每写入一次数据,需要访问几次磁盘
运维·数据库·mysql
爱莉希雅&&&15 小时前
GitLab 完整学习笔记
linux·运维·服务器