Terraform EKS 配置图被禁止

Posted

技术标签:

【中文标题】Terraform EKS 配置图被禁止【英文标题】:Terraform EKS configmaps is forbidden 【发布时间】:2021-11-17 16:28:37 【问题描述】:

我正在尝试使用TerraformAWS 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 检查您是否有 roleclusterrole(对于新手来说,集群角色“更好” - 它是集群范围的,不像命名空间范围的角色)。如果这不是生产,您可以使用高权限角色“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 配置 EKS ALB

如何使用 Terraform 配置 AWS EKS 自动扩缩器?

在 EKS 上,我如何验证我通过 Terraform 配置了 Spot 实例

Terraform 用户 TF_VAR 不工作的嵌套模块

Terraform EKS 标记

使用 Terraform 将 `configMap` 应用到 EKS 集群