1

我想运行一个 pod 来监听端点列表的更新(我还没有准备好采用端点集的 alpha 级功能,但我最终会扩展到那个。)

我有这个代码:

package main

import (
    "fmt"
    "os"
    "os/signal"
    "sync"
    "syscall"

    "k8s.io/apimachinery/pkg/util/runtime"
    "k8s.io/client-go/informers"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/cache"
)

func ReadKubeConfig() (*rest.Config, *kubernetes.Clientset, error) {
    config, err := rest.InClusterConfig()
    if err != nil {
            return nil, nil, err
    }
    clients, err := kubernetes.NewForConfig(config)
    if err != nil {
            return nil, nil, err
    }
    return config, clients, nil
}

func main() {
    _, cs, err := ReadKubeConfig()
    if err != nil {
            fmt.Printf("could not create Clientset: %s\n", err)
            os.Exit(1)
    }
    factory := informers.NewSharedInformerFactory(cs, 0)
    ifmr := factory.Core().V1().Endpoints().Informer()
    stop := make(chan struct{})
    ifmr.AddEventHandler(cache.ResourceEventHandlerFuncs{
            AddFunc: func(next interface{}) {
                    fmt.Printf("AddFunc(%v)\n", next)
            },
            UpdateFunc: func(prev, next interface{}) {
                    fmt.Printf("UpdateFunc(%v, %v)\n", prev, next)
            },
            DeleteFunc: func(prev interface{}) {
                    fmt.Printf("DeleteFunc(%v)\n", prev)
            },
    })
    wg := &sync.WaitGroup{}
    wg.Add(1)
    go func() {
            defer runtime.HandleCrash()
            ifmr.Run(stop)
            wg.Done()
    }()
    ch := make(chan os.Signal, 1)
    signal.Notify(ch, os.Interrupt)
    signal.Notify(ch, os.Signal(syscall.SIGTERM))
    signal.Notify(ch, os.Signal(syscall.SIGHUP))
    sig := <-ch
    fmt.Printf("Received signal %s\n", sig)
    close(stop)
    wg.Wait()
}

部署和运行时出现此错误:

kubeendpointwatcher.go:55: Failed to list *v1.Endpoints: endpoints is forbidden: User "system:serviceaccount:eng:default" cannot list resource "endpoints" in API group "" at the cluster scope

我定义了以下角色和角色绑定并将其部署到“eng”命名空间:

watch_endpoints$ kubectl -n eng get role mesh-endpoint-read -o yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: "2021-07-08T19:59:20Z"
  name: mesh-endpoint-read
  namespace: eng
  resourceVersion: "182975428"
  selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/eng/roles/mesh-endpoint-read
  uid: fcadcc2a-19d0-4d6e-bee1-78413f51b91b
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  verbs:
  - get
  - list
  - watch

我有以下角色绑定:

watch_endpoints$ kubectl -n eng get rolebinding mesh-endpoint-read -o yaml | sed -e 's/^/    /g'

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: "2021-07-08T19:59:20Z"
  name: mesh-endpoint-read
  namespace: eng
  resourceVersion: "182977845"
  selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/eng/rolebindings/mesh-endpoint-read
  uid: 705a3e50-2a73-47ed-aa62-0ea48f3493ee
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: mesh-endpoint-read
subjects:
- kind: ServiceAccount
  name: default
  namespace: default

您会注意到,我将它应用于default命名空间和eng命名空间 serviceaccount default,尽管错误消息似乎表明它确实在命名空间中的defaultserviceaccount 中运行eng

我以前使用过按预期工作的 Role 和 RoleBinding 和 ServiceAccount 对象,所以我不明白为什么这不起作用。我错过了什么?

出于测试/复制目的,我通过kubectl cp将构建的二进制文件(cgo off)放入使用kubectl -n eng create deplpoyvanillaubuntu映像运行创建的容器中/bin/sh -c sleep 999999999,然后在该 pod-container 中执行 /bin/bash shell 来运行此程序。

4

1 回答 1

2

您已经创建了rolerolebindingforeng命名空间。但是,根据错误消息:

kubeendpointwatcher.go:55: Failed to list *v1.Endpoints: endpoints is forbidden: User "system:serviceaccount:eng:default" cannot list resource "endpoints" in API group "" at the cluster scope

您正在查询“ cluster”范围内的端点。尝试将您的查询限制为 eng 命名空间或使用clusterrole/clusterbindings

错误消息提供了在命名空间中运行的提示( system:serviceaccount:eng:default),其名称为无权在集群范围内查询。serviceaccountengdefaultep

要验证这一点,您可以运行两个curl调用,首先exec使用相同的方法进入 pod sa,然后对eng命名空间运行以下命令,然后在其他命名空间上尝试。

curl -v --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc/api/v1/namespaces/default/pods
于 2021-07-08T21:34:31.573 回答