Pull to refresh

Comments 21

Зачем для одного сайта docker? Пустая трата оперативки

Например за тем чтобы не париться с тем какие версии по есть в репозиториях того дистрибутива, который сейчас на сервере. Обновить версию докеризированной субд становится в разы проще.

По той же причине не страшно переезжать с какого-нибудь умирающего центоса на убунту.

Запуск прод версии сайта в докере полезно тем, что становится очень просто развернуть dev версию контейнера, т.е. вы получаете окружение максимально похожее на боевое.

Плюсов в этом подходе больше чем минусов. Можно порассуждать о том, что для прода можно выбрать что-то посерьёзнее чем docker-compose, но и кубернетис был бы тут вероятно избыточным.

Так или иначе это уже шаг в сторону современной архитектуры и это лучше чем некоторые альтернативы.

Обновить версию докеризированной субд становится в разы проще.

Вы пробовали? Хотя бы постгрес. Хотя бы между соседними версиями. Допустим, 11 -> 12. Можно даже не слишком большую, гиг на 300. Просто чтобы pg_dump/pg_restore стал слишком долгим для использования в продакшене, где даунтайм имеет значение.

О, я скоро буду пробовать. Без простоя, пожалуй, только логическая репликация остаётся, благо с "десятки" она встроенная. И напомню, что этот "вопрос с подковыркой" годами был одним из самых горячих внутри сообщества, в том числе из-за сложностей с обновлением с Postgres ушёл Uber, здесь обсуждение их проблем и упоминается много всего интересного, включая некое таинственное "коммерческое решение", которое позволяет снизить простой.

Нет, совсем без даунтайма не обязательно. 5-10 минут может быть допустимо, часы - вряд ли. Речь о том, что обкатанные, проверенные временем быстрые способы типа `pg_upgrade --link` легко и просто работают на машинах. Но в контейнерах (а ещё лучше в кубе) это превращается в упражнения, без которых лучше бы обойтись. При этом проблема даже не в контейнерах как таковых: если данные хранятся локально, то контейнеры бесплатны с т.з. производительности (но не когнитивной нагрузки). Проблема в докере и его PID 1. С тем же LXC сложностей нет.

Поэтому я бы десять раз подумал, прежде чем применять докер для stateful нагрузок вообще и баз в частности.

Если говорить о системе где недопустим даунтайм, то да, схема развёртывания тут неверна.

Но когда видишь в одном месте битрикс и запуск бд и веб-сервера на одной машине, остаётся только порадоваться что тут используется докер и что все компоненты не завернуты в один контейнер.

Вы буквально описали мою ситуацию. Имеется сервер под Centos 6, на котором на php 7.1 работает сайт. И надо как-то все это обновить до актуальных версий, причем в процессе обновления надо временно приостановиться на PHP 7.4, чтобы успешно установить самые старые обновления CMS, которые на версии PHP младше 7.4 не установятся

Зачем для одного сайта docker? Пустая трата оперативки

Я например, очень активно использую Docker в разработке. Недавно как раз настраивал себе среду для веб-приложений с HTTPS и прочими свистоперделками вроде автоматической сборкой проекта и перезагрузкой сервера по сохранению файла снаружи контейнера.

Если речь не идёт о Docker Desktop, а о нативных контейнерах (Linux), то оверхеда нет ни по памяти, ни по CPU, потому что это всего лишь механизм изоляции процессов на уровне ядра, а не виртуалка или эмуляция. А вот по сети оверхед есть

Ядро-то изолировано, а над ядром – отдельный юзерспейс, ортогональный хостовому. Как тут может не быть оверхеда по памяти?

Легко. Механизмы изоляции процессов, на которых основана контейнеризация, используются даже тогда, когда вы не используете контейнеры. Например systemd использует и cgroups и namespaces. Просто на всякий случай, вдруг вы захотите ими управлять.

Да, создавая новый нейсмпейс вы выделяете в ядре какие-то дополнительные дескрипторы. Это можно посчитать тратой памяти. Потратите несколько килобайт. Думаю это где-то в пределах погрешности, т.к. процессы внутри контейнеров потребляют на два-три порядка больше.

Выражусь поконкретней. У меня хост-система, допустим, Debian с glibc, а в контейнере – Alpine с musl. Соответственно, хостовые приложения у нас связаны с одной библиотекой, а контейнеризованные – с другой. Так под glibc и musl что, не выделяется память отдельно под ту и другую?

Далее, представим себе, что у нас уже контейнеризовано что-то на Alpine версии 3.15 с musl=1.2.2, и тут мы создаём новый контейнер с Alpine 3.16 и musl=1.2.3. У нас опять происходит магия и никакого оверхеда, или всё-таки расходуется память под обе версии musl?

А если ещё чуть-чуть подумать, разве не весь юзерспейс у нас ведёт себя точно так же? Библиотеки, утилиты, шеллы? На хосте и в каждом контейнере?

Ну так и на хосте, без контейнеров, можно запустить разные версии приложений с разными версиями либ под капотом. Но почему-то никто не называет это оверхедом, это просто следствие использования разных версий приложений одновременно. Если файлы разные, то кэшироваться они будут независимо друг от друга.

А вот если запускать несколько контейнеров из одного образа, где версии приложений/либ совпадают, то по сути все контейнеры ссылаются на один и тот же файл внутри образа, поэтому он загружается в память только один раз. Дисковый кэш находится уровнем ниже разделения на namespace, поэтому для него не важно, запустили приложение на хосте, в контейнере или в нескольких.

Более подробно можно почитать здесь: https://biriukov.dev/docs/page-cache/7-how-much-memory-my-program-uses-or-the-tale-of-working-set-size/

И да, не userspace, а namespace. Причем это не один namespace на контейнер, а несколько - изолируется файловая система, процессы, сеть и т.п.:

https://habr.com/ru/company/ruvds/blog/592057/

https://habr.com/ru/company/ruvds/blog/593335/

Ну так и на хосте, без контейнеров, можно запустить разные версии приложений с разными версиями либ под капотом.

Ключевое слово «можно». При том, что обычно так не делается. Обычно все приложения в дистрибутиве линкуются с одной версией либы, насколько это возможно. На то он и дистрибутив. Докеризация, напротив, позволяет для каждого приложения тащить разные версии всего подряд – не только слинкованных либ, а вообще всего, кроме ядра – при том, что никакой необходимости в этом нет.

А вот если запускать несколько контейнеров из одного образа, где версии приложений/либ совпадают, то по сути все контейнеры ссылаются на один и тот же файл внутри образа

Я это прекрасно понимаю, но мне почему-то кажется, что на практике такие счастливые совпадения происходят нечасто.

И да, не userspace, а namespace.

А давайте я вам тоже ссылку дам: https://en.wikipedia.org/wiki/User_space_and_kernel_space.

У меня так лендинг и документация в альпинку завёрнуты. При пуше в мастер Github Actions собирает докер контейнер, пушит в хаб, а на беке watchtower получает обновление и разворачивает образ. Довольно удобно.

К mysql можно достучаться из мира? По какому адресу?

Можно ли выполнить из командной строки php-скрипт? Как?

Можно ли перезапускать php через systemctl?

Можно ли подключиться к контейнеру по ssh?

К mysql достучаться - нельзя, поскольку на хосте открыты только 22, 80, 443 порты. Если есть такая необходимость - то надо на хосте открыть порт 3306, а в compose-app.yml в сервисе database в секции "ports" указать:

ports:
  - "3306:3306"

Выполнить скрипт из командной строки - можно. Поскольку PHP у нас только в контейнере application, то запускать php скрипт мы будем именно через этот контейнер. Путей два:

  1. Напрямую из командной строки контейнера application

docker exec -it application bash \
php public/index.php
  1. Из командной строки хоста через контейнер application:

docker exec application sh -c "php public/index.php"

Перезапуск php через systemctl - нет, не предусмотрено. Если нужно, то есть довольно подробная инструкция как это сделать.

По поводу подключения по ssh - если речь о том, что сайт размещен на удаленной машине, а подключиться надо с локальной - то да. На локальной машине выполняем:

docker context create remote-env --docker host=ssh://www@example.com
docker context use remote-env

В результате у нас локальный docker будет работать с сайтом на удаленном сервере, например команда

docker-exec -it application bash

запустит командную строку bash в контейнере application не локально, а на удаленном сервере.

ports:
- "3306:3306"

а вот так не надо делать, порт будет смотреть в мир, докер вне правил фаервола по умолчанию, надо 127.0.0.1:3306:3306 и уже в том же датагрип подключаться через тунель
1. image: mysql надо указывать конкретную версию
2. links устарели
3. certbot можно успешно заменить на traefik
4. у вас окружение для дева но не прода, на прод уже готовые образы доставляются с кодом внутри

3. certbot можно успешно заменить на traefik

Тот факт, что traefik умеет сам ставить и обновлять сертификаты, это несомненно плюс. Только это не отменяет того, что certbot — просто утилита для работы с сертификатами, а traefik — проксирующий веб-сервер.

Лучше ставить Caddy взамен nginx'а, раз уж на то пошло.

Sign up to leave a comment.

Articles