Много работая с командами разработки, только что перешедшими на OpenShift, мы стремимся дать им рекомендации и лучшие практики для успешного создания и внедрения приложений на этой платформе. По итогам этой работы мы отобрали 14 ключевых, на наш взгляд, практик, которые можно разбить на две категории: надежность приложений и безопасность приложений. Эти категории пересекаются, поскольку чем выше надежность, тем лучше безопасность, и наоборот, а сам список лучших практик выглядит следующим образом.
Надежность приложений
В этом разделе собраны 9 передовых практик, помогающих повысить доступность и аптайм приложений, а также сделать их лучше в плане пользовательского опыта.
1. Не храните конфигурацию приложения внутри контейнера
Если контейнерный образ содержит конфигурацию для какой-то конкретной среды (Dev, QA, Prod), его не получится без изменений переносить между средами. Это плохо с точки зрения надежности процесса выпуска версий, поскольку в продакшн пойдет уже не тот образ, который тестировался на предыдущих этапах. Поэтому не держите внутри контейнера конфигурацию приложения для конкретной среды, а храните ее отдельно, например, с помощью ConfigMaps и Secrets.
2. Задавайте ресурсные требования и лимиты в определениях pod’а
Без должной настройки требований к ресурсам приложения могут создавать непосильную нагрузку на память и процессор. И наоборот, имея явно прописанные требования приложения к ЦП и памяти, кластер может эффективно выполнять диспетчеризацию так, чтобы предоставлять приложению запрашиваемые ресурсы.
3. Прописывайте зонды активности (liveness) и готовности (readiness) в определениях pod’а
С помощью этих зондов кластер может обеспечивать базовую устойчивость: перезапускать приложение, если не проходит liveness, или больше не маршрутизировать на него трафик, когда не отвечает readiness. Подробнее см. раздел Мониторинг работоспособности приложений в документации OpenShift Platform.
4. Используйте PodDisruptionBudget для защиты приложений
Иногда pod’ы приходится убирать с узла кластера, например, при обслуживании хоста, или когда autoscaler даунсайзит кластер, отключая лишние узлы. Чтобы приложение при этом оставалось доступным, надо настроить объекты PodDistruptionBudget.
5. Правильное завершение работы pod’ов
При завершении работы pod должен доводить до конца все текущие запросы и корректно закрывать все открытые подключения, чтобы перезагрузка pod'а, например, при обновлении приложения, проходила незаметно для конечных пользователей.
6. Один контейнер – один процесс
Старайтесь, чтобы каждый процесс работал в своем собственном контейнере. Это повышает изоляцию процессов и предотвращает проблемы с маршрутизацией сигналов и появление зомби-процессов, которые иначе придется периодически вычищать. Подробнее см. раздел Избегайте нескольких процессов в документации OpenShift Platform.
7. Используйте системы мониторинга приложений и оповещения
Мониторинг приложений средствами Prometheus и Grafana помогает поддерживать нормальную работу приложений в продакшн-режиме согласно требованиям бизнеса.
8. Пусть приложения пишут свои логи в stdout/stderr
Тогда OpenShift сможет собирать и пересылать их в централизованную систему обработки (ELK, Splunk). Логи – это бесценный ресурс при анализе работы приложения в продакшн-режиме. Кроме того, оповещения, генерируемые на базе содержимого логов, помогают проконтролировать, что приложение работает как задумано.
9. Изучите целесообразность применения Circuit breakers, Timeouts, Retries, Rate Limiting
Эти механизмы повышают устойчивость приложения к отказам, защищая от перегрузок (Rate Limiting, Circuit Breakers) и помогая справляться с сетевыми проблемами (Timeouts, Retries). Рассмотрите возможность применения решения OpenShift Service Mesh, которое позволяет реализовать эти функции, не трогая код приложений.
Безопасность приложений
Ниже приводятся 5 передовых и, на наш взгляд, абсолютно необходимых практик усиления безопасности приложений, которые вам обязательно надо рассмотреть к применению.
10. Используйте только доверенные контейнерные образы
Применяйте вендор-образы везде, где это возможно, поскольку они гарантировано тестируются, дорабатываются на безопасность и обеспечиваются поддержкой. Что касается community-образов, используйте наработки только тех сообществ, которым доверяете. И помните, что в публичных реестрах, вроде Docker Hub, имеются образы неизвестного происхождения – не используйте их ни в коем случае!
11. Используйте последние версии базовых контейнерных образов
Потому что только в них есть все доступные на текущий момент исправления безопасности. Настройте свой конвейер непрерывной интеграции так, чтобы при каждой сборке образов приложений он всегда подтягивал последние версии базовых образов, а также пересобирал образы приложений при выходе новых версий базовых образов.
12. build-образы отдельно, runtime-образы отдельно
Build-образ содержит зависимости, которые нужны при сборке приложения, но не нужны при запуске. Поэтому создавайте отдельные runtime-образы с минимумом зависимостей, чтобы уменьшить поверхность атак, а заодно и размер образа.
13. Restricted security context constraint (SCC) – везде, где только возможно
Модифицируйте образы, чтобы они могли работать в рамках restricted SCC (подробнее см. раздел Поддержка произвольных идентификаторов пользователей в документации). Риски взлома приложений включают в себя и ситуации, когда злоумышленник получает контроль над самим приложением, и restricted SCC позволяет обезопасить узел кластера на этот случай.
14. TLS для защиты коммуникаций между компонентами приложения
Компоненты приложения могут пересылать друг другу конфиденциальные данные. Если сеть, в которой работает OpenShift, не может считаться безопасной, то трафик между компонентами приложения можно защитить с помощью TLS-шифрования, а уже упомянутый OpenShift Service Mesh позволяет сделать это, не трогая код приложений.
Заключение
Итак, теперь у вас есть список из 14 лучших практик для построения более надежных и безопасных приложений OpenShift. Это хорошее начало для выработки собственного кодекса разработки для членов вашей команды. Дополнительные сведения и рекомендации можно найти в разделе Создание образов документации OpenShift.