Отсутствуют разрешения для тестового пользователя - PullRequest
0 голосов
/ 11 февраля 2020

Я использую watcherList, который поддерживается официальной golang kubernetes lib, для получения уведомлений о созданных, обновленных и удаленных сервисах в пространстве имен 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 через адрес API publi c, который определен в переменной k8sAPI. Кроме того, я устанавливаю токен носителя для аутентификации на кластере и пропускаю проверку небезопасного сертификата 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 // косвенный

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Вы можете проверить разрешение учетной записи службы, используя следующую команду:

kubectl auth can-i list services --namespace t1k --as=system:serviceaccount:t1k:t1k-test-serviceaccount

Вам не нужно устанавливать токен вручную ... вы можете использовать InClusterConfig, как в этом примере .Client- go использует токен учетной записи службы, смонтированный в модуле по пути /var/run/secrets/kubernetes.io/serviceaccount, когда используется rest.InClusterConfig ().

0 голосов
/ 18 февраля 2020

Я нашел решение. Атрибут k8sClientSet структуры KubernetesCollector был указателем. Функция отражения пакета pkg/mod/k8s.io/client-go@v0.0.0-20200106225816-7985654fe8ee не может обрабатывать объекты-указатели.

type KubernetesCollector struct {
    ...
    k8sClient *kubernetes.ClientSet
    namespace string
    ...
}

Я заменил k8sClient на CoreV1Interface из k8s.io/client-go/kubernetes/typed/core/v1. Поэтому я изменил вызов для ListWatch.

type KubernetesCollector struct {
   .... 
   iface         corev1.CoreV1Interface
   namespace     string
   ....
}

func (kc *KubernetesCollector) start(ctx context.Context) {
    watchList := cache.NewListWatchFromClient(kc.iface.RESTClient(), "services", kc.namespace, fields.Everything())
    ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...