Объяснение паттерна Sidecar на примере
Kubernetes — это движок оркестрации контейнеров с открытым исходным кодом для автоматического развертывания, масштабирования и управления контейнеризированными приложениями. Под (Pod) – это базовое понятие при проектировании приложений в Kubernetes. Kubernetes оперирует подами, а не контейнерами, при этом поды включают в себя контейнеры. Под может содержать в себе описания одного или нескольких контейнеров, монтируемых разделов, IP-адресов и настроек того, как контейнеры должны работать внутри пода.
Под, содержащий один контейнер, относится к одно-контейнерным подам и это самый распространенный вариант их использования в Kubernetes. Под, который содержит несколько связанных контейнеров, относится к мульти-контейнерным подам. Есть несколько паттернов для мульти-контейнерных подов и один из них — это паттерн sidecar. В этом посте мы на примере проекта детально рассмотрим этот паттерн.
-
Что такое контейнер Sidecar
-
Другие паттерны
-
Пример
-
Тестируем с объектом Deployment
-
Как настроить ресурсные ограничения Resource Limits
-
Когда мы должны использовать этот паттерн
-
Итог
-
Заключение
Что такое Sidecar-контейнер
Sidecar-контейнер — это контейнер, который должен быть запущен рядом с основным контейнером внутри пода. Этот паттерн нужен для расширения и улучшения функциональности основного приложения без внесения в него изменений. Сейчас мы знаем, что технология контейнеризации позволяет собирать все зависимости, чтобы мы могли запустить приложение где угодно. Контейнер делает только одну вещь и делает её хорошо.
Представьте, что у вас есть под с одним контейнером, который очень хорошо работает, и вы бы хотели добавить какой-то функционал к этому контейнеру, не внося в него изменений. Как тогда можно добавить или расширить для него какие-то функции? Паттерн Sidecar может помочь именно в такой ситуации.

На диаграмме выше видно, как вы можете создать любое количество Sidecar контейнеров и ваш основной контейнер будет успешно с ними взаимодействовать. Все контейнеры работают параллельно и полный функционал будет доступен только если каждый из контейнеров успешно запущен. В большинстве случаев sidecar-контейнеры просты и легковесны и потребляют намного меньше ресурсов чем основной контейнер.
Другие паттерны
Вот некоторые другие паттерны, которые можно использовать для повседневной работы в Kubernetes:
Пример проекта
Здесь пример проекта, который вы можете скопировать и запустить на своих мощностях. Предварительно вам нужно установить Minikube.
https://github.com/bbachi/k8s-sidecar-container-pattern.git
Давайте запустим простой проект, чтобы понять как работает этот паттерн. Здесь под, в котором есть основной и sidecar контейнеры. Основной контейнер это Nginx, слушающий на порту 80, который отдает страницу index.html из volume, примонтированного в location workdir. И sidecar-контейнер с образом busybox, который пишет лог с timestamp в тот же самый файл. Так как sidecar-контейнер и основной контейнер запущены параллельно, Nginx будет показывать новую информацию каждый раз, когда вы делаете обращение через браузер.
apiVersion: v1 kind: Pod metadata: name: sidecar-container-demo spec: containers: - image: busybox command: ["/bin/sh"] args: ["-c", "while true; do echo echo $(date -u) 'Hi I am from Sidecar container' >> /var/log/index.html; sleep 5;done"] name: sidecar-container resources: {} volumeMounts: - name: var-logs mountPath: /var/log - image: nginx name: main-container resources: {} ports: - containerPort: 80 volumeMounts: - name: var-logs mountPath: /usr/share/nginx/html dnsPolicy: Default volumes: - name: var-logs emptyDir: {}
// create the pod kubectl create -f pod.yml // list the pods kubectl get po // exec into pod kubectl exec -it sidecar-container-demo -c main-container -- /bin/sh # apt-get update && apt-get install -y curl # curl localhost
Вы можете установить curl и сделать запрос на localhost, чтобы проверить ответ сервера.

Тестирование с объектом Deployment
Давайте создадим сущность deployment с тем же определением подов и 5 репликами. Я создал service с типом порта NodePort, чтобы мы могли получить доступ к deployment через браузер. Поды создаются динамически и поддержкой заданного состояния всегда занимается deployment controller, поэтому у вас не может быть одного статического IP для доступа к поду, вместо этого вам нужно создать сущность service, которая будет открывать определенный порт во внешний мир. Внутри кластера service перенаправляет запросы извне на 80 порт контейнеров с соответствующими селекторами (тут много изменений оригинального текста). Вы увидите как это работает через некоторое время.

Теперь давайте посмотрим на приведенный ниже deployment, в котором мы определили один основной контейнер и два sidecar-контейнера. Все контейнеры работают параллельно. Два sidecar-контейнера пишут лог в директорию /var/log. Основной контейнер с Nginx будет отдавать эти файлы, когда мы будем подключаться к порту 80. Вы увидите это в действии через некоторое время.
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: nginx-webapp name: nginx-webapp spec: replicas: 5 selector: matchLabels: app: nginx-webapp strategy: {} template: metadata: creationTimestamp: null labels: app: nginx-webapp spec: containers: - image: busybox command: ["/bin/sh"] args: ["-c", "while true; do echo echo $(date -u) 'Hi I am from Sidecar container 1' >> /var/log/index.html; sleep 5;done"] name: sidecar-container1 resources: {} volumeMounts: - name: var-logs mountPath: /var/log - image: busybox command: ["/bin/sh"] args: ["-c", "while true; do echo echo $(date -u) 'Hi I am from Sidecar container 2' >> /var/log/index.html; sleep 5;done"] name: sidecar-container2 resources: {} volumeMounts: - name: var-logs mountPath: /var/log - image: nginx name: main-container resources: {} ports: - containerPort: 80 volumeMounts: - name: var-logs mountPath: /usr/share/nginx/html dnsPolicy: Default volumes: - name: var-logs emptyDir: {} status: {} --- apiVersion: v1 kind: Service metadata: name: nginx-webapp labels: run: nginx-webapp spec: ports: - port: 80 protocol: TCP selector: app: nginx-webapp type: NodePort
И выполним следующие команды, чтобы протестировать deployment.
// create a deployment kubectl create -f manifest.yml // list the deployment, pods, and service kubectl get deploy -o wide kubectl get po -o wide kubectl get svc -o wide

На диаграмме выше вы можете видеть 5 подов, запущенных на разных IP-адресах и service, связывающие порты 32123 и 80. Вы можете получить доступ к этому deployment из браузера через IP ворке-ноды Kubernetes 192.168.64.2 и через порт сервиса 32123:
http://192.168.64.2:32123
Вы также можете протестировать под следующими командами:
// exec into main container of the pod kubectl exec -it nginx-webapp-7c8b4d4f8d-9qmdm -c main-container -- /bin/sh // install curl # apt-get update && apt-get install -y curl # curl localhost

Как настроить ограничения ресурсов
Настроить ограничения ресурсов очень важно, если речь идет о sidecar-контейнерах. Главное, что нам нужно понять, это то, что все контейнеры работают параллельно, поэтому при настройке ограничений ресурсов для пода вы должны это учитывать.
-
Суммировать все ограничения ресурсов для основных контейнеров, а также для дополнительных контейнеров (поскольку все контейнеры работают параллельно).
Когда нам нужно использовать этот паттерн
Вот несколько сценариев, в которых вы можете использовать этот паттерн:
-
Всегда, когда вы хотите дополнить функционал уже существующего единичного контейнера без внесения в него изменений
-
Вы можете использовать этот контейнер для синхронизации кода основного контейнера с кодом на git-сервере используя pull.(You can use this pattern to synchronize the main container code with the git server pull.)
-
Вы можете использовать этот контейнер, чтобы отправлять логи основного контейнера на внешний сервер.
-
Вы можете использовать этот контейнер для задач, связанных с установлением сети (network-related tasks.).
Итог
-
Под, который содержит один контейнер, относится к одно-контейнерному поду и это самый распространенный шаблон его использования.
-
Под, содержащий несколько взаимосвязанных контейнеров, относится к мульти-контейнерному поду.
-
Паттерн Sidecar — это один из паттернов, которые мы используем постоянно для расширения или изменения функционала существующих контейнеров.
-
Sidecar-контейнер запускается параллельно с основным контейнером. Поэтому вам нужно учитывать ограничения ресурсов для sidecar-контейнера прежде, чем вы задаете запросы/ограничения ресурсов для пода.
-
Контейнер с приложением и Sidecar-контейнер запускаются параллельно, что значит, что они будут работать в одно и то же время. Поэтому вам нужно суммировать все запросы/ограничения ресурсов для контейнеров, прежде чем задавать запросы/ограничения ресурсов для подов.
-
Вам нужно настроить health checks для sidecar-контейнеров так же, как и для основных контейнеров, что бы быть уверенными, что они в порядке.
-
Все поды, порожденные deployment не имеют статического IP-адреса, поэтому вам нужно создать сущность service, чтобы дать к ним доступ из внешнего мира.
-
Сущность service перенаправляет трафик внутри кластера с внешних портов на порты контейнера в соответствии с выбранными селекторами.
Заключение
Знать проверенные временем паттерны в kubernetes полезно. Убедитесь, что все ваши sidecar-контейнеры достаточно просты и малы, потому что вам нужно будет просуммировать все запросы и ограничения ресурсов прежде чем задавать их для пода в целом. Также нужно быть уверенным, что Sidecar-контейнеры “здоровы”, настроив health checks. Помните об этих моментах, когда добавляете функционал в основной контейнер или используйте отдельный контейнер.
ссылка на оригинал статьи https://habr.com/ru/company/nixys/blog/559368/
Добавить комментарий