Как автоматически загрузить новые сертификаты TLS для Envoy Proxy?
Я использую https://github.com/jetstack/cert-manager в среде Kubernetes для автоматической загрузки https://letsencrypt.org/. Он создает сертификаты, срок действия которых истекает через 90 дней. За 30 дней до истечения срока действия сертификат-менеджер обновляет сертификаты и заменяет сертификаты. Сертификаты хранятся в секретах k8s.
Как вы получаете Envoy Proxy для автоматической перезагрузки сертификатов? Проблемы были закрыты и, похоже, остались без ответа. Есть некоторые упоминания о секретной службе обнаружения (SDS), которая может помочь в решении проблемы, но я пока не смог ее найти.
Для nginx можно настроить TLS, добавив секреты k8s к томам k8s, подключив том к файловой системе для использования nginx. Затем наблюдатель файловой системы можно использовать для вызова перезагрузки sudo nginx -s для перезагрузки конфигурации при изменении сертификатов. Я вижу, что Envoy Proxy поддерживает горячий перезапуск, но я не вижу команды, похожей на nginx, чтобы сделать горячий перезапуск.
Существует hot-restarter.py, но это не средство просмотра файлов, и я бы не стал устанавливать python в образе envoyproxy / envoy: latest docker. Я подумал, что некоторые функции этой программы могут быть встроены в приложение ржавчины, которое также выполняет просмотр файлов, но должно быть что-то, что уже существует для этого очень распространенного сценария, верно?
2 ответа
Похоже, вы настраиваете (или планируете настраивать) Envoy, используя статическую конфигурацию, тогда как Envoy действительно выделяется, когда вы предоставляете ему динамически сгенерированную конфигурацию на лету. Основное различие между ними заключается в том, что у вас есть служба, которую вы настраиваете для Envoy на регулярную проверку обновлений, но то, что служба должна будет отправлять обратно, очень похоже на статическую конфигурацию.
Это то, что они называют xDS, что включает в себя различные сервисы, которые вы можете написать, которые генерируют разные части конфигурации. Эта одна служба (которую вы должны предоставить и запустить) может эффективно предоставлять все другие службы (например, службу обнаружения прослушивателя) через разные конечные точки, которые она предоставляет. Envoy позволяет вам настроить его для опроса REST-подобного API, потоковой службы gRPC или даже для просмотра файла в определенном месте (я подозреваю, что это лучший вариант для вас). На самом деле вам нужно только реализовать LDS для динамически управляемых сертификатов TLS. Остальная часть конфига может оставаться статичной.
Если вы выберете маршрут записи динамической службы, с которой Envoy консультируется для конфигурации, тогда не сложно настроить ее так, чтобы она просто считывала содержимое файлов на диске и предоставляла Envoy все, что там находит. Для этого вы можете просто предоставить встроенный строковый источник данных для объекта Common TLS Context. Если у вас нет тысяч сертификатов и слушателей, тело ответа не приблизится к вашим пределам пропускной способности / памяти.
Признаюсь, я исчерпал время, которое мог позволить себе начать работу с Envoy, в попытках интерпретировать их обширную машинно-ориентированную документацию, поэтому в конце концов я остановился на HTTP-сервисе с опросом для нашей конфигурации. Даже с опросом каждые несколько секунд это единственный реальный трафик, поэтому его довольно легко настроить и продолжить. Я расскажу об этом подходе, так как он мне наиболее знаком. Возможно, вы начали с чего-то вроде статического примера, но все, что вам нужно сделать, чтобы сделать его более динамичным, - это перейти к динамической конфигурации чуть ниже. Просто замените REST на gRPC, поскольку это немного проще, и реализуйте конечные точки REST.задокументировано ниже. Это требует небольшого количества проб и ошибок, но хороший способ начать - просто заставить службу возвращать JSON-версию конфигурации, которую вы уже используете. Следует обратить внимание на то, что вам нужно добавить"type"
а также "version"
ключи на объекте JSON верхнего уровня, который ссылается на прототип того типа, который вы возвращаете, т.е. ответ службе LDS может выглядеть следующим образом:
{
"version_info": "0",
"resources": [{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "http_listener",
"address": "{...}",
"filter_chains": [{
"filters": [
"{...}"
]
}]
}]
}
Это оказалось не так просто, как я надеялся начать работать с Python. У них есть довольно хороший пример в Go сервера xDS, который использует gRPC, но это не помогло мне почти так сильно, как просмотр некоторых других попыток реализации сервера xDS, который я нашел на Github. Этот проект был мне особенно полезен. Также мне еще предстоит столкнуться с чем-либо, что действительно потребовало бы горячего перезапуска, если вы уже динамически настраиваете envoy, кроме стабильных вещей, таких как идентификаторы кластера самого экземпляра Envoy.
Добавив к ответу @jeteon об использовании xDS и динамической конфигурации, вместо использования LDS и каждый раз меняя динамический файл слушателей, вы можете настроить SDS и использовать функцию watch_directory . Взгляните на раздел о ротации ключей в документации Enovy.