Обновление Docker-контейнера без простоев

17

Допустим, у меня есть контейнер Docker с веб-сервером (например, Apache 2). Теперь я хочу обновить ОС под него. Этот ответ SF говорит, что лучший способ - восстановить базовый образ и мой образ Apache. Но развертывание образа означает время простоя, потому что мне нужно удалить старый контейнер, прежде чем я смогу создать новый, поэтому есть только один контейнер, привязанный к порту 80/443.

Но как я могу развернуть это обновление без простоев? Должен ли я использовать балансировщик нагрузки и использовать межконтейнерную связь? А как мне обновить балансировщик нагрузки?

das_j
источник

Ответы:

18

Идеальный целевой сценарий

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

Например, представьте, что у вас есть балансировщик нагрузки, который обслуживает ваш сайт A. Пользователи подключаются к нему только и знают его только как «A». Балансировщик нагрузки знает, что есть два или более бэкэнда (B, C и т. Д.), И не важно, являются ли они виртуальными машинами или контейнерами.

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

  1. уберите B из подходящих бэкэндов для балансировщика нагрузки, чтобы он больше не принимал трафик.
  2. дождитесь обработки текущих запросов и закрытия существующих подключений.
  3. обновить контейнер или базовую виртуальную машину, которая обслуживает B
  4. перезагрузите B, дождитесь его загрузки и начните работать
  5. тест B, чтобы убедиться, что он обслуживает новые запросы правильно
  6. добавьте B обратно в пул подсистемы балансировки нагрузки, чтобы снова включить трафик

Затем выполните тот же процесс для C, D и т. Д.

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

Что делать для существующего живого сайта

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

Давайте предположим, что:

  • у вас есть DNS-имя, указывающее на ваш контейнер
  • ваш контейнер работает на каком-то IP-адресе
  • ваши пользователи не знают IP-адрес контейнера, и он нигде не запрограммирован

Если эти предположения неверны, вы должны сначала исправить это так, чтобы это было правильно.

Затем выполните следующие действия:

  1. создайте балансировщик нагрузки на новом IP и укажите его на существующий контейнер как его единственный бэкэнд
  2. изменить DNS, чтобы он указывал на балансировщик нагрузки, а не на IP-адрес контейнера напрямую
  3. добавить идентичный бэкэнд Apache с той же настройкой контейнера VM +
  4. Теперь у вас есть балансировщик нагрузки с двумя бэкэндами B и C, поэтому следуйте указаниям в разделе «идеальный целевой сценарий», чтобы обновлять их по одному за раз

Как обновить балансировщик нагрузки

Простой (хостинг) способ

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

Ручной способ

Если вы используете свой собственный балансировщик нагрузки, то поможет еще один уровень косвенной адресации (например, DNS). Давайте предположим следующее:

  • что у нас есть имя хоста, разрешающее IP нашего балансировщика нагрузки A, которое мы хотели бы обновить
  • наш балансировщик нагрузки имеет внутренний пул P1, P2 и т. д.

Мы действуем следующим образом:

  • создать новый балансировщик нагрузки B с новой версией программного обеспечения
  • добавьте все экземпляры пула бэкэндов P1, P2 и т. д. в наш новый балансировщик нагрузки B в качестве бэкэндов
  • добавить IP-адрес B к разрешению DNS вместе с A

    • теперь мы эффективно используем DNS в качестве балансировщика нагрузки
    • если записи для A и B невзвешенные, они фактически 50-50
    • Теперь посмотрите, как B работает, есть ли ошибки и т. д.
    • если что-то не так с B, отмените следующее:

      1. удалить B из конфигурации DNS
      2. дождитесь исчезновения записи B в DNS (т. е. дождитесь окончания срока действия TTL )
      3. выключить B
  • Предположим, вы выполнили тест «прожигания» для B, и все в порядке.
  • обновлять приоритет и вес для B в DNS постепенно
  • полностью удалить из DNS
  • дождаться истечения срока действия DNS TTL; А не должен больше получать запросы
  • выключи А

и вы сделали.

Детали, схемы и инструменты

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

Мораль

«Все проблемы в информатике могут быть решены с помощью другого уровня косвенности, за исключением, конечно, проблемы слишком большого числа косвенных ошибок». - Дэвид Уилер

Миша Брукман
источник
Но когда балансировщик нагрузки находится в контейнере (при использовании CoreOS), как мне обновить этот контейнер?
das_j
@das_j Я отредактировал ответ, чтобы добавить также инструкцию по обновлению балансировщика нагрузки. Подсказка: все дело в другом уровне косвенности. :-)
Миша Брукман
1
В целом, это звучит как обновление физических серверов и балансировщиков нагрузки.
Стефан Ласевски
@ StefanLasiewski Вы абсолютно правы, и я удалил примечание «контейнеры» в одном из заголовков. Для внешнего пользователя, является ли приложение или балансировщик нагрузки запущенным на голом железе, контейнером или виртуальной машиной, в значительной степени не видно.
Миша Брукман