Вопрос или проблема
Я работаю над новым кластером K8s с Terraform и испытываю проблемы с установкой издателя сертификатов.
Вот моя текущая настройка.
sealed-secrets.tf:
# helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets && helm repo update
resource "helm_release" "sealed_secrests" {
count = 1
name = "sealed-secrets"
namespace = "argocd"
repository = "https://bitnami-labs.github.io/sealed-secrets"
chart = "sealed-secrets"
version = "2.17.1"
timeout = 600
create_namespace = true
cleanup_on_fail = true
# dependency_update = true
# verify = true
}
cert-manager.tf:
# helm repo add jetstack https://charts.jetstack.io && helm repo update
data "http" "cert_manager_crds_yaml" {
url = "https://github.com/cert-manager/cert-manager/releases/download/v1.16.3/cert-manager.crds.yaml"
}
resource "kubectl_manifest" "cert_manager_crds" {
yaml_body = data.http.cert_manager_crds_yaml.response_body
}
resource "helm_release" "cert_manager" {
count = 1
name = "cert-manager"
namespace = "cert-manager"
repository = "https://charts.jetstack.io"
chart = "cert-manager"
version = "v1.16.3"
timeout = 600
create_namespace = true
cleanup_on_fail = true
# dependency_update = true
# verify = true
values = [ file("values/cert-manager.yaml") ]
depends_on = [kubectl_manifest.cert_manager_crds]
}
# Подключение к Cloudflare
data "local_file" "cloudflare_api_token_secret_file" {
filename = "secrets/cloudflare-api-token-secret.yaml"
}
resource "kubectl_manifest" "cloudflare_api_token_secret" {
yaml_body = data.local_file.cloudflare_api_token_secret_file.content
depends_on = [ helm_release.cert_manager ]
}
data "local_file" "certificate_issuer_manifest_file" {
filename = "manifests/cert-issuer.yaml"
}
resource "kubectl_manifest" "certificate_issuer" {
yaml_body = data.local_file.certificate_issuer_manifest_file.content
depends_on = [ kubectl_manifest.cloudflare_api_token_secret, helm_release.cert_manager ]
}
cloudflare-api-token-secret.yaml:
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
namespace: ambassador
type: Opaque
stringData:
api-token: ********
cert-issuer.yaml:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: cloudflare-ambassador-wcard
namespace: ambassador
spec:
# Конфигурация издателя ACME:
# `email` - электронная почта, связанная с учетной записью ACME (убедитесь, что она действительна).
# `server` - URL-адрес, используемый для доступа к конечной точке каталога сервера ACME.
# `privateKeySecretRef` - Секрет Kubernetes для хранения автоматически сгенерированного приватного ключа учетной записи ACME.
acme:
email: ****@*****.****
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: cloudflare-ambassador-wcard-private
# Список решателей вызовов, которые будут использоваться для решения вызовов ACME для соответствующих доменов.
solvers:
- dns01:
cloudflare:
email: ****@*****.****
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
selector:
dnsNames:
- '*.priz.guru'
- 'priz.guru'
Все устанавливается как ожидалось, пока не доходит до Издателя.
Вот ошибка, которую я получаю:
2025-01-20T23:34:51.580-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: 2025/01/20 23:34:51 [ERROR] creating manifest failed: ambassador/cloudflare-ambassador-wcard failed to create kubernetes rest client for update of resource: resource [cert-manager.io/v1/Issuer] isn't valid for cluster, check the APIVersion and Kind fields are valid
2025-01-20T23:34:55.286-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: 2025/01/20 23:34:55 [DEBUG] ambassador/cloudflare-ambassador-wcard Unstructed YAML: map[apiVersion:cert-manager.io/v1 kind:Issuer metadata:map[name:cloudflare-ambassador-wcard namespace:ambassador] spec:map[acme:map[email:[email protected] privateKeySecretRef:map[name:cloudflare-ambassador-wcard-private] server:https://acme-v02.api.letsencrypt.org/directory solvers:[map[dns01:map[cloudflare:map[apiTokenSecretRef:map[key:api-token name:cloudflare-api-token-secret] email:[email protected]]] selector:map[dnsNames:[*.priz.guru priz.guru]]]]]]]
2025-01-20T23:34:55.286-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: 2025/01/20 23:34:55 [DEBUG] ambassador/cloudflare-ambassador-wcard apply kubernetes resource:
2025-01-20T23:34:55.286-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: apiVersion: cert-manager.io/v1
2025-01-20T23:34:55.286-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: kind: Issuer
2025-01-20T23:34:55.286-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: metadata:
2025-01-20T23:34:55.286-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: name: cloudflare-ambassador-wcard
2025-01-20T23:34:55.286-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: namespace: ambassador
2025-01-20T23:34:55.286-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: spec:
2025-01-20T23:34:55.286-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: # Конфигурация издателя ACME:
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: # `email` - электронная почта, связанная с учетной записью ACME (убедитесь, что она действительна).
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: # `server` - URL-адрес, используемый для доступа к конечной точке каталога сервера ACME.
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: # `privateKeySecretRef` - Секрет Kubernetes для хранения автоматически сгенерированного приватного ключа учетной записи ACME.
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: acme:
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: email: [email protected]
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: server: https://acme-v02.api.letsencrypt.org/directory
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: privateKeySecretRef:
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: name: cloudflare-ambassador-wcard-private
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: # Список решателей вызовов, которые будут использоваться для решения вызовов ACME для соответствующих доменов.
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: solvers:
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: - dns01:
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: cloudflare:
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: email: [email protected]
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: apiTokenSecretRef:
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: name: cloudflare-api-token-secret
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: key: api-token
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: selector:
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: dnsNames:
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: - '*.priz.guru'
2025-01-20T23:34:55.287-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: - 'priz.guru'
2025-01-20T23:34:55.359-0800 [DEBUG] provider.terraform-provider-kubectl_v1.19.0: 2025/01/20 23:34:55 [ERROR] creating manifest failed: ambassador/cloudflare-ambassador-wcard failed to create kubernetes rest client for update of resource: resource [cert-manager.io/v1/Issuer] isn't valid for cluster, check the APIVersion and Kind fields are valid
2025-01-20T23:34:55.359-0800 [ERROR] provider.terraform-provider-kubectl_v1.19.0: Response contains error diagnostic: @module=sdk.proto tf_proto_version=5.7 tf_req_id=2faebf9b-8624-79dd-3b0d-cd4b01ce8f47 @caller=github.com/hashicorp/[email protected]/tfprotov5/internal/diag/diagnostics.go:58 diagnostic_detail="" diagnostic_severity=ERROR diagnostic_summary="ambassador/cloudflare-ambassador-wcard failed to create kubernetes rest client for update of resource: resource [cert-manager.io/v1/Issuer] isn't valid for cluster, check the APIVersion and Kind fields are valid" tf_provider_addr="" tf_resource_type=kubectl_manifest tf_rpc=ApplyResourceChange timestamp=2025-01-20T23:34:55.359-0800
2025-01-20T23:34:55.583-0800 [DEBUG] State storage *statemgr.Filesystem declined to persist a state snapshot
2025-01-20T23:34:55.583-0800 [ERROR] vertex "kubectl_manifest.certificate_issuer" error: ambassador/cloudflare-ambassador-wcard failed to create kubernetes rest client for update of resource: resource [cert-manager.io/v1/Issuer] isn't valid for cluster, check the APIVersion and Kind fields are valid
╷
│ Error: ambassador/cloudflare-ambassador-wcard failed to create kubernetes rest client for update of resource: resource [cert-manager.io/v1/Issuer] isn't valid for cluster, check the APIVersion and Kind fields are valid
│
│ with kubectl_manifest.certificate_issuer,
│ on cert-manager.tf line 45, in resource "kubectl_manifest" "certificate_issuer":
│ 45: resource "kubectl_manifest" "certificate_issuer" {
│
╵
2025-01-20T23:34:55.823-0800 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2025-01-20T23:34:55.825-0800 [INFO] provider: plugin process exited: plugin=.terraform/providers/registry.terraform.io/gavinbunney/kubectl/1.19.0/darwin_amd64/terraform-provider-kubectl_v1.19.0 id=15363
Я все перепроверил:
- У меня установлена правильная поддерживаемая версия API cert-manager.
- Если отключить шаг создания Издателя, все остальное применяется правильно.
Я не уверен, куда еще копать…
Ответ или решение
Ошибка, с которой вы столкнулись, связана с установкой объекта типа Issuer
из CRD (Custom Resource Definition) cert-manager.io/v1
в Kubernetes-кластере с использованием Terraform и манифестов Helm. Давайте разберем эту проблему более подробно и предложим возможные решения.
Теория
Ошибка гласит, что ресурс [cert-manager.io/v1/Issuer]
не является допустимым для кластера, и необходимо проверить, корректны ли поля APIVersion
и Kind
. Это говорит о том, что Kubernetes REST клиент, использующийся для работы с ресурсами в вашем кластере, не может найти или распознать Issuer
, что может быть связано с несколькими возможными проблемами:
- Несовместимость версий: Версия cert-manager, которую вы используете, может не поддерживать задекларированные API ресурсы.
- Отсутствие CRD: Для использования Issuer в вашем кластере должен быть установлен CRD
cert-manager.io/v1
. Если этого нет, ресурс не сможет корректно создаться. - Проблемы с настройками Namespace: Использование некорректного Namespace также может стать причиной ошибки, если необходимые зависимости отсутствуют в нужном пространстве имён.
Пример
Ситуации, когда возникает подобная ошибка:
- Обновление кластера, но не обновление CRD для cert-manager.
- Неправильное указание Namespace для манифеста Issuer, когда cert-manager не обнаружен в указанном пространстве имён.
- Установка новой версии cert-manager без учёта изменений в API.
Применение
Для решения проблемы необходимо предпринять следующие шаги:
-
Проверьте установку CRD: Убедитесь, что Custom Resource Definitions для
cert-manager
действительно применены. Используйте следующую команду для проверки установленных CRD:kubectl get crd | grep issuers.cert-manager.io
Если CRD отсутствует, вручную примите файл
cert-manager.crds.yaml
, который вы загрузили ранее:kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.3/cert-manager.crds.yaml
-
Верность конфигурации: Откройте ваш файл
cert-issuer.yaml
и убедитесь, что все ссылки, такие как API версии и пространоства имён, соответствуют актуальной версии cert-manager и вашему кластеру. -
Отладка зависимости: Возможно, следует пересмотреть блок
depends_on
в конфигурации Terraform. Убедитесь, что ресурсы, от которых зависит ваш Issuer, действительно установлены и доступны. -
Проверка Namespace: Убедитесь, что Namespace
ambassador
, указанный в ваших манифестах, действительно существует, и в нём доступны все указанные ресурсы. -
Проверка версии: Хотя вы утверждаете, что версия cert-manager API поддерживается, двойная проверка версии Kubernetes и ее совместимости с версией cert-manager не будет лишней.
-
Обновление провайдеров Terraform: Иногда проблема может заключаться в версии Terraform провайдера. Проверьте, что версия
terraform-provider-kubectl
актуальна и известна о всех CRD вашего кластера. -
Логи и выводы: Перепроверьте любые другие связанные с ошибкой логи, так как они могут дать дополнительную информацию о том, где система не может найти ресурс или почему его не может распознать.
Заключение
Ваша проблема, вероятно, связана с тем, что не все части вашего окружения корректно настроены для работы с cert-manager. Выполнив перечисленные шаги и тщательно проверив все конфигурации, вы сможете выявить и устранить причину ошибки. Работа с инфраструктурой как кодом требует особого внимания к версиям и совместимости, и ваш случай не исключение. Пожалуйста, следите за обновлениями документации к используемым инструментам и библиотекам, и это поможет избежать подобных проблем в будущем.