Если спросить опытного многомудрого инженера, что он думает о cert-manager и почему все им пользуются, то спец вздохнёт, доверительно обнимет и устало скажет: «Все им пользуются, потому что нет альтернатив вменяемых. Наши мыши плачут, колются, но продолжают жить с этим кактусом. Почему любим? Потому что работает. Почему не любим? Потому что постоянно выходят новые версии, которые используют новые фичи. И приходится раз за разом обновлять кластер. А старые версии перестают работать, потому что заговор есть и великое таинственное шаманство».

Но разработчики уверяют, что с cert-manager 1.0 всё изменится.

Поверим?

Cert-manager - «родной» контроллер управления сертификатами Kubernetes. С его помощью можно выпустить сертификаты из различных источников: Let's Encrypt, HashiCorp Vault, Venafi, пары ключей для подписи и самоподписанных. Он также позволяет поддерживать ключи актуальными по времени действия, а также пытается автоматически обновлять сертификаты в заданное до их истечения время. Cert-manager основан на kube-lego, а также использовал некоторые приемы из других схожих проектов, например kube-cert-manager.

Примечания к выпуску

Версией 1.0 мы ставим знак доверия за три года разработки проекта cert-manager. За это время он значительно развился в функциональности и стабильности, но больше всего - в сообществе. Сегодня мы видим, как многие люди используют его для защиты своих кластеров Kubernetes, а также проводят внедрение в различные части экосистемы. В последних 16 выпусках было исправлено куча ошибок. А то, что надо было сломать - сломано. Несколько заходов по работе с API улучшили его взаимодействие с пользователями. Мы решили 1500 проблем на GitHub с еще большим числом запросов на слияние от 253 участников сообщества.

Выпуская 1.0 мы официально заявляем, что cert-manager - зрелый проект. Мы также обещаем поддерживать совместимость нашего API v1.

Огромная благодарность всем, кто нам помогал делать cert-manager все эти три года! Пусть версия 1.0 станет первым из многих будущих больших достижений.

Выпуск 1.0 - стабильный выпуск с несколькими приоритетными направлениями:

  • v1 API;

  • Команда kubectl cert-manager status, для помощи при анализе проблем;

  • Использование новейших стабильных API Kubernetes;

  • Улучшенное журналирование;

  • Улучшения ACME.

Перед обновлением обязательно прочитайте примечания к обновлению.

API v1

Версия v0.16 работала с API v1beta1. Это добавило некоторые структурные изменения, а также улучшило документацию по полям API. Версия 1.0 опирается на это все с помощью API v1. Этот API является нашим первым стабильным, в то же время мы уже давали гарантии совместимости, но с API v1 мы обещаем поддерживать совместимость на годы вперед.

Внесенные изменения (примечание: наши средства для конвертирования позаботятся обо всем для вас):

Сертификат:

  • emailSANs теперь называется emailAddresses

  • uriSANs - uris

Эти изменения добавляют совместимость с другими SAN (subject alt names, прим. переводчика), а также с Go API. Мы убираем этот термин из нашего API.

Обновление

Если вы используете Kubernetes 1.16+ - конвертирующие webhooks позволят вам одновременно и бесшовно работать с версиями API v1alpha2, v1alpha3, v1beta1 и v1. С их помощью вы сможете использовать новую версию API без изменения или повторного развертывания ваших старых ресурсов. Мы настоятельно рекомендуем выполнить обновление манифестов до API v1, поскольку предыдущие версии скоро будут объявлены устаревшими. Пользователи legacy версии cert-manager будут по-прежнему иметь доступ только к v1, шаги по обновлению можно найти здесь.

Команда kubectl cert-manager status

C новыми улучшениями в нашем расширении к kubectl стало проще исследовать проблемы, связанные с невыдачей сертификатов. kubectl cert-manager status теперь выдает намного больше информации о том, что происходит с сертификатами, а также показывает этап выдачи сертификата.

После установки расширения вы можете запустить kubectl cert-manager status certificate <имя-сертификата>, что приведет к поиску сертификата с указанным именем и любых связанных ресурсов, например CertificateRequest, Secret, Issuer, а также Order и Challenges в случае использования сертификатов от ACME.

Пример отладки еще не готового сертификата:

$ kubectl cert-manager status certificate acme-certificate

Name: acme-certificate
Namespace: default
Created at: 2020-08-21T16:44:13+02:00
Conditions:
  Ready: False, Reason: DoesNotExist, Message: Issuing certificate as Secret does not exist
  Issuing: True, Reason: DoesNotExist, Message: Issuing certificate as Secret does not exist
DNS Names:
- example.com
Events:
  Type    Reason     Age   From          Message
  ----    ------     ----  ----          -------
  Normal  Issuing    18m   cert-manager  Issuing certificate as Secret does not exist
  Normal  Generated  18m   cert-manager  Stored new private key in temporary Secret resource "acme-certificate-tr8b2"
  Normal  Requested  18m   cert-manager  Created new CertificateRequest resource "acme-certificate-qp5dm"
Issuer:
  Name: acme-issuer
  Kind: Issuer
  Conditions:
    Ready: True, Reason: ACMEAccountRegistered, Message: The ACME account was registered with the ACME server
error when finding Secret "acme-tls": secrets "acme-tls" not found
Not Before: <none>
Not After: <none>
Renewal Time: <none>
CertificateRequest:
  Name: acme-certificate-qp5dm
  Namespace: default
  Conditions:
    Ready: False, Reason: Pending, Message: Waiting on certificate issuance from order default/acme-certificate-qp5dm-1319513028: "pending"
  Events:
    Type    Reason        Age   From          Message
    ----    ------        ----  ----          -------
    Normal  OrderCreated  18m   cert-manager  Created Order resource default/acme-certificate-qp5dm-1319513028
Order:
  Name: acme-certificate-qp5dm-1319513028
  State: pending, Reason:
  Authorizations:
    URL: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/97777571, Identifier: example.com, Initial State: pending, Wildcard: false
Challenges:
- Name: acme-certificate-qp5dm-1319513028-1825664779, Type: DNS-01, Token: J-lOZ39yNDQLZTtP_ZyrYojDqjutMAJOxCL1AkOEZWw, Key: U_W3gGV2KWgIUonlO2me3rvvEOTrfTb-L5s0V1TJMCw, State: pending, Reason: error getting clouddns service account: secret "clouddns-accoun" not found, Processing: true, Presented: false

Команда также может помочь узнать подробнее о содержимом сертификата. Пример детализации для сертификата, выданного Letsencrypt:

$ kubectl cert-manager status certificate example
Name: example
[...]
Secret:
  Name: example
  Issuer Country: US
  Issuer Organisation: Let's Encrypt
  Issuer Common Name: Let's Encrypt Authority X3
  Key Usage: Digital Signature, Key Encipherment
  Extended Key Usages: Server Authentication, Client Authentication
  Public Key Algorithm: RSA
  Signature Algorithm: SHA256-RSA
  Subject Key ID: 65081d98a9870764590829b88c53240571997862
  Authority Key ID: a84a6a63047dddbae6d139b7a64565eff3a8eca1
  Serial Number: 0462ffaa887ea17797e0057ca81d7ba2a6fb
  Events:  <none>
Not Before: 2020-06-02T04:29:56+02:00
Not After: 2020-08-31T04:29:56+02:00
Renewal Time: 2020-08-01T04:29:56+02:00
[...]

Использование новейших стабильных API Kubernetes

Cert-manager был одним из первых, кто внедрил Kubernetes CRDs. Это, а также наша поддержка версий Kubernetes вплоть до 1.11, привели к тому, что нам надо было поддерживать устаревший apiextensions.k8s.io/v1beta1 для наших CRD, а также admissionregistration.k8s.io/v1beta1 для наших webhooks. Сейчас они устарели и будут удалены в Kubernetes с версии 1.22. С нашей 1.0 мы теперь предлагаем полную поддержку apiextensions.k8s.io/v1 и admissionregistration.k8s.io/v1 для Kubernetes 1.16 (где они были добавлены) и новее. Для пользователей предыдущих версий мы продолжаем предлагать поддержку v1beta1 в нашей legacy версии.

Улучшенное журналирование

В этой версии мы обновили библиотеку для журналирования до klog/v2, используемой в Kubernetes 1.19. Мы также проверяем каждый журнал, который пишем, для назначения ему соответствующего уровня. Мы руководствовались при этом руководством от Kubernetes. Есть пять (по факту - шесть, прим. переводчика) уровней журналирования, начиная с Error (уровень 0), который выводит только важные ошибки, и заканчивая Trace (уровень 5), который поможет узнать точно, что происходит. Этим изменением мы сократили количество журналов, если вым не нужна отладочная информация при работе cert-manager.

Совет: по-умолчанию cert-manager работает на уровне 2 (Info), вы можете переопределить это используя global.logLevel в Helm chart.

Примечание: просмотр журналов - последнее средство при устранении неполадок. Для дополнительной информации ознакомьтесь с нашим руководством.

N.B. редактора: Чтобы подробнее узнать, как это всё работает под капотом у Kubernetes, получить ценные советы у практиков-преподавателей, а также качественную помощь техподдержки, можно принять участие в онлайн-интенсивах Kubernetes База, который пройдёт 28-30 сентября, и Kubernetes Мега, который пройдёт 14–16 октября.

Улучшения ACME

Наиболее частое применение cert-manager возможно связано с выпуском сертификатов от Let's Encrypt используя ACME. Версия 1.0 примечательна использованием отзывов от сообщества для добавления двух небольших, но важных улучшений в наш ACME issuer.

Отключение создания ключа учетной записи

Если вы используете сертификаты ACME в больших объемах, вы скорее всего используете одну и ту же учетную запись на нескольких кластерах, так что ваши ограничения по выпуску сертификатов будут касаться их всех. Это уже было возможно в cert-manager при копировании секрета, указанного в privateKeySecretRef. Такой вариант использования был достаточно глючный, поскольку cert-manager пытался быть полезным и радостно создавал новый ключ учетной записи, если его не находил. Поэтому мы и добавили disableAccountKeyGeneration, чтобы защитить вас от такого поведения, если установить этот параметр в true - cert-manager не будет создавать ключ и предупредит вас о том, что ему не был предоставлен ключ учетной записи.

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt
spec:
  acme:
    privateKeySecretRef:
      name: example-issuer-account-key
    disableAccountKeyGeneration: false

Предпочитаемая цепочка

29 сентября Let's Encrypt перейдет на собственный корневой центр сертификации ISRG Root. Сертификаты с перекрестными подписями будут заменены на Identrust. Это изменение не требует правок в настройках cert-manager, все обновленные или новые сертификаты, выпущенные после этой даты, будут использовать новый корневой CA.

Let's Encrypt уже подписывает сертификаты с помощью этого CA и предлагает их в качестве «альтернативной цепочки сертификатов» через ACME. В этой версии cert-manager есть возможность задания доступа к этим цепочкам в настройках issuer. В параметре preferredChain можно указать имя используемого CA, с помощью которого будет выдан сертификат. Если будет доступен сертификат CA, соотвествующий запросу, он выдаст вам сертификат. Обратите внимание, что это предпочтительный вариант, если ничего не будет найдено - будет выдан сертификат по-умолчанию. Это даст гарантию того, что вы все равно произведете обновление своего сертификата после удаления альтернативной цепочки на стороне ACME issuer.

Уже сегодня можно получать сертификаты, подписанные ISRG Root, так:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    preferredChain: "ISRG Root X1"

Если вы предпочитаете оставить цепочку IdenTrust - выставляйте этот параметр в DST Root CA X3:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    preferredChain: "DST Root CA X3"

Обратите внимание, что этот корневой центр сертификации скоро устареет, Let's Encrypt будет поддерживать эту цепочку активной до 29 сентября 2021 года.