Kubernetes: автоматическая установка бесплатных TLS/SSL сертификатов
Примерно с конца 2015-го года Google начал форсировать владельцев online ресурсов переходить с HTTP на HTTPS, заставляя владельцев последних в спешном порядке устанавливать у себя TLS/SSL сертификаты.
Введение. TL;DR
В настоящий момент то, по какому протоколу можно получить доступ к вашему сайту, влияет на результаты поисковой выдачи.
Также процессе повседневной работы мы с вами устанавливаем большое количество различных online сервисов, защищаемых логином и паролем, т.к. например, Web-интерфейс управления СУБД MySQL — PhpMyAdmin , сервер CICD Jenkins , удобный интерфейс администрирования групп хостов Docker и Swarm кластеров — Portainer , Nexus Repository Manager , GitLab и т.д. На самом деле, совершенно не важно что именно, но хотелось бы не передавать свои логины и пароли в открытом виде по сетям Интернет, а защищать и шифровать соединение от нашего рабочего места до этих ресурсов.
- Покупать простые SSL сертификаты на ваши ресурсы: защита всего лишь одного URL, стоит в среднем 4000 рубгод на защищаемое доменное имя (например, https://avmaksimov.ru)
- Покупать Wildcadr SSL сертификаты : защита группы доменов следующего уровня, т.е. покупая Wildcard SSL сертификат на домен, например, *.avmaksimov.ru, одним сертификатом можно защищать URL: blog.avmaksimov.ru, jenkins.avmaksimov.ru, vpn.avmaksimov.ru и т.д. Такое удовольствие стоит в среднем 10000 рубгод.
- Можно создавать собственные центры сертификации (CA) и генерировать самоподписанные сертификаты : все бесплатно, но тяжело следить за актуальностью сертификатов, вовремя их обновлять, а также в браузере у всех, кто не скачал сертификат вашего CA, ваш ресурс все равно будет отображаться с без приятного зеленого значка «Secured».
- А можно пользоваться сервисом Let’s Encrypt — это бесплатный сервис предоставляющий бесплатные сертификаты X.509 для шифрования с защитой транспортного уровня (TLS). Особенность сервиса в том, что он позволяет автоматизировать работу с собой и избавить нас от текущего сложного процесса ручного создания, проверки, подписи, установки и обновления сертификатов для защищаемых нами online-ресурсов.
Сделать это можно несколькими способами:
Решаемая проблема
Для тех из вас, кто использует Kubernetes для оркестрации и хостинга ваших микросервисных приложений, в этой статье я продемонстрирую каким образом можно совершенно бесплатно и автоматизированно защищать опубликованные, а также новые приложения бесплатными сертификатами Let’s Encrypt.
Требования
Предполагается, что у вас уже есть работающий кластер Kubernetes, а также какое-либо опубликованное там приложение. Если у вас пока еще нет собственного кластера, то создать его быстро и с нуля в любой платформе виртуализации вы сможете воспользовавшись статьей «Kubeadm: создание Kubernetes кластера за 10 минут». В этой же статье показано как развернуть демонстрационное микросервисное приложение Sock-Shop. На примере этого web-приложения в статье «Kubernetes: использование Ingress» было показано, как в Kubernetes настроить собственный балансировщик трафика. В этой статье мы продолжим настройку балансировщика Nginx и добавим к нему поддержку SSL сертификатов для всех опубликованных вами приложений.
Добавление поддержки SSL в Ingress
Как уже рассказывалось в статье «Kubernetes: использование Ingress», Ingress — это набор правил, описывающий правила доступа к сервисам (Services) Kubernetes через балансировщик трафика (IngressController). В этой же статье мы уже запустили отдельный IngressController (Nginx) и отдельный Ingress для обработки HTTP трафика на демо-приложение. Теперь, для включения шифрования трафика до этого же демо-магазина необходимо добавить еще одну сущность Ingress для обработки HTTPS трафика.
Kube-Lego
Помимо Ingress ресурса, для решения задачки автоматического обновления сертификатов от Let’s Encrypt, нам понадобится Kube-Lego. Этот проект автоматизирует процесс работы с TLS Let’s Encrypt сертификатами в Kubernetes, просматривая ресурсы Ingress и автоматически запрашивая отсутствующие или истекшие сертификаты. Аннотация для Ingress ресурсов, для которых Kube-Lego будет выполнять эти действия, выглядит следующим образом:
metadata:
annotations:
kubernetes.io/tls-acme: «true»
После того, как Pod и Kube-lego запустится, он начнет непрерывно проверять все доступные Ingress объекты во всех пространствах имен (Namespaces) на наличие TLS конфигурации, убеждаясь, что секрет (Secret) для каждого Ingress, аннотированный вышеуказанным способом:
- Существует и содержит действительную пару приватного/публичного ключа;
- Срок действия сертификата не истек;
- Сертификат охватывает все доменные имена, указанные в конфигурации.
Установка Kube-Lego
Установка и запуск Kube-Lego в работающем кластере Kubernetes выполняется очень просто. Для этого вам необходимо склонировать репозиторий с примером конфигурации:
git clone https://github.com/jetstack/kube-lego.git
Отредактировать файл конфигурации (lego/configmap.yaml), указав в нем ваш работающий email:
cd kube-lego/examples/nginx
vi lego/configmap.yaml
Содержимое файла lego/configmap.yaml в моем случае будет следующим:
apiVersion: v1
metadata:
name: kube-lego
namespace: kube-lego
data:
# modify this to specify your address
lego.email: «maksimov.andrei@gmail.com»
# configure letencrypt’s production api
lego.url: «https://acme-v01.api.letsencrypt.org/directory»
kind: ConfigMap
Далее создайте все необходимые для работы Kube-Lego сущности в Kubernetes и запустите этот сервис:
kubectl apply -f lego/00-namespace.yaml
kubectl apply -f lego/configmap.yaml
kubectl apply -f lego/deployment.yaml
Создание и запуск HTTPS Ingress правил
socks-ingress.yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: front-end
namespace: sock-shop
spec:
rules:
— host: socks.comp.avmaksimov.ru
http:
paths:
— path: /
backend:
serviceName: front-end
servicePort: 80
HTTPS же трафик будет обрабатываться конфигурацией
socks-ingress-tls.yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: front-end-tls
namespace: sock-shop
annotations:
kubernetes.io/tls-acme: «true»
kubernetes.io/ingress.class: «nginx»
spec:
tls:
— hosts:
— socks.comp.avmaksimov.ru
secretName: sock-shop-tls
rules:
— host: socks.comp.avmaksimov.ru
http:
paths:
— path: /
backend:
serviceName: front-end
servicePort: 80
Как видите, по сути обе Ingress конфигурации очень похожи и различаются лишь именами, аннотацией для Kube-Lego и наличием описания tls: FQDN демо-магазина и название секрета, в котором хранится сертификат, обновляемый Kube-Lego.
Примените новые правила для защиты соединения до вашего демо-магазина командой:
kubectl apply -f socks-ingress-tls.yaml
Проверить применение нового правила можно командой:
kubectl get ing -n sock-shop
NAME HOSTS ADDRESS PORTS AGE
front-end socks.comp.avmaksimov.ru 192.168.0.8 80 11d
front-end-tls socks.comp.avmaksimov.ru 192.168.0.8 80, 443 3d
При после запуска внутри вашего кластера Kube-Lego стало очень легко защищать TLS/SSL сертификатом открываемые наружу сервисы и приложения. Все, что вам для этого требуется — это описать Ingress правила для обработки HTTPS трафика, которые почти ничем не отличаются от обычных. Всю остальную работу возьмет на себя Kube-Lego.