Skip to content

Murkysik/devops_lab1_base_open

Repository files navigation

1 часть dockerfile

Изучив реальные Dockerfile и доступную литературу, я выделил несколько базовых bad practices. Для своего кейса я попытался осуществить как можно больше, не только 3, но из-за слишком простого проекта получилось не все.

Bad practices:

  1. Выбор образа - стоит использовать официальные образы и alpine или с минимальными дополнительными пакетами, также использование тега: latest.
  2. Ипользовать ADD вместо COPY. ADD -примущемтвенно для распковки архивов или удаленного ресурса. Для всех остальных слуачев лучше COPY - недежнее без сюрпризов.
  3. Не оптимизировать кэши и слои - пример: часто изменяющеся файлы копировать раньше(файлы проекта, раньше файла с зависомостями) и другие варианты.
  4. Не объединять RUN инструкций - стоит обьеденять RUN иструкции, так как каждая отдельная, отдельный слой занимающий больше места.
  5. Не думать о безопасности в Dockerfile - не хранить секреты в dockerfile, не запускать приложени в dockerfile из под root.
  6. Не пользоваться healthcheck
  7. Не использовать multi-stage сборки - с компелируемыми языками програмирования полезно для ускорения сборки использовать multi-stage.
  8. Использовать shell-форму в Endpoint и CMD вместо exec — при shell-форме могут возникнуть проблемы с сигналами, так как все процессы запускаются после PID 1 — интерпретатора в системе, в то время как при exec-форме PID 1 получает сам процесс, описанный в CMD или Endpoint.

Мои bad practices:

  1. Выбор образа — использовал Python:latest вместо slim-версии. Разница: занимает на 1 гигабайт больше места, долго скачивается.
  2. Использовать ADD вместо COPY — в моем случае влияния нет, но так не стоит делать.
  3. Не оптимизировать кэши и слои — файлы кода загружаются раньше списка зависимостей, хотя изменяются чаще и не может использоваться тот же кэш.
  4. Запуск из-под root — небезопасно, 4 моих года безопасника испытывали физическую боль, выполняя этот пункт. Решение: создание пользователя без root и запуск с его правами проекта.
  5. Не использовал healthcheck — хотя бы так организовать мониторинг доступности.
  6. Использовать shell-форму в Endpoint и CMD вместо exec — в моем случае не влияло, но не стоит так делать.

Плохие практики по работе с контейнерами:

  1. Не устанавливать лимиты по контейнеру: запуск контейнера без лимитов может привести к тому, что он использует все возможные ресурсы и не оставит другим. Чтобы этого избежать, стоит использовать --memory, --cpus, --pids-limit.
  2. Использовать проброс docker.sock, таким образом, даже если приложение внутри контейнера запущено не от root, у потенциального злоумышленника появляется возможность получить доступ к инфраструктуре, используя docker API.

2 часть docker compose

Для продолжения выполнения задания пришлось усложнить проект, для этого sqllite был заменен на postgres. Были выбраны следующие bad practices для реализации:

  1. Хранение секретов в файле сборки.
  2. Запуск базы данных с избыточными привилегиями.
  3. Использование базовой сети.
  4. Не использовать volume при работе с БД.

То, как исправил и что добавил в good docker compose:

  1. Использую secrets и немного изменил app.py.
  2. Убрал запуск с избыточными привилегиями.
  3. Создал отдельную сеть, куда и включил оба сервиса.
  4. Использовал volume для БД.

Сетевая изоляция: Изначально я помещал сервисы в одну сеть, поэтому сервисы могли обращаться друг к другу по имени. Для изоляции двух сервисов мне пришлось создать вторую сеть и разделить сервисы по разным сетям, таким образом у них нет общей сети и docker DNS не может резолвить запросы по имени сервиса.

Этот вариант изоляции работает, так как Docker специально изолирует все виртуальные сети и docker DNS работает только в рамках одной сети. Таким образом обеспечивается безопасность и сеть получается плоской, что упрощает работу с сетями внутри контейнеров.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors