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

и с тобой покончено.

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

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

Моральный

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