在gitlab中连接到kubernetes集群的禁止错误CI

Forbidden error to connect to kubernetes cluster in gitlab CI

我正在尝试访问我自己托管的 gitlab 实例中的 kubernetes 集群,如 docs.

中所述
deploy:
  stage: deployment
  script: 
    - kubectl create secret docker-registry gitlab-registry --docker-server="$CI_REGISTRY" --docker-username="$CI_DEPLOY_USER" --docker-password="$CI_DEPLOY_PASSWORD" --docker-email="$GITLAB_USER_EMAIL" -o yaml --dry-run=client | kubectl apply -f -

但我确实收到错误

Error from server (Forbidden): error when retrieving current configuration of:
Resource: "/v1, Resource=secrets", GroupVersionKind: "/v1, Kind=Secret"
Name: "gitlab-registry", Namespace: "gitlab"
from server for: "STDIN": secrets "gitlab-registry" is forbidden: User "system:serviceaccount:gitlab:default" cannot get resource "secrets" in API group "" in the namespace "gitlab"

我不明白错误。为什么我会收到禁止错误?


更新

gitlab实例级集成kubernetes集群

但是 CI 管道中的 运行 kubectl config view 给了我

apiVersion: v1
clusters: null
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null

更新2

感谢 AndD,可以使用此角色/服务帐户创建秘密:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: gitlab
  name: gitlab-deploy
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["secrets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: use-secrets
  namespace: gitlab
subjects:
- kind: ServiceAccount
  name: default
  namespace: gitlab
roleRef:
  kind: ClusterRole
  name: gitlab-deploy
  apiGroup: rbac.authorization.k8s.io

但是运行一个简单的申请这个namespace.yaml文件

apiVersion: v1
kind: Namespace
metadata:
  name: myns

给我一个类似的错误:

Error from server (Forbidden): error when retrieving current configuration of:
Resource: "/v1, Resource=namespaces", GroupVersionKind: "/v1, Kind=Namespace"
Name: "myns", Namespace: ""
from server for: "namespace.yaml": namespaces "myns" is forbidden: User "system:serviceaccount:gitlab:default" cannot get resource "namespaces" in API group "" in the namespace "myns"

我使用 ClusterBinding 使它即使在不同的命名空间下也能正常工作。我做错了什么?

Kubernetes 使用基于角色的访问控制 (RBAC) 来防止 Pods 和用户能够与集群中的资源进行交互,除非他们未经授权。

从错误中,您可以看到 Gitlab 正在尝试使用 secrets 资源,并且还在其命名空间中使用 ServiceAccount default 服务帐户。

这意味着 Gitlab 未配置为使用特定的 ServiceAccount,这意味着它使用默认服务帐户(集群的每个命名空间中都有一个默认服务帐户)


您可以使用 Role / ClusterRoleRoleBinding / ClusterRoleBinding.

将角色授权和权限附加到服务帐户

角色或集群角色描述权限。例如,角色可以是:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: gitlab
  name: secret-user
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["secrets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

这表明“无论谁担任此角色,都可以使用秘密 但只能在命名空间 gitlab 做任何事情(所有动词)”

如果您想在所有命名空间中授予通用权限,您可以改用 ClusterRole,这非常相似。

创建角色后,您可以将其附加到用户、组或服务帐户,例如:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: use-secrets
  namespace: gitlab
subjects:
subjects:
- kind: ServiceAccount
  name: default
  namespace: gitlab
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  kind: Role # this must be Role or ClusterRole
  name: secret-user # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

这会将之前创建的角色绑定到命名空间 gitlab.

中名为 default 的 ServiceAccount

然后,all Pods 运行 在命名空间 gitlab 中并使用 default 服务帐户,将能够使用 secrets(使用角色中列出的动词)但只能在角色指定的命名空间中使用


如您所见,Kubernetes 的这一方面非常复杂且功能强大,因此请查看文档,因为它们确实 很好地解释了一些事情,并且还提供了很多示例:

服务帐户 - https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

RBAC - https://kubernetes.io/docs/reference/access-authn-authz/rbac/

RBAC 资源列表 - How to refer to all subresources in a Role definition?


更新

你没有做错任何事。只是您正在尝试使用资源 namespace 但 Gitlab 没有可以访问该类型资源的绑定。对于您的 ClusterRole,您只是授予它访问 secrets 的权限,仅此而已。

考虑赋予 ClusterRole 更多权限,将其更改为列出您需要访问的所有资源:

rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["secrets", "namespaces", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

例如,这将提供对机密、名称空间和 Pods 的访问权限。

作为替代方案,您可以将 Gitlab 的服务帐户绑定到 cluster-admin 以直接授予它访问 everything.

kubectl create clusterrolebinding gitlab-is-now-cluster-admin \
  --clusterrole=cluster-admin \
  --serviceaccount=gitlab:default

在这样做之前,请考虑以下事项:

Fine-grained role bindings provide greater security, but require more effort to administrate. Broader grants can give unnecessary (and potentially escalating) API access to ServiceAccounts, but are easier to administrate.

因此,首先决定 Gitlab 可以使用哪些资源然后创建一个 Role / ClusterRole 只允许访问这些资源(以及您需要的动词)会更安全