ServerAdmin.ru
26.5K subscribers
184 photos
24 videos
7 files
2.46K links
Авторская информация о системном администрировании.

Информация о рекламе: @srv_admin_reklama_bot
Автор: @zeroxzed

Второй канал: @srv_admin_live
Сайт: serveradmin.ru
Download Telegram
Недавно рассказывал про open source систему контроля доступа к сервисам и системам Teleport. На днях как по заказу вышел подробный ролик с описанием его установки за проксируемым сервером Traefik. Это, кстати, фича последних версий. Раньше Teleport не удавалось разместить за прокси.

Installing Teleport + Traefik (Letsencrypt TLS certs)

Видео наглядное и подробное. Автор на наших глазах разворачивает всё хозяйство в Docker и настраивает. В качестве примера Application настраивает доступ к серверу Proxmox. Всё как мы любим. Не хватает только Mikrotik. Доступ через web, при желании, к нему настраивается по аналогии. Мне очень интересно узнать, записывает ли Teleport сессии к Application так же как к серверам по SSH. На своём стенде забыл это проверить.

Если не понимаете на слух английский, включите субтитры или синхронный перевод от Яндекса. Я с ним слушал, всё понятно. Качество перевода приемлемое. Я бы даже сказал хорошее, если бы он "teleport" не переводил как "телепортация".

#security #управление #devops
​​Предлагаю вашему вниманию любопытную утилиту, которую мне давно посоветовали посмотреть в контексте обсуждения темы Port knocking. На практике она может пригодиться в очень широком диапазоне костылей.

Речь пойдёт про программу updater. Она слушает запросы на специальный url и выполняет заданные действия, если запрос легитимный. То есть курлом можно дёрнуть какой-то урл и на сервере выполнится определённое действие. Например, iptables создаст разрешающее правила для подключения по ssh. Урлы можно выбирать любые, в том числе те, что не поддаются подбору. А также наличие аутентификации через токен, делают этот инструмент замаскированным и относительно безопасным. Можно посадить его за прокси, чтобы совсем спрятать.

У автора в репозитории примеры сразу в составе с docker-compose с использованием reproxy в качестве reversed proxy. Если хотите просто погонять утилиту и посмотреть, как работает, может приспособить для своих простых задач, то можете просто запустить в одиночном контейнере:

# docker run -p 8080:8080 -e LISTEN=0.0.0.0:8080 \
-e KEY=super-secret-password \
-e CONF=/srv/etc/updater.yml \
--name=updater -v ./etc:/srv/etc \
ghcr.io/umputun/updater:master

Создаёте директорию etc там, откуда будете запускать команду. В неё положите конфиг updater.yml для простейшего задания с echo:

tasks:

 - name: echo-test
  command: |
   echo "Test updater work"

Формат yaml, так что будьте аккуратны с пробелами. Теперь проверяем, как работает:

# curl 172.17.196.25:8080/update/echo-test/super-secret-password
{"task":"echo-test","updated":"ok"}

Думаю, принцип понятен. Автор пишет, что написал этот софт для использования в CI/CD без необходимости работы по SSH, а следовательно передачи паролей или ключей. По его задумке с помощью updater можно выполнять обновление и перезапуск docker контейнеров. Для этого в составе его контейнера есть docker client и туда пробрасывается docker.sock.

Кстати, его идею я сразу понял, так как в простых случаях я именно так и костылил в Teamcity. Заходил по SSH, обновлял и перезапускал контейнер консольными командами. В целом, это не очень хорошая практика, но задачу решает быстро и в лоб. Для небольших проектов нормальная тема. До этого разработчики руками это делали. Потом попросили настроить что-нибудь для автоматизации. Я воткнул бесплатный Teamcity и автоматизировал в лоб все их действия. Они были довольны.

Для работы на хосте updater нужно вытащить из контейнера и запустить напрямую. Это не трудно сделать, так как updater обычное приложение на GO, состоящее из одного бинарника. Ключи описаны автором в репозитории.

# docker cp f41a990d84c0:/srv/updater updater

Теперь можно запускать локально. Полезная небольшая утилита. Рекомендую запомнить её. Напомню, что есть похожая программа, про которую я пару раз писал и использую сам - labean.

Исходники

#security #cicd #devops
​​Когда-то давно на одном из обучений услышал необычное сравнение работы классических сисадминов и девопсов, как разницу между домашними животными и крупным рогатым скотом - pet vs cattle. Многие, наверное, уже знают, о чём тут речь. Напишу для тех, кто, возможно, об этом не слышал.

Идея в том, что в стародавние времена инфраструктура состояла из отдельных серверов и ими занимались админы как с домашними животными. Каждого знали лично, занимались ими, настраивали, обновляли и т.д. Даже имена давали осмысленно, иногда что-то красивое выдумывали.

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

У меня лично сейчас все сервера, как домашние животные. Из-за того, что их немного (штук 50-60 VPS и 15 железных в сумме, но всё сильно разнородное и принадлежащее разным юр. лицам), я всех знаю лично, регулярно подключаюсь по SSH и что-то делаю вручную. Мне так больше нравится. Потребность в таких услугах всё равно есть, поэтому я остался в этой нише.

Отличить подход pet от cattle очень просто. Если у вас какой-то сервер сломался и работа сервиса нарушена, а вы начинаете думать, как быстрее его восстановить и в каком состоянии бэкапы, то у вас домашние животные. Если вы просто прибили упавший сервер и подняли новый, автоматически накатив на него всё, что надо, то у вас крупный рогатый скот. Очевидно, что для подхода cattle нужны бОльшие масштабы и бОльшие бюджеты. До какого-то уровня это будет экономически не оправданно.

А вам какой подход больше по душе? Ручной или массовое управление с автоматизацией? У меня, как я уже сказал, ручной. Поэтому и вся тематика канала соответствующая. Думаю, это и так заметно.

#разное #devops
​​Немного поизучал тему self-hosted решений для S3 и понял, что аналогов MiniO по сути и нет. Всё, что есть, либо малофункционально, либо малоизвестно. Нет ни руководств, ни отзывов. Но в процессе заметил любопытный продукт от известной компании Zenko, которая специализируется на multi-cloud решениях.

Речь пойдёт про их open source продукт Zenko CloudServer. Заявлено, что он полностью совместим и заменяем для Amazon S3 хранилищ. Он может выступать как обычный S3 сервер с сохранением файлов локально, так и использовать для хранения другие публичные или приватные бэкенды. То есть его назначение в том числе выступать неким прокси для S3 запросов.

CloudServer может принимать запросы на сохранение в одно место, а реально сохранять в другое, либо сразу в несколько. Это ложится в концепцию продуктов Zenko по мультиоблачной работе. Допустим, у вас приложение настроено на сохранение данных в конкретный бакет AWS. Вы можете настроить CloudServer так, что приложение будет считать его за AWS, а реально данные будут складываться, к примеру, в локальный кластер, а их копия в какой-то другой сервис, отличный от AWS. Надеюсь, идею поняли.

Я немного погонял этот сервер локально и могу сказать, что настроить его непросто. Запустить у меня получилось, но вот полноценно настроить хранение на внешнем бэкенде при обращении к локальному серверу я не смог. Документация не очень подробная, готовых полных примеров не увидел, только отрывки конфигов. Часа два провозился и бросил.

В целом инструмент рабочий. Есть живой репозиторий, документация, да и самому серверу уже много лет. Если вам реально нужна подобная функциональность, то можно разобраться. Можно один раз настроить CloudServer, а потом у него переключать различные бэкенды для управления хранением.

Дам немного подсказок, чтобы сэкономить время тем, кому это реально нужно будет. Запускал через Docker вот так:

docker run -p 8000:8000 --name=cloudserver \
-v $(pwd)/config.json:/usr/src/app/config.json \
-v $(pwd)/locationConfig.json /usr/src/app/locationConfig.json \
-v $(pwd)/data:/usr/src/app/localData \
-v $(pwd)/metadata:/usr/src/app/localMetadata \
-e REMOTE_MANAGEMENT_DISABLE=1
-d zenko/cloudserver

Примеры конфигов есть в репозитории, а описание в документации. Конфигурация rclone для работы с сервером:
[remote]
type = s3
env_auth = false
access_key_id = accessKey1
secret_access_key = verySecretKey1
region = other-v2-signature
endpoint = http://localhost:8000
location_constraint =
acl = private
server_side_encryption =
storage_class =

Соответственно используются дефолтные секреты accessKey1 и verySecretKey1. Их можно переназначить через conf/authdata.json, пример конфига тоже есть в репозитории. По умолчанию управление только через конфиги и API, веб интерфейса нет. В качестве веб интерфейса может выступать Zenko Orbit, входящий в состав продукта multi-cloud data controller. Он опенсорсный, но это уже отдельная история.

Сайт / Исходники / Документация

#S3 #devops
Я не так давно рассказывал про сервис рисования схем excalidraw.com. Тогда впервые о нём узнал, и он мне очень понравился. В комментариях кто-то упомянул, что у него есть плагин для VSCode, но я не придал значения.

На канале realmanual вышло наглядное видео, где показано, как работает этот плагин. А работает он очень круто. Там идея такая. У вас есть репозиторий, где вы в том числе храните схему в виде картинки. Плагин позволяет рисовать схему прямо в редакторе, управляя изменениями через GIT. Но это не всё. На файл со схемой можно оставить ссылку в другом документе, например README.md и по этой ссылке схема будет автоматически отрисовываться в статичную картинку.

По описанию возможно не очень понятно, как это работает. Лучше посмотреть короткое видео (13 мин):

Рисуем документацию прямо внутри IDE - excalidraw

Это реально очень удобно. Причём нет никакой привязки к онлайн сервису. Мало того, что вы excalidraw можете развернуть у себя, так в плагине VSCode он уже запускается полностью автономно, без привязки к внешнему сервису.

По идее это получается наиболее красивый и удобный сервис для рисования схем. Я поставил себе плагин. Схемы теперь в нём буду рисовать.

#схемы #devops
​​Протестировал новый для себя инструмент, с которым раньше не был знаком. Он очень понравился и показался удобнее аналогичных, про которые знал и использовал раньше. Речь пойдёт про систему планирования и управления задачами серверов Cronicle. Условно его можно назвать продвинутым Cron с веб интерфейсом. Очень похож на Rundeck, про который когда-то писал.

С помощью Cronicle вы можете создавать различные задачи, тип которых зависит от подключенных плагинов. Например, это может быть SHELL скрипт или HTTP запрос. Управление всё через веб интерфейс, там же и отслеживание результатов в виде логов и другой статистики. Помимо перечисленного Cronicle умеет:
работать с распределённой сетью машин, объединённых в единый веб интерфейс;
работать в отказоустойчивом режиме по схеме master ⇨ backup сервер;
автоматически находить соседние сервера;
запускать задачи в веб интерфейсе с отслеживанием работы в режиме онлайн;
подсчитывать затраты CPU и Memory и управлять лимитами на каждую задачу;
отправлять уведомления и выполнять вебхуки по результатам выполнения задач;
поддерживает API для управления задачами извне.

Возможности хорошие, плюс всё это просто и быстро настраивается. Я разобрался буквально за час, установив сначала локально и погоняв задачи, а потом и подключив дополнительный сервер. Не сразу понял, как это сделать.

Cronicle написана на JavaScript, поэтому для работы надо установить на сервер NodeJS версии 16+. Я тестировал на Debian, версию взял 20 LTS. Вот краткая инструкция:
# apt update
# apt install ca-certificates curl gnupg
# mkdir -p /etc/apt/keyrings
# curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
# NODE_MAJOR=20
# echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" \
| tee /etc/apt/sources.list.d/nodesource.list
# apt update
# apt install nodejs

Теперь ставим сам Cronicle. Для этого есть готовый скрипт:
# curl -s https://raw.githubusercontent.com/jhuckaby/Cronicle/master/bin/install.js \
| node
Установка будет выполнена в директорию /opt/cronicle. Если ставите master сервер, то после установки выполните setup:
# /opt/cronicle/bin/control.sh setup
А потом запустите:
# /opt/cronicle/bin/control.sh start

Теперь можно идти в веб интерфейс на порт сервера 3012. Учётка по умолчанию - admin / admin. В веб интерфейсе всё понятно, разобраться не составит труда. Для подключения второго сервера, на него надо так же установить Cronicle, но не выполнять setup, а сразу запустить, скопировав на него конфиг /opt/cronicle/conf/config.json с master сервера. Там прописаны ключи, которые должны везде быть одинаковые.

В веб интерфейсе можно добавить новое задание, настроить расписание, выбрать в качестве типа shell script и прям тут же в веб интерфейсе написать его. Дальше выбрать сервер, где он будет исполняться и вручную запустить для проверки. Я потестировал, работает нормально.

На выходе получилось довольно удобная и практичная система управления задачами. Насколько она безопасна архитектурно, не берусь судить. По идее не очень. В любом случае на серверах доступ к службе cronicle нужно ограничить на уровне firewall запросами только с master сервера. Ну а его тоже надо скрыть от посторонних глаз и лишнего доступа.

Если кто-то использовал эту систему, дайте обратную связь. Мне идея понравилась, потому что я любитель всевозможных скриптов и костылей.

Сайт / Исходники

#scripts #devops
​​В комментариях к заметкам про синхронизацию файлов не раз упоминались отказоустойчивые сетевые файловые системы. Прямым представителем такой файловой системы является GlusterFS. Это условный аналог Ceph, которая по своей сути не файловая система, а отказоустойчивая сеть хранения данных. Но в целом обе эти системы используются для решения одних и тех же задач. Про Ceph я писал (#ceph) уже не раз, а вот про GlusterFS не было ни одного упоминания.

Вообще, когда выбирают, на основе чего построить распределённое файловое хранилище, выбирают и сравнивают как раз GlusterFS и Ceph. Между ними есть серьёзные отличия. Первое и самое основное, GlusterFS - это файловая система Linux. При этом Ceph - объектное, файловое и блочное хранилище с доступом через собственное API, минуя операционную систему. Архитектурно для настройки и использования GlusterFS более простая система и это видно на практике, когда начинаешь её настраивать и сравнивать с Ceph.

Я покажу на конкретном примере, как быстро поднять и потестировать GlusterFS на трёх нодах. Для этого нам понадобятся три идентичных сервера на базе Debian с двумя жёсткими дисками. Один под систему, второй под GlusterFS. Вообще, GlusterFS - детище в том числе RedHat. На её основе у них построен продукт Red Hat Gluster Storage. Поэтому часто можно увидеть рекомендацию настраивать GlusterFS на базе форков RHEL с использованием файловой системы xfs, но это не обязательно.

❗️ВАЖНО. Перед тем, как настраивать, убедитесь, что все 3 сервера доступны друг другу по именам. Добавьте в /etc/hosts на каждый сервер примерно такие записи:
server1 10.20.1.1
server2 10.20.1.2
server3 10.20.1.3

На все 3 сервера устанавливаем glusterfs-server:
# apt install glusterfs-server
Запускаем также на всех серверах:
# service glusterd start

На server1 добавляем в пул два других сервера:
# gluster peer probe server2
# gluster peer probe server3
На остальных серверах делаем то же самое, только указываем соответствующие имена серверов.

Проверяем статус пиров пула:
# gluster peer status
На каждом сервере вы должны видеть два других сервера.

На всех серверах на втором жёстком диске создайте отдельный раздел, отформатируйте его в файловую систему xfs или ext4. Я в своём тесте использовал ext4. И примонтируйте в /mnt/gv0.
# mkfs.ext4 /dev/sdb1
# mkdir /mnt/gv0
# mount /dev/sdb1 /mnt/gv0

Создаём на этой точке монтирования том glusterfs:
# gluster volume create gv0 replica 3 server1:/mnt/gv0 server2:/mnt/gv0 server3:/mnt/gv0
Если получите ошибку:
volume create: gv0: failed: Host server1 is not in 'Peer in Cluster' state
то проверьте ещё раз файл hosts. На каждом хосте должны быть указаны все три ноды кластера. После исправления ошибок, если есть, остановите службу glusterfs и почистите каталог /var/lib/glusterd.

Если всё пошло без ошибок, то можно запускать том:
# gluster volume start gv0
Смотрим о нём информацию:
# gluster volume info

Теперь этот volume можно подключить любому клиенту, в роли которого может выступать один из серверов:
# mkdir /mnt/gluster-test
# mount -t glusterfs server1:/gv0 /mnt/gluster-test

Можете зайти в эту директорию и добавить файлы. Они автоматически появятся на всех нодах кластера в директории /mnt/gv0.

По этому руководству наглядно видно, что запустить glusterfs реально очень просто. Чего нельзя сказать о настройке и промышленно эксплуатации. В подобных системах очень много нюансов, которые трудно учесть и сразу всё сделать правильно. Нужен реальный опыт работы, чтобы правильно отрабатывать отказы, подбирать настройки под свою нагрузку, расширять тома и пулы и т.д. Поэтому в простых ситуациях, если есть возможность, лучше обойтись синхронизацией на базе lsyncd, unison и т.д. Особенно, если хосты территориально разнесены. И отдельное внимание нужно уделить ситуациям, когда у вас сотни тысяч мелких файлов. Настройка распределённых хранилищ будет нетривиальной задачей, так как остро встанет вопрос хранения и репликации метаданных.

Сайт / Исходники

#fileserver #devops
​​Я вроде бы уже когда-то упоминал про англоязычную рассылку devopsweekly.com, но не могу найти этой записи. Возможно и нет. В общем, это такая олдскульная рассылка на почту в текстовом формате раз в неделю с некоторыми новостями. Я её давно уже читаю, более двух лет.

Мне нравится такой формат, когда раз в неделю, в воскресенье, приходят новости по определённой тематике. Читаю я там далеко не всё, но просматриваю регулярно. Я как раз в воскресенье вечером сажусь за компьютер, проверить и подготовить список основных дел на неделю. Заодно читаю эту рассылку.

Вчерашнюю заметку про HTTPS записи DNS как раз там повстречал. Было бы круто, если бы кто-то ещё начал вести подобные рассылки по разным направлениям: безопасность, сети, обновления, Windows, Linux и т.д. Можно в Telegram. А лучше и здесь, и по почте.

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

Если кто-то знает похожие рассылки, не обязательно на русском языке, поделитесь.

#devops
This media is not supported in your browser
VIEW IN TELEGRAM
Что такое Devops 😂
https://www.youtube.com/watch?v=NXwtcjOdaHw

Work-life balance ставишь 0.

Не понял только одно. Зачем докер контейнер упаковали в zip?

#юмор #devops
Я уже не раз делал заметки про Gitea - легковесную open source систему для управления git репозиториями. Изначально это был просто веб интерфейс для git, который можно было сделать с помощью соответствующей темы очень похожей на github. Написана Gitea на Go и по своей сути это просто бинарник, поэтому с установкой и настройкой никаких проблем. Бонусом гошечки идёт очень быстрая работа и отзывчивость веб интерфейса.

Как я уже сказал, Gitea была создана просто для работы с кодом, без какой-либо автоматизации. Для построения конвейера для сборки, деплоя и хранения образов я предлагал связку: Gitea + Drone CI + Docker Registry.

С недавних пор в Gitea завезли Gitea Actions, которые полностью совместимы с GitHub Actions. То есть она превратилась в полноценную CI/CD систему с собственным Package Registry и Gitea Runner. Получился аналог gitlab на минималках.

Подробно посмотреть обзор всех этих возможностей, а также инструкцию по настройке, можно в серии из двух видеороликов:
▶️ Gitea-01: домашний github (+ actions)
▶️ Gitea-02: домашний github (+ actions)

#git #devops #cicd
This media is not supported in your browser
VIEW IN TELEGRAM
Есть тут настоящие девопсы? У вас так же в среднем проходит рабочий день? В целом, распорядок неплохой.

Музыкальная комната немного удивила. Впервые услышал, что такие есть в офисах. Немного поискал информации в интернете. Оказывается, такие комнаты много где есть - Яндекс, VK, Ростелеком и т.д.

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

p.s. видео отсюда

#devops
​​Для автоматической проверки Docker образов на уязвимости (CVE) есть хороший open source инструмент Trivy. Год назад я делал по нему пару заметок с обзором и автоматическим исправлением уязвимостей. Потом всё это в небольшую статью оформил.

Этот продукт хорошо дополняет open source утилита Dockle. Она тоже проверяет контейнеры на уязвимости, но помимо этого проверяет образ на соответствие best-practice Dockerfile и рекомендации CIS Docker Benchmarks (#cis).

Использовать очень просто, так как это по сути одиночный бинарник. В репозитории есть пакеты для установки под все популярные системы. Можно запустить и в Docker без установки:

# docker run --rm goodwithtech/dockle:v0.4.14 [YOUR_IMAGE_NAME]

Пример отчёта можно посмотреть на тестовом образе, для которого есть замечания:

# docker run --rm goodwithtech/dockle:v0.4.14 goodwithtech/dockle-test:v2

С помощью ключа -f json вывод можно сохранить в json файле. Dockle легко интегрировать в пайплайн. В репозитории есть примеры (gitlab).

Исходники

#docker #devops #cicd #security
​​Если вам нужно продебажить какой-то контейнер, в котором нет никаких инструментов для диагностики (а это почти всегда так), то для этого можно воспользоваться специально собранным для этих целей контейнером - Network-Multitool. Его ещё любят в кубернетисе запускать для отладки. Известная штука.

Работает он примерно так. Запускаем контейнер, внутри которого ничего нет, кроме nginx:

# docker run --name nginx -d -p 8080:80 nginx
# docker exec -it nginx bash
# ps axf
bash: ps: command not found

Подключаем к нему network-multitool:

# docker run --rm -it \
--network=container:nginx \
--pid container:nginx \
wbitt/network-multitool:alpine-extra bash

# ps axf
  PID TTY   STAT  TIME COMMAND
   47 pts/0  Ss   0:00 bash
   60 pts/0  R+   0:00 \_ ps axf
   1 ?    Ss   0:00 nginx: master process nginx -g daemon off;
   29 ?    S   0:00 nginx: worker process
   31 ?    S   0:00 nginx: worker process
   30 ?    S   0:00 nginx: worker process
   32 ?    S   0:00 nginx: worker process

Дальше всё остальное можно запускать: ping, dig, tcpdump и т.д.

Я тут выбрал самую жирную сборку alpine-extra, где максимальный набор инструментов, в том числе tshark, ApacheBench, mysql & postgresql client, git и т.д. Если всё это не надо, то используйте alpine-minimal. Описание сборок в репозитории.

Похожую функциональность имеет cdebug. У него принцип работы такой же, только он для удобства собран в бинарник. А подключается он к контейнерам точно так же.

Кстати, с помощью network-multitool можно и хост дебажить, если не хочется его засорять различными утилитами. Запускаем его в сети хоста и пользуемся:

# docker run --rm -it --network=host wbitt/network-multitool:alpine-extra bash
# tcpdump

На хост ничего ставить не надо. Полезная штука, берите на вооружение.

#docker #devops
​​Недавно посмотрел видео про Diun (Docker Image Update Notifier). Это маленькая консольная утилита, которая делает одно простое действие - проверяет наличие обновлений для образов запущенных контейнеров на хосте. Если обновление есть, уведомляет через email, telegram, gotify, slack и другие каналы. Больше ничего не делает, не качает обновление, не применяет, не перезапускает образ.

Diun состоит из одного бинарника. Запустить можно как на хосте, создав службу systemd, так и в контейнере, прокинув туда docker.sock. Процесс описан в документации:

# docker run -d --name diun \
 -e "TZ=Europe/Moscow" \
 -e "DIUN_WATCH_WORKERS=20" \
 -e "DIUN_WATCH_SCHEDULE=0 */6 * * *" \
 -e "DIUN_WATCH_JITTER=30s" \
 -e "DIUN_PROVIDERS_DOCKER=true" \
 -e "DIUN_NOTIF_TELEGRAM_TOKEN=1493678911:AAHtETAKqxUH8ZpyC28R-wxKfvH8WR6-vdNw" \
 -e "DIUN_NOTIF_TELEGRAM_CHATIDS=211805263" \
 -v "$PWD/data:/data" \
 -v "/var/run/docker.sock:/var/run/docker.sock" \
 -l "diun.enable=true" \
 crazymax/diun:latest

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

Diun умеет следить за актуальностью образов запущенных Docker контейнеров, образов подов в Kubernetes, Swarm, Nomad. Также можно настроить наблюдение за образами, используемыми в определённых Dockerfiles или конфигурационных файлах yaml, где указаны образы.

Простая, маленькая, удобная утилита. Описание установки, настройки, работы:
▶️ Diun - это вам не watchtower

⇨ Сайт / Исходники

#docker #devops
​​Наиболее популярным и простым в настройке мониторингом сейчас является Prometheus. Простым не в плане возможностей, а в плане начальной настройки. Так как для него очень много всего автоматизировано, начать сбор метрик можно в несколько простых действий. Мониторинг сразу заработает и дальше с ним можно разбираться и настраивать.

Напишу краткую шпаргалку по запуску связки Prometheus + Grafana, чтобы её можно было сохранить и использовать по мере надобности. Я установлю их в Docker, сразу буду мониторить сам Prometheus и локальных хост Linux. Подключу для примера ещё один внешний Linux сервер.

Ставим Docker:

# curl https://get.docker.com | bash -

Готовим файл docker-compose.yml:

# mkdir ~/prometheus && cd ~/prometheus
# touch docker-compose.yml

Содержимое файла:

version: '3.9'
networks:
monitoring:
driver: bridge
volumes:
prometheus_data: {}

services:

prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
container_name: prometheus
hostname: prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
expose:
- 9090
restart: unless-stopped
environment:
TZ: "Europe/Moscow"
networks:
- monitoring

node-exporter:
image: prom/node-exporter
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
container_name: exporter
hostname: exporter
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
expose:
- 9100
restart: unless-stopped
environment:
TZ: "Europe/Moscow"
networks:
- monitoring

grafana:
image: grafana/grafana
user: root
depends_on:
- prometheus
ports:
- 3000:3000
volumes:
- ./grafana:/var/lib/grafana
- ./grafana/provisioning/:/etc/grafana/provisioning/
container_name: grafana
hostname: grafana
restart: unless-stopped
environment:
TZ: "Europe/Moscow"
networks:
- monitoring

И рядом кладём конфиг prometheus.yml:

scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
scrape_timeout: 5s
static_configs:
- targets: ['localhost:9090']

- job_name: 'node-local'
scrape_interval: 5s
static_configs:
- targets: ['node-exporter:9100']

Запускаем весь стек:

# docker-compose up -d

Если будут ошибки, прогоните весь yaml через какой-нибудь валидатор. При копировании он часто ломается.

Ждём, когда всё поднимется, и идём по IP адресу сервера на порт 3000. Логинимся в Grafana под учёткой admin / admin. Заходим в Connections ⇨ Data sources и добавляем источник prometheus. В качестве параметра Prometheus server URL указываем http://prometheus:9090. Сохраняем.

Идём в Dashboards, нажимаем New ⇨ Import. Вводим ID дашборда для Node Exporter - 1860. Сохраняем и идём смотреть дашборд. Увидите все доступные графики и метрики хоста Linux, на котором всё запущено.

Идём на удалённый Linux хост и запускаем там любым подходящим способом node-exporter. Например, через Docker напрямую:

# docker run -d --net="host" --pid="host" -v "/:/host:ro,rslave" prom/node-exporter:latest --path.rootfs=/host

Проверяем, что сервис запущен на порту 9100:

# ss -tulnp | grep 9100

Возвращаемся на сервер с prometheus и добавляем в его конфиг еще одну job с этим сервером:

- job_name: 'node-remote'
scrape_interval: 5s
static_configs:
- targets: ['10.20.1.56:9100']

Перезапускаем стек:

# docker compose restart

Идём в Dashboard в Grafana и выбираем сверху в выпадающем списке job от этого нового сервера - node-remote.

На всю настройку уйдёт минут 10. Потом ещё 10 на настройку базовых уведомлений. У меня уже места не хватило их добавить сюда. Наглядно видна простота и скорость настройки, о которых я сказал в начале.

❗️В проде не забывайте ограничивать доступ ко всем открытым портам хостов с помощью файрвола.

#мониторинг #prometheus #devops
​​Вчера была заметка про быструю установку связки Prometheus + Grafana. Из-за лимита Telegram на длину сообщений разом всё описать не представляется возможным. А для полноты картины не хватает настройки уведомлений, так как мониторинг без них это не мониторинг, а красивые картинки.

Для примера я настрою два типа уведомлений:

SMTP для только для метки critical
Telegram для меток critical и warning

Уведомления будут отправляться на основе двух событий:

▪️ С хоста нету метрик, то есть он недоступен мониторингу, метка critical
▪️ На хосте процессор занят в течении минуты более чем на 70%, метка warning

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

Постить сюда все конфигурации в формате yaml неудобно, поэтому решил их собрать в архив и прикрепить в следующем сообщении. Там будут 4 файла:

- docker-compose.yml - основной файл с конфигурацией всех сервисов. Его описание можно посмотреть в предыдущем посте. Там добавился новый контейнер с alertmanager и файл с правилами для prometheus - alert.rules
- prometheus.yml - настройки Прометеуса.
- alert.rules - файл с двумя правилами уведомлений о недоступности хоста и превышении нагрузки CPU.
- alertmanager.yml - настройки alertmanager с двумя источниками для уведомлений: email и telegram. Не забудьте там поменять токен бота, id своего аккаунта, куда бот будет отправлять уведомления и настройки smtp.

Для запуска всего стека с уведомлениями достаточно положить эти 4 файла в отдельную директорию и там запустить compose:

# docker compose up

На момент отладки рекомендую запускать прямо в консоли, чтобы отлавливать ошибки. Если где-то ошибётесь в конфигурациях правил или alertmanager, сразу увидите ошибки и конкретные строки конфигурации, с которыми что-то не так. В таком случае останавливайте стэк:

# docker compose stop

Исправляйте конфиги и заново запускайте. Зайдя по IP адресу сервера на порт 9090, вы попадёте в веб интерфейс Prometheus. Там будет отдельный раздел Alerts, где можно следить за работой уведомлений.

В данном примере со всем стэком наглядно показан принцип построения современного мониторинга с подходом инфраструктура как код (IaC). Имея несколько файлов конфигурации, мы поднимаем необходимую систему во всей полноте. Её легко переносить, изменять конфигурацию и отслеживать эти изменения через git.

#мониторинг #prometheus #devops
​​Вчера свершилось знаменательное событие - заблокировали доступ к hub.docker.com с IP адресов в России. Теперь без лишних телодвижений не скачать образы из этого репозитория. Не очень понятно, зачем это сделали, почему только сейчас и в чём тут смысл, если обойти эту блокировку, как и многие другие, не представляет каких-то проблем.

Расскажу несколько простых разных способов обхода этой блокировки.

1️⃣ Самый простой - переключиться на какое-то зеркало. Их сейчас много появится и встанет вопрос доверия к ним. Пока можно гугловское зеркало использовать, но его скорее всего тоже рано или поздно для нас заблокируют. Для этого достаточно создать конфиг /etc/docker/daemon.json, если у вас его нет, следующего содержания:

{ "registry-mirrors": ["https://mirror.gcr.io"] }

Перезапускаем службу и пользуемся, как раньше.

# systemctl restart docker

Больше ничего менять не надо.

2️⃣ Использовать локально подключение докера к своему реджистри через прокси. Недавно я об этом рассказывал и там многие написали, типа зачем всё это, доступ не заблокирован. Потому что не будет вашего итальянского сыра ХАХАХАХА. Сегодня этот реджистри, завтра все остальные. Прокси тоже относительно просто решает вопрос для единичного хоста.

3️⃣ Можно глобально на общем шлюзе настроить VPN подключение к серверу за пределами РФ, маркировать весь трафик, что блокируется и отправлять его через VPN соединение. Я так делаю дома для себя и своих тестовых стендов. Рассказывал про эту настройку на примере Mikrotik.

4️⃣ Поднять собственный прокси для докера, который будет иметь доступ к hub.docker.com. Не важно, как это будет сделано у него: через VPN он будет подключаться, или сразу поднят на VPS за пределами РФ. Вы со своей стороны будете подключаться к этому прокси, а он будет по вашим запросам загружать образы.

Проще всего подобный прокси поднять с помощью Nexus repository. Показываю, как это сделать. Я сразу взял VPS за пределами РФ и развернул там:

# docker volume create --name nexus-data
# docker run -d -p 8081:8081 -p 8082:8082 --name nexus \
-v nexus-data:/nexus-data sonatype/nexus3

В файле /var/lib/docker/volumes/nexus-data/_data/admin.password смотрим пароль от пользователя admin. Идём в веб интерфейс Nexus по IP адресу сервера на порт 8081.

Переходим в раздел управления и добавляем новый репозиторий. Тип выбираем docker (proxy). Если вы сами к прокси будете подключаться через VPN или проксировать к нему запросы через ещё какой-то прокси, типа Nginx или HAproxy, то можно в свойствах репозитория выбрать только HTTP и порт 8082. Это упростит настройку. Рекомендую идти именно по этому пути, чтобы ограничить тем или иным способом доступ к этому репозиторию. Вы же не будете его открывать в общий доступ для всех. В таком случае можно будет установить флаг Allow anonymous docker pull. Не нужно будет на всех хостах аутентификацию проходить.

В качестве Remote Storage можно указать https://registry-1.docker.io. Это докеровский репозиторий. Остальные настройки можно оставить по умолчанию, либо изменить в зависимости от ваших предпочтений.

Также зайдите в раздел Security ⇨ Realms и добавьте Docker Bearer Token Realm. Без него аутентификация в реджистри не будет работать.

После создания репозитория, можно его открыть. Там будет показан его url в зависимости от ваших настроек порта, http и адреса самого Nexus. Теперь его можно использовать в настройках /etc/docker/daemon.json:

{
    "insecure-registries": ["10.105.10.105:8082"],
    "registry-mirrors": ["http://10.105.10.105:8082"]
}

Перезапускайте службу Docker и пробуйте. Можно аутентифицироваться в своём реджистри и что-то загрузить:

# docker login 10.105.10.105:8082
# docker pull nginx

Идём в веб интерфейс Nexus, смотрим обзор репозитория и видим там скачанный образ Nginx.

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

#devops #docker
​​Я в пятницу рассказал про систему мониторинга Gatus. Система мне понравилась, так что решил её сразу внедрить у себя. Понравилась за 3 вещи:

▪️ простая настройка в едином конфигурационном файле;
▪️ информативные уведомления в Telegram;
▪️ наглядный дашборд со статусами как отдельных проверок, так и объединённых в группы.

На примере настройки Gatus я покажу, как собрал простейший конвейер по деплою настроек для этой системы мониторинга.

Настройка Gatus у меня сейчас выглядит следующим образом. Я открываю в VSCode конфигурационный файл config.yaml, который сохранён у меня локально на ноуте. Вношу в него правки, сохраняю и пушу в git репозиторий. Дальше изменения автоматом доходят до VPS, где всё развёрнуто и автоматически применяются. Через 10 секунд после пуша я иду в браузере проверять изменения.

Рассказываю по шагам, что я сделал для этого.

1️⃣ Взял самую простую VPS с 1 CPU и 1 GB оперативной памяти. Установил туда Docker и запустил Gatus.

2️⃣ В бесплатной учётной записи на gitlab.com создал отдельный репозиторий для Gatus.

3️⃣ На VPS установил gitlub-runner с shell executor, запустил и подключил к проекту Gatus.

4️⃣ Для проекта настроил простейший CI/CD средствами Gitlab (по факту только CD) с помощью файла .gitlab-ci.yml. Добавил туда всего 3 действия:
deploy-prod:
stage: deploy
script:
- cd /home/gitlab-runner/gatus
- git pull
- /usr/bin/docker restart gatus

5️⃣ Скопировал репозиторий к себе на ноут, где установлен VSCode с расширением GitLab Workflow. С его помощью подключаю локальные репозитории к репозиториям gitlab.

Итого у меня в репозитории 2 файла:

config.yaml - конфигурация gatus
.gitlab-ci.yml - описание команд, которые будет выполнять gitlab-runner

Когда мне нужно добавить или отредактировать проверку в Gatus, я открываю у себя на ноуте конфиг и вношу туда изменения. Коммичу их и пушу изменения в репозиторий в Gitlab. Сервис видит наличие файла .gitlab-ci.yml и отдаёт команду gitlab-runner, установленному на VPS на выполнение заданных действий: обновление локального репозитория, чтобы поучить обновлённый конфиг и перезапуск контейнера, который необходим для применения изменений.

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

#devops #cicd
Я много раз упоминал в заметках, что надо стараться максимально скрывать сервисы от доступа из интернета. И проверять это, потому что часто они туда попадают случайно из-за того, что что-то забыли или неверно настроили. Решил через shodan глянуть открытые Node Exporter от Prometheus. Они часто болтаются в открытом виде, потому что по умолчанию никаких ограничений доступа в них нет. Заходи, кто хочешь, и смотри, что там есть.

И первым же IP адресом с открытым Node Exporter, на который я зашёл, оказалась чья-то нода Kubernetes. Причём для меня она сразу стала не чей-то, а я конкретно нашёл, кому она принадлежит. Мало того, что сам Node Exporter вываливает просто кучу информации в открытый доступ. Например, по volumes от контейнеров стало понятно, какие сервисы там крутятся. Видны названия lvm томов, точки монтирования, информация о разделах и дисках, биос, материнка, версия ОС, система виртуализации и т.д.

На этом же IP висел Kubernetes API. Доступа к нему не было, он отдавал 401 Unauthorized. Но по сертификату, который доступен, в Alternative Name можно найти кучу доменов и сервисов, которые засветились на этом кластере. Я не знаю, по какому принципу они туда попадают, но я их увидел. Там я нашёл сервисы n8n, vaultwarden, freshrss. Не знаю, должны ли в данном случае их веб интерфейсы быть в открытом доступе или нет, но я в окна аутентификации от этих сервисов попал.

Там же нашёл информацию о блоге судя по всему владельца этого хозяйства. Плодовитый специалист из Бахрейна. Много open source проектов, которые он развивает и поддерживает. Там же резюме его как DevOps, разработчика, SysOps. Нашёл на поддоменах и прошлую версию блога, черновики и кучу каких-то других сервисов. Не стал уже дальше ковыряться.

Ссылки и IP адреса приводить не буду, чтобы не навредить этому человеку. Скорее всего это какие-то его личные проекты, но не факт. В любом случае, вываливать в открытый доступ всю свою подноготную смысла нет. Закрыть файрволом и нет проблем. Конечно, всё это так или иначе можно собрать. История выпущенных сертификатов и dns записей хранится в открытом доступе. Но тем не менее, тут всё вообще в куче лежит прямо на активном сервере.

Для тех, кто не в курсе, поясню, что всю историю выпущенных сертификатов конкретного домена со всеми поддоменами можно посмотреть тут:

https://crt.sh

Можете себя проверить.

#devops #security
Часто доступ к веб ресурсам осуществляется не напрямую, а через обратные прокси. Причём чаще доступ именно такой, а не прямой. При возможности, я всегда ставлю обратные прокси перед сайтами даже в небольших проектах. Это и удобнее, и безопаснее, но немного более хлопотно в управлении.

Для проксирования запросов в Docker контейнеры очень удобно использовать Traefik. Удобство это в первую очередь проявляется в тестовых задачах, где часто меняется конфигурация контейнеров с приложениями, их домены, а также возникают задачи по запуску нескольких копий типовых проектов. Для прода это не так актуально, потому что он обычно более статичен в этом плане.

Сразу покажу на практике, в чём заключается удобство Traefik и в каких случаях имеет смысл им воспользоваться. Для примера запущу через Traefik 2 проекта test1 и test2, состоящих из nginx и apache и тестовой страницы, где будет указано имя проекта. В этом примере будет наглядно виден принцип работы Traefik.

Запускаем Traefik через docker-compose.yaml:

# mkdir traefik && cd traefik
# mcedit docker-compose.yaml


services:
reverse-proxy:
image: traefik:v3.0
command: --api.insecure=true --providers.docker
ports:
- "80:80"
- "8080:8080"
networks:
- traefik_default
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
traefik_default:
external: true


# docker compose up


Можно сходить в веб интерфейс по ip адресу сервера на порт 8080. Пока там пусто, так как нет проектов. Создаём первый тестовый проект. Готовим для него файлы:

# mkdir test1 && cd test1
# mcedit docker-compose.yaml


services:
nginx:
image: nginx:latest
volumes:
- ./app/index.html:/app/index.html
- ./default.conf:/etc/nginx/conf.d/default.conf
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx-test1.rule=Host(`test1.server.local`)"
- "traefik.http.services.nginx-test1.loadbalancer.server.port=8080"
- "traefik.docker.network=traefik_default"
networks:
- traefik_default
- test1

httpd:
image: httpd:latest
volumes:
- ./app/index.html:/usr/local/apache2/htdocs/index.html
networks:
- test1

networks:
traefik_default:
external: true
test1:
internal: true


# mcedit default.conf 

server {
listen 8080;
server_name _;

root /app;
index index.php index.html;

location / {
proxy_pass http://httpd:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}


# mcedit app/index.html


It's Container for project test1


Запускаем этот проект:

# docker compose up


В веб интерфейсе Traefik, в разделе HTTP появится запись:

Host(`test1.server.local`) http nginx-test1@docker  nginx-test1

Он по меткам в docker-compose проекта test1 автоматом подхватил настройки и включил проксирование всех запросов к домену test1.server.local в контейнер nginx-test1. При этом сам проект test1 внутри себя взаимодействует по своей внутренней сети test1, а с Traefik по сети traefik_default, которая является внешней для приёма запросов извне.

Теперь можно скопировать проект test1, изменить в нём имя домена и имя внутренней сети на test2 и запустить. Traefik автоматом подцепит этот проект и будет проксировать запросы к test2.server.local в nginx-test2. Работу этой схемы легко проверить, зайдя откуда-то извне браузером на test1.server.local и test2.server.local. Вы получите соответствующую страницу index.html от запрошенного проекта.

К Traefik легко добавить автоматическое получение TLS сертификатов от Let's Encrypt. Примеров в сети и документации много, настроить не составляет проблемы. Не стал показывать этот пример, так как не уместил бы его в формат заметки. Мне важно было показать суть - запустив один раз Traefik, можно его больше не трогать. По меткам в контейнерах он будет автоматом настраивать проксирование. В некоторых ситуациях это очень удобно.

#webserver #traefik #devops