🛠 Liveness и Readiness пробы: docker compose
👨🔬 Вступление: проблема
Предположим, что вам необходимо запустить два контейнера через docker compose. Но один из контейнеров требует доступ ко второму.
В моём случае есть два контейнера: keycloak и backend. backend при запуске обращается к keycloak. Но возникает следующая проблема: docker compose стартует два контейнера одновременно, но backend поднимается быстрее. Получаем ошибку:
🤔 depends_on: разве не решение?
Можно подумать, что следующий кусок YAML-а должен избавить нас от проблем:
❌ Нет. Дело в том, что по-умолчанию условием для depends_on указано "service_started". А запуск контейнера не означает, что сервис внутри этого самого контейнера запущен. Поэтому мы и получаем такую же ошибку.
🤒 healthcheck: выход!
Относительно недавно услышал про так называемые "пробы" в Kubernetes. Они позволяют отслеживать состояние запущенных в контейнере сервисов и в случае чего реагировать на их остановку. Про пробы в K8s поговорим позже. Сегодня заденем healthcheck в docker compose.
healthcheck в docker compose позволяет определить всё ли в порядке с нашим контейнером. Я уже добавил healthcheck для контейнера backend:
🤓 В healthcheck.test указывается команда, которая должна повторяться каждые healthcheck.interval секунд. Если команда выполняется успешно (code: 0), тогда контейнер переходит из статуса started в статус healthy. Если команда выполняется с ошибкой (code: >0) или время выполнения команды занимает более healthcheck.timout, то делается повторная попытка через healthcheck.interval секунд. Если проблемы повторяются таким образом healthcheck.retries раз, то контейнер переходит в статус unhealthy.
🤨 depends_on: он нам всё таки нужен
Как я писал выше, условием по-умолчанию для depends_on является статус "service_started" у контейнера. Мы должны его поменять на статус "service_healthy":
Попробуем запустить наши контейнеры и посмотреть что будет происходить:
1) запускаем docker-compose up, смотрим логи: запустился только keycloak, backend ждёт. "docker compose ps" сообщает о том, что keycloak находится в статусе "started":
2) Ждём 15 секунд, смотрим по логам запустился ли office-api. Пока нет, так как keycloak ещё не перешёл в статус healthy
3) Ждём еще 15 секунд, keycloak до сих пор не перешёл в нужный нам статус
4) На 39 секунде keycloak запустился. Но контейнер не перешёл в статус healthy. Ждём до 45 секунды (время итерации) и видим, что keycloak теперь healthy!
5) backend стартует, ждём, всё ок!
Вывод
Таким образом, при помощи healthcheck вы можете выстроить зависимости одних приложений от других. Это бывает необходимо, если, например, один сервис должен запуститься раньше, чем другой.
👨🔬 Вступление: проблема
Предположим, что вам необходимо запустить два контейнера через docker compose. Но один из контейнеров требует доступ ко второму.
В моём случае есть два контейнера: keycloak и backend. backend при запуске обращается к keycloak. Но возникает следующая проблема: docker compose стартует два контейнера одновременно, но backend поднимается быстрее. Получаем ошибку:
I/O error on GET request for "http://keycloak:8080/realms/master/.well-known/openid-configuration": Connection refused
🤔 depends_on: разве не решение?
Можно подумать, что следующий кусок YAML-а должен избавить нас от проблем:
backend:
<some_other_yaml_content>
depends_on:
- keycloak
❌ Нет. Дело в том, что по-умолчанию условием для depends_on указано "service_started". А запуск контейнера не означает, что сервис внутри этого самого контейнера запущен. Поэтому мы и получаем такую же ошибку.
🤒 healthcheck: выход!
Относительно недавно услышал про так называемые "пробы" в Kubernetes. Они позволяют отслеживать состояние запущенных в контейнере сервисов и в случае чего реагировать на их остановку. Про пробы в K8s поговорим позже. Сегодня заденем healthcheck в docker compose.
healthcheck в docker compose позволяет определить всё ли в порядке с нашим контейнером. Я уже добавил healthcheck для контейнера backend:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health/ready"]
interval: 15s
timeout: 3s
retries: 3
🤓 В healthcheck.test указывается команда, которая должна повторяться каждые healthcheck.interval секунд. Если команда выполняется успешно (code: 0), тогда контейнер переходит из статуса started в статус healthy. Если команда выполняется с ошибкой (code: >0) или время выполнения команды занимает более healthcheck.timout, то делается повторная попытка через healthcheck.interval секунд. Если проблемы повторяются таким образом healthcheck.retries раз, то контейнер переходит в статус unhealthy.
🤨 depends_on: он нам всё таки нужен
Как я писал выше, условием по-умолчанию для depends_on является статус "service_started" у контейнера. Мы должны его поменять на статус "service_healthy":
backend:
<some_other_yaml_content>
depends_on:
keycloak:
condition: service_healthy
Попробуем запустить наши контейнеры и посмотреть что будет происходить:
1) запускаем docker-compose up, смотрим логи: запустился только keycloak, backend ждёт. "docker compose ps" сообщает о том, что keycloak находится в статусе "started":
Up 22 seconds (health: starting)
2) Ждём 15 секунд, смотрим по логам запустился ли office-api. Пока нет, так как keycloak ещё не перешёл в статус healthy
3) Ждём еще 15 секунд, keycloak до сих пор не перешёл в нужный нам статус
4) На 39 секунде keycloak запустился. Но контейнер не перешёл в статус healthy. Ждём до 45 секунды (время итерации) и видим, что keycloak теперь healthy!
Up 46 seconds (healthy)
5) backend стартует, ждём, всё ок!
Вывод
Таким образом, при помощи healthcheck вы можете выстроить зависимости одних приложений от других. Это бывает необходимо, если, например, один сервис должен запуститься раньше, чем другой.
🛠 Liveness и Readiness пробы: Kubernetes
🤡 Шо, опять? Нит. Теперь поговорим про пробы в Kubernetes. Проблема в K8s отличается от проблемы с docker compose (в прошлом посту)
👨🔬 Проблема
После того, как разработчики заливают код в GitLab, собирается образ, а затем в Kubernetes запускается новый контейнер. Дело в том, что новый контейнер сразу же заменяет старый, при том, что сам сервис ещё находится в стадий запуска. В этот момент приложение по сути становится недоступным, что влечёт за собой ошибки других сервисов, пинающих этот самый запускаемый контейнер, а также негодование фронтендеров , тестировщиков и в будущем клиентов....
🙉 Решение: Readiness Probes
Про то, как работают пробы я уже рассказывал в прошлом посту. Принцип их работы такой же, как в Kubernetes. Но тут есть отличие: нет healthcheck, а есть возможность настроить readinessProbe и/или livenessProbe. Разница в том, что readinessProbe проверяет, что контейнер готов принимать трафик (если нет, то ждать пока проба выполнится), тогда как livenessProbe, что сервис запущен (если нет, то рестартануть контейнер). В моём случае, нужна проба readiness.
🌿 Открываем эндпоинт /health для Spring Boot
Для начала нужно определить какой какой эндпоинт "дёргать". Изучив документацию спринга, без проблем можно найти ответ. Нужно всего-лишь установить зависимость:
После запуска приложения, конечная точка автоматически станет доступна:
🧑🏻💻 Настраиваем пробу
Сразу приступим к коду:
🤓
🤩 Смотрим это работает на практике
На данный момент у нас запущен контейнер. Сделаем git push, подождём завершения пайплайна и посмотрим что будет дальше.
Пайп завершился. Смотрим на список подов:
Как видим, старый под все ещё запущен и ожидает, пока новый контейнер не встанет. Выполним describe:
Как видим, за 81 секунду проба прошла неудачно 3 раза (на 60, 70 и 80 секундах). Поэтому ждём пока бэк внутри контейнера стартанет. А пока можем убедиться, что приложение в рабочем состоянии:
Подождём немного и снова получим список всех подов:
Как мы видим, теперь у нас один под! А старого просто убили... Press F 🥺
🔥 Итоги
Некоторые контейнеры старуют очень долго, поэтому потребность в readinessProbe будет всегда. Важно сделать так, чтобы замену нового контейнера на старый никто не заметил, поэтому не откладывайте внедрение проб в ваши деплойменты, сделайте жизнь окружающих легче! 🤝
🤡 Шо, опять? Нит. Теперь поговорим про пробы в Kubernetes. Проблема в K8s отличается от проблемы с docker compose (в прошлом посту)
👨🔬 Проблема
После того, как разработчики заливают код в GitLab, собирается образ, а затем в Kubernetes запускается новый контейнер. Дело в том, что новый контейнер сразу же заменяет старый, при том, что сам сервис ещё находится в стадий запуска. В этот момент приложение по сути становится недоступным, что влечёт за собой ошибки других сервисов, пинающих этот самый запускаемый контейнер, а также негодование фронтендеров , тестировщиков и в будущем клиентов....
🙉 Решение: Readiness Probes
Про то, как работают пробы я уже рассказывал в прошлом посту. Принцип их работы такой же, как в Kubernetes. Но тут есть отличие: нет healthcheck, а есть возможность настроить readinessProbe и/или livenessProbe. Разница в том, что readinessProbe проверяет, что контейнер готов принимать трафик (если нет, то ждать пока проба выполнится), тогда как livenessProbe, что сервис запущен (если нет, то рестартануть контейнер). В моём случае, нужна проба readiness.
🌿 Открываем эндпоинт /health для Spring Boot
Для начала нужно определить какой какой эндпоинт "дёргать". Изучив документацию спринга, без проблем можно найти ответ. Нужно всего-лишь установить зависимость:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
}
После запуска приложения, конечная точка автоматически станет доступна:
$ curl http://localhost:8000/actuator/health
{"status":"UP","groups":["liveness","readiness"]}
🧑🏻💻 Настраиваем пробу
Сразу приступим к коду:
spec:
containers:
- name: my_app
<some_other_yaml_content>
ports:
- name: http
containerPort: 8080
readinessProbe:
httpGet:
path: /actuator/health
port: http
initialDelaySeconds: 50
periodSeconds: 10
🤓
httpGet.path
указывает путь для отправки запроса, httpGet.port
- название порта или число. initialDelaySeconds
отвечает за количество секунд, после которых нужно осуществить первую пробу. periodSeconds
отвечает за то, как часто осуществлять пробу. 🤩 Смотрим это работает на практике
На данный момент у нас запущен контейнер. Сделаем git push, подождём завершения пайплайна и посмотрим что будет дальше.
Пайп завершился. Смотрим на список подов:
$ kubectl get pods
my_app-5765888b6f-w7t6f 0/1 Running 0 66s
my_app-6f578d599d-22vsk 1/1 Running 0 4d22h
Как видим, старый под все ещё запущен и ожидает, пока новый контейнер не встанет. Выполним describe:
$ kubectl describe pods/my_app-5765888b6f-w7t6f
Normal Created 81s kubelet Created container my_app-app
Normal Started 81s kubelet Started container my_app-app
Warning Unhealthy 6s (x3 over 26s) kubelet Readiness probe failed: Get "http://10.112.129.116:8080/actuator/health": dial tcp 10.112.129.116:8080: connect: connection refused
Как видим, за 81 секунду проба прошла неудачно 3 раза (на 60, 70 и 80 секундах). Поэтому ждём пока бэк внутри контейнера стартанет. А пока можем убедиться, что приложение в рабочем состоянии:
$ curl https://my_app.ru/actuator/health
{"status":"UP","groups":["liveness","readiness"]}
Подождём немного и снова получим список всех подов:
$ kubectl get pods
my_app-5765888b6f-w7t6f 1/1 Running 0 13m
Как мы видим, теперь у нас один под! А старого просто убили... Press F 🥺
🔥 Итоги
Некоторые контейнеры старуют очень долго, поэтому потребность в readinessProbe будет всегда. Важно сделать так, чтобы замену нового контейнера на старый никто не заметил, поэтому не откладывайте внедрение проб в ваши деплойменты, сделайте жизнь окружающих легче! 🤝
👍4
DevOps-им по-взрослому
Photo
В начале года люди обычно подводят итоги уходящего года, а также строят цели на следующий...
Ну что ж, я решил поделиться откровением... В этом году я вёл себя плохо: ронял сервера, забивал на сертификаты, с самого начала использовал неправильные решения. Поэтому подарок от Деда Мороза не получил :(
Зато получил опыт! Как бы это банально не звучало, совершать ошибки нормально! Ненормально их скрывать или не признавать. Поэтому я и решил вскрыть чёрный ящик....
1) Не лезь, иначе убьёт: DNS-записи, почта и Ru-Center
Я впервые столкнулся с Ru-Center и первое (и последнее тоже) впечатление было ужасным. В отличие от reg.ru, с которым я работал ранее, тут было недостаточно купить домен, чтобы просто добавить DNS-запись для поддомена. Во-первых, вам нужно приобрести отдельную услугу "DNS-хостинг". Во-вторых, вам нужно выбрать правильные DNS-зоны, которые, к тому же, для нашего домена были настроены неверно. На это всё суммарно была затрачена неделя!
Случилось страшное....Я уронил почту на домене! 😱 Как это случилось?
Я достаточно долго боролся с тем, что не мог выпустить TLS-сертификат для поддомена (как оказалось, дело было в DNS-зонах). Я перепробовал почти все способы, поэтому подумал в сторону DNS-записей.... И просто удалил MX и CNAME записи, необходимых для работы почты....
Моя реакция была мгновенной: почта упала сразу же, а я стал в панике искать как вернуть те самые записи. 🤕 Почти час прошуршав весь интернет (по nic.ru достаточно мало источников), я всё же обнаружил в настройках DNS-записей вкладку "Шаблоны", где и смог найти заветную кнопку "Записи для почты".
Но она заработала не сразу.... Дело в том, что обновление записей может занять от 10 минут до 24 часов! Таким образом, почта встала только спустя 4 часа.
Что можно из этого вынести? Как и из всех косяков, всегда думать про последствия. А также не забывать про бекапы, (можно импортировать DNS-записи в текстовом формате) которые я забыл сделать(
2) Используйте terraform с умом и внимательностью...
Я много писал про Terraform. Это очень полезная штука, позволяющая управлять инфраструктурой-как-код. Важно понимать, что Terraform также является весьма опасным инструментом в руках неопытного девопса. Про какого девопса идёт речь вы уже поняли) 😅
Когда я только перевёл всю существующую инфраструктуру в код, я занялся некоторым редактированием конфигов. Я понимал опасность команды
В один прекрасный летний день я выполнил
Последствия были не такими серьезными, но всё же были. Один разработчик обратился ко мне с тем, что отвалился пайплайн. Я быстро ему объяснил ситуацию и он с пониманием набрался терпением, чтобы я всё поднял. (респект коллеге 🤝)
Как оказалось, поднять ВМ и поставить туда gitlab-runner оказалось недостаточным, потому что гитлаб не мог его увидеть. Дошло до того, что пришлось пересоздавать ВМ. Таким образом, на все манипуляции было затрачено ~полтора часа. 🙁 Эти полтора часа никто не мог залить свой код на дев окружение!
Что из этого следует? А то, что нужно внимательно следить за каждым своим действием, особенно если есть риск затронуть что-нибудь важное. С тех пор, я дважды пересматриваю вывод
Ну что ж, я решил поделиться откровением... В этом году я вёл себя плохо: ронял сервера, забивал на сертификаты, с самого начала использовал неправильные решения. Поэтому подарок от Деда Мороза не получил :(
Зато получил опыт! Как бы это банально не звучало, совершать ошибки нормально! Ненормально их скрывать или не признавать. Поэтому я и решил вскрыть чёрный ящик....
1) Не лезь, иначе убьёт: DNS-записи, почта и Ru-Center
Я впервые столкнулся с Ru-Center и первое (и последнее тоже) впечатление было ужасным. В отличие от reg.ru, с которым я работал ранее, тут было недостаточно купить домен, чтобы просто добавить DNS-запись для поддомена. Во-первых, вам нужно приобрести отдельную услугу "DNS-хостинг". Во-вторых, вам нужно выбрать правильные DNS-зоны, которые, к тому же, для нашего домена были настроены неверно. На это всё суммарно была затрачена неделя!
Случилось страшное....Я уронил почту на домене! 😱 Как это случилось?
Я достаточно долго боролся с тем, что не мог выпустить TLS-сертификат для поддомена (как оказалось, дело было в DNS-зонах). Я перепробовал почти все способы, поэтому подумал в сторону DNS-записей.... И просто удалил MX и CNAME записи, необходимых для работы почты....
Моя реакция была мгновенной: почта упала сразу же, а я стал в панике искать как вернуть те самые записи. 🤕 Почти час прошуршав весь интернет (по nic.ru достаточно мало источников), я всё же обнаружил в настройках DNS-записей вкладку "Шаблоны", где и смог найти заветную кнопку "Записи для почты".
Но она заработала не сразу.... Дело в том, что обновление записей может занять от 10 минут до 24 часов! Таким образом, почта встала только спустя 4 часа.
Что можно из этого вынести? Как и из всех косяков, всегда думать про последствия. А также не забывать про бекапы, (можно импортировать DNS-записи в текстовом формате) которые я забыл сделать(
2) Используйте terraform с умом и внимательностью...
Я много писал про Terraform. Это очень полезная штука, позволяющая управлять инфраструктурой-как-код. Важно понимать, что Terraform также является весьма опасным инструментом в руках неопытного девопса. Про какого девопса идёт речь вы уже поняли) 😅
Когда я только перевёл всю существующую инфраструктуру в код, я занялся некоторым редактированием конфигов. Я понимал опасность команды
terraform apply
, что нужно прежде выполнять terraform plan
и внимательно читать вывод команд утилиты. Но скорее всего понимал не до конца....В один прекрасный летний день я выполнил
terraform apply
, при этом лишь частично взглянув на изменения. Как оказалось, я удалил совсем не то, что нужно, а именно ВМ с работающим gitlab-runner в разгар рабочего дня... 🥴Последствия были не такими серьезными, но всё же были. Один разработчик обратился ко мне с тем, что отвалился пайплайн. Я быстро ему объяснил ситуацию и он с пониманием набрался терпением, чтобы я всё поднял. (респект коллеге 🤝)
Как оказалось, поднять ВМ и поставить туда gitlab-runner оказалось недостаточным, потому что гитлаб не мог его увидеть. Дошло до того, что пришлось пересоздавать ВМ. Таким образом, на все манипуляции было затрачено ~полтора часа. 🙁 Эти полтора часа никто не мог залить свой код на дев окружение!
Что из этого следует? А то, что нужно внимательно следить за каждым своим действием, особенно если есть риск затронуть что-нибудь важное. С тех пор, я дважды пересматриваю вывод
terraform plan
, а затем ещё трижды от terraform apply
прежде чем ввести yes. Потому что на месте этой ВМ могла оказаться вся инфраструктура!❤🔥1👎1
DevOps-им по-взрослому
В начале года люди обычно подводят итоги уходящего года, а также строят цели на следующий... Ну что ж, я решил поделиться откровением... В этом году я вёл себя плохо: ронял сервера, забивал на сертификаты, с самого начала использовал неправильные решения.…
...
3) Эта штука точно не нужна! Так стоп... Кластер Kubernetes перестал работать 😓
Эта штука называется Yandex Key Management Service (KMS). Наверное это единственный сервис, который я использую, при этом не понимая как он работает или работает вообще. 🤡
Последний фактор сыграл со мной злую шутку... Так как я хотел сделать всё "по бэст практисам" и "секьюрно", то перед созданием кластера Kubernetes я сначала создал ключ KMS, а затем указал его при создании кластера кубера. 🙂
Спустя некоторое время, проводя "инвентаризацию" инфраструктуры и наткнувшись на этот ключ, решил, что он только глаза мозолит и решил данную проблему удалением. 😶🌫️
Что же случилось? Кластер Kubernetes не мог продолжать работу, так как ключ был утерян, а восстановить его было невозможным. Пришлось сносить... 👷
А удаление Kubernetes означает, что все сервисы сразу станут недоступны, данные будут утеряны и придется настраивать всё с нуля. К счастью, никаких важных данных утеряно не было, а поднять все поды оказалось весьма простой задачей. Дополнительным фактором, который немного успокоил меня, было то, что это происходило вечером, поэтому за ночь смог развернуть кластер с нуля. Надеюсь, что никто не был блокнут и пострадал только мой режим сна. 🥹
Урок из этого был вынесен: во-первых, прежде чем что-то удалять, убедитесь, что это никак не затронет работу других сервисов. Во-вторых, читайте документацию! 📃
——
Это был список самых-самых ошибок в прошлом году. Конечно, это не весь список, были и остальные, но их последствия были не такими, как в вышеописанных "косяках".
3) Эта штука точно не нужна! Так стоп... Кластер Kubernetes перестал работать 😓
Эта штука называется Yandex Key Management Service (KMS). Наверное это единственный сервис, который я использую, при этом не понимая как он работает или работает вообще. 🤡
Последний фактор сыграл со мной злую шутку... Так как я хотел сделать всё "по бэст практисам" и "секьюрно", то перед созданием кластера Kubernetes я сначала создал ключ KMS, а затем указал его при создании кластера кубера. 🙂
Спустя некоторое время, проводя "инвентаризацию" инфраструктуры и наткнувшись на этот ключ, решил, что он только глаза мозолит и решил данную проблему удалением. 😶🌫️
Что же случилось? Кластер Kubernetes не мог продолжать работу, так как ключ был утерян, а восстановить его было невозможным. Пришлось сносить... 👷
А удаление Kubernetes означает, что все сервисы сразу станут недоступны, данные будут утеряны и придется настраивать всё с нуля. К счастью, никаких важных данных утеряно не было, а поднять все поды оказалось весьма простой задачей. Дополнительным фактором, который немного успокоил меня, было то, что это происходило вечером, поэтому за ночь смог развернуть кластер с нуля. Надеюсь, что никто не был блокнут и пострадал только мой режим сна. 🥹
Урок из этого был вынесен: во-первых, прежде чем что-то удалять, убедитесь, что это никак не затронет работу других сервисов. Во-вторых, читайте документацию! 📃
——
Это был список самых-самых ошибок в прошлом году. Конечно, это не весь список, были и остальные, но их последствия были не такими, как в вышеописанных "косяках".
❤🔥1👎1
Telegraph
Выбросьте принты, используйте Debugger!
Вы решаете сложную задачу на алгоритмы, пишите аналог VK, сидите на олимпиаде и ничего не понимаете (жиза) - в любом случае вам, скорее всего, нужен Debugger. Зачем? Стоит смириться с тем, что баги в коде будут возникать всегда. При этом важно их быстро и…
До сих пор используете кипячение принты? Начните использовать тайд дебаггер и ваша жизнь станет намного легче!
Читать: тык
Читать: тык
❤3👎1🔥1
Расчехляем DevOps-инный софт тут: тык
Habr
Ansible + Grafana Loki: Настраиваем отправку уведомлений в чат после логина на сервер по SSH
Вступление Не задумывались ли вы когда-нибудь над тем, чтобы знать о каждом входе на ваши сервера? Меня охватила такая же паранойя: а вдруг, когда я сплю, на мой сервер заходит домовой и творит там...
🤣4🥴1
Продолжаем негласную рубрику "О затраченных ресурсах".
Первая часть: тык
Terraform мастхев! На этот раз я брал несколько серверов. В отличие от первой статьи, мне не нужен был один мощный инстанс. Но нужно было несколько.
Хватило самых слабых инстансов, настройка "Прерываемая" также позволила снизить стоимость почти в два раза. Единственное на что наткнулся - размер SSD, пришлось апать с 5Гб до 10Гб.
Итог цены за один сервер на втором фото. Их четыре, поэтому умножаем на 4. Суммарная затрата получилась меньше, чем в прошлый раз.
Первая часть: тык
Terraform мастхев! На этот раз я брал несколько серверов. В отличие от первой статьи, мне не нужен был один мощный инстанс. Но нужно было несколько.
Хватило самых слабых инстансов, настройка "Прерываемая" также позволила снизить стоимость почти в два раза. Единственное на что наткнулся - размер SSD, пришлось апать с 5Гб до 10Гб.
Итог цены за один сервер на втором фото. Их четыре, поэтому умножаем на 4. Суммарная затрата получилась меньше, чем в прошлый раз.
🍌3🥴1🤣1
#devops, #gitlab, #cicd
🦊 GitLab CI/CD: облегчаем работу с кодом для пайплайнов
☝️ GitLab это отличное решение при выборе системы управления репозиториями. Кроме этого, GitLab также позиционирует себя, как инструмент DevOps, имеющий в своём арсенале CI/CD, Container Registry и много других полезных инструментов. Остановимся на GitLab CI/CD. А именно на полезных штуках, которые могут облегчить вашу жизнь.
🏕 1) Окружения (environments)
Часто случается так, что у вас может быть несколько окружении. Для каждого, соответственно, используется своя ветка (develop, stage, main, etc).
🤓 С помощью GitLab окружении можно указать переменные с одинаковыми ключами, но при этом с разными значениями. Окружение для переменной назначается при её созданий, затем в Job-е необходимо указать, какое окружение вы будете использовать:
🙋♂️ Для Build Develop используется KUBE_TOKEN для подключения к девовскому кластеру, для Build Prod - продовскому. Но не всё так идеально...
👥 2) Переменные для группы (Group Variables)
Одна и та же переменная нужна для нескольких репозиториев. Что делать? Определить переменную на уровне группы!
Тут также есть окружения, но если у вас Free версия GitLab, то доступа к ним на уровне групп у вас не будет 🙁.
🤠 Но никто не мешает вам использовать префиксы! PROD_, STAGE_, DEVELOP_. При этом вы можете совмещать переменные на уровне репозиториев с переменными на уровне групп!
3) include и скрытые джобы
💭 Вы любитель разносить повторяющийся код по классам и обожаете DRY, но при этом вам приходится регулярно смотреть на ужасы, которые творятся в
😵💫 Всё замечательно, пока у вас два-три репозитория. Но когда у вас их больше, при этом содержимое
🔨 Он позволяет импортировать джобы для CI/CD в ваш текущий файл. Таким образом, вы можете переиспользовать одни и те же куски кода!
Сразу к примеру! В репозиторий 'my-templates' есть файл
💡 Обратите внимание на точку перед названием джобы: это означает, что джоба является скрытой и служит шаблоном, поэтому запускаться не будет.
Теперь мы можем использовать эту скрытую джобу в других файлах или даже репозиториях!
🧑🏻💻 К примеру, есть репозиторий
🙋 Теперь создадим таски для текущего проекта. Переопределим переменные и при помощи extends укажем в качестве шаблона .build джобу:
Обратите внимание на переменные: мы можем их переопределять. Похоже на аргументы функций, не так ли?)
📌 Вы можете переопределить любое поле. Если вам нужно добавить какой-то дополнительный скрипт, то вы можете воспользоваться полями before_script и after_script, что также очень удобно!
🦊 GitLab CI/CD: облегчаем работу с кодом для пайплайнов
☝️ GitLab это отличное решение при выборе системы управления репозиториями. Кроме этого, GitLab также позиционирует себя, как инструмент DevOps, имеющий в своём арсенале CI/CD, Container Registry и много других полезных инструментов. Остановимся на GitLab CI/CD. А именно на полезных штуках, которые могут облегчить вашу жизнь.
🏕 1) Окружения (environments)
Часто случается так, что у вас может быть несколько окружении. Для каждого, соответственно, используется своя ветка (develop, stage, main, etc).
🤓 С помощью GitLab окружении можно указать переменные с одинаковыми ключами, но при этом с разными значениями. Окружение для переменной назначается при её созданий, затем в Job-е необходимо указать, какое окружение вы будете использовать:
stages:
- build
Build For Development:
stage: setup
environment: development # !
image: ubuntu:22.04
only:
- develop
script:
- echo "Building project for development...."
- echo $KUBE_TOKEN # !
Build For Production:
stage: setup
environment: production # !
image: ubuntu:22.04
only:
- main
script:
- echo "Building project for production...."
- echo $KUBE_TOKEN # !
🙋♂️ Для Build Develop используется KUBE_TOKEN для подключения к девовскому кластеру, для Build Prod - продовскому. Но не всё так идеально...
👥 2) Переменные для группы (Group Variables)
Одна и та же переменная нужна для нескольких репозиториев. Что делать? Определить переменную на уровне группы!
Тут также есть окружения, но если у вас Free версия GitLab, то доступа к ним на уровне групп у вас не будет 🙁.
🤠 Но никто не мешает вам использовать префиксы! PROD_, STAGE_, DEVELOP_. При этом вы можете совмещать переменные на уровне репозиториев с переменными на уровне групп!
3) include и скрытые джобы
💭 Вы любитель разносить повторяющийся код по классам и обожаете DRY, но при этом вам приходится регулярно смотреть на ужасы, которые творятся в
.gitlab-ci.yml
файлах?😵💫 Всё замечательно, пока у вас два-три репозитория. Но когда у вас их больше, при этом содержимое
.gitlab-ci.yml
повторяется, то приходят проблемы: в случае необходимости, нужно редактировать все файлы, чтение таких ямлов становится невыносимой задачей, код растягивается на тысячи строк. И тут мы можем воспользоваться include!🔨 Он позволяет импортировать джобы для CI/CD в ваш текущий файл. Таким образом, вы можете переиспользовать одни и те же куски кода!
Сразу к примеру! В репозиторий 'my-templates' есть файл
base-build.yml
со следующим содержимым:.build:
image: ubuntu:22.04
variables:
KUBE_URL: ""
KUBE_TOKEN: ""
script:
- echo "Set up connection to cluster $KUBE_URL with token $KUBE_TOKEN"
💡 Обратите внимание на точку перед названием джобы: это означает, что джоба является скрытой и служит шаблоном, поэтому запускаться не будет.
Теперь мы можем использовать эту скрытую джобу в других файлах или даже репозиториях!
🧑🏻💻 К примеру, есть репозиторий
my-app-repo-1
. "Заинклюдим" джобы из ранее созданного файла, при этом укажем путь до репозитория (группу/репо):include:
- project: '<group_name>/my-templates'
ref: main
file: '/base-build.yml'
🙋 Теперь создадим таски для текущего проекта. Переопределим переменные и при помощи extends укажем в качестве шаблона .build джобу:
Build For Development:
extends: .build
stage: build
only:
- develop
variables:
KUBE_URL: DEVELOP_KUBE_URL
KUBE_TOKEN: DEVELOP_KUBE_TOKEN
Build For Production:
extends: .build
stage: build
only:
- main
variables:
KUBE_URL: PROD_KUBE_URL
KUBE_TOKEN: PROD_KUBE_TOKEN
Обратите внимание на переменные: мы можем их переопределять. Похоже на аргументы функций, не так ли?)
📌 Вы можете переопределить любое поле. Если вам нужно добавить какой-то дополнительный скрипт, то вы можете воспользоваться полями before_script и after_script, что также очень удобно!
❤4👎2🍌1🤓1
#yandexcloud
⛅️ Вот бы был ЕГЭ по облачным технологиям...
🥷🏼 Так, подождите... Yandex.Cloud завёз программу сертификации (пока в бета) для специалистов, работающих с сервисами их облака.
💪🏻 Ранее у меня уже возникал интерес к подобным сертификациям, а именно к Certified Kubernetes Administrator (CKA). Но ценник там в разы выше, а возможность оплаты из России может быть весомой проблемой на пути становления гигачадом K8s. ❌
📝 В онлайн-тестировании от Яндекс Облака 65 заданий по 6 разделам в виде экзамена и выдача сертификата в случае более 70% правильных ответов. Привлекает не столько возможность получениябумажки электронки PDF файла, сколько возможность проверить свои знания о сервисах, с которыми ты работаешь довольно продолжительное время. Первое тестирование состоится 11 апреля, я же выбрал дату сдачи 18 апреля.
Участвуем? Участвуем! 😎
⛅️ Вот бы был ЕГЭ по облачным технологиям...
🥷🏼 Так, подождите... Yandex.Cloud завёз программу сертификации (пока в бета) для специалистов, работающих с сервисами их облака.
💪🏻 Ранее у меня уже возникал интерес к подобным сертификациям, а именно к Certified Kubernetes Administrator (CKA). Но ценник там в разы выше, а возможность оплаты из России может быть весомой проблемой на пути становления гигачадом K8s. ❌
📝 В онлайн-тестировании от Яндекс Облака 65 заданий по 6 разделам в виде экзамена и выдача сертификата в случае более 70% правильных ответов. Привлекает не столько возможность получения
Участвуем? Участвуем! 😎
❤7⚡1🔥1🍌1
Хотели обновить версию своего кластера Kubernetes, но никак не доходили до этого руки?
"Самый милый релиз" UwUBernetes позволит вам сделать ваш кластер "симпатичнее"!
"Самый милый релиз" UwUBernetes позволит вам сделать ваш кластер "симпатичнее"!
👍4🍌2❤1
DevOps-им по-взрослому
2024-04-20_23-06.png
#devops, #monitoring, #k8s
🕵️♂️ Не отслеживаете метрики Kubernetes? Фатальная ошибка!
💡В одной из своих статей я писал о том, что мониторинг и логирование запущенных сервисов является одной из задачей в сфере DevOps. Я лишь частично прошёлся по самим метрикам, экспортировав готовый дашборд и уделив большее внимание установке нужных компонентов. Ну что же, на этот раз я решил больше углубиться в создание дашборда с нужными мне метриками. Начнём с полезных фишек и плавно перейдем к самому содержимому дашборда.
1) Используйте переменные.
И это касается не только программирования или GitLab CI. В Grafana для дашборда есть возможность создавать переменные, которые затем могут использоваться в запросах панелей. Зачем это нужно?
☝️ Для гибкости! Самый простой пример: переменные $prom_datasource и $namespace. С помощью первого можно задать источник данных, это полезно, если у вас их несколько (допустим, Prometheus в разных кластерах). $namespace поможет произвести фильтр по пространству имён. В моём дашборде есть и другие переменные, прошу к знакомству! Их практическое применение далее...
2) Используйте Rows.
Row это отдельная сущность дашборда, позволяющая группировать панели. Помимо этого, она позволит сделать ваш дашборд оптимизированным и быстрым!
🏃♂️ Если вы когда нибудь пробовали посмотреть кучу панелей одновременно, ваш браузер с большей вероятностью испытывал огромный стресс. Панели, принадлежащие "строкам", будут загружаться только после их раскрытия.
3) Настраивайте алерты
Я собрал именно те метрики, для которых собираюсь настраивать алертинг. Как показала "практика", всегда удобнее создавать алерт на базе панели. Плюсом вы получите сердечко в правом верхнем углу, показывающее статус алерта. ❤️🩹
Список Rows
Распределить панели я решил по следующим строкам:
- Logging
- Cluster (Nodes)
- Storage (Volumes)
- Replicas
- Requests/Limits
- Resource Real Usage (RAM/CPU/Network)
Расскажу о каждой по отдельности.
Row I: Logging
Одна панель с источником данных Loki:
Ранее для логов я использовал отдельный дашборд с кучей панелей, где на каждой панели отображались логи для одного конкретного сервиса. Это было крайне неудобно, особенно для разработчиков, которым нужен регулярный доступ к логам. Колхоз! Гораздо удобнее делать это через переменные, как указано в запросе выше и с помощью одной панели.
Row II: Cluster
"Сырая" строка, содержащая совсем небольшую информацию о рабочих узлах, а именно количество узлов и использование CPU/RAM с возможностью фильтра по $namespace.
Row III: Storage
Просто список PVC. В своей работе я их не использую, но есть несколько томов для Loki и Prometheus.
Row IV: Replicas
Строка, содержащая панели, связанные с репликами и контейнерами. Тут целых пять панелей, которые позволят полностью отследить падение сервиса и его причину. Самый простой способ - повесить алерт на Container Restarts Total, тем самым отслеживая количество рестартов, а затем уже просматривать остальные панели. Но можно сделать алерт по Container Phase, чтобы отслеживать контейнеры со статусом "Failed" или "Pending" (об этом чуть дальше). Container Last Terminated Reason помимо проблемного контейнера отобразит метрику reason (например OOMKilled), где будет указана причина падения. Свободный простор для алертов!
P.S. NoData - нормальное состояние для панелей из этой строки. Это показывает, что всё ок
Row V: Requests/Limits
Очень важно отслеживать доступные для запросов и лимитов ресурсы, чтобы избежать неприятностей с запуском и работоспособностью подов! В строке Replicas есть панель, позволяющая отслеживать поды в статусе Pending, но лучше держать отметку свободного Memory на безопасной отметке. (на личном опыте).
Row VI: Resource Real Usage
Отслеживание потребления CPU/Memory подами и пропускной способность сети. Можно оформить в виде таблицы, что я сначала и сделал. Результат убил в прямом смысле слова, но не меня, а графану (до 10 раз возросло потребление RAM, OOMKilled из-за больших нагрузок 😁). Советую оставить в виде Time Series.
Ссылка на Dashboard: тык
🕵️♂️ Не отслеживаете метрики Kubernetes? Фатальная ошибка!
💡В одной из своих статей я писал о том, что мониторинг и логирование запущенных сервисов является одной из задачей в сфере DevOps. Я лишь частично прошёлся по самим метрикам, экспортировав готовый дашборд и уделив большее внимание установке нужных компонентов. Ну что же, на этот раз я решил больше углубиться в создание дашборда с нужными мне метриками. Начнём с полезных фишек и плавно перейдем к самому содержимому дашборда.
1) Используйте переменные.
И это касается не только программирования или GitLab CI. В Grafana для дашборда есть возможность создавать переменные, которые затем могут использоваться в запросах панелей. Зачем это нужно?
☝️ Для гибкости! Самый простой пример: переменные $prom_datasource и $namespace. С помощью первого можно задать источник данных, это полезно, если у вас их несколько (допустим, Prometheus в разных кластерах). $namespace поможет произвести фильтр по пространству имён. В моём дашборде есть и другие переменные, прошу к знакомству! Их практическое применение далее...
2) Используйте Rows.
Row это отдельная сущность дашборда, позволяющая группировать панели. Помимо этого, она позволит сделать ваш дашборд оптимизированным и быстрым!
🏃♂️ Если вы когда нибудь пробовали посмотреть кучу панелей одновременно, ваш браузер с большей вероятностью испытывал огромный стресс. Панели, принадлежащие "строкам", будут загружаться только после их раскрытия.
3) Настраивайте алерты
Я собрал именно те метрики, для которых собираюсь настраивать алертинг. Как показала "практика", всегда удобнее создавать алерт на базе панели. Плюсом вы получите сердечко в правом верхнем углу, показывающее статус алерта. ❤️🩹
Список Rows
Распределить панели я решил по следующим строкам:
- Logging
- Cluster (Nodes)
- Storage (Volumes)
- Replicas
- Requests/Limits
- Resource Real Usage (RAM/CPU/Network)
Расскажу о каждой по отдельности.
Row I: Logging
Одна панель с источником данных Loki:
{namespace=~"$namespace", container=~"$container"}
Ранее для логов я использовал отдельный дашборд с кучей панелей, где на каждой панели отображались логи для одного конкретного сервиса. Это было крайне неудобно, особенно для разработчиков, которым нужен регулярный доступ к логам. Колхоз! Гораздо удобнее делать это через переменные, как указано в запросе выше и с помощью одной панели.
Row II: Cluster
"Сырая" строка, содержащая совсем небольшую информацию о рабочих узлах, а именно количество узлов и использование CPU/RAM с возможностью фильтра по $namespace.
Row III: Storage
Просто список PVC. В своей работе я их не использую, но есть несколько томов для Loki и Prometheus.
Row IV: Replicas
Строка, содержащая панели, связанные с репликами и контейнерами. Тут целых пять панелей, которые позволят полностью отследить падение сервиса и его причину. Самый простой способ - повесить алерт на Container Restarts Total, тем самым отслеживая количество рестартов, а затем уже просматривать остальные панели. Но можно сделать алерт по Container Phase, чтобы отслеживать контейнеры со статусом "Failed" или "Pending" (об этом чуть дальше). Container Last Terminated Reason помимо проблемного контейнера отобразит метрику reason (например OOMKilled), где будет указана причина падения. Свободный простор для алертов!
P.S. NoData - нормальное состояние для панелей из этой строки. Это показывает, что всё ок
Row V: Requests/Limits
Очень важно отслеживать доступные для запросов и лимитов ресурсы, чтобы избежать неприятностей с запуском и работоспособностью подов! В строке Replicas есть панель, позволяющая отслеживать поды в статусе Pending, но лучше держать отметку свободного Memory на безопасной отметке. (на личном опыте).
Row VI: Resource Real Usage
Отслеживание потребления CPU/Memory подами и пропускной способность сети. Можно оформить в виде таблицы, что я сначала и сделал. Результат убил в прямом смысле слова, но не меня, а графану (до 10 раз возросло потребление RAM, OOMKilled из-за больших нагрузок 😁). Советую оставить в виде Time Series.
Ссылка на Dashboard: тык
👍1