Назад | Перейти на главную страницу

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

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

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

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

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

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

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

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

Затем проделайте то же самое для C, D и т. Д.

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

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

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

Предположим, что:

  • у вас есть 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 постепенно
  • полностью удалить A из DNS
  • дождитесь истечения срока действия DNS TTL; A больше не должно получать никаких запросов
  • выключить A

и вы сделали.

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

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

Мораль

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