Terraform EKS 配置图被禁止
Posted
技术标签:
【中文标题】Terraform EKS 配置图被禁止【英文标题】:Terraform EKS configmaps is forbidden 【发布时间】:2021-11-17 16:28:37 【问题描述】:我正在尝试使用Terraform
在AWS EKS
上部署Kubernetes
集群,从Gitlab CI
管道运行。我的代码目前启动并运行了一个完整的集群,除了有一个步骤尝试将节点(单独创建)添加到集群中。
当它尝试这样做时,这是我收到的错误:
│ Error: configmaps is forbidden: User "system:serviceaccount:gitlab-managed-apps:default" cannot create resource "configmaps" in API group "" in the namespace "kube-system"
│
│ with module.mastercluster.kubernetes_config_map.aws_auth[0],
│ on .terraform/modules/mastercluster/aws_auth.tf line 63, in resource "kubernetes_config_map" "aws_auth":
│ 63: resource "kubernetes_config_map" "aws_auth"
│
Terraform
我相信正在尝试编辑 kube-system
命名空间中的 configmap aws_auth
,但由于某种原因,它没有这样做的权限?
我在 *** 上找到了与几年前不同的答案,目前与文档中关于添加 aws_eks_cluster_auth
数据源并将其添加到 kubernetes
提供程序的内容相匹配。
我目前的配置如下:
data "aws_eks_cluster" "mastercluster"
name = module.mastercluster.cluster_id
data "aws_eks_cluster_auth" "mastercluster"
name = module.mastercluster.cluster_id
provider "kubernetes"
alias = "mastercluster"
host = data.aws_eks_cluster.mastercluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.mastercluster.certificate_authority[0].data)
token = data.aws_eks_cluster_auth.mastercluster.token
load_config_file = false
奇怪的是,这以前对我有用。我已经使用这种方法成功部署了多个集群。这个配置与我之前的配置几乎相同,只是集群的名称不同。我完全不知道为什么这可能会出错。
【问题讨论】:
【参考方案1】:使用semver
锁定hashicorp provider
版本
这就是为什么在 terraform
清单中使用 semver
如此重要的原因。
根据Terraform documentation:
Terraform 提供者通过 Terraform 和目标 API 之间的通信来管理资源。每当目标 API 更改或添加功能时,提供者维护者都可以更新和版本化提供者。
当多个用户或自动化工具运行相同的 Terraform 配置时,他们都应该使用相同版本的所需提供程序。
对Kubernetes
使用RBAC
规则
有一个关于此问题的 Github 问题:v2.0.1: Resources cannot be created. Does kubectl reference to kube config properly? · Issue #1127 · hashicorp/terraform-provider-kubernetes,错误消息与您的情况相同。
还有one of the comments answers:
顺便说一句,这看起来与集群中的RBAC 规则有关(可能已由 helm chart 安装)。此命令可能有助于诊断与错误消息中的服务帐户相关的权限问题。
$ kubectl auth can-i create namespace --as=system:serviceaccount:gitlab-prod:default $ kubectl auth can-i --list --as=system:serviceaccount:gitlab-prod:default
您或许可以将该列表与集群中的其他用户进行比较:
kubectl auth can-i --list --namespace=default --as=system:serviceaccount:default:default
$ kubectl auth can-i create configmaps yes $ kubectl auth can-i create configmaps --namespace=nginx-ingress --as=system:serviceaccount:gitlab-prod:default no
并调查相关的集群角色:
$ kube describe clusterrolebinding system:basic-user Name: system:basic-user Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: system:basic-user Subjects: Kind Name Namespace ---- ---- --------- Group system:authenticated $ kubectl describe clusterrole system:basic-user Name: system:basic-user Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- selfsubjectacces-s-reviews.authorization.k8s.io [] [] [create] selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
我的猜测是有问题的图表或 Terraform 配置负责创建服务帐户以及 [集群] 角色和角色绑定,但它可能以错误的顺序执行此操作,或者不是幂等的(所以你会得到不同重新安装与初始安装的结果)。但是我们需要看到一个重现这个错误的配置。在我对AKS、EKS、GKE 和minikube 上的第 2 版提供程序的测试中,我没有看到这个问题出现。
随意浏览这些构建特定集群并将它们与 Kubernetes 和 Helm 提供程序一起使用的工作示例。略读配置可能会给您一些进一步排除故障的想法。
如何解决RBAC
问题
至于错误
Error: configmaps is forbidden: User "system:serviceaccount:kube-system:default" cannot list
有great explanation by @m-abramovich:
首先,给新手一些信息。 在 Kubernetes 中有:
帐户 - 类似于您的 ID。示例:约翰 角色 - 项目中的某个组允许做某事。示例:cluster-admin、it-support、... 绑定 - 将帐户加入角色。 “John in it-support” - 是一种绑定。因此,在我们上面的消息中,我们看到我们的 Tiller 作为在命名空间“kube-system”注册的帐户“默认”。很可能您没有将他绑定到足够的角色。
现在回到问题上来。 我们如何跟踪它:
检查您是否有特定的 帐户 用于分蘖。通常它具有相同的名称 - “tiller”:kubectl [--namespace kube-system] get serviceaccount
如果没有,请创建:kubectl [--namespace kube-system] create serviceaccount tiller
检查您是否有 role 或 clusterrole(对于新手来说,集群角色“更好” - 它是集群范围的,不像命名空间范围的角色)。如果这不是生产,您可以使用高权限角色“cluster-admin”:kubectl [--namespace kube-system] get clusterrole
您可以通过以下方式查看角色内容:kubectl [--namespace kube-system] get clusterrole cluster-admin -o yaml
检查第一个子句中的 account“tiller”是否与您认为足够的 clusterrole“cluster-admin”绑定:kubectl [--namespace kube-system] get clusterrolebinding
如果根据名称很难弄清楚,您可以简单地创建新的:kubectl [--namespace kube-system] create clusterrolebinding tiller-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
最后,当你有了账号、角色以及它们之间的绑定后,你可以检查一下你是否真的是这个账号:kubectl [--namespace kube-system] get deploy tiller-deploy -o yaml
我怀疑您的输出将没有设置“serviceAccount”和“serviceAccountName”:
dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: terminationGracePeriodSeconds: 30
如果是,则添加一个您希望tiller 使用的帐户:
kubectl [--namespace kube-system] patch deploy tiller-deploy -p '"spec":"template":"spec":"serviceAccount":"tiller"'
(如果您使用 PowerShell,请查看下面来自 @snpdev 的帖子) 现在你重复前面的检查命令,看看有什么不同:dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: serviceAccount: tiller <-- new line serviceAccountName: tiller <-- new line terminationGracePeriodSeconds: 30
资源:
Using RBAC Authorization | Kubernetes Demystifying RBAC in Kubernetes | Cloud Native Computing Foundation Helm | Role-based Access Control Lock and Upgrade Provider Versions | Terraform - HashiCorp Learn【讨论】:
非常感谢您的超级深入的回答。我做了更多的挖掘,似乎没有创建 aws-auth 配置映射,即使它应该是并且 gitlab 有权限。发生这种情况是因为出于某种原因,Terraform 尝试将 configmap 放在 localhost 上的集群中,而不是 EKS 集群中。由于 Terraform 在 pod 内运行,因此它运行的集群会回复身份验证问题。这似乎与我试图在一次 Terraform 运行中添加两个集群这一事实有关。以上是关于Terraform EKS 配置图被禁止的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Terraform 配置 AWS EKS 自动扩缩器?