通过 Gin 处理程序函数传输 pod 日志

时间:2021-06-09 16:38:21

标签: go kubernetes go-gin kubernetes-go-client

我正在尝试通过 Gin 处理程序函数将日志从特定 pod 流式传输回客户端

import (
    "context"
    ...
    "github.com/gin-gonic/gin"
    "io"
    v1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    ...
    "k8s.io/client-go/tools/clientcmd"
)

func Logs(c *gin.Context) {
    ...
    clientset := i.getClient(err, configuration)

    options := metav1.ListOptions{
        LabelSelector: fmt.Sprintf("dhis2-id=%d", instance.ID),
    }

    podList, err := clientset.CoreV1().Pods("").List(context.TODO(), options)
    if err != nil {
        log.Fatalln(err)
    }

    if len(podList.Items) > 1 {
        log.Fatalln("More than one pod found... TODO")
    }

    pod := podList.Items[0]

    logOptions := v1.PodLogOptions{
        Follow:    true,
    }

    logs := clientset.
        CoreV1().
        Pods(pod.Namespace).
        GetLogs(pod.Name, &logOptions)

    reader, err := logs.Stream(context.TODO())
    if err != nil {
        log.Fatalln(err)
    }

    c.Stream(func(writer io.Writer) bool {
        _, err := io.Copy(writer, reader)
        if err != nil {
            return false
        }
        return true
    })

    c.Status(http.StatusOK)
}

func getClient(err error, configuration *model.ClusterConfiguration) *kubernetes.Clientset {
    configurationInCleartext, err := configuration.GetKubernetesConfigurationInCleartext()
    if err != nil {
        log.Fatalln(err)
    }

    config, err := clientcmd.NewClientConfigFromBytes(configurationInCleartext)
    if err != nil {
        log.Fatalln(err)
    }

    clientConfig, err := config.ClientConfig()
    if err != nil {
        log.Fatalln(err)
    }

    clientset, err := kubernetes.NewForConfig(clientConfig)
    if err != nil {
        log.Fatalln(err)
    }

    return clientset
}

我面临两个问题

  1. 它不流。它获取日志直到“现在”,然后它不会继续

  2. 它得到的日志被两个换行符分隔,而不仅仅是一个。一个例子可以在下面看到

    ...

    2021/06/09 16:25:55 端点命中:/health

    2021/06/09 16:25:59 端点命中:/health

    2021/06/09 16:26:05 端点命中:/health

    2021/06/09 16:26:09 端点命中:/health

    2021/06/09 16:26:15 端点命中:/health

    2021/06/09 16:26:19 端点命中:/health

    2021/06/09 16:26:25 端点命中:/health

    2021/06/09 16:26:29 端点命中:/health

任何关于我做错了什么的线索?

更新:下面的代码修复了流媒体缺失的问题,但仍有一个\n太多

(灵感来自:https://github.com/kubernetes/kubectl/blob/master/pkg/cmd/logs/logs.go#L418

c.Stream(func(writer io.Writer) bool {
    bytes, err := bufferedReader.ReadBytes('\n')
    if err != nil {
        return false
    }

    _, err = writer.Write(bytes)
    if err != nil {
        return false
    }

    return true
})

0 个答案:

没有答案