GO 获取 K8S api 服务器健康状态

bre*_*uts 4 go kubernetes

我有一个 golang 程序,我需要向K8S API server状态 (livez) api添加一个新调用以获取健康状态。

https://kubernetes.io/docs/reference/using-api/health-checks/

该程序应该在 api 服务器的同一个集群上运行并需要获取/livez状态,我试图在 client-go lib 中找到这个 API,但没有找到实现它的方法......

https://github.com/kubernetes/client-go

有没有办法从运行在 API 服务器运行的同一个集群上的 Go 程序中做到这一点?

Mat*_*ich 6

更新(最终答案)

附加

OP 要求我修改答案以显示“微调”或“特定”服务帐户的配置,而不使用集群管理员。

据我所知,/healthz默认情况下每个 pod 都有读取权限。例如,以下内容CronJob在不使用 a 的情况下也能正常工作ServiceAccount

# cronjob
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: is-healthz-ok-no-svc
spec:
  schedule: "*/5 * * * *" # at every fifth minute
  jobTemplate:
    spec:
      template:
        spec:
######### serviceAccountName: health-reader-sa
          containers:
            - name: is-healthz-ok-no-svc
              image: oze4/is-healthz-ok:latest
          restartPolicy: OnFailure
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

原来的

我继续为此写了一个概念证明。你可以在这里找到完整的 repo,但代码在下面。

main.go

package main

import (
    "os"
    "errors"
    "fmt"

    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
)

func main() {
    client, err := newInClusterClient()
    if err != nil {
        panic(err.Error())
    }

    path := "/healthz"
    content, err := client.Discovery().RESTClient().Get().AbsPath(path).DoRaw()
    if err != nil {
        fmt.Printf("ErrorBadRequst : %s\n", err.Error())
        os.Exit(1)
    }

    contentStr := string(content)
    if contentStr != "ok" {
        fmt.Printf("ErrorNotOk : response != 'ok' : %s\n", contentStr)
        os.Exit(1)
    }

    fmt.Printf("Success : ok!")
    os.Exit(0)
}

func newInClusterClient() (*kubernetes.Clientset, error) {
    config, err := rest.InClusterConfig()
    if err != nil {
        return &kubernetes.Clientset{}, errors.New("Failed loading client config")
    }
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        return &kubernetes.Clientset{}, errors.New("Failed getting clientset")
    }
    return clientset, nil
}
Run Code Online (Sandbox Code Playgroud)

文件

FROM golang:latest
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN go build -o main .
CMD ["/app/main"]
Run Code Online (Sandbox Code Playgroud)

部署.yaml

(作为 CronJob)

FROM golang:latest
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN go build -o main .
CMD ["/app/main"]
Run Code Online (Sandbox Code Playgroud)

截屏

成功运行 CronJob

在此处输入图片说明


更新 1

OP 询问如何部署“in-cluster-client-config”,所以我提供了一个示例部署(我正在使用的一个)。

你可以在这里找到回购

示例部署(我使用的是 CronJob,但它可以是任何东西):

cronjob.yaml

# cronjob
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: is-healthz-ok
spec:
  schedule: "*/5 * * * *" # at every fifth minute
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: is-healthz-ok
          containers:
            - name: is-healthz-ok
              image: oze4/is-healthz-ok:latest
          restartPolicy: OnFailure
---
# service account
apiVersion: v1
kind: ServiceAccount
metadata:
  name: is-healthz-ok
  namespace: default
---
# cluster role binding
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: is-healthz-ok
subjects:
  - kind: ServiceAccount
    name: is-healthz-ok
    namespace: default
roleRef:
  kind: ClusterRole
  ##########################################################################
  # Instead of assigning cluster-admin you can create your own ClusterRole #
  # I used cluster-admin because this is a homelab                         #
  ##########################################################################
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
---
Run Code Online (Sandbox Code Playgroud)

rbac.yaml

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: remove-terminating-namespaces-cronjob
spec:
  schedule: "0 */1 * * *" # at minute 0 of each hour aka once per hour
  #successfulJobsHistoryLimit: 0
  #failedJobsHistoryLimit: 0
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: svc-remove-terminating-namespaces
          containers:
          - name: remove-terminating-namespaces
            image: oze4/service.remove-terminating-namespaces:latest
          restartPolicy: OnFailure
Run Code Online (Sandbox Code Playgroud)

原答案

听起来您正在寻找的是来自 client-go 的“in-cluster-client-config”。

请务必记住,当使用“in-cluster-client-config”时,Go 代码中的 API 调用使用“那个”pod 的服务帐户。只是想确保您正在使用有权读取“/livez”的帐户进行测试。

我测试了以下代码,我能够获得“livez”状态..

apiVersion: v1
kind: ServiceAccount
metadata:
  name: svc-remove-terminating-namespaces
  namespace: default
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: crb-namespace-reader-writer
subjects:
- kind: ServiceAccount
  name: svc-remove-terminating-namespaces
  namespace: default
roleRef:
  kind: ClusterRole
  ##########################################################################
  # Instead of assigning cluster-admin you can create your own ClusterRole #
  # I used cluster-admin because this is a homelab                         #
  ##########################################################################
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
---
Run Code Online (Sandbox Code Playgroud)