eve*_*der 9 kubernetes terraform kubernetes-helm
我正在尝试在 Terraform 中创建一个模块,以在 Kubernetes 集群中创建基本资源,这意味着一个cert-manager, ingress-nginx(作为入口控制器)和一个ClusterIssuer用于证书。按照这个确切的顺序。
前两个我使用helm_release资源和cluster_issuervia进行安装kubernetes_manifest。
我收到以下错误,经过一些 Google 搜索后,我发现这是因为cert-manager安装了所需的 CRD ,ClusterIssuer但在这个terraform plan阶段,由于它们尚未安装,清单无法检测到ClusterIssuer.
然后,我想知道是否有一种方法可以绕过这个问题,但仍然可以在相同的配置中仅使用一个来创建所有内容terraform apply?
注意:我尝试使用 dependent_on 参数并包含一个time_sleep块,但它没有用,因为计划中没有安装任何内容,这就是它失败的地方
| Error: Failed to determine GroupVersionResource for manifest\n\xe2\x94\x82 \n\xe2\x94\x82 with module.k8s_base.kubernetes_manifest.cluster_issuer,\n\xe2\x94\x82 on ../../modules/k8s_base/main.tf line 37, in resource "kubernetes_manifest" "cluster_issuer":\n\xe2\x94\x82 37: resource "kubernetes_manifest" "cluster_issuer" {\n\xe2\x94\x82 \n\xe2\x94\x82 no matches for kind "ClusterIssuer" in group "cert-manager.io"\nRun Code Online (Sandbox Code Playgroud)\nresource "helm_release" "cert_manager" {\n chart = "cert-manager"\n repository = "https://charts.jetstack.io"\n name = "cert-manager"\n\n create_namespace = var.cert_manager_create_namespace\n namespace = var.cert_manager_namespace\n\n set {\n name = "installCRDs"\n value = "true"\n }\n}\n\nresource "helm_release" "ingress_nginx" {\n name = "ingress-nginx"\n\n repository = "https://kubernetes.github.io/ingress-nginx"\n chart = "ingress-nginx"\n\n create_namespace = var.ingress_nginx_create_namespace\n namespace = var.ingress_nginx_namespace\n\n wait = true\n\n depends_on = [\n helm_release.cert_manager\n ]\n}\n\nresource "time_sleep" "wait" {\n create_duration = "60s"\n\n depends_on = [helm_release.ingress_nginx]\n}\n\nresource "kubernetes_manifest" "cluster_issuer" {\n manifest = {\n "apiVersion" = "cert-manager.io/v1"\n "kind" = "ClusterIssuer"\n "metadata" = {\n "name" = var.cluster_issuer_name\n }\n "spec" = {\n "acme" = {\n "email" = var.cluster_issuer_email\n "privateKeySecretRef" = {\n "name" = var.cluster_issuer_private_key_secret_name\n }\n "server" = var.cluster_issuer_server\n "solvers" = [\n {\n "http01" = {\n "ingress" = {\n "class" = "nginx"\n }\n }\n }\n ]\n }\n }\n }\n depends_on = [helm_release.cert_manager, helm_release.ingress_nginx, time_sleep.wait]\n}\nRun Code Online (Sandbox Code Playgroud)\n
官方文档说在安装它之前使用kubectl apply舵图,使其成为一个两步过程。使用 Terraform,这将使其成为一个 3 步过程,因为您必须应用目标部分来创建集群,以便您可以访问 kubeconfig 凭据,然后运行 kubectl apply 命令来安装 CRD,最后再次运行 terraform apply安装 Helm Chart 和 IaC 的其余部分。这更不理想。
我会kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.crds.yaml按照上面的评论建议使用 kubectl_manifest 资源,但这是不可能的,因为这不会链接到单个 yaml 文件,但其中很多文件将无法跟上更改。不幸的是,Helm Chart 没有“kubectl_apply”terraform 资源**来依赖于首先安装的 CRD。
尽管有这些古怪之处,还是有一个解决方案,那就是使用 helm_release 资源两次。它需要为证书颁发者创建一个模块并引用自定义 helm 图表。考虑到为满足自定义需求而创建它需要花费大量的精力,它并不理想,但一旦创建,它就是一个可重用的模块化解决方案。
#
# Cert-manager
# main.tf
#
resource "helm_release" "cert_manager" {
name = "cert-manager"
repository = "https://charts.jetstack.io"
chart = "cert-manager"
version = var.cert_manager_chart_version
namespace = var.cert_manager_namespace
create_namespace = true
set {
name = "installCRDs"
value = true
}
}
Run Code Online (Sandbox Code Playgroud)
自定义图表参考:
#
# cert-issuer.tf
#
# Cert Issuer using Helm
resource "helm_release" "cert_issuer" {
name = "cert-issuer"
repository = path.module
chart = "cert-issuer"
namespace = var.namespace
set {
name = "fullnameOverride"
value = local.issuer_name
}
set {
name = "privateKeySecretRef"
value = local.issuer_name
}
set {
name = "ingressClass"
value = var.ingress_class
}
set {
name = "acmeEmail"
value = var.cert_manager_email
}
set {
name = "acmeServer"
value = var.acme_server
}
depends_on = [helm_release.cert_manager]
}
Run Code Online (Sandbox Code Playgroud)
你可以看到上面的用法helm_release是在本地引用自己作为存储库,这需要你有一个自定义的 Helm Chart,如下所示:
# ./cluster-issuer/cluster-issuer.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: {{ include "cert-issuer.fullname" . }}
namespace: {{ .Release.Namespace }}
spec:
acme:
# The ACME server URL
server: {{ .Values.acmeServer }}
email: {{ .Values.acmeEmail }}
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: {{ .Values.privateKeySecretRef }}
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: {{ .Values.ingressClass }}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,这避免了 terraform 用来引发错误的依赖项检查,并且可以很好地将其安装在单个apply
通过创建纯图表而不使用values.yaml 值,可以进一步简化这一过程。
** 注意,我认为另一种解决方法是在创建集群后可以使用“local-exec”或“remote-exec”等配置程序直接运行 CRds 的 kubectl apply 命令,但我还没有测试过这一点然而。它还仍然需要您的配置环境安装了 kubectl 并正确配置了 .kubeconfig,从而创建依赖关系树。
另外,这当然不是完全有效的代码。有关要使用或分叉的模块的完整示例,请参阅此 github 存储库。
| 归档时间: |
|
| 查看次数: |
5425 次 |
| 最近记录: |