gitlab CI 中连接 kubernetes 集群时出现禁止错误

use*_*695 5 gitlab gitlab-ci kubernetes

我正在尝试访问我的自托管 gitlab 实例中的 kubernetes 集群,如文档中所述

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 -
Run Code Online (Sandbox Code Playgroud)

但我确实得到了错误

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"
Run Code Online (Sandbox Code Playgroud)

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


更新

kubernetes 集群在实例级别集成到 gitlab 中。

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

apiVersion: v1
clusters: null
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null
Run Code Online (Sandbox Code Playgroud)

更新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
Run Code Online (Sandbox Code Playgroud)

但是对此namespace.yaml 文件运行一个简单的apply

apiVersion: v1
kind: Namespace
metadata:
  name: myns
Run Code Online (Sandbox Code Playgroud)

给了我类似的错误:

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"
Run Code Online (Sandbox Code Playgroud)

我使用 ClusterBinding 来使其工作,即使对于不同的命名空间也是如此。我究竟做错了什么?

And*_*ndD 6

Kubernetes 利用基于角色的访问控制 (RBAC) 来阻止 Pod 和用户与集群中的资源进行交互,除非未经授权。

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

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


您可以使用Role/ClusterRoleRoleBinding/将角色身份验证和权限附加到服务帐户ClusterRoleBinding

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

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"]
Run Code Online (Sandbox Code Playgroud)

这表明“无论谁拥有这个角色,都可以使用秘密做任何事情(所有动词),但只能在名称空间中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
Run Code Online (Sandbox Code Playgroud)

并将先前创建的角色绑定到ServiceAccount命名空间中被调用的默认角色gitlab

然后,在命名空间中运行并使用服务帐户的所有Pod将能够使用(使用角色中列出的动词),但只能在角色指定的命名空间中使用。gitlabdefaultsecrets


正如您所看到的,Kubernetes 的这方面非常复杂和强大,所以请查看文档,因为它们解释得非常好并且还充满了示例:

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

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

RBAC 资源列表 -如何引用角色定义中的所有子资源?


更新

你没有做错什么。只是您正在尝试使用该资源namespace,但 Gitlab 没有提供对该类型资源的访问权限的 Bind。对于您来说ClusterRole,您只是授予了它访问 的权限secrets,仅此而已。

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

rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["secrets", "namespaces", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
Run Code Online (Sandbox Code Playgroud)

例如,这将允许访问机密、命名空间和 Pod。

作为替代方案,您可以绑定 Gitlab 的服务帐户以cluster-admin直接授予其访问所有内容的权限。

kubectl create clusterrolebinding gitlab-is-now-cluster-admin \
  --clusterrole=cluster-admin \
  --serviceaccount=gitlab:default
Run Code Online (Sandbox Code Playgroud)

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

细粒度的角色绑定提供了更高的安全性,但需要更多的精力来管理。更广泛的授权可以为 ServiceAccounts 提供不必要的(并且可能升级的)API 访问权限,但更容易管理。

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