在 gitlab CI 中连接到 kubernetes 集群时出现禁止错误
Posted
技术标签:
【中文标题】在 gitlab CI 中连接到 kubernetes 集群时出现禁止错误【英文标题】:Forbidden error to connect to kubernetes cluster in gitlab CI 【发布时间】:2021-11-10 17:37:03 【问题描述】:我正在尝试在我的自托管 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"
我不明白这个错误。为什么会出现禁止错误?
更新
kubernetes 集群在实例级别集成在 gitlab 中。
但是在 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 来让它工作,即使是在不同的命名空间。我做错了什么?
【问题讨论】:
【参考方案1】:Kubernetes 使用基于角色的访问控制 (RBAC) 来防止 Pod 和用户能够与集群中的资源进行交互,除非他们未经授权。
从错误中,您可以看到 Gitlab 正在尝试使用 secrets
资源,并且它在其命名空间中使用 ServiceAccount
default
服务帐户。
这意味着 Gitlab 没有配置为使用特定的 ServiceAccount,这意味着它使用了默认的(集群的每个命名空间中都有一个默认的服务帐户)
您可以使用 Role
/ ClusterRole
和 RoleBinding
/ ClusterRoleBinding
将角色身份验证和权限附加到服务帐户。
Roles 或 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"]
这表明“拥有这个角色的人,可以用秘密但只能在命名空间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
。
然后,所有在命名空间 gitlab
中运行并使用 default
服务帐户的 Pod 将能够使用 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 没有 Bind 可以访问该类型的资源。使用您的 ClusterRole
,您只需授予它访问 secrets
的权限,仅此而已。
考虑赋予 ClusterRole 更多权限,将其更改为列出您需要访问的所有资源:
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["secrets", "namespaces", "pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
例如,这将提供对机密、命名空间和 Pod 的访问权限。
作为替代方案,您可以将 Gitlab 的服务帐户绑定到 cluster-admin
以直接授予它访问一切的权限。
kubectl create clusterrolebinding gitlab-is-now-cluster-admin \
--clusterrole=cluster-admin \
--serviceaccount=gitlab:default
在这样做之前,请考虑以下事项:
细粒度的角色绑定提供更高的安全性,但需要更多 努力管理。更广泛的赠款可以提供不必要的(和 可能会升级)对 ServiceAccounts 的 API 访问,但更容易 管理。
因此,首先决定 Gitlab 可以使用哪些资源,然后创建一个 Role / ClusterRole 只允许访问这些资源(以及您需要的动词)会更加安全
【讨论】:
非常感谢您的精彩解释。我已经更新了帖子,因为现在我可以自己创建秘密,但我仍然收到类似的错误,只是为了应用文件 @user3142695 我用更多信息更新了答案。通常,您需要列出并绑定您想要访问的所有资源。您还可以使用某些角色或通配符来授予对所有内容(或大多数内容)的访问权限,但这当然有可能升级为问题的缺点(例如,如果您不信任的容器需要在命名空间中运行,您想限制它可以做什么)。如果您查看 RBAC 文档,那里有很多关于最佳实践的示例和说明!以上是关于在 gitlab CI 中连接到 kubernetes 集群时出现禁止错误的主要内容,如果未能解决你的问题,请参考以下文章
Jenkins + Gitlab + harbor + Kubernetes实现CI/CD
Jenkins + Gitlab + harbor + Kubernetes实现CI/CD
如何将 gitlab ci/cd 变量传递给 kubernetes(AKS) deployment.yaml
如何将 GitLab-Ci 与 Azure Kubernetes + Kubectl + ACR 集成以进行部署?
如何将 Azure AKS Kubernetes 集群自签名 CA 添加到 GitLab CI/CD Kubernetes 集成?