Один из самых частых вопросов, которые мне задают как консультанту это: В чем разница между liveness и readiness пробами?. Следующий самый частый вопрос: Какие из них нужны моему приложению?.
Любой, кто пробовал за Duck Duck Go-ить этот вопрос знает, что на него непросто найти ответ в интернете. В этой статье, надеюсь, я смогу помочь вам ответить на эти вопросы самостоятельно. Я поделюсь своим мнением о том, каким образом лучше использовать liveness и readiness пробы в приложениях развернутых в Red Hat OpenShift. И я предлагаю не строгий алгоритм, а, скорее, общую схему, которую вы можете использовать для принятия своих собственных архитектурных решений.
Чтобы сделать абстракции более конкретными я предлагаю рассмотреть четыре общих примера приложений. Для каждого из них мы выясним нужно ли нам настраивать liveness и readiness probes, и если нужно, то как. Прежде чем перейти к примерам, давайте ближе посмотрим на эти два разных типа проб.
Примечание: Kubernetes недавно внедрили новую startup probe, доступную в OpenShift 4.5 clusters. Вы быстро разберетесь со startup probe, когда поймете liveness и readiness probes. Здесь я не буду рассказывать о startup probes.
Liveness (работоспособности) и readiness (готовности) пробы это два основных типа проверок, доступных в OpenShift. Они имеют схожий интерфейс настройки, но разные значения для платформы.
Когда liveness проверка не проходит, то это сигнализирует OpenShiftу, что контейнер мертв и должен быть перезагружен. Когда readiness проверка не проходит, то это опознается OpenShiftом как то, что проверяемый контейнер не готов к принятию входящего сетевого трафика. В будущем это приложение может прийти в готовность, но сейчас оно не должно принимать трафик.
Если liveness проверка успешна, и в то же время readiness проверка не прошла, OpenShift знает, что контейнер не готов принимать сетевой трафик, но он работает над тем, чтобы прийти в готовность. Например, часто приложениям нужно длительное время для инициализации или для синхронной обработки длительных запросов. (Синхронная обработка длительных запросов - это анти-паттерн, но, к несчастью, мы сталкиваемся с этим в некоторых legacy-приложениях.)
Далее мы подробнее рассмотрим специфику использования каждой из этих проверок. Как только мы поймем как работает каждая из них, я покажу примеры того, как они работают вместе в OpenShift.
Liveness проверка отправляет сигнал OpenShiftу, что контейнер либо жив (прошел проверку), либо мертв (не прошел). Если контейнер жив, тогда OpenShift не делает ничего, потому что текущее состояние контейнера в порядке. Если контейнер мертв, то OpenShift пытается починить приложение через его перезапуск.
Название liveness проверки (проверка живучести) имеет семантическое значение. По сути проверка отвечает Да или Нет на вопрос: Жив ли этот контейнер?.
Если вы не задали liveness проверку, тогда OpenShift будет принимать решение о перезапуске вашего контейнера на основе статуса процесса в контейнере с PID 1. Процесс с PID 1 это родительский процесс для всех других процессов, которые запущены внутри контейнера. Так как каждый контейнер начинает жить внутри его собственного пространства имен процессов, первый процесс в контейнере берет на себя особенные обязательства процесса с PID 1.
Если процесс с PID 1 завершается и liveness пробы не заданы, OpenShift предполагает (обычно безопасно), что контейнер умер. Перезапуск процесса - это единственное не зависящее от приложения универсально эффективное корректирующее действие. Пока PID 1 жив, не зависимо от того, живы ли дочерние процессы, OpenShift оставит контейнер работать дальше.
Если ваше приложение это один процесс, и он имеет PID 1, то это поведение по умолчанию может быть именно тем, что вам нужно, и тогда нет необходимости в liveness пробах. Если вы используйте init инструменты, такие как tini или dumb-init, тогда это может быть не то, что вы хотите. Решение о том, задавать ли свои liveness вместо того, чтобы использовать поведение по умолчанию, зависит от специфики каждого приложения.
Сервисы OpenShift используют readiness проверки (проверки готовности) для того, чтобы узнать когда проверяемый контейнер будет готов принимать сетевой трафик. Если ваш контейнер вошел в состояние, когда он все ещё жив, но не может обрабатывать входящий трафик (частый сценарий во время запуска), вам нужно, чтобы readiness проверка не проходила. В этом случае OpenShift не будет отправлять сетевой трафик в контейнер, который к этому не готов. Если OpenShift преждевременно отправит трафик в контейнер, это может привести к тому, что балансировщик (или роутер) вернет 502 ошибку клиенту и завершит запрос, либо клиент получит сообщение с ошибкой connection refused.
Как и liveness проверки, название readiness проба (проба готовности) передает семантическое значение. Фактически это проверка отвечает на вопрос: Готов ли этот контейнер принимать сетевой трафик?.
Если вы не зададите readiness проверку, OpenShift решит, что контейнер готов к принятию трафика как только процесс с PID 1 запустился. Это никогда не является желаемым поведением.
Принятие готовности без проверки приведет к ошибкам (таким, как 502 от роутера OpenShift) каждый раз при запуске нового контейнера, при масштабировании или развертывании. Без readiness проб вы будете получать пакет ошибок при каждом развертывании, когда старые контейнеры выключаются и запускаются новые. Ели вы используете автоматическое масштабирование, тогда в зависимости от установленного порога метрик новые инстансы могут запускаться и останавливаться в любое время, особенно во время колебаний нагрузки. Когда приложение будет масштабироваться вверх или вниз, вы будете получать пачки ошибок, так как контейнеры, которые не совсем готовы получать сетевой трафик включаются в распределение балансировщиком.
Вы можете легко исправить эти проблемы через задание readiness проверки. Проверка дает OpenShift'у возможность спросить ваш контейнер, готов ли он принимать трафик.
Теперь давайте взглянем на конкретные примеры, которые помогут нам понять разницу между двумя типами проб и то, как важно задать их правильно.
Примечание: Из-за того, что у этих двух разных типов проверок одинаковый интерфейс часто возникает путаница. Но наличие двух или более типов проб - это хорошее решение: это делает OpenShift гибче для разных типов приложений. Доступность обеих liveness и readiness проб критична для репутации OpenShift как Container-as-a-Service, который подходит для широкого спектра приложений.
В примере приложение, изображенное на рисунке 1 - это простой сервер для отдачи статики, который использует Nginx, чтобы отдавать файлы. Сервер запускается быстро и проверить, обрабатывает ли сервер трафик легко: вы можете запросить определенную страницу и проверить, что вернулся 200 код HTTP ответа.
Приложение запускается быстро и завершается, если обнаружит ошибку, которая не позволит ему отдавать страницы. Поэтому, в данном случае, нам не нужны liveness пробы. Завершенный процесс Nginx означает, что приложение умерло и его нужно перезапустить (отметим, что неполадки, такие как проблемы с SELinux или неправильно настроенные права в файловой системе могут быть причиной выключений Nginx, но перезапуск не исправит их в любом случае).
Nginx обрабатывает входящий трафик поэтому нам нужны readiness пробы. Всегда, когда вы обрабатываете сетевой трафик вам нужны readiness пробы для предотвращения возникновения ошибок во время запуска контейнеров, при развертывании или масштабировании. Nginx запускается быстро, поэтому может вам повезет и вы не успеете увидеть ошибку, но мы все ещё хотим предотвратить передачу трафика до тех пор, пока контейнер не придет в готовность, в соответствии с best practice.
Нам нужно будет сделать определенные изменения для каждого
примера, но сначала, приведем здесь первую часть
Deployment
. Мы изменим этот файл по ходу статьи, но
верхняя часть останется той же. В следующих примерах, нам нужно
будет изменять только секцию template.
apiVersion: apps/v1kind: Deploymentmetadata: labels: app: application-nginx name: application-nginxspec: replicas: 1 selector: matchLabels: app: application-nginx template: metadata: labels: app: application-nginx spec: # Will appear below as it changes
Здесь настройка проверки для первого примера:
spec: containers: - image: quay.io/<username>/nginx:latest name: application-nginx imagePullPolicy: Always ports: - containerPort: 8443 protocol: TCP readinessProbe: httpGet: scheme: HTTPS path: /index.html port: 8443 initialDelaySeconds: 10 periodSeconds: 5
Рис. 2: Реализация сервера Nginx для
отдачи статики с настроенными readiness проверками
Многие приложения имеют HTTP веб-компонент, а так же компонент выполняющий асинхронные задания. Серверу с заданиями не нужны readiness проверки, так как он не обрабатывает входящий трафик. Однако, ему в любом случае нужны liveness проверки. Если процесс, выполняющий задания умирает, то контейнер становится бесполезным, и задания будут накапливаться в очереди. Обычно, перезапуск контейнера является правильным решением, поэтому liveness пробы идеальны для такого случая.
Пример с приложением на рис. 3 это простой сервер заданий который забирает и запускает задания из очереди . Он не обслуживает напрямую входящий трафик.
Рис. 3: Реализация сервера заданий без liveness проверок.Я уже упоминал, что этот тип приложений выигрывает от наличия liveness проб, но более детальное пояснение не повредит в любом случае.
Когда сервер заданий запущен корректно, это будет живой процесс. Если контейнер сервера заданий перестает работать, это скорее всего означает сбой, необработанное исключение или что-то в этом духе. В этом случае настройка проверки будет зависеть от того, запущен ли процесс нашего задания с PID 1.
Если наш процесс задания запущен с PID 1, то он завершится, когда поймает исключение. Без настроенных liveness проверок OpenShift распознает завершение процесса с PID 1 как смерть и перезапустит контейнер. Для простого сервера заданий перезапуск может быть нежелательным поведением.
Однако, в реальной жизни ситуации могут быть сложнее. Например, если наш процесс с заданием получил deadlock, он может все ещё считаться живым, так как процесс запущен, но он определенно в нерабочем состоянии и должен быть перезапущен.
Чтобы помочь вычислить deadlock, наше приложение будет писать
текущее системное время в миллисекундах в
файл/tmp/jobs.update
когда выполняет задание. Это время
потом будет проверяться через shell команду (через exec liveness
пробы) для того, чтобы убедиться, что текущее задание не запущено
дольше определенного значения таймаута. Тогда приложение само
сможет проверять себя на liveness
выполняя/usr/bin/my-application-jobs --alive
.
Мы можем настроить liveness так (опять же, я пропускаю первую
часть YAML-файла Deploymenta
, который я показывал
ранее):
spec: containers: - image: quay.io/<username>/my-application-jobs:latest name: my-application-jobs imagePullPolicy: Always livenessProbe: exec: command: - /bin/sh - -c - "/usr/bin/my-application-jobs --alive" initialDelaySeconds: 10 periodSeconds: 5
В это случае readiness не нужны. Помним, что readiness пробы отправляют OpenShift сигнал о том, что контейнер готов принимать трафик и поэтому может быть добавлен в конфигурацию балансировщика. Так как это приложение не обрабатывает входящий трафик, оно не нуждается в проверке на готовность. Мы можем отключить readiness пробу. Рис. 4 показывает реализацию сервиса заданий с настроенными liveness проверками.
Рис. 4: Реализация сервера заданий с liveness проверкамиЭто пример стандартного приложение рендеринга на стороне сервера SSR: оно отрисовывает HTML-страницы на сервере по востребованию, и отправляет его клиенту. Мы можем собрать такое приложение используя Spring Boot, PHP, Ruby on Rails, Django, Node.js, или любой другой похожий фреймворк.
Если приложение запускается за несколько секунд или меньше, то liveness проверки, скорее всего, не обязательны. Если запуск занимает больше нескольких секунд, мы должны настроить liveness проверки, чтобы понять, что контейнер инициализировался без ошибок и не произошел сбой.
В этом случае мы могли бы использовать liveness пробы типа exec, которые запускает команду в shell, чтобы убедиться, что приложение по-прежнему работает. Эта команда будет отличаться в зависимости от приложения. Например, если приложение создает PID файл, мы можем проверить, что он все еще жив:
livenessProbe: exec: command: - /bin/sh - -c - "[ -f /run/my-application-web.pid ] && ps -A | grep my-application-web" initialDelaySeconds: 10 periodSeconds: 5
Так как данное приложение обрабатывает входящий трафик нам определенно нужны readiness пробы. Без readiness OpenShift немедленно отправит сетевой трафик в наш контейнер после его запуска, независимо от того, готово приложение или нет. Если контейнер начинает отбрасывать запросы, но не завершает работу аварийно, он продолжит получать трафик бесконечно, что, конечно же, не то, что нам нужно.
Мы хотим, чтобы OpenShift удалил контейнер из балансировщика, если приложение перестанет возвращать правильные ответы. Мы можем использовать readiness пробы, подобные этой, чтобы сообщить OpenShift, что контейнер готов к приему сетевого трафика:
readinessProbe: httpGet: scheme: HTTPS path: /healthz port: 8443 initialDelaySeconds: 10 periodSeconds: 5
Для удобства, вот полный YAML для этого приложения из этого примера:
apiVersion: apps/v1kind: Deploymentmetadata: labels: app: backend-service name: backend-servicespec: replicas: 1 selector: matchLabels: app: backend-service template: metadata: labels: app: backend-service spec: containers: - image: quay.io/<username>/backend-service:latest name: backend-service imagePullPolicy: Always ports: - containerPort: 8443 protocol: TCP readinessProbe: httpGet: scheme: HTTPS path: /healthz port: 8443 initialDelaySeconds: 10 periodSeconds: 5
На рисунке 6 показана схема приложения SSR с настроенными liveness и readiness пробами.
Рис. 6. Приложение SSR с настроенными liveness и readiness пробами.В конечном, сложном и реалистичном приложении у вас могут быть элементы из всех трех предыдущих примеров. Рассмотрение их по отдельности полезно при анализе работы проб, но также полезно увидеть, как они могут работать вместе для обслуживания большого приложения с миллионами запросов. Этот последний пример объединяет остальные три.
Рис. 7: Реалистичный пример приложения в OpenShift для изучения использования проб.В примере приложение состоит из трех частей, это контейнеры:
Сервер приложений: Этот сервер предоставляет REST API и выполняет рендеринг на стороне сервера для некоторых страниц. Эта конфигурация широко распространена, поскольку приложения, которые создаются в качестве простых серверов для отрисовки, позже расширяются для обеспечения конечных точек REST API.
Сервер для отдачи статики Nginx: У этого контейнера есть две задачи: он отображает статические ресурсы для приложения (например, ресурсы JavaScript и CSS). И также он реализует завершение TLS-соединений (Transport Layer Security) для сервера приложений, действуя как обратный прокси для определенных URL. Это также широко используемая настройка.
Сервер заданий: этот контейнер не обрабатывает входящий сетевой трафик самостоятельно, но обрабатывает задания. Сервер приложений помещает каждое задание в очередь, где сервер заданий берет его и выполняет. Сервер заданий разгружает сервер приложений, чтобы он мог сосредоточиться на обработке сетевых запросов, а не на обработке длинных заданий.
Приложение также включает в себя несколько сервисов хранения данных:
Реляционная база данных: реляционная база данных будет хранить состояние для нашего приложения. Почти каждое приложение нуждается в какой-либо базе данных, и реляционные являются наиболее предпочтительным выбором.
Очередь. Очередь предоставляет серверу приложений путь первым пришел - первым вышел (FIFO) для передачи задач серверу заданий. Сервер приложений всегда будет пушить задания в очередь, а сервер заданий извлекать.
Наши контейнеры разделены на два пода:
Первый под состоит из нашего сервера приложений и Nginx TLS-прокси или сервера для статики. Это упрощает работу сервера приложений, позволяя ему взаимодействовать напрямую через HTTP. Благодаря расположению в одном поде эти контейнеры могут безопасно и напрямую связываться с минимальной задержкой. Они также могут получить доступ к общему volume space. Эти контейнеры также нужно масштабировать вместе и рассматривать как единое целое, поэтому под является идеальным решением.
Второй под состоит из сервера заданий. Этот сервер необходимо масштабировать независимо от других контейнеров, поэтому он должен находиться в собственном поде. Поскольку весь стейт хранится в базе данных и очереди, сервер заданий может легко получить доступ к необходимым ему ресурсам.
Если вы читали предыдущие примеры, решению здесь вы не удивитесь. Для интеграции мы переключаем сервер приложений на использование HTTP и порта 8080 вместо HTTPS и 8443 для readiness проб. Мы также добавляем liveness пробы на сервер приложений, чтобы прикрыть нас, если сервер приложений не завершает работу в случае ошибки. Таким образом, наш контейнер будет перезапущен Kubelet'ом, когда он мертв:
# Pod One - Application Server and NginxapiVersion: apps/v1kind: Deploymentmetadata: labels: app: my-application-web name: my-application-webspec: replicas: 1 selector: matchLabels: app: my-application-web template: metadata: labels: app: my-application-web spec: containers: - image: quay.io/<username>/my-application-nginx:latest name: my-application-nginx imagePullPolicy: Always ports: - containerPort: 8443 protocol: TCP livenessProbe: exec: command: - /bin/sh - -c - "[ -f /run/nginx.pid ] && ps -A | grep nginx" initialDelaySeconds: 10 periodSeconds: 5 readinessProbe: httpGet: scheme: HTTPS path: /index.html port: 8443 initialDelaySeconds: 10 periodSeconds: 5 - image: quay.io/<username>/my-application-app-server:latest name: my-application-app-server imagePullPolicy: Always ports: - containerPort: 8080 protocol: TCP livenessProbe: exec: command: - /bin/sh - -c - "/usr/bin/my-application-web --alive" initialDelaySeconds: 10 periodSeconds: 5 readinessProbe: httpGet: scheme: HTTP path: /healthz port: 8080 initialDelaySeconds: 10 periodSeconds: 5# Pod Two - Jobs ServerapiVersion: apps/v1kind: Deploymentmetadata: labels: app: my-application-jobs name: my-application-jobsspec: replicas: 1 selector: matchLabels: app: my-application-jobs template: metadata: labels: app: my-application-jobs spec: containers: - image: quay.io/<username>/my-application-jobs:latest name: my-application-jobs imagePullPolicy: Always livenessProbe: exec: command: - /bin/sh - -c - "/usr/bin/my-application-jobs --alive" initialDelaySeconds: 10 periodSeconds: 5
На рисунке 8 показаны полные примеры приложений с обеими настроенными пробами.
Рис. 8: Полный пример приложений с обеими настроенными пробами.На мой взгляд, хотя этот шаблон используется чересчур часто, в некоторых случаях он имеет смысл. Если приложение начинает некорректно отвечать на HTTP-запросы и, вероятно, никогда не восстановит свою работу без перезапуска, то вы, вероятно, захотите, чтобы OpenShift перезапустил под. Было бы лучше, если бы ваше приложение восстанавливалось само по себе, но это бывает нецелесообразно в реальном мире.
Если у вас есть HTTP endpoint, который может быть исчерпывающим индикатором, вы можете настроить и liveness и readiness пробы на работу с этим endpoint. Используя один и тот же endpoint убедитесь, что ваш под будет перезапущен, если этот endpoint не сможет вернуть корректный ответ.
Liveness и readiness пробы отправляют разные сигналы в OpenShift.Каждый имеет свое определенное значение и они не взаимозаменяемы. Не пройденная liveness проверка говорит OpenShift, что контейнер должен быть перезапущен. Не пройденная readiness проба говорит OpenShift придержать трафик от отправки в этот контейнер.
Нет универсального рецепта для проб, потому что правильный выбор будет зависеть от того, как написано приложение. Приложению, которое умеет самовосстанавливаться нужна иная настройка от того, которое просто дает сбой и умирает.
Выбирая корректные проверки для приложения я обращаюсь к семантическому смыслу в сочетании с поведением приложения. Зная, что проваленная liveness проба перезапустит контейнер, а проваленная readiness проба удалит его из балансировщика. Обычно это не сложно, определить какие пробы нужны приложению.
Мы рассмотрели реалистичные примеры, но вы можете увидеть значительно более сложные случаи в реальных системах. Для инстанса в сервис-ориентированной архитектуре (SOA), сервис может зависеть от другого сервиса при обработке соединений. Если нисходящий сервис не готов, должен ли проходить readiness проверку восходящий сервис или нет? Ответ зависит от приложения. Вам нужно провести анализ стоимости/преимуществ решения, чтобы определить, что добавочная сложность того стоит.
Хотя концептуально пробы очень просты, они могут быть сложны на практике. Лучший подход для нахождения оптимального решения - это итеративный! Проведите тестирование производительности и хаотичное тестирование для наблюдения за поведением вашей конфигурации и улучшайте её в процессе. Мы редко делаем все правильно с первого раза.
Кое-что застряло у меня в голове очень давно, когда я был молодым младшим разработчиком. Я работал, пытаясь ускорить доступ к данным в веб-приложении. Первая итерация кода вызывала базу данных каждый раз, когда пользователь просматривал данные. В поисках оптимизации я решил кешировать исходные возвращённые данные, чтобы не возвращаться к базе. Это было разумно.
Итак, опустив голову, я целыми днями придумывал нечто, что было бы лучшим кеширующим кодом Java из всех, что я видел! Я придумал сложные алгоритмы вызова, хранения, пейджинга и удаления данных для одного юзкейса. После 5 дней и ночей тяжёлого труда я гордо встретил своего ведущего разработчика и познакомил его с моим кодом; я одурачил его великолепием алгоритмов.
Смутило, что меня встретили не поздравлением о реализации революционной техники пейджинга данных, а глубоким вздохом и обещанием ревью.
На следующий день лид вызвал меня и сказал: "Не знаю, что ты там наделал, но я удалил весь твой код и просто сохранил данные в списке, который обновляется при каждом новом поиске".
Сначала он сказал мне, что мой код излишняя инженерия, а затем, что я написал нечто, решающее проблему, для которой уже есть шаблоны и инструменты.
Поджав хвост, я принял это и получил самый важный урок для младшего разработчика, метафорически получив подзатыльник.
Один из самых ранних моих уроков в программной инженерии решая проблему, не садиться сразу же за код.
Этот урок напомнил мне о недавнем разговоре с молодым разработчиком, представившим проблему с использованием кода в RedHat OpenShift (предупреждаю: я работаю в Red Hat). Во всех деталях он объяснил, что написал множество микросервисов, чтобы сидеть перед множеством API, которые читают данные из различных источников и манипулируют ими перед отправкой в различные конечные точки. Он был очень горд своим множеством микросервисов, которые разработал, чтобы решить проблему. Там были агрегаторы, трансляторы и другие паттерны.
Я выслушал и вздохнул
Я сказал ему, что решение выглядит действительно сложным и что он немного переусердствовал с инженерией. В вежливой форме я сказал ему, что люди решили все эти и другие проблемы много раз. Указал на Apache Camel и сказал, что не нужно разрабатывать микросервисы ради микросервисов.
Не стройте микросервисы ради микросервисов!
В IT мы, кажется, думаем, что нужно заново изобретать что-то каждый раз, всегда. Я полностью за новые захватывающие парадигмы, которые меняют наш подход, но не за счёт выбрасывания того, что уже есть.
Apache Camel один из великолепных примеров того, что не нужно заново изобретать велосипед
Я большой поклонник Apache Camel как в смысле интегратора, так и в смысле большого успеха сообщества Open Source. История утверждает, что Camel появился из разговора Грегори Хофа и Джеймса Стрейкена. Грегор написал библию интеграции Enterprise Integration Patterns, книгу с проектами общих задач интеграции в виде набора шаблонов так что вам не нужно изобретать одни и те же архитектурные шаблоны.
Джеймс, разработчик Open Source и основатель языка Groovy, и Грегор беседовали на конференции, и Джеймс подумал, что было бы неплохо создать переиспользуемые реализации этих шаблонов на Java так что вам не нужно продолжать писать один и тот же код, когда необходимо что-то сделать! Apache Camel родился из этой беседы как набор реализующих шаблоны интеграции библиотек.
Итак, мы взглянули на Red Hat Integration, которая представляет собой Apache Camel и кучу других вещей для развёртывания и запуска сервисов интеграции. Я сказал младшему разработчику, что он не только может делать всё, что ему нужно, но и подогнать всё в его архитектуру микросервисов и, глядя на некоторые новые разработки, такие как Camel K, он также может сервировать свои микросервисы бессерверно [have his microservices servederr, serverless! заставить работать свои микросервисы с помощью технологии serverless, бессерверно].
Бессерверная интеграция микросервисов
Camel К самая захватывающая вещь в интеграции на данный момент. Некоторые из самых больших проблем, с которыми сталкиваются специалисты по интеграции, всегда были связаны с тем, как с помощью архитектур интеграционных решений добиться доступности в больших масштабах. Такие инструменты, как Camel K и OpenShift, учитывают все аспекты развёртывания, запуска и масштабирования в этой задаче.
Apache Camel предоставляет реализацию шаблонов и сотни адаптеров. Глубокие знания нужны, только чтобы выяснить, какие коннекторы и шаблоны использовать, и, что важно, нужно знать о том, как компоненты развёртываются в масштабируемой и доступной архитектуре таким образом, чтобы поддерживать требования.
Такие проекты, как Camel K, это новая порода нативных инструментов kubernetes, которые стремятся задействовать мощь Kubernetes, чтобы воспользоваться огромными масштабами и возможностями доступности этой платформы. Некоторые сложные вещи в определении и проектировании масштаба и доступности уже реализованы при помощи Kubernetes, так что мне не нужно заново изобретать масштабирование и доступность!
Что такое Apache Camel?
Ок, я расскажу быстро, если вы не сталкивались с Apache Camel, то это инструмент потрясающей красоты, который по-настоящему упрощает интеграцию и соединение сотен разных вещей:
Бросим быстрый взгляд на Apache Camel.
Он предоставляет более 50 паттернов интеграции.
Имеет более 350 коннекторов.
Он прекрасен.
Вот что лежит в основе каждой интеграции. Данные или вызов приходит из источника (FROM), затем идут в обработчик (PROCESSOR), в котором как-то обрабатываются, и затем направляются к (TO) месту назначения.
Компоненты FROM и TO или адаптеры соединяют технологии от нативных сервисов AWS, файлов CSV и SAP до реактивных потоков и коннекторов Kafka их больше трёхсот пятидесяти.
Эта история о том, что компоненты Camel блестящий способ показать мощь сообществ и проектов с открытым исходным кодом. Много лет я был большим поклонником Camel и видел, как с каждым выпуском количество компонентов растёт.
Вот мощь Open Source
Вот что обычно происходит: разработчик использует Camel, и плагина, в котором он нуждается, в Camel ещё нет. Итак, разработчик пишет компонент, удовлетворяющий его требованиям. Будучи порядочным гражданином страны Open Source, разработчик радует сообщество Camel вносит свой компонент в исходный код Camel, и этот компонент включается в следующий выпуск Camel. Теперь, когда компонент нужен вам, не нужно создавать его заново это потрясающе!
Множество источников могут помочь вам с Camel. Один из лучших книга Клауса Ибсона и Джонатана Энсти, Camel in Action библия Camel. Джеймс Стрейкен часто говорил, что он изобрёл Camel, но Клаус заставил инструмент работать. Кроме того, взгляните на блестящие статьи Тома Донахью о Camel.
Я быстро покажу что-нибудь удивительное (ладно, это будет удивительно для такого старого интеграционного писаки, как я). Я выполню довольно простую задачу интеграции всего в несколько строк кода.
Я собираюсь создать Telegram-бота, который будет отправлять комплименты в канал Telegram. У Telegram есть API загрузки, которым я могу воспользоваться, чтобы отправлять сообщения в каналы, которыми могу пользоваться.
А вот сервис комплиментов Grant Codes: complimentr.com, который возвращает приятные слова, чтобы поднять настроение.
Ух ты, потрясающие цветовые схемы Гранта!Сейчас я хочу интегрировать эти два сервиса, чтобы отправлять комплименты моим друзьям в Telegram. Итак, я собираюсь погрузиться в код? Нет, чёрт возьми!
Взгляните на коннекторы Apache Camel среди 350 компонентов, с помощью которых я могу соединить разные вещи, я нашёл Camel Telegram: кто-то, кто хотел пообщаться с Telegram, уже написал что-то для этого, так что я писать ничего не должен!
Стандартные компоненты Camel помогут с вызовом простого HTTP в моём сервисе комплиментов. Я легкомысленно говорю стандартные, потому что на самом деле есть HTTP-компонент, который работает со всем, что я мог бы написать, но мне он не нужен!
Итак, я собираюсь воспользоваться компонентом Camel Telegram, чтобы получить сообщение от бота, затем вызываю внешний сервис, чтобы получить комплимент, и отправляю его боту Telegram. Вещь не самая захватывающая, но немного забавная. Вот чего я хочу от бота: чтобы я отправил имя и в ответ получил комплимент.
У меня есть кластер kubernetes, поэтому я сделаю бота с помощью Camel K и воспользуюсь Red Hat OpenShift и Camel K Operator, чтобы всё настроить.
Вот, что нужно сделать:
1. Загрузить CLI Camel K.
2. Установить Camel K Operator.
3. Запустить мой код.
Об этом есть много статей и документации, поэтому я не буду вдаваться в кучу подробностей, но Camel K CLI (или kamel) это, по сути, CLI взаимодействия с вашей платформой Kubernetes (или, точнее, с пользовательскими ресурсами Camel K на платформе) для развёртывания интеграций (есть также плагины для VSCode).
CLI позволяет установить операторы Camel K, запустить интеграции в режиме интерактивной разработки (с обновлениями запущенного кода интеграции на лету) и т. д.
В Camel K есть ряд операторов Kubernetes, чтобы создавать, развёртывать и запускать интеграции. Весь смысл операторов Kubernetes заключается в том, чтобы абстрагировать сложности всего того, что работает на платформе, и Camel K справляется великолепно! Так что просто возьмите и установите оператор из CLI, используя командную строку:
Или, если вы работаете в Openshift, откройте вкладку Operators, чтобы установить операторы.
После установки я могу отправить код интеграции на свою работающую платформу OpenShift из IDE или из командной строки.
Давайте посмотрим на код. Помните, что я работаю с компонентом Telegram. Мне нужно просто взять токен авторизации Telegram и передать его в компонент, который будет читать сообщения от бота.
from("telegram:bots?authorizationToken=[YOUR TOKEN])
Если я добавлю простое логирование, чтобы увидеть, как работает маршрут:
from("telegram:bots?authorizationToken=[YOUR TOKEN]").to("log:bots")
То на выходе всего пара строк кода. Сохранив их в файле hello.groovy, я получу скрипт groovy, им можно воспользоваться в качестве интеграции CamelK, которая подключится к моему telegram-боту и будет логировать всё, что я напечатаю!
Здесь начинается нечто удивительное. Я хочу, чтобы мой двухстрочный скрипт groovy развёртывался и запускался как масштабируемый интеграционный компонент. Вот что такое Camel К! Из командной строки я запускаю простую команду:
С помощью команды run я превратил свой двухстрочный скрипт groovy в контейнер, развёрнутый и работающий как маршрут Apache Camel на моём кластере OpenShift.
Зачем флаг --dev
Добавив флаг --dev, я оказался в странном мире, где я могу изменить свой файл hello.groovy, и изменения отразятся в кластере OpenShift! Опция --dev сильно упрощает разработку.
Вы уже видели, как работает Camel K, и вот оставшаяся часть моего скрипта с уклонением от кодирования:
from("telegram:bots?authorizationToken=[YOUR TOKEN]").setHeader("USER", body()).to("https://complimentr.com/api?asGET=true").transform().jsonpath("\$.compliment").setBody(simple("\${body} \${in.header.USER}")).to("telegram:bots?authorizationToken=[YOUR TOKEN]")
Чтобы получить сообщения из канала Telegram, я использую компонент Camel Telegram.
Спрячьте имя в заголовок, передаваемый в теле сообщения Telegram.
Вызовите API комплиментов.
Обратитесь к пользователю по имени.
Верните комплимент в канал Telegram.
Вот шесть строк кода, выполняющие интеграцию, повторно используя компоненты.
Есть несколько действительно блестящих шаблонов интеграции Camel, таких как агрегаторы, брокеры, динамическая маршрутизация, и даже более удивительные вещи в Camel K, например бессерверность или масштабирование до нуля [отключение, когда платформа не используется] по запросу, они помогут вам не писать код!
Разумные разработчики, которые не занимаются программированием, давно уже не новость. Причины, по которым мы создаём фреймворки и инструменты, заключаются в желании абстрагироваться от рутины и работать продуктивнее. Иногда нужно понять, какие фреймворки и инструменты помогут вам не писать код. Надеюсь, я показал вам один из таких фреймворков!
Узнайте подробности, как получить Level Up по навыкам и зарплате или востребованную профессию с нуля, пройдя онлайн-курсы SkillFactory со скидкой 40% и промокодомHABR, который даст еще +10% скидки на обучение.
Другие профессии и курсыПРОФЕССИИ
КУРС
Мы собрали для вас короткий дайджест полезных материалов, найденных нами в сети за последние две недели. Оставайтесь с нами станьте частью DevNation!
Бесплатная подписка на RHEL что и
как
Как
зарегистрировать и активировать бесплатную подписку на Red Hat
Enterprise Linux и что она дает
Как Red Hat портировала OpenJDK на
ARM64
Инженеры Red Hat
и энтузиасты open source реализовали стандартный OpenJDK для
платформы AArch64.
Обновленный static analysis в GCC
11
Исправления и
улучшения режима -fanalyzer в GNU Compiler Collection
(безопасность, state tracking и другое).
Руководство по использования кода CentOS
Project
Как мы теперь
будем публиковать исходники CentOS и как вам их правильно
использовать в своих проектах и продуктах
Фонд OpenJS запустил опрос по
Node.js
Он называется
2021 Node.js User Survey и призван дать ответы на вопросы: кто и
как использует Node.js, а также дать возможность высказаться по
этому проекту всем желающим.
Вебинар DevNation Tech Talk Искусство конструирования
Java API
В ходе
презентации мы обсудим стандартный Java API, а также реальные
примеры плохого и хорошего API, а также API идеального - насколько
такое возможно.
Справочное руководство Quarkus Cookbook
(НОВИНКА)
Как не
выпасть из темы и работать продуктивнее в мире облачных приложений,
используя Quarkus.
Удаленная работа: 10 советов, как улучшить
сотрудничество на
удаленке
Несоответствие
ожиданиям, плохие инструменты и даже плохие манеры все это вредит
сотрудничеству. Представляем лучшие практики удаленной работы,
которые пригодятся как руководителям, так и всем сотрудникам.
Бесплатный Developer Sandbox for
OpenShift
Это ваш
личный OpenShift в облаке, всего за пару минут и без какой бы то ни
было инсталляции. Среда создана специально для разработчиков и
включает в себя Helm-диаграммы, builder-образы Red Hat, инструменты
сборки s2i, также CodeReady Workspaces, облачную IDE с
веб-интерфейсом.
Построение
интеграционной архитектуры нового поколения с Red Hat Middleware,
26 февраля, 11:00
Red
Hat и официальный дистрибьютор вендора компания Axoft, приглашают
вас принять участие в экспертной сессии Построение интеграционной
архитектуры нового поколения с Red Hat Middleware.
Red Hat: Обзор событий за 2020 год от MONT, 26 февраля,
11:00
Центр компетенций
Red Hat at MONT подведет итоги неоднозначного 2020 года и поговорит
о планах на 2021.
Виртуальный Red Hat Summit 2021, 27-28
апреля
Бесплатная
онлайн-конференция Red Hat Summit это отличный способ узнать
последние новости ИТ-индустрии, задать свои вопросы техническим
экспертам, услышать истории успеха непосредственно от заказчиков
Red Hat и увидеть, как открытый код генерирует инновации в
корпоративном секторе.
В компьютерных науках есть только две трудные вещи: аннулирование кэша и именование сущностей.
Фил Карлтон (Phil Karlton)
Red Hat очень серьезно относится к будущему Java, остающейся самым популярным языком разработки корпоративных приложений. Почти две трети всех программистов мира относят себя к умеренным или заядлым пользователям Java, которая вот уже 18 лет подряд входит в тройку лучших языков программирования в рейтинге TIOBE. Можно смело сказать, что несмотря на небывалый выбор и доступность новых языков программирования, Java остается де-факто стандартом разработки критически важных бизнес-приложений. Мы в Red Hat считаем своим долгом поддерживать Java-разработчиков и прокладывать для них новые пути для продолжения инноваций.
Среди множества технологий, призванных сохранить роль и место Java в облачных реалиях будущего, одной из наиболее перспективных является Quarkus, фреймворк для разработки Kubernetes-нативных Java-приложений. Quarkus изначально создавался как способ оптимизировать Java для контейнерных сред, и, как результат, способен значительно повысить продуктивность разработчиков и снизить эксплуатационные расходы, превращаясь в ключевой компонент контейнерных рабочих нагрузок. Несмотря на свою молодость и бурный рост, Quarkus уже стал заметным игроком на рынке технологий разработки и задает новый формат работы программистов. Сегодня мы рады сообщить, что Quarkus теперь входит в состав Red Hat OpenShift, и это важный шаг для будущего Java как инструмента разработки современных облачных приложений.
Quarkus и до этого уже полностью поддерживался и был доступен в рамках Red Hat Runtimes, но теперь он входит в состав и полностью интегрирован с Red Hat OpenShift, что еще больше упрощает разработку. Разработчики получают знакомые инструменты, возможность удаленной разработки на кластерах с помощью IDE, таких как CodeReady Workspaces, интеграцию с управляемыми конфигурациями, развертывание serverless-нагрузок и управление хранилищами приложений.
В состав Quarkus входят несколько компонентов для разработки и развертывания на OpenShift:
Quarkus-расширение генерация кода для новых проектов, управление зависимостями проектов, удаленная разработка и отладка, а также простое, в один шаг, развертывание в OpenShiftPlugins для CodeReady Workspaces, включая предварительно настроенные стеки рабочих пространств разработчика, подсказки по свойствам конфигураций и автозавершение кода, снипеты для стандартных типов классов Quarkus, а также создание и развертывание кода в OpenShift непосредственно из IDE.
Автоматическая привязка тестов исправности (health checks), подключение секретов и предоставление метрик для простой интеграции со средствами мониторинга, наподобие Prometheus
Автоматическое развертывание контейнеризированных приложений Quarkus в качестве serverless-нагрузок OpenShift.
Knative-развертывания в один шаг.
Также обеспечивается интеграция с Kubernetes API, включая generic API client и поддержку динамической конфигурации приложений с использованием Kubernetes ConfigMaps и Secrets.
Мы также обновили Migration Toolkit for Applications, чтобы помочь с переносом приложения Spring Boot в Quarkus на OpenShift. Этот тулкит для консультантов, архитекторов и разработчиков помогает проанализировать Java-код или двоичные файлы с точки зрения различных вариантов трансформации (задаются в виде наборов правил) для эффективной модернизации и миграции приложений. Свежая версия Migration Toolkit for Applications сочетает правила Containerization, OpenJDK и Linux со специально разработанными и протестированными правилами для переноса кода Spring Boot в Quarkus на OpenShift, чтобы лучше учесть особенности гибридного облака.
Теперь Quarkus доступен еще большему число разработчиков, а чтобы узнать о нем больше и начать использовать, обратитесь к сайту: https://developers.redhat.com/products/quarkus/getting-started
Много работая с командами разработки, только что перешедшими на 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.
В этом посте мы собрали советы и рекомендации, которые стоит изучить, прежде чем переносить свои приложения в сервисную сетку OpenShift Service Mesh (OSSM). Если вы никогда не сталкивались с сервисными сетками Service Mesh, то для начала можно глянуть страницу OSSM на сайте Red Hat и почитать о том, как система Istio реализована на платформе OpenShift.
Начав изучать Istio, вы скорее всего столкнетесь с приложением bookinfo, которое почти повсеместно используется в качеств наглядного пособия, или же с более продвинутым вариантом в виде приложения Travel Agency. Разбирая эти и другие примеры, вы сможете лучшее понять, как устроена mesh-сетка, и затем уже переносить в нее свои приложения
Начать стоит с официальная документация OpenShift Service Mesh 2.0 (OSSM), в ней можно найти массу полезных материалов, в том числе:
Описание различий между OSSM и родительским СПО-проектом Istio.
Описание, как установить OSSMи
Протестировать ее с помощью приложения-примера bookinfo.
Istiov1.6(архив версий).
Kialiv1.24(архив версий).
Jaeger1.20.
Когда дойдет до интеграции вашего приложения в mesh-сетку, надо будет копнуть поглубже и заглянуть в документацию по Istio. Также стоит ознакомиться с release notes соответствующих версий компонентов, входящих Red Hat OSSM.
Если еще не сделали это, то протестируйте свою mesh-сетку с помощью приложения-примера Bookinfo. Если все пройдет нормально, то в нее уже можно будет добавлять ваше приложение.
Первое, что надо сделать при добавлении в mesh-сетку своего приложения убедиться, что sidecarы проксей Envoy правильно внедрены в podы вашего приложения. В OSSM такое внедрение делается довольно просто и хорошо описывается в документации.
Потом воспользуйтесь примером, где описывается, как настраивать ingress-шлюз для приложения Bookinfo, и примените эту конфигурацию к своему приложению, чтобы к нему можно было получать доступ не только изнутри кластера OpenShift, но и извне.
Важно четко понимать, как Istio определяет, какие протоколы использует ваше приложение. Для этого изучите все, что связано с Protocol Selection и app and version labelsв разделе документации Pods and Services.
В противном случае скорее всего произойдет следующий казус. Допустим, вы внедряете в свое приложение sidecarы проксей Istio, загружаете его тестовым трафиком и идёте смотреть граф Kiali. И видите там совсем не то, что ожидали (рис. ниже). Почему? Потому что Kiali и Istio не смогли правильно определить, какие протоколы используют наши сервисы, и отобразили соединения между ними как TCP, а не HTTP.
На графе Kiali есть только TCP-соединенияIstio должен точно знать, какой протокол используется. Если Istio не может определить протокол автоматически, то трактует трафик как обычный (plain) TCP. Если у вас какие-то другие протоколы, их надо вручную прописать в определениях служб Kubernetes Service вашего приложения. Подробнее об этом написано в документации, раздел Protocol Selection.
Чтобы вручную задать, какой протокол использует ваш сервис, надо соответствующим образом настроить объекты Kubernetes Service. В нашем случае в них по умолчанию отсутствовало значение параметра spec -> ports -> name. Если прописать "name: http" для сервисов A, B и C, то граф отобразит эти соединения как HTTP.
Kiali это отличный инструмент для того, чтобы начать работать с OpenShift Service Mesh. Можно даже сказать, что именно на нем и надо сосредоточиться, когда вы начинаете работать с mesh-сеткой.
Kiali визуализирует метрики, генерируемые Istio, и помогает понять, что происходит в mesh-сетке. В качестве одной из первоочередных задач мы настоятельно рекомендуем изучить документацию Kiali.
Kiali не только пригодится для визуализации вашего приложения, но и поможет с созданием, проверкой и управлением конфигурациями mesh-сетки. Поначалу изучение конфигураций Istio может быть делом сложным, и Kiali тут сильно поможет.
В Kiali есть много полезных вещей, поэтому мы очень советуем изучить список ее возможностей и FAQ. Например, там есть следующие интересные вещи:
Другая важная вещь умение маркировать сервисы приложения с помощью меток (label). Istio, а следовательно и Kiali, требует, чтобы маркировка велась строго определенным образом, который поначалу отнюдь не кажется очевидным, особенно когда весь ваш опыт исчерпывается работой с приложением-примером Bookinfo, где все метки уже есть и всё прекрасно работает из коробки.
Развертывания с использованием меток app и version это важно, поскольку они добавляет контекстную информацию к метрикам и телеметрии, которые собираются Istio и затем используются в Kiali и Jaeger.
Istio может показать такие связи между внутренними и внешними сервисами, о существовании которых вы даже не догадывались. Это полезно, но иногда может раздражать при просмотре графа. К счастью, с графа всегда можно убрать эти Неизвестные узлы.
Еще одна полезная вещь в Kiali это то, что она может провести проверку вашей mesh-сетки, что особенно полезно, когда вы сами создаете конфигурации.
Поначалу графы Kiali могут несколько обескураживать. Поэтому стоит изучить различные типы графов, начав с того, как генерировать графа сервиса и какие бывают функций наблюдения.
При первоначальном тестировании своего приложения в mesh-сетке вам, скорее всего, захочется, чтобы частота трассировки была больше 50%, желательно, 100%, чтобы отслеживать все тестовые запросы, проходящие через приложение. В этом случае Jaeger и Kiali быстрее наберут необходимые данные, а вам не придется долго ждать обновления информации.
Иначе говоря, нам надо, чтобы sample rate был равен 100% (тут есть соответствие: 10000 = 100%).
Для этого надо подредактировать объект ServiceMeshControlPlane (обычно называется basic-install) в вашем проекте Control Plane (обычно istio-system) и добавить или изменить там следующее значение:
spec: tracing: sampling: 10000 # 100%
Понятно, что после запуска приложения в продакшн уже не надо мониторить каждый запрос и частоту выборки стоит понизить процентов до пяти или ниже.
Jaeger помогает убрать одну из проблем, которая возникает при переходе на микросервисную архитектуру, но для этого все сервисы вашего приложения должны правильно распространять заголовки трассировки (trace headers).
Очень полезно отслеживать, как запросы ходят через сервисы (или даже множество сервисов) в вашей mesh-сетке. OSSM может здесь помочь за счет сбора данных в форме spanов и трасс (trace). Просмотр трасс очень помогает понять сериализацию, параллелизм и источники задержек в вашем приложении. Вкратце, span это интервал от начала выполнения единицы работы до ее завершения (например, полная отработка запроса клиент-сервер). Трасса это путь, по которому запрос проходит, двигаясь по mesh-сети, или, другими словами, по мере того, как он передается от одного сервиса вашего приложения к другому. Подробнее об этом можно и нужно почитать в документации OSSM.
Обратите внимание, что в OSSM spanы (единицы работы) автоматически генерируются средствами Istio, а вот трассы нет. Поэтому чтобы распределенные трассы (distributed traces) были полностью просматриваемыми, разработчик должен изменить код так, чтобы любые существующие trace-заголовки правильно копировались при передаче запроса между сервисами. К счастью, вы не обязаны сами генерировать эти заголовки. Если изначально их нет, то они будут автоматически сгенерированы и добавлены первым Envoy-прокси, который встретится на пути запроса (обычно это прокси на ingress-шлюзе).
Вот список заголовков для распространения:
x-request-id
x-b3-traceid
x-b3-spanid
x-b3-parentspanid
x-b3-sampled
x-b3-flags
x-ot-span-context
Распространение заголовков может выполняться вручную или с использованием клиентских библиотек Jaeger, реализующих OpenTracing API.
Вот как делается ручное распространение trace-контекста на Java:
HttpHeaders upstreamHttpHeaders = new HttpHeaders();if (downstreamHttpHeaders.getHeader(headerName: "x-request-id") != null) upstreamHttpHeaders.set("x-request-id", downstreamHttpHeaders.getHeader( headerName: "x-request-id"));
Примечание: это надо повторить для всех заголовков из списка выше.
Ручная настройка yaml-манифестов дело утомительное, особенно если значения в одном yaml должны совпадать со значениями в другом, а еще ведь есть жесткие правила отступов. К счастью, в Kiali есть отличная функция, которая поможет при создании и проверке конфигураций.
Создание Istio-ресурсов с помощью Kiali-мастеров
Большую часть конфигураций, которые понадобятся вам в первое время, можно создать с помощью соответствующих мастеров Kiali, которые вызываются через меню Services.
YAML-редактор
Kiali имеет собственный редактор YAML для просмотра и редактирования конфигурационных ресурсов Istio напрямую, который также выявляет некорректные конфигурации.
Часто бывает так, что граф Kiali вдруг выявляет в вашем приложении неизвестные ранее (в том числе и разработчикам) коммуникационные пути. Другими словами, Kiali помогает найти и выявить все существующие пути во время тестирования вашего приложения. Это, конечно, полезно, но иногда может и раздражать. В этом случае их можно просто не отображать на графе, введя "node=unknown" в поле ввода над графом Kiali.
Если вы уже защитили соединения между своими сервисами и/или (скорее всего) используете TLS для внешних соединений, то при переводе приложения в mesh-сетку их надо будет в обязательном порядке выключить и переключиться на чистый HTTP без шифрования. А всем шифрованием теперь займутся Envoy-прокси.
Если ваши сервисы будут связываться с внешними сервисами по TLS, то Istio не сможет инспектировать трафик и Kiali будет отображать эти соединения только как TCP.
В общем, используйте для взаимодействия сервисов только HTTP, но не HTTPS.
Также про внешние сервисы надо поставить в известность и вашу mesh-сетку (см. ниже Настройка внешних сервисов).
Самое время пересмотреть код вашего приложения и убрать из него лишнее.
Одно из преимуществ Service Mesh состоит в том, что реализацию многих вещей по сервисам можно убрать из приложения и отдать на откуп платформе, что помогает разработчикам сосредоточиться на бизнес-логике и упростить код. Например, можно рассмотреть следующие доработки:
Как сказано выше, убрать HTTPS-шифрование.
Убрать всю логику обработки таймаутов и повторных попыток.
Убрать все ставшие ненужными библиотеки.
Помните, что mesh-сетка увеличивает количество пулов подключений. Если раньше два сервиса связывались напрямую, то теперь у каждого из них есть свой прокси-посредник. То есть фактически вместо одного пула подключений появляются три:
От вашего первого сервиса к локальному для него sidecarу Envoy (расположены в одном и том же podе).
От этого sidecarа к другому sidecarу Envoy, который обслуживает второй сервис и расположен в одном podе с этим сервисом.
И наконец, от того другого sidecarа, собственно, ко второму сервису. Поэтому, возможно, стоит упростить конфигурацию, чтобы не раздувать пулы подключений. Подробнее об этом хорошо написано здесь.
Еще один плюс оптимизации кода это возможность уменьшить размер сервисов и (возможно) поднять их производительность, убрав из них те вещи, которые теперь реализуются на уровне mesh-сетки.
Убедитесь, что все сервисы вашего приложения взаимодействуют друг с другом через имена объектов Kubernetes Service, а не через OpenShift Routes.
Просто проверьте, вдруг ваши разработчики используют OpenShift Routes (конечные точки ingress на кластере) для организации коммуникаций между сервисами в пределах одного кластера. Если эти сервисы должны входить в одну и ту же mesh-сетку, то разработчиков надо заставить поменять конфигурации/манифесты своих приложений, чтобы вместо конечных точек OpenShift Route использовались имена объектов Kubernetes Service.
В коде вашего приложения, возможно, потребуется поменять еще кое-что. Envoy-прокси конечно заботятся о таймаутах и повторах, чтобы межсервисные коммуникации были более надежными, но иногда сервисы падают полностью, и такие отказы можно отработать только на уровне приложения. Для этого в коде приложения надо реализовать функции аварийного переключения (fallback), чтобы оно уже само решало, как быть дальше, когда Envoy-прокси уже ничем не может помочь.
Envoy-прокси могут работать не только внутри кластера, но и отправлять трафик за его пределы, если зарегистрировать внешние сервисы в mesh-сетке.
Скорее всего, ваше приложение общается с сервисами за пределами mesh-сетки. Поскольку это внешние по отношению mesh-сетке сервисы, то толку от нее здесь не будет, да? А вот и нет. Эти внешние сервисы можно прописать в Service Mesh и использовать часть её функций и для них.
Подробнее и с примерами можно почитать об этом в документации OSSM. Есть и подробный разбор, как визуализировать внешний трафик Istio в Kiali, и как использовать TLS originationдля зашифрованного egress-трафика.
Вот некоторые из функций Istio, которые можно использовать при работе с внешними сервисами:
Шифрование (и простое, и Mutual TLS).
Таймауты и повторы.
Circuit breakerы.
Маршрутизация трафика.
С OpenShift Service Mesh вы можете лучше понять, как устроена ваша mesh-сетка, сделать ее более просматриваемой, что, в свою очередь, помогает поднять общий уровень сложности микросервисной архитектуры. Бонусом идет возможность реализовать больше функций и возможностей на уровне самой платформе OpenShift, а не кодировать их на уровне отдельных приложений, что облегчает жизнь разработчикам. Еще один плюс реализация вещей, которые раньше казались неподъемными, например, канареечное развертывание, A/B-тестирование и т.п. Кроме того, вы получаете целостный подход к управлению микросервисными приложениями на всех своих кластерах OpenShift, что хорошо с точки зрения преемственности людей и непрерывности процессов. В конечном итоге, это поможет перейти от монолитных приложений к распределенной микросервисной архитектуре и работать в большей степени на уровне конфигураций, чем кода.
Традиционно конвейеры CI/CD строились поверх физических серверов и виртуальных машин. Контейнерные платформы, вроде Kubernetes и OpenShift, появились на этой сцене гораздо позже. Однако по мере того, как все больше и больше рабочих нагрузок переводится на платформу OpenShift, туда же движутся и конвейеры CI/CD, а конвейерные задания все чаще выполняются внутри контейнеров, работающих на кластере.
Этот пост представляет собой перевод блога нашего друга Алеса Носика, автора блога имени себя ("Helping you navigate the world of Kubernetes"). Девиз Алеса: "Software developer and architect passionate about new technologies, open-source and the DevOps culture. Making the world a better place with software".
Вы можете задать любой вопрос после прочтения Алесу в комментариях. Ну и куда без этого Алес хочет подарить за самые каверзные вопросы набор пешего туриста с картой маршрутов от Red Hat. И шляпу.
В реальном мире компании не ограничиваются одним-единственным кластером OpenShift, а имеют их сразу несколько. Почему? Чтобы запускать рабочие нагрузки как в различных публичных облаках, так и на своих собственных ИТ-мощностях. Либо если организация хранит верность какому-то одному поставщику платформ для того, чтобы эффективно работать в различных регионах мира. А иногда необходимо иметь несколько кластеров и в одном регионе, например, при наличии нескольких зон безопасности, в каждой из которых должен быть свой кластер.
Как видим, у организаций есть масса причин иметь нескольких кластеров OpenShift. Соответственно, конвейеры CI/CD должны уметь работать в таких мультикластерных системах, и ниже мы расскажем, как проектировать такие конвейеры.
Jenkins это настоящая легенда в мире CI/CD. А ведь когда-то давно он назывался Hudson, впрочем, это совсем уже древняя история. Вернемся к нашей теме и зададимся вопросом, как построить конвейер Jenkins, охватывающий сразу несколько кластеров OpenShift? При проектировании такого конвейера очень важно предусмотреть единую информационную панель, где отображались бы результаты выполнения всех заданий, задействованных в этом конвейере. Если немного подумать, то для этого надо иметь некий главный Jenkins (назовем его мастер-Jenkins), который будет связан с каждым кластером OpenShift. При выполнении конвейера мастер-Jenkins сможет запускать отдельные задания на любом из подключенных кластеров, а журналы вывода заданий будут собираться отправляться на этот мастер-Jenkins, как обычно. Если у нас есть три кластера OpenShift (Dev, Test и Prod), то схема будет выглядеть следующим образом:
Для подключения Jenkins к OpenShift есть замечательный Kubernetes-plugin, с помощью которого мастер-Jenkins сможет создавать эфемерные worker-ы на кластере. Каждому кластеру можно присвоить свою метку узла, чтобы иметь возможность запускать каждый этап конвейера на разных кластерах, просто задавая соответствующую метку. Вот как выглядит простое определение такого конвейера:
stage ('Build') { node ("dev") { // running on dev cluster }}stage ('Test') { node ("test") { // running on test cluster }}stage ('Prod') { node ("prod") { // running on prod cluster }}
В OpenShift есть специальный шаблон для Jenkins, который можно найти в проекте openshift. Этот шаблон позволяет создать мастер-Jenkins, который преднастроен для запуска worker-podов на одном кластере. А дальше придется приложить определенные усилия, чтобы подключить этот мастер-Jenkins к другим кластерам OpenShift, и вся хитрость здесь заключается в настройке сети. Jenkins-овский worker-pod после запуска подключается к мастер-Jenkins. Поэтому нам надо, чтобы мастер-Jenkins был доступен для worker-ов, работающих на любом из наших кластеров OpenShift.
Кроме того, стоит обсудить безопасность. Если мастер-Jenkins может запускать worker-овские pod-ы на OpenShift, то значит он может запускать на этих worker-ах произвольный код. Кластер OpenShift не имеет возможности контролировать, какой код запустит Jenkins-овский worker. Определения заданий управляется Jenkins, поэтому только Jenkins-овские средства контроля доступа решают, можно ли выполнять то или иное задание на том или ином кластере.
Теперь посмотрим, как организовать мультикластерный конвейер CI/CDВ с помощью Tekton. В отличие от Jenkins, Tekton это Kubernetes-нативное решение: он реализован на основе строительных блоков Kubernetes и тесно интегрирован с Kubernetes. Естественная граница Tekton это кластер. И как тут построить конвейер, который будет охватывать сразу несколько кластеров OpenShift?
Для этого можно скомпоновать схему из несколько конвейеров Tekton. Чтобы объединить несколько конвейеров в один, мы создадим задачу execute-remote-pipeline, которая будет запускать Tekton-конвейер, расположенный на удаленном кластере OpenShift. При выполнении удаленного конвейера эта задача будет подхватывать его вывод. Теперь с помощью этой задачи мы можем объединять несколько конвейеров Tekton на разных кластерах OpenShift и запускать их как один конвейер. Например, на диаграмме ниже показана композиция из трех конвейеров, где каждый из них расположен на своем кластере OpenShift (Dev, Test и Prod):
Выполнение этого конвейера начинается на кластере Dev. Конвейер Dev запустит конвейер Test, который, в свою очередь, запустит конвейер Prod. Объединенные логи можно отследить к окне терминала:
$ tkn pipeline start dev --showlogPipelinerun started: dev-run-bd5fsWaiting for logs to be available...[execute-remote-pipeline : execute-remote-pipeline-step] Logged into "https://api.cluster-affc.sandbox1480.opentlc.com:6443" as "system:serviceaccount:test-pipeline:pipeline-starter" using the token provided.[execute-remote-pipeline : execute-remote-pipeline-step][execute-remote-pipeline : execute-remote-pipeline-step] You have one project on this server: "test-pipeline"[execute-remote-pipeline : execute-remote-pipeline-step][execute-remote-pipeline : execute-remote-pipeline-step] Using project "test-pipeline".[execute-remote-pipeline : execute-remote-pipeline-step] Welcome! See 'oc help' to get started.[execute-remote-pipeline : execute-remote-pipeline-step] [execute-remote-pipeline : execute-remote-pipeline-step] Logged into "https://api.cluster-affc.sandbox1480.opentlc.com:6443" as "system:serviceaccount:prod-pipeline:pipeline-starter" using the token provided.[execute-remote-pipeline : execute-remote-pipeline-step] [execute-remote-pipeline : execute-remote-pipeline-step][execute-remote-pipeline : execute-remote-pipeline-step] [execute-remote-pipeline : execute-remote-pipeline-step] You have one project on this server: "prod-pipeline"[execute-remote-pipeline : execute-remote-pipeline-step] [execute-remote-pipeline : execute-remote-pipeline-step][execute-remote-pipeline : execute-remote-pipeline-step] [execute-remote-pipeline : execute-remote-pipeline-step] Using project "prod-pipeline".[execute-remote-pipeline : execute-remote-pipeline-step] [execute-remote-pipeline : execute-remote-pipeline-step] Welcome! See 'oc help' to get started.[execute-remote-pipeline : execute-remote-pipeline-step] [execute-remote-pipeline : execute-remote-pipeline-step] [prod : prod-step] Running on prod cluster[execute-remote-pipeline : execute-remote-pipeline-step] [execute-remote-pipeline : execute-remote-pipeline-step][execute-remote-pipeline : execute-remote-pipeline-step]
Обратите внимание, что в этом примере показано каскадное выполнение конвейеров Tekton. Есть и способ компоновки последовательное выполнение нескольких удаленных конвейеров.
Прежде чем переходить к заключению, кратко обсудим компоновку конвейеров с точки зрения безопасности. Kubernetes-нативность Tekton означает, что все управление доступом в нем осуществляется через RBAC. Поэтому, чтобы задача, запущенная на локальном кластере (допустим, на кластере Test на нашей схеме), могла запустить конвейер на удаленном кластере (Prod), у нее должны быть соответствующие разрешения, которые задаются на удаленном кластере (Prod). Таким образом, удаленный кластер, работающий в среде более высоко уровня (Prod), может ограничивать доступ для задач, работающие в среде более низкого уровня (Test). Например, Prod может разрешать Test-у запускать только штатные продакшн-конвейеры, поэтому Test не сможет создавать новые конвейеры в кластере Prod.
Итак, мы показали, как в Jenkins и Tekton создавать конвейеры CI/CD, охватывающие сразу несколько кластеров OpenShift, обсудив некоторые аспекты их проектирования, безопасности и реализации.
Нет нужды говорить, что контейнеризированные конвейеры будут работать одним и тем же образом на любом кластере OpenShift, неважно, расположен ли он в публичном облаке или в корпоративном дата-центре, что хорошо иллюстрирует преимущества гибридного облака.
Автор: Ales Nosek
13 мая Алес расскажет про Apache Airflow на OpenShift, и там тоже можно будет задавать вопросы, получать подарки и все такое.
13 мая.
Вебинар про бессерверные технологии в
OpenShift
Мы начинаем серию вебинаров, посвященных OpenShift'у и его
окружению.
Первый вебинар в серии про бессерверные технологии.
20 мая.
Вебинар OpenShift Virtualization: Виртуальные машины,
контейнеры и serverless вместе, в идеальном
порядке
Третий вебинар в серии про OpenShift Virtualization.
3 мая 2021 года Red Hat выпустила первую общедоступную версию OpenShift Pipelines, облачно-ориентированной системы непрерывной интеграции на базе СПО-проекта Tekton. Решение реализует Kubernetes фреймворк CI/CD для разработки и выполнения конвейеров, в которых каждый шаг запускается в своем собственном контейнере, что позволяет масштабировать шаги независимо друг от друга. Сегодня мы вкратце рассмотрим ключевые особенности и преимущества этого решения, а также приведем список дополнительных ресурсов для дальнейшего знакомства с ней и освоения.
Но, прежде чем переходить к OpenShift Pipelines, освежим в памяти основные концепты Tekton.
OpenShift Pipelines дополняет Kubernetes/OpenShift соответствующими CRD (ресурсами, определяемыми пользователем) для концептов CI/CD, таких как конвейер (pipeline), задача (task), шаг (step). В результате, эти концепты становятся своими (native) инстанцируемыми их можно создавать в виде отдельных экземпляров и, как следствие, полноценно масштабировать и развертывать, а также обеспечивать их безопасность средствами Kubernetes.
Поэтому для начала вспомним, что такое концепты Tekton:
Рис. 1. КонцептыTektonПо сути, основные концепты Tekton делятся на два вида: те, что задают конвейер, и те, что запускают конвейер.
Концепты, задающие конвейер (define pipeline)
Task повторно используемые и слабо связанные серии шагов (step), которые выполняют определенную задачу, например, сборку контейнерного образа.
Pipeline описание конвейера и задач (Task), которые он должен выполнять.
Концепты, запускающие конвейер (run pipelines)
TaskRun запуск и результаты выполнения экземпляра Task.
PipelineRun запуск и результаты выполнения экземпляра конвейера, который включает в себя ряд концептов TaskRun.
Подробнее об этих концептах можно почитать в официальной документации.
Теперь разберемся, что такое OpenShift Pipelines и для чего он нужен
OpenShift Container Platform это ведущая отраслевая Kubernetes-платформа корпоративного класса, которая предоставляет разработчикам множество функций, среди которых есть и CI/CD.
OpenShift Pipelines базируется на СПО-проекте Tekton и расширяет функционал платформы OpenShift стандратными методами, что сильно облегчает жизнь разработчикам.
OpenShift Pipelines поддерживается на уровне механизма операторов, поэтому он легко устанавливается и обновляется, и, соответственно, легко администрируется.
OpenShift Pipelines доступен на сайте OperatorHub, где представлены более 450 различных операторов для OpenShift Container Platform:
Установка OpenShift Pipelines предельно проста, и он сразу устанавливается как оператор уровня кластера, автоматически становясь доступным для всех проектов:
OpenShift Pipelines также дополняет OpenShift соответствующими CR, которые позволят добиться еще большей универсальности в плане конфигурации и интеграции с консолью OpenShift и т.д.
При появлении в OperatorHub новой версии OpenShift Pipelines, вы как администратор можете выбрать обновление до следующей версии, задав нужный канал обновления.
Tekton тоже дополняет стандартную поставку OpenShift концептами CI/CD, но в нем при создании и запуске конвейеров сложно обойтись без создания YAML-кода, и этого кода требуется писать очень много, тысячи строк. Поэтому Red Hat реализовала в консоли OpenShift полноценный UI для запуска и визуализации конвейеров (как тех, что работают сейчас, так и тех, что уже отработали), а также для графического создания конвейеров. При этом все необходимые YAML-файлы создаются автоматически, без написания какого-либо кода.
Ниже показано графическое представление конвейера, который уже был выполнен на платформе OpenShift, причем прямо из него можно получить доступ к журналам и событиям всех задач этого конвейера:
Рис. 2. Конвейеры в консоли OpenShiftПри желании можно легко просмотреть полный лог выбранной задачи:
Чтобы еще больше облегчить жизнь разработчикам, OpenShift Pipelines позволяет рисовать конвейеры прямо в консоли OpenShift, поэтому вам больше не нужен черный пояс по YAML, чтобы создать свой первый конвейер Tekton:
Рис. 3. Графическое проектирование конвейера в консоли OpenShiftНо если вы, как обладатель черного пояса по YAML, захотите что-то подправить, это всегда можно сделать прямо из консоли OpenShift:
Рис. 4. YAML примеры и снипеты в консоли OpenShiftБолее того, OpenShift Pipelines пригодится, даже если вы решите пойти по пути чистого YAML, и предложит вам готовые примеры и снипеты кода для более быстрой разработки конвейеров YAML. Кроме того, в систему можно интегрировать ваши корпоративные снипеты, сделав их доступными всем разработчикам. Именно для этого мы и добавили специальный CRD под названием ConsoleYAMLSamples.
Хотите увязать запуск конвейеров с некими внешними событиями (в терминах Tekton это называется Trigger), например, push- или pull-запросами Github или Gitlab? Вообще не проблема, в OpenShift Pipelines это есть из коробки, причем поддерживаются различные вендоры, включая Github, Gitlab, BitBucket и т.д.
Рис. 5. Добавление триггера в консоли OpenShiftВы просто создаете нужный триггер в UI, а OpenShift сам формирует все необходимые концепты, такие как EventListeners, TriggerTemplates (подробнее о них можно почитать в официальной документации).
OpenShift Pipelines из коробки содержит десятки готовых задач, которые можно использовать в составе конвейеров, включая задачи по клонированию кода из репозитория, сборки приложений на различных языках программирования, таких как java, dotnet core, python go, nodejs или использования инструментов сборки вроде maven, развертывания приложений и т.д. Список доступных задач можно увидеть в консоли OpenShift, раздел ClusterTasks, меню Pipelines -> Tasks:
Рис. 6. OpenShift Pipelines из коробки предлагает десятки готовых задачКроме того, этот список можно легко расширить. Для этого достаточно добавить ClusterTasks в кластер, после чего вам станут доступны сотни дополнительных задач на сайте TektonHub, который представляет собой публичный репозиторий для обмена задачами Tekton:
Рис. 7.TektonHub публичный репозиторий повторно используемых задач и конвейеров TektonРазработчики, использующие командную строку и IDE, могут воспользоваться преимуществами Tekton CLI, расширения Tekton для Visual Studio Code и плагина Tekton для IntelliJ, чтобы взаимодействовать с конвейерами прямо из своей обычной среды разработки и создавать, запускать, просматривать и выполнять действия на кластере непосредственно из командной строки.
Рис. 8. Расширение VSCode для OpenShift PipelinesВ заключение советуем посмотреть видеоверсию этой статьи на английском:
А также рекомендуем следующие ресурсы (EN):
Запись в блоге Red Hat к выпуску первых общедоступных версий OpenShift Pipelines и OpenShift GitOps
Демовидео от Siamak Sadeghianfar, продакт-менеджера OpenShift Pipelines
Серия статей Guide to OpenShift Pipelines в блоге Red Hat OpenShift
Видеоролики на русском:
Вебинары:
1 июня.
Red Hat Advanced Cluster Security Надежная защита облачных
приложений
На вебинаре рассмотрим
инструментыRed
Hat Advanced Cluster Security, необходимые для обеспечения
безопасности облачных приложений. Эксперты Red Hat и BCC расскажут,
как Advanced Cluster Security защищает жизненно важные приложения
на протяжении всего процесса сборки, развертывания и выполнения.
Устраняет слепые зоны в безопасности и сокращает время и усилия,
необходимые для реализации максимального уровня безопасности, а
также упрощает анализ, расследование и исправление в системе
безопасности
17 июня.Установка
и операции второго дня
Расскажем
про то, как ставитьOpenShiftс помощью Helper Node и еще немного про
Day-2, а также проведеммастер-класс, на котором объясним, что стоит
проделать после того, как OpenShift вошел в вашу жизнь.
И вновь мы приготовили для вас много инсайтов, мероприятий, книжек и шпаргалок. Оставайтесь с нами станьте частью DevNation!
Делаем свой личный Флайтрадар на Raspberry
Pi
Еще понадобится
недорогое USB-радио, антенна и опенсорный софт.
Опенсорсные инструменты для управления
проектами
Открытые
альтернативы Microsoft Project для профессиональной работы с
большими проектами.
Шпаргалка по Linux-команде
sed
SED (Stream EDitor)
это потоковый текстовый редактор, который построчно обрабатывает
входной поток (файл).
Бесплатный Developer Sandbox for
OpenShift
Это ваш
личный OpenShift в облаке, всего за пару минут и без какой бы то ни
было инсталляции. Среда создана специально для разработчиков и
включает в себя Helm-диаграммы, builder-образы Red Hat, инструменты
сборки s2i, также CodeReady Workspaces, облачную IDE с
веб-интерфейсом.
Виртуальный Red Hat Summit 2021, 27-28
апреля
Бесплатная
онлайн-конференция Red Hat Summit это отличный способ узнать
последние новости ИТ-индустрии, задать свои вопросы техническим
экспертам, услышать истории успеха непосредственно от заказчиков
Red Hat и увидеть, как открытый код генерирует инновации в
корпоративном секторе
oc --context hub create -f https://raw.githubusercontent.com/RHsyseng/acm-app-lifecycle-blog/master/acm-manifests/reversewords-region/00_namespace.yaml
# PlacementRule targeting EU region clustersoc --context hub create -f https://raw.githubusercontent.com/RHsyseng/acm-app-lifecycle-blog/master/acm-manifests/reversewords-region/01_placement_rule_EU.yaml# PlacementRule targeting US region clustersoc --context hub create -f https://raw.githubusercontent.com/RHsyseng/acm-app-lifecycle-blog/master/acm-manifests/reversewords-region/02_placement_rule_US.yaml
oc --context hub create -f https://raw.githubusercontent.com/RHsyseng/acm-app-lifecycle-blog/master/acm-manifests/reversewords-region/03_subscription-region.yamloc --context hub create -f https://raw.githubusercontent.com/RHsyseng/acm-app-lifecycle-blog/master/acm-manifests/reversewords-region/04_application-region.yaml
oc --context dev -n reverse-words-region get deployments,services,podsNAME READY UP-TO-DATE AVAILABLE AGEdeployment.extensions/reverse-words 1/1 1 1 4m39sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/reverse-words LoadBalancer 172.30.79.111 a3115b78bce924ddc885d2b7dab766a6-1199935412.eu-central-1.elb.amazonaws.com 8080:30254/TCP 4m39sNAME READY STATUS RESTARTS AGEpod/reverse-words-68795d69ff-xmwc6 1/1 Running 0 4m39s
oc --context pro -n reverse-words-region get deployments,services,podsNo resources found in reverse-words-region namespace.
oc --context hub -n reverse-words-region patch subscription.apps.open-cluster-management.io/reversewords-region-app-subscription -p '{"spec":{"placement":{"placementRef":{"name":"us-region-clusters"}}}}' --type=merge
oc --context dev -n reverse-words-region get deployments,services,podsNo resources found in reverse-words-region namespace.
oc --context pro -n reverse-words-region get deployments,services,podsNAME READY UP-TO-DATE AVAILABLE AGEdeployment.extensions/reverse-words 1/1 1 1 92sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/reverse-words LoadBalancer 172.30.177.196 a90273a7fa3ea4015989fac522b6b36e-709976322.us-west-2.elb.amazonaws.com 8080:30375/TCP 2m33sNAME READY STATUS RESTARTS AGEpod/reverse-words-68795d69ff-jlktw 1/1 Running 0 92s
apiVersion: apps.open-cluster-management.io/v1kind: PlacementRulemetadata: name: us-eu-region-clusters namespace: reverse-words-regionspec: clusterConditions: - type: "ManagedClusterConditionAvailable" status: "True" clusterSelector: matchExpressions: - key: region operator: In values: - EU - US matchLabels: {} clusterReplicas: 1
oc --context hub create -f https://raw.githubusercontent.com/RHsyseng/acm-app-lifecycle-blog/master/acm-manifests/reversewords-region/05_placement_rule_DR.yaml
oc --context hub -n reverse-words-region get placementrule us-eu-region-clusters -o yaml<OMITTED_OUTPUT>status: decisions: - clusterName: managed-cluster1-dev clusterNamespace: managed-cluster1-dev
oc --context hub -n reverse-words-region patch subscription.apps.open-cluster-management.io/reversewords-region-app-subscription -p '{"spec":{"placement":{"placementRef":{"name":"us-eu-region-clusters"}}}}' --type=merge
oc --context dev -n reverse-words-region get deployments,services,podsNAME READY UP-TO-DATE AVAILABLE AGEdeployment.extensions/reverse-words 1/1 1 1 42sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/reverse-words LoadBalancer 172.30.185.94 a520ed21ff982452abeacf63b0b58cc5-31012041.eu-central-1.elb.amazonaws.com 8080:32283/TCP 42sNAME READY STATUS RESTARTS AGEpod/reverse-words-68795d69ff-crzqp 1/1 Running 0 42s
oc --context hub -n reverse-words-region get placementrule us-eu-region-clusters -o yaml
<OMITTED_OUTPUT>status: decisions: - clusterName: managed-cluster2-prod clusterNamespace: managed-cluster2-prod
oc --context pro -n reverse-words-region get deployments,services,podsNAME READY UP-TO-DATE AVAILABLE AGEdeployment.extensions/reverse-words 1/1 1 1 76sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/reverse-words LoadBalancer 172.30.187.142 a1c7d218d901c40ac98375f4a9474084-1310645059.us-west-2.elb.amazonaws.com 8080:31095/TCP 78sNAME READY STATUS RESTARTS AGEpod/reverse-words-68795d69ff-ttzz5 1/1 Running 0 77s
Мы приготовили для вас много новых инсайтов, записей важных вебинаров, книжек и шпаргалок. Прокачивайте скилы, читайте, смотрите, думайте, применяйте на практике! Станьте частью DevNation!
4 строчки, которые сделают ваш Ansible-код намного
полезнее
Минимум
усилий, и вы не только обозначите безопасный путь для того, кто
будет потом с ним работать, но и предостережете последователя от
опасностей.
Учим Си, программируя простую игру
Игра Угадай число это отличная вводная программа для изучения
нового языка программирования. Сегодня напишем ее на Си.
3 моих любимых приложения с открытым кодом из разряда
productivity
Помогают
оптимизировать рабочие agile-процессы и повысить свою
продуктивность.
8 шпаргалок по софту Open Source, которые пригодятся в 2021 году
Шпаргалка по команде
Curl
Примеры
использования и синтаксис curl, включая ее использование для
запроса API.
Debezium на
OpenShift
Debezium это
распределенная опенсорсная платформа для отслеживания изменений в
данных. Благодаря ее надежности и скорости ваши приложения смогут
реагировать быстрее и никогда не пропустят события, даже если
что-то пойдет на так. Наша шпаргалка поможет с развертыванием,
созданием, запуском и обновление DebeziumConnector на
OpenShift.
Загрузить шпаргалку
Бесплатный онлайн-курс Разработка облачных приложений с микросервисными архитектурами
Что будет в готовящемся тренинге по установке Red Hat OpenShift Container Platform
28 января, DevNation: The Show
Еженедельный часовой чат в прямом эфире. Как обычно, в программе
свежие новости и интерактивная игра для участников.
DevNation Deep Dive: Kubernetes
Поспешите, поезд Kubernetes уже отправляется узнайте, как
применять, развертывать и использовать Kubernetes для решения
задач, с которые вы сталкиваетесь в облаке .
Вебинар DevNation Tech Talk Сборка kubectl-плагина с
помощью Quarkus
Разбираем, как с нуля спроектировать kubectl-плагин и собрать его,
используя Quarkus. Также рассмотрим удобную работу с
Kubernetes-кластером с использованием нативной компиляции для
получения сверхбыстрых бинарников и расширений для
Kubernetes-клиента.
jconf.dev
Бесплатная
виртуальная Java-конференция прямо у вас на экране: четыре
техно-трека с нашими комьюнити-экспертами по Java и облаку, 28
углубленных сессий и два потрясающих основных доклада.
AnsibleFest
Два
дня интереснейших докладов, демонстраций и практических занятий.
Отличная возможность узнать, как разработчики, администраторы и ЛПР
в сфере ИТ отвечают на вызовы перемен с помощью гибких технологий
автоматизации с открытым кодом, которые позволяют перейти от того,
что есть, к тому, что нужно.
J4K
Conference
Новая
виртуальная конференция по Kubernetes, Java и облаку: 17 сессий с
сотрудниками Red Hat, включая доклад Марка Литтла (Mark Little),
главного человека в Red Hat по связующему ПО.
Унаследованные приложения, как правило, имеют монолитную архитектуру и запускаются на одной или нескольких виртуальных машинах. Некоторые из таких систем легче поддаются модернизации, поскольку в мире контейнеров для них есть неплохие аналоги (EAP, Spring Boot и т.д.). Однако большие классические приложения на .Net, работающие под IIS на Windows-сервере, модернизировать гораздо сложнее, тем более за одну итерацию. Но благодаря OpenShift Virtualization такие ВМ-нагрузки можно импортировать в OpenShift как есть и затем контейнеризировать их поэтапно.
В OpenShift виртуальные машины являются привилегированными гражданами и имеют ровно те же возможности, что и podы, включая обращение к другим объектам и предоставление доступа к себе через конечные точки служб (service endpoints). Поэтому выполнив первичный перенос ВМ-приложения в OpenShift, его затем можно поэтапно модернизировать, а заодно и расширять функционал.
Чтобы показать, как это делается, мы для примера возьмем приложение .Net, работающее под IIS на виртуалке Windows Server, импортируем его в OpenShift Virtualization, а затем поэтапно контейнеризуем все его логические слои. Обратите внимание, что стратегия shift and modernize подходит и для других связок операционная системасвязующее ПО.
Импорт ВМ в OpenShift возможен несколькими способами. Для виртуальных машин VMware можно использоватьвстроенный инструментарий миграции, который позволяет подключиться к экземпляру VSphere и напрямую импортировать эти виртуалки в OpenShift Virtualization. Для других платформ виртуализации, включая Hyper-V и Xen, можно использовать virt-v2v, чтобы конвертировать образ ВМ в формат, поддерживаемый OpenShift Virtualization, а затем импортировать этот образ, используя методы описанные здесь (EN).
Виртуальная машина запускается с помощью Yaml-конфигурации, базовый вариант которой можно найтиздесь. Этот Yaml-файл содержит определение ВМ, а также объектов service и route, плюс, некоторые функциональные конфигурации для более эффективной работы Windows-ВМ на платформе OpenShift Virtualization.
Нас интересует следующее секция:
features: acpi: {} apic: {} hyperv: reenlightenment: {} ipi: {} synic: {} synictimer: {} spinlocks: spinlocks: 8191 reset: {} relaxed: {} vpindex: {} runtime: {} tlbflush: {} frequencies: {} vapic: {} evmcs: {} # do not use evmcs if testing with nested virt
После применения этого yaml, мы получаем доступ к графическому интерфейсу Windows UI через VNC Console, которую нам дает OpenShift Virtualization.
Кроме того, теперь у нас есть доступ к приложению через exposed route.
Не всегда можно мигрировать всё сразу, особенно в случае больших приложений. Например, этому могут препятствовать зависимости от библиотек, которые есть в классическом .NET, но отсутствуют в .Net Core. В этом случае код приложения придется доработать.
И поскольку это можно делать поэтапно, мы начнем с веб-интерфейса и после того, как переведем UI-слой на .Net Core, упакуем его в контейнерный образ для OpenShift. Этот новый UI-pod будет потреблять API, которые предоставляются старым сайтом, работающем под IIS на виртуальной машине.
Приведенный ниже Dockerfile компилирует ваш код .Net Core и создает runtime-образ. Это также можно сделать через сборки S2I.
# https://hub.docker.com/_/microsoft-dotnet-coreFROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS buildWORKDIR /source# copy csproj and restore as distinct layersCOPY ./source .RUN dotnet restore# copy and publish app and librariesCOPY . .RUN dotnet publish -c release -o /app --no-restore# final stage/imageFROM mcr.microsoft.com/dotnet/core/aspnet:3.1WORKDIR /appCOPY --from=build /app .ENTRYPOINT ["dotnet", "ClientListUI.dll"]
Для сборки и отправки этого образа в реестр можно использовать podman. Затем остается только развернуть этот отвечающий за веб-интерфейс pod вместе с виртуальной машиной приложения.
Вслед за UI-слоем мигрируем на .Net Core слой API и развернем его в виде отдельного podа. После чего на исходной виртуалке остается только база данных SQL Server. Соответствующим образом поправим сервис ВМ в части описания доступа:
kind: ServiceapiVersion: v1metadata: name: stage3-win2019-db-vm namespace: stage3 labels: kubevirt.io: virt-launcher kubevirt.io/domain: stage3-win2019-iis-vmspec: ports: - protocol: TCP port: 1433 targetPort: 1433 selector: kubevirt.io: virt-launcher kubevirt.io/domain: stage3-win2019-iis-vm
Итак, теперь UI-pod нашего приложения вызывает API через service URL нашего API-podа, а тот в свою очередь использует service URL нашей виртуальной машины, чтобы делать запросы к базе данных.
Да, вы правильно поняли: миграция экземпляра MS SQL в контейнер RHEL. Лет пять назад такое и в голову бы никому не пришло, но сегодня это вполне рабочий вариант и подробнее узнать о том, как настроить и запустить MS SQL в контейнере, можно узнать здесь (EN).
После того, SQL-pod будет готов, остается настроить port forwarding, чтобы можно было работать с БД через MS SQL Management Studio или Azure Data Studio:
oc get pod | grep sql | grep Runningsql2019-1-1-gp29h 1/1 Running 0 39h oc port-forward sql2019-1-1-gp29h 1433:1433Forwarding from 127.0.0.1:1433 -> 1433Forwarding from [::1]:1433 -> 1433Handling connection for 1433
Теперь можно переносить БД из экземпляра MS SQL на Windows-виртуалке в контейнер SQL Server. После чего, необходимо изменить строку подключения для API-podа приложения и указать в ней pod, где теперь живет ваш MS SQL.
Всё, приложение полностью, на 100% контейнеризовано, и виртуальную машину которую, мы перенесли на первом этапе, можно навсегда отключить.
Поэтапная миграция ВМ-нагрузки по методу shift and modernize позволяет снизить технический долг, минимизировать любого рода регрессии, которые могут возникнуть входе этого процесса, ну и попутно расширить функционал приложения в рамках проводимой при такой миграции доработки кода.
Мы знаем, как провести эти праздники максимально полезно: собрали для вас много новых инсайтов, записей важных вебинаров, книжек и шпаргалок. Прокачивайте скилы, читайте, смотрите, думайте, применяйте на практике! Станьте частью DevNation!
6 советов по защите Linux-сервера для
начинающих
Воспользуетесь
ими, чтобы сделать свою среду Linux более безопасной.
Играем в прикольную арифметическую игру с помощью команд
Linux
Почему бы не устроить
британское телевикторину Countdown у себя дома?
4 способа переключения контекста в
Git
Сравниваем плюсы и
минусы четырех подходов к смене бранчей в Git.
Как зариповать и каталогизировать свои аудио-CD с помощью опенсорсных инструментов
Шпаргалка по Linux-командам для работы
сетями
Основные команды и
что можно узнать с их помощью.
Шпаргалка по GNU
Screen
В GNU Screen есть
море клавиатурных команд. Часто используемые запоминаются легко, а
вот за остальными приходится обращаться к экрану справки. Или их
можно распечатать и держать под рукой.
5 аппаратных архитектур для машинного обучения на edge-системах
5 признаков, что вам надо поработать над эмоциональным интеллектом
Домашняя автоматизация: запускаем Home Assistant через Podman
6 мая. DevNation: The Show
13 мая.
Вебинар про бессерверные технологии в
OpenShift
Мы начинаем серию
вебинаров, посвященных OpenShift'у и его окружению.
Первый вебинар в серии про бессерверные технологии.
20 мая.
Вебинар OpenShift Virtualization: Виртуальные машины,
контейнеры и serverless вместе, в идеальном
порядке
Третий вебинар в
серии про OpenShift Virtualization
[ocp@shift-is01 macvlan]$ oc new-project multus-test
spec: additionalNetworks: - name : net1 namespace: multus-test type: Raw rawCNIConfig: |- { "cniVersion": "0.3.1", "type": "ipvlan", "mode": "l2", "master": "ens224", "ipam": { "type": "static" } }
[ocp@shift-is01 macvlan]$ oc get network-attachment-definitions --all-namespacesNAMESPACE NAME AGEmultus-test net1 3m4s[ocp@shift-is01 macvlan]$ oc get network-attachment-definitions.k8s.cni.cncf.io -n multus-test net1 -o yamlapiVersion: k8s.cni.cncf.io/v1kind: NetworkAttachmentDefinitionmetadata: creationTimestamp: "2020-11-02T16:44:46Z" generation: 1 managedFields: - apiVersion: k8s.cni.cncf.io/v1 fieldsType: FieldsV1 fieldsV1: f:metadata: f:ownerReferences: .: {} k:{"uid":"01a4f46a-fc3c-495f-b196-b39352421e2a"}: .: {} f:apiVersion: {} f:blockOwnerDeletion: {} f:controller: {} f:kind: {} f:name: {} f:uid: {} f:spec: .: {} f:config: {} manager: cluster-network-operator operation: Update time: "2020-11-02T16:44:46Z" name: net1 namespace: multus-test ownerReferences: - apiVersion: operator.openshift.io/v1 blockOwnerDeletion: true controller: true kind: Network name: cluster uid: 01a4f46a-fc3c-495f-b196-b39352421e2a resourceVersion: "25898949" selfLink: /apis/k8s.cni.cncf.io/v1/namespaces/multus-test/network-attachment-definitions/net1 uid: 7a7d718b-82c5-46fe-8f72-8fd4299508ecspec: config: |- { "cniVersion": "0.3.1", "type": "ipvlan", "mode": "l2", "master": "ens224", "ipam": { "type": "static" } }
[ocp@shift-is01 ipvlan]$ cat ./pod-ipvlan-static.yamlapiVersion: v1kind: Podmetadata: namespace: multus-test name: test-multus-pod labels: app: test-multus-pod annotations: k8s.v1.cni.cncf.io/networks: '[ { "name": "net1", "ips": ["192.168.112.250/24"] }]'spec: nodeSelector: node-role.kubernetes.io/multus-node: yes containers: - name: test-multus-pod image: centos/tools command: ["/bin/bash", "-c", "sleep 9000000"]
ocp@shift-is01 ipvlan]$ oc rsh test-multus-podsh-4.2# ip a1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever3: eth0@if2142: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default link/ether 0a:58:0a:fe:04:a0 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.254.4.160/24 brd 10.254.4.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::bc4b:abff:fe0b:91f8/64 scope link valid_lft forever preferred_lft forever4: net1@if826: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether 00:50:56:96:f3:02 brd ff:ff:ff:ff:ff:ff inet 192.168.112.250/24 brd 192.168.112.255 scope global net1 valid_lft forever preferred_lft forever inet6 fe80::50:5600:196:f302/64 scope link valid_lft forever preferred_lft foreversh-4.2# ping 192.168.112.1 -c 3PING 192.168.112.1 (192.168.112.1) 56(84) bytes of data.64 bytes from 192.168.112.1: icmp_seq=1 ttl=64 time=0.179 ms64 bytes from 192.168.112.1: icmp_seq=2 ttl=64 time=0.230 ms64 bytes from 192.168.112.1: icmp_seq=3 ttl=64 time=0.223 ms--- 192.168.112.1 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2041msrtt min/avg/max/mdev = 0.179/0.210/0.230/0.028 ms