Предоставьте свои микросервисы внешнему миру через TLS
Istio предоставляет вам множество функций, которые помогут вам подключаться, защищать, контролировать и наблюдать за вашими микросервисами. Это дает Kubernetes большой контроль над тем, на что он обычно способен. Шлюзы Istio - это мощный ресурс, который позволяет вам определять точки входа в вашу сервисную сеть из внешнего мира.
В предыдущей статье мы представили приложение BookInfo протоколу HTTP. Однако Istio предоставляет безопасные шлюзы для размещения ваших микросервисов по протоколу HTTPS. Istio обеспечивает как простую, так и взаимную аутентификацию TLS, что упрощает вашу жизнь, поскольку вам больше не нужно управлять сертификатами вне кластера Kubernetes.
Эта статья является продолжением статьи Как управлять трафиком с помощью Istio в Kubernetes. Сегодня давайте обсудим, как предоставить доступ к микросервисам внешнему миру через HTTPS с помощью безопасных шлюзов Istio.
Предпосылки
Для практического упражнения вам понадобится работающий кластер Kubernetes.
Установите Istio в своем кластере Kubernetes, следуя руководству Начало работы с Istio в Kubernetes.
Определите INGRESS_HOST
и SECURE_INGRESS_PORT
, выполнив приведенный ниже код.
Если вы используете балансировщик нагрузки, выполните следующее.
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') $ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
Если вы не используете балансировщик нагрузки, вы также можете использовать комбинацию IP-адреса узла и порта узла. Запустите ниже, чтобы использовать это.
export INGRESS_HOST=<worker-node-address> export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
Создать сертификаты TLS
Для практической демонстрации мы предполагаем, что домен example.com
.
Давайте воспользуемся OpenSSL для создания самозаверяющего корневого сертификата для example.com
.
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
Создайте сертификат и закрытый ключ для bookinfo.example.com
, используя корневой сертификат example.com
. Давайте сначала сгенерируем закрытый ключ и CSR, а затем воспользуемся корневым сертификатом example.com
, чтобы подписать CSR и создать общедоступный bookinfo.example.com
сертификат.
$ openssl req -out bookinfo.example.com.csr -newkey rsa:2048 -nodes -keyout bookinfo.example.com.key -subj "/CN=bookinfo.example.com/O=bookinfo organization" $ openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in bookinfo.example.com.csr -out bookinfo.example.com.crt
Настройте простой TLS для приложения BookInfo
Создайте секрет с сгенерированным ключом и сертификатом в пространстве имен istio-system
. Обратите внимание, что имя секрета не должно начинаться с istio
или prometheus
, поскольку это ключевые слова, зарезервированные для системных секретов.
$ kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt secret/bookinfo-credential created
Создайте шлюз BookInfo на входящем входе Istio по умолчанию, используя учетные данные. Нижеприведенный YAML определяет шлюз с именем bookinfogateway
на Istio ingressgateway
по умолчанию, прослушивает порт 443
по simple
протоколу TLS и использует bookinfo-credential
для хоста bookinfo.example.com
.
Создайте виртуальный сервис для подключения к странице продукта.
Примените правила назначения.
$ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml destinationrule.networking.istio.io/productpage created destinationrule.networking.istio.io/reviews created destinationrule.networking.istio.io/ratings created destinationrule.networking.istio.io/details created
Сделайте следующую запись в вашем хост-файле. Он нужен, если вы хотите получить доступ к странице продукта из браузера.
<INGRESS_HOST> bookinfo.example.com
Откройте приложение BookInfo из браузера.
Перейдите на https://bookinfo.example.com/productpage, и вы должны увидеть следующее.
Поскольку сертификат является самоподписанным, мы получаем небезопасное предупреждение. Если вы используете сертификат, подписанный общедоступным центром сертификации, уведомление должно исчезнуть.
Давайте зайдем на страницу через curl
, чтобы увидеть, получим ли мы ошибку проверки, если мы будем использовать example.com
сертификат CA для проверки.
И мы получаем HTTP 200
ответ. Это доказывает, что простой TLS работает нормально.
Ротация сертификатов
Ротация сертификатов для входящего шлюза находится всего в нескольких командах.
Создайте новый набор сертификатов из корневого сертификата.
$ mkdir new_certificates $ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout new_certificates/example.com.key -out new_certificates/example.com.crt $ openssl req -out new_certificates/bookinfo.example.com.csr -newkey rsa:2048 -nodes -keyout new_certificates/bookinfo.example.com.key -subj "/CN=bookinfo.example.com/O=bookinfo organization" $ openssl x509 -req -days 365 -CA new_certificates/example.com.crt -CAkey new_certificates/example.com.key -set_serial 0 -in new_certificates/bookinfo.example.com.csr -out new_certificates/bookinfo.example.com.crt
Теперь удалите старый секрет и создайте новый с новыми учетными данными.
$ kubectl -n istio-system delete secret bookinfo-credential secret "bookinfo-credential" deleted $ kubectl create -n istio-system secret tls bookinfo-credential \ --key=new_certificates/bookinfo.example.com.key \ --cert=new_certificates/bookinfo.example.com.crt secret/bookinfo-credential created
Теперь перейдем к приложению BookInfo с помощью нового сертификата.
Что бы произошло, если бы мы использовали старые сертификаты для подключения к сервису? Давайте разберемся.
И это не удается! Это показывает, что ротация сертификатов работает правильно.
Настройка взаимного TLS
Взаимный TLS может потребоваться, если вам нужно установить доверительные отношения между клиентом и сервером и наоборот. Это может быть необходимо, если вы размещаете API и хотите, чтобы к нему имели доступ только доверенные клиенты.
Чтобы шлюз использовал Mutual TLS, нам нужно переопределить bookinfo-credential
, чтобы установить свойства tls.key
, tls.cert
и cacert
для хранения сертификата CA. Это необходимо, так как теперь сервер должен доверять клиенту, и ему необходимо проверить сертификат клиента, используя настроенный сертификат CA.
$ kubectl -n istio-system delete secret bookinfo-credential secret "bookinfo-credential" deleted $ kubectl create -n istio-system secret generic bookinfo-credential --from-file=tls.key=bookinfo.example.com.key \ --from-file=tls.crt=bookinfo.example.com.crt --from-file=ca.crt=example.com.crt secret/bookinfo-credential created
Обновите входной шлюз, чтобы использовать MUTUAL
TLS-аутентификацию.
Теперь обратимся к приложению старым методом.
И получаем ошибку! Это означает, что для аутентификации в приложении BookInfo требуется сертификат клиента. Давайте сгенерируем клиентский ключ и сертификат с помощью OpenSSL.
$ openssl req -out client.example.com.csr -newkey rsa:2048 -nodes -keyout client.example.com.key -subj "/CN=client.example.com/O=client organization" $ openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 1 -in client.example.com.csr -out client.example.com.crt
Давайте воспользуемся сертификатом клиента для аутентификации в приложении BookInfo.
И мы получаем HTTP 200
ответ.
Попробуем зайти в приложение BookInfo из браузера.
И теперь мы видим, что он не позволяет нам подключиться, потому что мы не предоставили действительный сертификат клиента, когда открываем страницу из браузера.
Поздравляю! Вы успешно настроили взаимный TLS в Istio!
Заключение
Спасибо за прочтение. Надеюсь, вам понравилась статья.
В следующей части я расскажу о зеркалировании трафика в Kubernetes с использованием Istio с практической демонстрацией, так что до встречи!