clientset.AuthorizationV1().SelfSubjectAccessReviews().Create() 的意外结果

Unexpected results from clientset.AuthorizationV1().SelfSubjectAccessReviews().Create()

我正在尝试将 kubectl auth can-i logic 合并到我的代码库中,但是当代码运行时,结果不是我所期望的。

我有 2 个用户 (minikube/jenny)。 minikube 具有完整的集群范围访问权限,但 jenny 仅限于命名空间 role/rolebinding:

kubectl create role "jenny-pod-creator" --verb=create --resource=pod -n "jenny"
kubectl create rolebinding "jenny-creator-binding" --role="jenny-pod-creator" --user="jenny" --namespace="jenny"

使用 cli,我得到了预期的结果:

$ kubectl auth can-i create pod --context jenny -n jenny
yes
$ kubectl auth can-i create pod --context jenny -n default
no - RBAC: role.rbac.authorization.k8s.io "jenny-pod-creator" not found

但在我的代码中,jenny 没有获得创建权限。 response.Status.Allowed 对于 jenny 总是 false(对于 minikube 总是如此)

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "path/filepath"

    authorizationv1 "k8s.io/api/authorization/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    kubeconfig := filepath.Join(
        os.Getenv("HOME"), ".kube", "config",
    )
    config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
    if err != nil {
        log.Fatal(err)
    }
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        log.Fatal(err)
    }
    a := clientset.AuthorizationV1().SelfSubjectAccessReviews()
    sar := &authorizationv1.SelfSubjectAccessReview{
        Spec: authorizationv1.SelfSubjectAccessReviewSpec{
            ResourceAttributes: &authorizationv1.ResourceAttributes{
                Namespace: "jenny",
                Verb:      "create",
                Resource:  "Pod",
            },
        },
    }
    response, err := a.Create(context.TODO(), sar, metav1.CreateOptions{})
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("create resource POD is %v \n", response.Status.Allowed)
}

在 Kubernetes 中有种类和资源的概念。如果您想了解更多, and in API Conventions 中对此有很好的解释。

简而言之:

  1. Kind 是告诉客户端它代表什么样的实体的类型,它总是大写,例如 Pod
  2. Resource 是通过 HTTP 发送的此类实体的表示,始终为小写和复数形式。

在您的情况下,您正在使用 Resource,因此您需要将 Pod (Kind) 更改为 pods (resource),这应该给你 true for jenny。至于 minikube,你总是得到 true 因为该用户是 system:admin,它具有对集群的完全访问权限。