суббота, 29 августа 2020 г.

Health Check для докер-контейнера

С версии докера 1.12 в докер-контейнере появилась возможность проверки работоспособности контейнера – так называемый health check. 

Типичный health check организуется периодическим вызовом некой команды, которая проверяет «жив» ли сервис, который исполняется в контейнере. Так, для веб-сервера который отвечает за работу некоторого сайта это может быть команда curl которая проверяет переделённую страницу веб-сайта, это может быть оценка используемой памяти сервисом или загрузка процессора в течении некоторого времени.

Статус «здоровья» докер-контейнера до первой проверки принимает значение “starting”. После любой успешной проверки он становится “healthy”. Если тест «падает» несколько раз подряд в течении определенного интервала, то такой контейнер считается «плохим» (unhealthy). Статус докер-контейнера можно проверить командами “docker ps” и “docker container ls”.

Если тексту с картинками вы предпочитаете видео, то вот мой обзор healthcheck для docker container на YouTube.


Как включить health check для докер-контейнера

Health check для докер-контейнера может быть указан в нескольких местах

  1. В командах “docker run” и “docker container run”
  2. В файле Dockerfile
  3. В файле Docker compose
  4. В команде docker service create

Рассмотрим установку health check на примере Dockerfile. Для Dockerfile она имеет вот такой формат. Вот здесь можно посмотреть спецификацию команды helalthcheck для dockerfile 

            HEALTHCHECK [OPTIONS] CMD command
  • OPTIONS – параметры проверки «здоровья» докер-контейнера. Их можно не указывать, если вас устраивают дефолтные параметры.
  • command – непосредственно команда из оболочки (shell) которая проверяет состояние докер-контейнера.
Например, она может выглядеть так. 

        HEALTHCHECK --interval=30s --timeout=1s --retries=3 --start-period=10s CMD curl --fail http://localhost:80/ping.html || exit 1
  • interval – указывает как часто надо проверять состояние докер-контейнера. По умолчанию - 30 секунд
  • timeout – если выполнение команды занимает больше времени чем указано в этом параметра, то он считается не успешным. По умолчанию - 30 секунд.
  • retries  -  число не успешных проверок выполненных подряд, после чего докер-контейнер считается «плохим» (unhealthy). По умолчанию - 3  попытки.
  • start-period – время, которое дается контейнеру на первоначальную загрузку.. По умолчанию - 0 секунд

Пример. Простейщий dockerfile с healthcheck
FROM nginx
RUN echo "ping" >> /usr/share/nginx/html/ping.html
HEALTHCHECK --interval=30s --timeout=10s --retries=5 --start-period=10s \
 CMD curl --fail http://localhost:80/ping.html || exit 1

Собираем образ командой 
docker image build  -t testhl .

и запускаем докер-контейнер
docker run --rm -d -p 80:80 testhl


Страница ping.html статическая, генерируется при сборке докер-образа, так что health check исправно определяется как “healthy”.

Меняем health check чтобы он выдавал ошибку, пересобираем докер-образ и запускаем докер-контейнер заново.

FROM nginx
RUN echo "ping" >> /usr/share/nginx/html/ping.html
HEALTHCHECK --interval=30s --timeout=10s --retries=5 --start-period=10s \
    CMD curl --fail http://localhost:80/ping2.html || exit 1

 
Страницы ping2.html в моем веб-сайте нет, так что health check через некоторое время определяется как unhealthy.

Автоматический перезапуск «проблемного» докер-контейнера

От одного понимания, что контейнер «испортился» пользы не много. Гораздо удобнее, было бы если докер мог бы перезапустить «проблемный» контейнер. К сожалению, «из коробки» такое работает только в режиме Docker Swarm, когда вы управляете кластером из докер-контейнеров. Более подробно про Swarm можно почитать https://docs.docker.com/engine/swarm/key-concepts/ 

Чтобы добиться такого же и для одного докер-контейнера нужно сделать следующее. 
  1. Заменить exit 1 на kill 1 в инструкции HEALTHCHECK
  2. Запускать докер-контейнер с опцией –restart always

Пример
  1. Меняем Dockerfile следующим образом
FROM nginx
RUN echo "ping" >> /usr/share/nginx/html/ping.html
HEALTHCHECK --interval=30s --timeout=10s --retries=5 --start-period=10s \
    CMD curl --fail http://localhost:80/ping2.html || kill 1

    2. Собираем новый имидж
    3. Запускаем имидж вот такой командой.
        docker container run --restart always -d -p 80:80 testhl

Обратите внимание, мне пришлось убрать опцию “--rm” так как она конфликтует с “--restart”

Обратите внимание на значения в поле STATUS. Я его проверял в разные интервалы времени и видно, что контейнер некоторое время работал (статус был up 5  seconds, up 22 seconds) и затем был перезапущен (статус стал up 11 seconds).

воскресенье, 2 августа 2020 г.

Azure Static Web Apps - еще один способ бесплатного хостинга статического веб-сайта

В прошлой статье я рассказывал как можно использовать Azure Storage Account для хостинга статических веб-сайтов. А сейчас я хочу рассказать еще об одном сервисе Azure для подобных задач - Azure Static Web Apps.

На данный момент сервис находится в стадии Preview и его использование бесплатно. В рамках бесплатного использования Azure разрешает задеплоить до 10 сайтов, веб-приложений. Полагаю, что, когда сервис выйдет из preview эта квота такой и останется.

Кстати, если тексту с картинками вы предпочитаете видео, то вот мой обзор Azure Static Web Apps на YouTube

Azure Free Account

Как обычно, хочу напомнить, что если сейчас у вас нет, аккаунта на Azure, то можно создать бесплатный. Вот здесь, в лекции "Step-by-step: Create Azure account and access to free resources" я рассказываю и показываю как его создать за 5 минут.


Деплоймент веб-сайта

Как и в случае с Storage Account, сервис Static Web Apps — это serverless решение и обладает всеми его преимуществами но при имеет и несколько существенных отличий от деплоймента при помощи Storage Account. Вот, наиболее важные, на мой взгляд
Во-первых, Static Web Apps (по крайней мере, на данный момент) требует привязки к аккаунту на GitHub и работает напрямую репозиториями на GitHub. Т. е. в отличие от Azure Storage Account файлы с локального компьютера с ним не задеплоишь
Во-вторых, сервис Static Web Apps позволяет в рамках этого же приложения. иметь и серверный код на основе Azure Functions.
И в-третьих, в сервисе ест ь возможность хранить конфигурационные параметры для веб-приложения (разного рода connection strings, secrets и пр.).

Перейдем непосредственно к тому, как работать с этим сервисом

1. В Azure Portal найдите сервис Static Web Apps. Проще всего это сделать через панель поиска.



2. Далее нажимаем на синюю кнопку Create static web app.
3. В форме Create Static Web App (Preview) нужно указать следующие поля
  • Resource group. Можно выбрать любою или создать новую кликнув на ссылку "Create new". Я создал новую и назвал ее MyStaticWebAppRG.
  • Static Web App details  - Name. Можно указать все что вам нравится.
  • Static Web App details  - Region. Место на земном шаре, где бы вы хотели задеплоить ваше приложение. Сервис еще в стадии Preview и не все регионы доступны.
Bот как эта форма выглядит в моем случае

4. Далее надо нажать на кнопку Sign in with GitHub. Откроется форма логина на GitHub. После успешного логина на форме Create Static Web App (Preview) появятся дополнительные поля для выбора организации, репозитория и бранчи. 
На GitHub я создал репозиторий StaticWebapp и залил в него веб-сайт из прошлой статьи
Вот как эти поля выглядят в моем случае

5. На вкладке Build можно указать, где расположены файлы сайта и где код сервисов. У моего репозитория простая структура, нет сервисов на Azure Functions, а файлы веб-сайта расположены сразу в корне. И поэтому в моем случае эти поля пустые.

6. Следующий шаг – нажимаем кнопку Review + create. .Azure проверит параметры и если все ОК переведет вас на последнюю вкладку Review + create. Здесь в последний раз можно проверить параметры и нажимаем синюю кнопку Create. 
7. Создание Static Web App происходит довольно быстро. У меня заняло где-то 30 секунд. Далее нажимаем Go to recourse чтобы попасть на страницу веб-приложения в Azure 

7. На этом в общем-то и все, сайт задеплоен. По клику на Browse или линку в URL в отдельной вкладке браузера откроется index.html сайта.
Интересны изменения, которые произошли с GitHub репозиторием. Azure добавил в него GitHub Workflow файл. Теперь, с его помощью на любое изменение в master бранче моего репозитория сайт будет автоматически передеплоен.
Вторая интересная фишка, заключается в том, что на каждый Pull Request Azure Static Web App создаст отдельный деплоймент сайта, который можно найти на Serttings/Enviroments
Как только pull request будет смержен, Staging деплоймент так же удалится.

Как вы, может быть уже заметили, в интерфейсе Static Web Apps нет возможности указать стартовую страницу сайта (например, что-то отличное от дефолтного index.html) или страницу для обработки 404. Все это и многое другое можно сделать при помощи специального routes.json файла. Он должен быть расположен в коне веб-сайта. Более детально со спецификацией этого файла можно познакомиться в документации.


Что можно сделать еще

Сайту так же можно указать доменное имя в элементе Settings/Custom domains. 
Что интересно, в отличие от решения на Storage Account в Settings нет опции Azure CDN. Все потому, что Azure CDN автоматически используется для веб-приложений задеплоенных при помощи Azure Static Web Apps. И что особенно приятно, платить за нее не надо.

Итог

В этой статье мы познакомились со Azure Static Web Apps. Если сравнивать это решение с деплойментом статических веб-сайтов при помощи Azure Storage Account, то все упирается в наличие репозитория на GitHub. По крайней мере сейчас. Если ваш репозиторий на GitHub, то конечно, этот вариант «из коробки» более прост удобен для работы. В добавок он поддерживает  серверную функциональность на основе Azure Functinos.