go - 缺少测试用户的权限
问题描述
我使用官方 golang kubernetes lib 支持的 watcherList 来获取有关 kubernetes 命名空间内创建、更新和删除服务的通知。这里是片段。
func (kc *KubernetesCollector) streamEvents(ctx context.Context) {
kc.debugChannel <- fmt.Sprintf("Start streaming events from kubernetes API")
watchList := cache.NewListWatchFromClient(kc.k8sClient.RESTClient(), "services", kc.k8sNamespace, fields.Everything())
notificationCallbackToAddService := func(svc interface{}) {
service := svc.(*v1.Service)
kc.serviceNotificationChannel <- &serviceNotification{service, "add"}
}
notificationCallbackToDeleteService := func(svc interface{}) {
service := svc.(*v1.Service)
kc.serviceNotificationChannel <- &serviceNotification{service, "remove"}
}
callbacks := cache.ResourceEventHandlerFuncs{
AddFunc: notificationCallbackToAddService,
DeleteFunc: notificationCallbackToDeleteService,
}
_, controller := cache.NewInformer(watchList, &v1.Service{}, time.Second*0, callbacks)
go controller.Run(ctx.Done())
}
在我的测试中,我声明了kc.k8sClient
在k8sAPI
变量中定义的公共 api 地址。此外,我将承载令牌设置为针对集群进行身份验证并跳过验证不安全的 ssl 证书。
func TestK8sWatchList(t *testing.T) {
require := require.New(t)
...
k8sConfig, err := clientcmd.BuildConfigFromFlags(k8sAPI, "")
require.NoError(err)
k8sConfig.BearerToken = "<bearerToken>"
k8sConfig.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
k8sClient, err := kubernetes.NewForConfig(k8sConfig)
k8sCollector := NewK8sCollector(k8sClient, k8sNamespace)
...
}
当我执行测试时,我收到以下错误消息:
go test -v -timeout 500s <replaced>/t1k/pkg/collector -run TestK8sWatchList
=== RUN TestK8sWatchList
11.02.2020 16:55:55 DEBUG: Start streaming events from kubernetes API
E0211 16:55:51.706530 121803 reflector.go:153] pkg/mod/k8s.io/client-go@v0.0.0-20200106225816-7985654fe8ee/tools/cache/reflector.go:105: Failed to list *v1.Service: forbidden: User "system:serviceaccount:t1k:t1k-test-serviceaccount" cannot get path "/namespaces/t1k/services"
E0211 16:55:52.707520 121803 reflector.go:153] pkg/mod/k8s.io/client-go@v0.0.0-20200106225816-7985654fe8ee/tools/cache/reflector.go:105: Failed to list *v1.Service: forbidden: User "system:serviceaccount:t1k:t1k-test-serviceaccount" cannot get path "/namespaces/t1k/services"
E0211 16:55:53.705539 121803 reflector.go:153] pkg/mod/k8s.io/client-go@v0.0.0-20200106225816-7985654fe8ee/tools/cache/reflector.go:105: Failed to list *v1.Service: forbidden: User "system:serviceaccount:t1k:t1k-test-serviceaccount" cannot get path "/namespaces/t1k/services"
我不明白为什么会收到错误消息,因为我认为服务帐户“t1k-test-serviceaccount”具有所有必需的权限。现在为测试用户定义了服务帐户、角色和角色绑定。
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: t1k
name: t1k-test-serviceaccount
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: t1k
name: t1k-test-role
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: t1k
name: t1k-test-rolebinding
subjects:
- name: t1k-test-serviceaccount
kind: ServiceAccount
apiGroup: ""
roleRef:
name: t1k-test-role
kind: Role
apiGroup: rbac.authorization.k8s.io
附加信息:
- kubeadm 版本 1.15.9
- kubectl 版本 1.17.2
- golib 版本
- k8s.io/api v0.17.2
- k8s.io/apimachinery v0.17.2
- k8s.io/client-go v0.0.0-20200106225816-7985654fe8ee
- k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31 //间接
解决方案
您可以使用以下命令检查服务帐户的权限:
kubectl auth can-i list services --namespace t1k --as=system:serviceaccount:t1k:t1k-test-serviceaccount
您不需要手动设置令牌...您可以InClusterConfig
像本示例中那样使用。Client-go 使用挂载在 Pod 内的服务帐户令牌,位于 /var/run/secrets/kubernetes.io/serviceaccount 路径时使用了 rest.InClusterConfig()。
推荐阅读
- ios - 如何从 iOS 上的文件应用程序共享文件夹?
- python - 解析回调时的 Scrapy 请求“IndentationError:意外缩进”
- ios - RxSwift onNext 不调用扫描
- elasticsearch - ElasticSearch - 将数据节点添加到现有集群。最佳做法是什么?
- javascript - 为什么 Number.isNaN('abc') 的结果为假?
- javascript - 为什么 textarea 的宽度和普通 div 的边框之间存在差异?
- python - 存储和访问函数是 Enum 的一个很好的用例吗?
- android - 具有 9 个补丁的多个阴影层?
- c++ - 引用派生类时基类的对象大小
- django - 将列表传递给 geodjango 多面体查找