В первой части этой серии статей объяснялось, как добиться реальных обновлений без простоев в кластерах Kubernetes. Мы специально работали с ошибками запросов, возникающими при переключении трафика со старых экземпляров на новые. Эта статья покажет, как достичь той же цели с помощью кластеров Istio.
Технология сервисной сетки, такая как Istio, часто используется в сочетании с оркестровкой контейнера. Istio предоставляет прозрачные решения для наших приложений, такие как отказоустойчивость, телеметрия и расширенное управление трафиком.
Когда мы используем Istio, модель кластерной внутренней сети выглядит несколько иначе, чем обычные Kubernetes. Вы можете посмотреть следующее пояснительное видео, если не знаете, как устроен текущий сетевой API Istio.
Попытка нулевого простоя с помощью Istio
Давайте начнем с того места, где закончилась первая часть статьи. Если мы возьмем наше приложение и повторно развернем его в кластере Istio аналогично предыдущему, мы заметим, что поведение во время обновлений отличается. Когда мы повторно запустим нагрузочные тесты, направленные на обнаружение пробелов в доступности, мы заметим, что, несмотря на наши preStop
жизненного цикла preStop
, существуют некоторые неудачные запросы.
1
2
3
4
5
6
7
8
9
|
Fortio 1.1 . 0 running at 500 queries per second, 4 -> 4 procs, for 20s Starting at 500 qps with 50 thread(s) [gomax 4 ] for 20s : 200 calls each (total 10000 ) 09 : 11 : 39 W http_client.go: 673 > Parsed non ok code 503 (HTTP/ 1.1 503 ) [...] Code 200 : 9960 ( 99.6 %) Code 503 : 40 ( 0.4 %) Response Header Sizes : count 10000 avg 165.204 +/- 10.43 min 0 max 167 sum 1652048 Response Body/Total Sizes : count 10000 avg 176.12 +/- 3.817 min 171 max 227 sum 1761200 [...] |
Как показывают выходные данные, некоторые HTTP-запросы не были выполнены с кодом состояния 503 Service Unavailable
. Независимо от того, как мы настраиваем время ожидания нашего обработчика preStop
, мы, похоже, preStop
как минимум несколько клиентских запросов при обновлении нашего сервиса во время большого трафика. Точно так же, кажется, есть небольшая разница в том, получаем ли мы доступ к сервису Istio из меша или снаружи кластера через шлюз.
Понимание того, что происходит
Чтобы понять, что происходит, давайте подробнее рассмотрим, как контейнеры с коляской Istio подключаются к отдельным сервисам.
Весь трафик в сетке направляется через прокси-серверы колясок, которые подключаются к отдельным экземплярам. То же самое верно для входящего трафика, который проходит через шлюз.
В нашем сценарии это означает, что коляски могут не подключаться к экземплярам, даже если они предположительно готовы обслуживать трафик. Прокси настраиваются в конечном итоге последовательным образом; изменения конфигурации от пилотной плоскости распространяются постепенно.
Посланник также выполняет активную проверку работоспособности экземпляров, выявляет выбросы и в конечном итоге предотвращает соединения с ними. Проверки готовности на основе HTTP, определенные для модулей, также будут включены и выполнены прокси-серверами Envoy. Другими словами, прокси-контейнеры не будут подключаться к модулям, чьи проверки готовности не пройдены, даже если они все еще будут принимать запросы. Повторите настройку, которую мы можем добавить к прокси-серверу через конфигурацию сетки, только смягчает, но не решает эту проблему.
К нулевому времени простоя с Istio
Существуют подходы к внедрению в будущем более совершенных концепций проверки здоровья в Кубернетес.
Однако в настоящее время разумным балансом между усилиями и надежностью является использование подмножеств Istio в качестве указателей версий и перенаправление трафика службы независимо от механизма скользящего обновления Kubernetes. При таком подходе мы используем подмножество служб для определения версии приложения, например v1
или v2
, и настраиваем виртуальную службу для маршрутизации на одну конкретную версию. Маршруты прокси-серверов Istio, которые настраиваются ресурсами виртуальных сервисов, могут быть перенаправлены на разные версии подмножеств с реальным временем простоя.
Чтобы использовать этот подход, мы создадим отдельные развертывания Kubernetes, по одному для каждой отдельной версии нашего приложения, и осуществим фактическое переключение через Istio.
Пример развертывания выглядит следующим образом:
- Первоначально: развертывание Kubernetes
coffee-shop-v1
с ярлыкамиapp=coffee-shop
,version=v1
, правилом назначения, определяющим подмножествоv1
, и виртуальным сервисом, который направляет вcoffee-shop
v1
- Мы улучшаем правило назначения, чтобы включить новое подмножество для версии
v2
- Мы создаем развертывание
coffee-shop-v2
сversion=v2
- После успешного развертывания мы перенаправляем виртуальный сервис на
v2
. Переключение произойдет без потерянного запроса. - После короткого периода ожидания мы удаляем подмножество
v1
из правила назначения и развертываниеcoffee-shop-v1
Если мы повторно запустим тот же нагрузочный тест из первой части, мы заметим, что мы можем выполнить фактическое развертывание без простоев.
1
2
3
4
5
6
7
|
Fortio 1.1 . 0 running at 500 queries per second, 4 -> 4 procs, for 20s Starting at 500 qps with 50 thread(s) [gomax 4 ] for 20s : 200 calls each (total 10000 ) [...] Code 200 : 10000 ( 100.0 %) Response Header Sizes : count 10000 avg 159.530 +/- 0.706 min 154 max 160 sum 1595305 Response Body/Total Sizes : count 10000 avg 167.853 +/- 2.51 min 161 max 171 sum 1678534 [...] |
Вы можете посмотреть видео с пояснениями, если не знаете, как реализовать этот процесс с помощью сетевого API Istio.
Автоматизация — это ключ
Конечно, мы не хотим выполнять эти шаги вручную. Идея состоит в том, чтобы определить автоматизированный процесс, который выполняется для каждой новой версии программного обеспечения. В конечном счете, это развертывание должно происходить как часть конвейера непрерывной доставки, который развертывает наше программное обеспечение в соответствующих средах.
Мы можем усовершенствовать наш конвейер непрерывной доставки для развертывания канареечных выпусков, куда мы направляем лишь небольшой процент пользовательского трафика. Это будет в равной степени включено в конвейер как автоматизированный подход: постепенно перенаправляя пользовательский трафик на вновь развернутую версию, а затем выполняя полное переключение, как только канареечная версия зарекомендовала себя хорошо.
Это поможет, если мы определим наши определения развертывания и маршрутизации Istio на языке шаблонов. Таким образом мы можем надежно определять и изменять версии приложений и версий изображений и последовательно вносить изменения. Пример проекта кофейни включает в себя сценарий автоматизации, который выполняет развертывание с нулевым временем простоя с помощью Istio и основан на шаблонном подходе YAML с использованием kontemplate .
Вывод
Производственная готовность Kubernetes — ценная особенность, которая включена из коробки. Однако нам необходимо принимать во внимание больше, чтобы полностью реализовать поведение без простоев. Крайне важно протестировать время простоя приложения, которое вы будете запускать в производство, и соответственно настроить пробники и различные таймауты.
Это, безусловно, помогает узнать, как Kubernetes и Istio управляют соединениями с бэкэндом, соответственно. Если мы слегка подправим поведение во время обновлений, мы сможем сгладить последние пробелы в доступности.
Нулевое время простоя с правильным истощением соединения и поддержанием активности соединения позволяет развертывать наши приложения в любое время, не мешая их пользователям. Как только мы достигнем этого уровня, мы сможем постоянно улучшать наше программное обеспечение и отправлять функции и исправлять ошибки в производство быстрее. Следовательно, развертывание без простоев является одной из предпосылок функционирования культуры непрерывной доставки и непрерывного улучшения.
- Пример проекта GitHub (версия Istio)
- Обновления с нулевым временем простоя с Kubernetes (первая часть)
- Видео объяснения API сети Istio
- Kontemplate (шаблонизатор Kubernetes)
Опубликовано на Java Code Geeks с разрешения Себастьяна Дашнера, партнера нашей программы JCG. Смотрите оригинальную статью здесь: Обновления с нулевым временем простоя с помощью Istio
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |