Π’Ρ‹ΡˆΠ΅Π» cert-manager 1.0

Если ΡΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΎΠΏΡ‹Ρ‚Π½ΠΎΠ³ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌΡƒΠ΄Ρ€ΠΎΠ³ΠΎ ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€Π°, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π΄ΡƒΠΌΠ°Π΅Ρ‚ ΠΎ cert-manager ΠΈ ΠΏΠΎΡ‡Π΅ΠΌΡƒ всС ΠΈΠΌ ΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ, Ρ‚ΠΎ спСц Π²Π·Π΄ΠΎΡ…Π½Ρ‘Ρ‚, Π΄ΠΎΠ²Π΅Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΠ±Π½ΠΈΠΌΠ΅Ρ‚ ΠΈ устало скаТСт: «ВсС ΠΈΠΌ ΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½Π΅Ρ‚ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ² вмСняСмых. Наши ΠΌΡ‹ΡˆΠΈ ΠΏΠ»Π°Ρ‡ΡƒΡ‚, ΠΊΠΎΠ»ΡŽΡ‚ΡΡ, Π½ΠΎ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡŽΡ‚ ΠΆΠΈΡ‚ΡŒ с этим кактусом. ΠŸΠΎΡ‡Π΅ΠΌΡƒ любим? ΠŸΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. ΠŸΠΎΡ‡Π΅ΠΌΡƒ Π½Π΅ любим? ΠŸΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ постоянно выходят Π½ΠΎΠ²Ρ‹Π΅ вСрсии, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π½ΠΎΠ²Ρ‹Π΅ Ρ„ΠΈΡ‡ΠΈ. И приходится Ρ€Π°Π· Π·Π° Ρ€Π°Π·ΠΎΠΌ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ кластСр. А старыС вСрсии ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°ΡŽΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π·Π°Π³ΠΎΠ²ΠΎΡ€ Π΅ΡΡ‚ΡŒ ΠΈ Π²Π΅Π»ΠΈΠΊΠΎΠ΅ таинствСнноС ΡˆΠ°ΠΌΠ°Π½ΡΡ‚Π²ΠΎΒ».

Но Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΡƒΠ²Π΅Ρ€ΡΡŽΡ‚, Ρ‡Ρ‚ΠΎ с cert-manager 1.0 всё измСнится.

ΠŸΠΎΠ²Π΅Ρ€ΠΈΠΌ?

Π’Ρ‹ΡˆΠ΅Π» 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

  • uriSANsuris

Π­Ρ‚ΠΈ измСнСния Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ 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 Π³ΠΎΠ΄Π°.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com