kubernetes - 在 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 -
但我确实得到了错误
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 中。
但是kubectl config view
在 CI 管道中运行给了我
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) 来防止 Pod 和用户能够与集群中的资源进行交互,除非他们未经授权。
从错误中,您可以看到 Gitlab 正在尝试使用该secrets
资源,并且它正在其命名空间中用作ServiceAccount
服务default
帐户。
这意味着 Gitlab 未配置为使用特定的 ServiceAccount,这意味着它使用了默认服务帐户(集群的每个命名空间中都有一个默认服务帐户)
您可以使用Role
/ClusterRole
和RoleBinding
/将角色身份验证和权限附加到服务帐户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"]
并且这表明“谁拥有这个角色,可以用秘密做任何事情(所有动词),但只能在命名空间中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
这会将先前创建的角色绑定到ServiceAccount
命名空间中的调用默认值gitlab
。
然后,在命名空间中运行并使用服务帐户的所有Pod将能够使用(使用角色中列出的动词),但只能在角色指定的命名空间中使用。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 资源列表 -如何引用角色定义中的所有子资源?
更新
你没有做错什么。只是您正在尝试使用该资源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 只允许访问这些资源(以及您需要的动词),这样会更加安全
推荐阅读
- reactjs - React console.log(i) 打印预览结果
- join - SAS如何高效查找和匹配
- windows - 无法让 Windows Docker 容器“以管理员身份运行”
- python - 打印列表中整数的一部分
- python - 如何从列表元素中提取特定字符串
- node.js - 使用 ng serve (Angular 6) 时,HttpClientModule 和 mat-icons 将不起作用
- r - UseMethod 和 .S3method() 之间有哪些区别?
- android - 如何设置 CameraX 以进行视频录制 Android 应用程序?
- node.js - 无法让 Puppeteer 工作和安装
- mvc-mini-profiler - SQL查询时间在哪里看?