可视化展示对k8s的pod的请求次数

首先

我决定通过学习 Kubernetes 来做点什么,于是我创建了一个可视化应用程序,用于显示对 Kubernetes 中 Pod 的请求次数。

k8s.gif
delete.gif

为了让客户端能够检测在pod上运行的服务器的启动、停止和API执行,我们使用了以下库。
我们将redis的发布/订阅功能与websocket和redis结合起来,以便从服务器向客户端发送推送通知。

    socket.io サーバー(Next.js)
    "socket.io": "^3.1.0",
    "socket.io-emitter": "^3.2.0",
    "socket.io-redis": "^6.0.1"
    クライアント(Next.js)
    "socket.io-client": "^3.1.0",
    API が実行されると redis のパブリッシュを実行するサーバー(golang)

这个服务器会以副本集的形式进行多次启动。

    "github.com/go-redis/redis/v8"
    redis
        - image: redis:6.0

The code.

    • フロントエンド / socket.io サーバー (Next.js)

 

    • https://github.com/pokotyan/k8s-request-counter

 

    • redis サーバーと、 redis のパブリッシュを実行するサーバー (golang)

 

    https://github.com/pokotyan/k8s-request-counter-emitter

汩汩流淌

将API的执行通知推送给客户端的步骤如下:

当在多个 pod 上启动的 Go 服务器的 API 被执行时,将进行 Redis 的发布操作。

    if err := rdb.Publish(ctx, "EXEC_API", os.Getenv("POD_NAME")).Err(); err != nil {
        fmt.Println(err)
    }

2) 当socket.io服务器接收到redis事件时,会触发websocket事件。

  redis.on("message", (channel, message) => {
    switch (channel) {
      case "EXEC_API":
        emitter.broadcast.emit("NOTICE_EXEC_API", message);
        break;

在订阅 WebSocket 事件的客户端端,绘制请求次数。

  useEffect(() => {
    const socket = io();
    socket.on("connect", () => {
      console.log(`connected, socket_id: ${socket.id}`);
    });
    socket.on("disconnect", () => {
      console.log("socket disconnected!!");
    });
    socket.on("NOTICE_EXEC_API", (podName: string) => {
      // リクエスト回数を更新する処理
    });

以相同的方式,服务器在停止和启动时也会发布redis事件,并以类似的方式通知客户端。

服务器启动时

        if err := rdb.Publish(ctx, "READY_ON", os.Getenv("POD_NAME")).Err(); err != nil {
            fmt.Println(err)
        }

服务器停止时

    if err := rdb.Publish(ctx, "SHUTDOWN", os.Getenv("POD_NAME")).Err(); err != nil {
        fmt.Println(err)
    }

Kubernetes

使用 Kubernetes(k8s)搭建了一个单独 Redis Pod 和多个在高可用副本集中运行的 Golang Pod 的架构一样的配置。

screencapture-localhost-8080-applications-k8s-request-counter-emitter-2021-01-30-14_04_53.png

Redis是一个开源的内存数据结构存储系统。

在使用NodePort服务启动redis后,执行kubectl port-forward svc/redis-service 6379:6379命令,以便在本地主机上进行监听。

这样一来,socket.io服务器就可以通过localhost访问redis了。

import redis from "redis";

const client = redis.createClient(6379, "localhost");

client.subscribe("EXEC_API");
client.subscribe("SHUTDOWN");

export { client };

从 go 服务器访问 redis 时,使用服务名:端口号的方式。

    rdb = redis.NewClient(&redis.Options{
        Addr: "redis-service:6379",
    })

在Go服务器上执行Redis的发布操作

为了应付压力,我选择了 ingress(nginx)=> service(NodePort)=> deployment(nginx、golang)的架构来搭建。

结束

我觉得通过实际亲手触摸,我对事情的理解有所加深。(对于如何处理制作的事物,我总是感到烦恼)
这次我只是在本地测试,下一次我要尝试在一个正式的环境中部署它。

广告
将在 10 秒后关闭
bannerAds