Vasiliy Ozerov – Telegram
Vasiliy Ozerov
3.41K subscribers
14 photos
1 file
77 links
Обожаю настраивать, траблшутить и помогать другим!

Youtube: youtube.com/@sysopslab

Founder - rebrainme.com
exFounder - fevlake.com

Для фидбека и вопросов - @vasiliyozerov
Download Telegram
Что-то давненько не писал - работки привалило. Но на днях мы наконец-то разрулили одну историю - вытащили сайтик из черного списка. И я бы хотел высказаться про все эти списки дурацкие.

Предыстория. Есть у нас доменчик. И с некоторых сеток он перестал быть доступен - выдавалась заглушка cisco umbrella, типа сайт фишинговый и все дела. Посидели, почитали, изучили. В общем и целом выходило, что сайтик наш добавили в блеклист и теперь надо оттуда вылезать. Пока читал, наткнулся на какие-то форумы, где писали, что сайты проверяют по spfbl, а он проверяет по reverse dns name и если его нет, то привет пока - в список. Ну типа как почтовые сервачки проверяют так же и тут. Как это к вебу относится правда - хрен его знает.

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

По сути ситуация разрешилась хорошо, НО! В этой истории есть одно большое и сильное НО! Даже не одно.

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

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

Во-третьих. Сама ситуация странная. Какая-то компания, создала какой-то свой список, как-то сама его менеджерит и сама решает кому куда можно ходить, а кому куда нельзя. Дальше осталось бы только деньги брать за исключение из списка и бизнес готов. Вон, из spfbl можно выйти платно - https://spfbl.net/en/delist/. Понятно, что там еще условия есть, но просто зацените - черный список и за деньги из него можно выйти. Ну такое себе.

Я в своей истории проходил черные списки только однажды - когда настраивал почтовые системы. Тогда это было мега популярно проверять отправителя по черным спискам. И знаете что? Туда попадали абсолютно все и вообще непонятно по каким причинам. То есть с включенной блокировкой по черным спискам почта не ходила от слова совсем. Ну и я сделал очень простой вывод на всю жизнь - нельзя блочить по черным спискам. Никогда и никого. Черт его знает как кто-то туда попал. Может айпишник старый меченным оказался, а сейчас там вполне валидный сервер располагается. Блочить можно только по совокупности факторов. Типа helo не прислал - вот тебе балл. Отправитель левый - вот тебе еще 5 баллов. В блеклистах есть - вот тебе еще 3 балла. Больше 7 баллов набрал? Идешь лесом.

В истории с их системой можно так же было поступить. Чекаем сайт, он набирает баллы - набрал меньше 50 - в whitelist, набрал от 50 до 70 - на ручную проверку модератором, набрал больше 70 - в бан с уведомлением. А если мы сразу набрали больше 70, то очевидна проблем каллибровки. Если вы вручную потом проверяете и исключаете из списка тут же - значит что-то не так с вашей системой распознования.

Короче раздолбал бы черные списки если б мог. Ах да, черный список в телефоне я регулярно пополняю, а то повадились звонить в одно и тоже время все кому ни лень.
👍596👎3🔥2
Ох, забыл. В догонку сразу - хочу задачку вам задать, не относящуюся к предыдущему посту.

Итак, нужно придумать самый быстрый способ выкрутиться из ситуации.

Ситуация такая. У вас есть виртуалка с айпшником из РФ. И у Вас еще есть виртуалка зарубежная. Между ними связь кайф - все работает. С виртуалки из РФ вы делаете curl -D - https://packages.gitlab.com и получаете 403 - gitlab заблочил доступ из РФ.

Как быстрее всего получить доступ к гитлабу с виртуалке из РФ? Типа за минуту. Ответы кидайте на vasiliyozerov@gmail.com - самый крутой ответ запощу сюда и упомяну автора (при желании). А может еще чего подарю 🙂 Ну и составим топ ответов и сюда закинем.

P.S. Вторую виртуалку зарубежную использовать необязательно - если знаете способ как без нее, но мега быстро - закидывайте.
😁14🔥82🆒2
Так, в последний раз я задал задачку и ушел в неизвестность. Исправляюсь.

Топ вариант номер 1 по ответам - это socks5 proxy в ssh. Я вообще забыл про эту штуку, поскольку практически никогда ее не юзал (АХАХА). Но действительно в ssh есть socks5 и таким образом можно быстро создавать проксики. Очень удобно и очень круто - вы большие молодцы! Выглядит способ так:


ssh -D 127.0.0.1:9999 <ipaddr>
curl -x socks5://127.0.0.1:9999 …


Еще были варианты с использованием squid, wireguard, openvpn и любыми прокси / vpn решениями на удаленных узлах. Но эти варианты я не брал, поскольку, они требуют установки софта, что навряд ли уложится в 1 минуту. Хотя тот же wireguard ставится быстро 🙂

Мой вариант сводился к настройке iptables на второй машинке в таком виде:


iptables -t nat -I PREROUTING -p tcp -m tcp --dport 443 -j DNAT --to-destination 188.114.98.224:443
iptables -t nat -I POSTROUTING -d 188.114.98.224 -p tcp -m tcp --dport 443 -j MASQUERADE


То есть мы меняем назначение для трафика, направленного на 443 порт на packages.gitlab.com и обязательно вторым правилом делаем маскарадинг на наш адрес, чтобы гитлаб не начал отвечать на реальный айпишник. Ну и на исходной машинке добавляем в /etc/hosts айпишник нашей машинки для packages.gitlab.com.

Я видел предложения сделать также в некоторых вариантах (если вариант через iptables подразумевал именно это :). Этот путь конечно не такой универсальный, как с socks5 proxy, поскольку требует чтобы на нашем внешнем хосте 443 был не занят. И он не позволяет проксировать несколько адресов через наш внешний хост - только один. Хотим больше - надо ставить что-то умное типа nginx с сертификатами и proxy_pass, либо прокси сервер, либо wireguard, либо что-то еще.

В общем делаю простой вывод - вы победили - socks5 proxy намного приятнее и быстрее чем мои iptables правила. Поздравлямба!

Самый нестандартный ответ был по поводу использования google translate в качестве proxy. Я честно немного попробовал загрузить файл packages.gitlab.com/gitlab/gitlab-ee/packages/ubuntu/jammy/gitlab-ee_15.11.3-ee.0_amd64.deb через google translate, но у меня не получилось - валю на свои кривые ручки 🙂

Всем хорошей ночки!
🔥49👍14👏41
Если вы, как и я, апгрейдите кубернетес через несколько версий, то в один прекрасный момент helm может сказать вам что-то типа:


Error: UPGRADE FAILED: unable to build kubernetes objects from current release manifest: resource mapping not found for name: "service" namespace: "" from "": no matches for kind "Ingress" in version "extensions/v1beta1"
ensure CRDs are installed first
helm.go:84: [debug] resource mapping not found for name: "service" namespace: "" from "": no matches for kind "Ingress" in version "extensions/v1beta1"


Что в переводе на русский означает, что в предыдущем релизе был ресурс Ingress в “extensions/v1beta1”, но теперь такой версии не существует и извините, я не могу нифига обновить.

Чтобы направить хельм на путь истинный, можно заюзать утилитку [https://github.com/helm/helm-mapkubeapis](https://github.com/helm/helm-mapkubeapis) - она ищет удаленные апишки в прошлом релизе и исправляет их на правильные. Возможно кому-то пригодится.
👍105🫡114👎4
Если вы используете argocd, а конкретно applicationSet, то знайте - вы можете столкнуться с проблемой обновления параметров через сам argocd (app set).

Я использую примерно следующую структуру для своих проектов:

core - корневой репозиторий, в котором я описываю terraform манифесты и параметры бутстрапа кластеров кубера (типа service accounts, cert-manager, etc…).
При развертывании argocd я сразу же создаю корневой проект и добавляю в него root application )https://argo-cd.readthedocs.io/en/stable/operator-manual/cluster-bootstrapping/#app-of-apps-pattern), которое смотрит на этот же core репозиторий, только в директорию apps. Задача этого приложения - создать еще приложения, но уже для отдельных продуктовых команд.
К примеру, там я могу создать приложение auth-root-app для команды аутентификации или email-root-app для команды, которая занимается всем что связано с email’ами. Каждое из этих приложений уже будет смотреть на отдельный репозиторий с манифестами для команды. Для auth-root-app - это gitlab.com/company/auth-team/manifest, а для email-root-app - gitlab.com/company/email-team/manifests.

manifests - это уже репозитории с манифестами для каждой отдельной команды, где описываются их приложения и параметры для них. Здесь каждая команда вольна добавлять какие-то параметры, удалять деплойменты, использовать helm, kustomize, jsonnet и так далее.

Так вот. Если вы приложения для команд создаете с помощью ApplicationSet, то при обновлении параметров приложения команды вы можете столкнуться с такой ошибкой (из логов):

time="x" level=info msg="received unary call /application.ApplicationService/UpdateSpec" grpc.method=UpdateSpec grpc.request.content="%!v(PANIC=String method: reflect.Value.Bytes of non-byte slice)" grpc.service=application.ApplicationService grpc.start_time="x" span.kind=server system=grpc

Подробнее можно посмотреть здесь: https://github.com/argoproj/argo-cd/issues/12151. Вообще есть похожая known issue - https://github.com/argoproj/argo-cd/pull/13061#discussion_r1199279829, но я не уверен что она исправит мою проблему при обновлении.

Поэтому совет - используйте пока только App of apps, а сами приложеньки генерируйте с помощью kustomize. Ну ладно. Или с помощью helm 🙂
👍222
Ох, читал тут статейку про ExternalSecrets Operator - https://hackernoon.com/cooking-helm-with-the-external-secrets-operator-and-reloader и у меня есть что сказать по этому поводу!

Вообще вы можете использовать кучу разных вариантов, чтобы хранить секретные данные в вашем репозитории. Некоторые из них:

1. ExternalSecretsOperator - https://external-secrets.io/v0.8.2/. Логика такая. Ставим его в кубер, настраиваем подключение к внешнему источнику секретов (vault, lockbox, etc..). Далее ESO периодически синкает секреты из внешних источников и сохраняет их в Secret в кубере, который вы можете использовать.
2. SealedSecrets - https://github.com/bitnami-labs/sealed-secrets - решение от битнами. Суть такая. В кубере запускается sealed secrets, который отдает наружу только public key. С помощью kubeseal cli вы можете трансформировать любой Secret в зашифрованный SealedSecret и положить его в git репозиторий. После применения в кубе, SealedSecrets трансформирует SealedSecret обратно в Secret, который вы можете использовать.
3. SOPS - https://github.com/mozilla/sops - sops / ksops / helm secrets - все идет сюда. Суть такая - мы шифруем yaml’ики локально и закидываем в git. Дальше наша ci система с помощью приватного ключа расшифровывает их и передает kustomize / helm или кому-то другому.
4. Argo Vault Plugin - https://argocd-vault-plugin.readthedocs.io/ - суть примерно как у скрещенного sops и external secrets operator, но только если вы используете argocd (хотя можно его и локально запускать на самом деле). Суть такая. Вы внутри secret или других yaml файлов ставите placeholders: <password>, которые заменит vault plugin. Взять данные для подстановки vault plugin может из sops файла, из kms или еще откуда-то. В общем удобно 🙂

Из всех вариантов выше мне нравится sops, поскольку он позволяет хранить секреты рядом с приложением (манифестами), а так же позволяет их легко менять при необходимости. То есть вам не надо придумывать а как же закинуть секретную строку в hashicorp vault (с помощью “ClickOps-Way”), при этом не положив ее в гит.

С ним бы мог поспорить только kubeseal, но тот не позволяет редактировать секреты локально. То есть вы можете их только зашифровать. Расшифровывать нельзя. И это реально неудобно - вам каждый раз придется пересоздавать секрет. А если учесть что в секрете может быть несколько переменных, а вам надо поменять только одну - то привет пока приехали.
👍17🔥10
Vasiliy Ozerov
Ох, читал тут статейку про ExternalSecrets Operator - https://hackernoon.com/cooking-helm-with-the-external-secrets-operator-and-reloader и у меня есть что сказать по этому поводу! Вообще вы можете использовать кучу разных вариантов, чтобы хранить секретные…
Небольшое дополнение к секретами, да и вообще в целом к безопасности.

После этого поста мне написали в личку примерно такое:

"Чем ближе ты расшифровываешь секрет к месту его использования, теб безопаснее система" (с) Дмитрий

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

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

Я со своей стороны могу сказать, что когда вы настраиваете любую систему вы всегда выбираете между безопасностью и удобством. Чем удобнее - тем менее безопасно. И наоборот. Поэтому я всегда придерживаюсь стандартных гигиенических правил из серии - все ресурсы храним внутри за vpn (gitlab'ы, куберы и тд), все сервисы общаются между собой по внутренней сети, желательно с каким-нибудь istio & mtls, вход на устройства по ключам ограниченному кругу лиц, разработчики не имеют доступа к системам - только к панелькам типа grafana (logs & metrics) и тд. Из вне доступны только те порты, которые используют пользователи - http & https. Для некоторых проектов правила могут быть намного жестче - например вообще отсутствие доступа из интернета. Но в каждой конкретной ситуации надо смотреть и оценивать риски - это главное.

Всем хороших выходных и отдельное спасибо Дмитрию за комментарий 🙂
🔥38👍29🙏1👨‍💻1👀1
Всем привет!

Тысячу лет не писал сюда, потому что просто не знал, что надо писать 🙂 Но теперь у меня появился повод. И этот повод позволит писать сюда намного чаще.

Как-то на вебинарчике я сказал: "Ща через пару недель будет Youtube". И вот, спустя 4 года, я наконец-то его сделал 😂 Вообще, конечно, я прямо долго мечтал и думал про это, и прикидывал как да что. Но все не доходили руки. И вот. Наконец-то! Встречайте - первый ютуб видос - https://youtu.be/kC1g1Z9G_XM.

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

Да, еще сделал отдельный телеграм-канал, где буду публиковать анонсы видосов и скидывать ссылки на используемые конфигурации - подписывайтесь - t.me/sysopslab. Думаю, туда же буду закидывать всякие интересности про инфраструктуру, а в остальных местах буду менее официальным.

Ну что! Смотрите и наслаждайтесь. Надеюсь, что вам понравится 🙂

P.S. В списке идей для сценариев 48 пунктов 🙂
🔥103👍23🫡94🎉3🥴3
Forwarded from SysOpsLab
Друзья, всем привет! Новости с полей.

Последние две недели писал сценарий про ssl сертификаты. Изначально думал сделать видос на 30 минут, чтобы повеселее было, но в итоге написалось 48 953 знаков 😂 В общем было принято трудно решение разбить этот сценарий на 3 части. Первая - про приватный CA и структуру сертификатов, вторая - про публичные центры сертификации и протокол acme. Ну а третья - про страх и боль отзыва сертификатов. Первую часть записываю сегодня - так что в начале следующей недели ждите на экранах :)

Чтобы вы не подумали что я только про сертификаты буду рассказывать - следующий видос будет про кубер. Self-hosted. Уже закупаю оборудование для лабы - надеюсь вам понравится. Но в 30 минут мы там навряд ли уложимся 😂

Ну а пока сценарии пишутся, оборудование закупается, а видосы монтируются у меня к вас есть просьба. Точнее просьба и предложение - “Давайте знакомиться!”. Вас в канале уже достаточно много, а я даже не знаю кто вы и чем занимаетесь, поэтому предлагаю заполнить данный опросик (на 2-3 минуты) - https://forms.gle/8RpWxuWWASxCYvnBA. Это позволит мне лучше понимать какие темы выбирать для роликов и в каком формате их делать. Спасибо всем кто пройдет! Кстати, внутри есть поле с комментарием - так что можете написать туда абсолютной любой фидбек. Опрос анонимный - почту и контакты оставлять не надо :)

Ах да, чуть не забыл. Мне тут предложили сделать формат random coffee. Сначала я отнесся к этому скептически, но потом поразмыслив понял что вообще прикольная идея. Не знаю правда нужна ли она кому-то, но если вдруг вы хотите познакомиться, поболтать, задать какие-то вопросы или высказать что-то лично, то я сделал два утренних слота в календарике - любой желающий может назначить нам встречу - https://calendly.com/vasiliyozerov/oneonone. Если вдруг затея окажется удачной - то возможно добавлю слотов в субботу или по вечерам.

Всех обнимаю, желаю хорошего дня и напоминаю про опрос - до встречи!
P.S. Фотка отсюда - https://soundbox.pro/hronometr/ (хоть и не читаю с суфлера, но все равно примерно оцениваю время)
🔥69👍64🐳2🫡2
Друзья, всем привет! Давно не виделись!

У меня сегодня будет небольшая просьба ко всем CTO и Тимлидам инфраструктурных команд, кто меня читает. А потом начнем постить всякие интересности.

Ребята в Февлейке сейчас пилят прикольную штуку, связанную с мониторингом. Если в двух словах - это про root cause analysis. Оно позволяет получать контекст и аналитику по алерту еще до момента, как вы откроете дашбоард в графане.

Решение само собирает контекст и подсказывает где стоит искать причину, тем самым позволяя быстрее восстановить сервис. Под капотом — LLM и интеграции через MCP, которые собственно и решают вопросы сбора контекста и рекомендаций.

Сейчас ребятам нужно провести 5-10 кастдевов с СТО и Тимлидами Девопсов, за это они дадут доступ на пол года, после релиза! У кого есть возможность выделить 10-15 минут на вопросы, заполните форму, и ребята с вами свяжутся.

Форма тут - https://forms.yandex.ru/u/6900a32c4936392a4e9377e5/
👍12👀10🤡8🔥31🤣1🤝1
Читал тут RFC по Model Context Protocol (MCP) и откопал интересную штуку. Там есть требование чтобы oAuth сервера, используемые для MCP должны поддерживать стандарт динамической регистрации клиентов (Dynamic Client Registration). Где-то я такое видел до этого, но не сталкивался. Поэтому пошел быстренько изучить, чтобы рассказать вам.

Начнем со статической регистрации. Обычно мы создаем OAuth-клиента вручную - идём в консоль разработчика, создаём приложение, указываем redirect_uri и другие параметры, а после - получаем client_id и client_secret. Эти креды мы можем использовать чтобы обменять пользовательский код (по authorization code flow) на токен. Вроде все просто и понятно.

А теперь - динамическая регистрация. Это когда клиент может сам себя зарегистрировать через API oauth сервера. То есть вместо того, чтобы идти в админку и создавать приложение, ты просто отправляешь POST-запрос на специальный url, описываешь параметры (редиректы, типы грантов, скопы и т.д.), а сервер возвращает тебе client_id, а иногда и client_secret.

Где взять этот url для регистрации и вообще понять поддерживает ли сервер этот стандарт? Оно описывается в http://.../.well-known/openid-configuration - параметры конфигурации openid, по которым клиент может получить все необходимые данные. Внутри есть параметр - registration_endpoint, который и указывает url, на котором можно зарегистрировать клиентов.

В общем это все подробно описано в RFC 7591. Есть даже надстройка — RFC 7592 — которая описывает, как клиент может обновлять или удалять свою регистрацию.

Теперь к вопросу нафига это нужно - ведь живем же сейчас и все отлично. Это конечно да. Но вот проблема в том, что клиент и oauth сервер знают друг о друге заранее. Пример. У вас есть мобильное приложение Spotify в appstore. Вы его скачали и внутри нажали кнопку Войти через Google. В Spotify зашит client_id, который они получили от гугла перед публикацией приложения. Собственно и все - все друг о друге знают и все отлично.

А теперь представим себе клиента для LLM, который так же находится в AppStore. Вы его скачиваете и точно так же входите через гугл - все работает по предыдущей схеме. Но дальше, вы хотите подключить MCP сервер, который ничего не знает про вашего клиента, а ваш клиент ничего не знает про него. Да и невозможно будет заранее разработчику LLM клиента зарегистрироваться во всех MCP серверах мира. И именно в этот момент и нужна динамическая рагистрация. Ваш клиент сначала сам регистрируется на oAuth провайдере, который обслуживает данный MCP (получает client_id), а уже после этого он может запустить стандартный OAuth flow. В рамках этого flow пользователь сможет спокойно залогиниться.

В общем полезная и нужная штука получается.
👍30🔥146🤯3😁1
Разбирали тут на вебчике service discovery у prometheusа - в целом как работает, зачем нужен и тд. Я показывал как можно использовать kubernetes_sd_configs, который позволяет собирать таргеты через Kubernetes API.

Я аж всплакнул если честно. Ну как же эта схема выглядит красиво. Вы просто настраиваете kubernetes_sd_configs:


scrape_configs:
# Задача для обнаружения подов
- job_name: 'kubernetes-pods'

# Конфигурация обнаружения сервисов Kubernetes
kubernetes_sd_configs:
- role: pod
# Конфигурация перемаркировки (Relabeling)
relabel_configs:
# Проверяем аннотацию prometheus.io/scrape
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true


И все! Остается только добавить аннотации на нужные поды 'prometheus.io/scrape: true' и все готово. Ну да, конечно - если промик запущен во вне, то надо еще api_server указать и token. И убедиться, что промик увидит ваши поды во внутренней сети кубера. Но если запускать внутри кубера, то никаких токенов настраивать не надо - промик будет использовать токен сервисного аккаунта, который ему подкинет кубер.

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

Kube-Prometheus-Stack добавляет некоторую обвязку к этому делу. Ну точнее Prometheus Operator, который в него входит. добавляет кастомные ресурсы - PodMonitor, ServiceMonitor и тд, которые вы можете использовать для настройки Prometheus. Например, вы создаете отдельный ресурс PodMonitor примерно такого вида:


apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: app
spec:
selector:
matchLabels:
app: app
podMetricsEndpoints:
- port: metrics
path: /metrics
interval: 30s
scrapeTimeout: 10s


Что происходит дальше. Когда вы добавляете PodMonitor из примера выше, Prometheus Operator видит это и генерируюет новую конфигурацию для Prometheus, в которой указываются kubernetes_sd_configs, relabel_configs и другие параметры. После этого он обновляет соответствующий ConfigMap. Дальше в дело вступает Sidecar config-reloader, который запущен в поде с prometheus сервером. Он видит обновление конфига и делает POST /reload на prometheus, чтобы тот перечитал конфигурацию.

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

Но это в общем я так - ностальгирую. Еще, кстати, откопал интересную штуку, которую как-то упустил - Agent Mode в Prometheus. В следующем посте расскажу.
🔥37👍235🐳2👏1🗿1
Рассказывал тут про Thanos и наткнулся на фичу для remote-write протокола в Clickhouse. Не спрашивайте как наткнулся. Случайно 🙂

Суть такая: у ClickHouse есть встроенные хендлеры для протокола Prometheus remote-write и remote-read. То есть промик может писать метрики прямо в ClickHouse, а при запросе старых данных — читать их обратно.

Включается это в конфиге ClickHouse примерно так:


<prometheus>
<port>9363</port>
<handlers>
<remote_write>
<url>/write</url>
<handler>
<type>remote_write</type>
<database>default</database>
<table>metrics</table>
</handler>
</remote_write>
<remote_read>
<url>/read</url>
<handler>
<type>remote_read</type>
<database>default</database>
<table>metrics</table>
</handler>
</remote_read>
</handlers>
</prometheus>


Подробнее вот тут - https://clickhouse.com/docs/interfaces/prometheus#remote-write.

И дальше в Prometheus надо накинуть эти настройки:


remote_write:
- url: http://host:9363/write
basic_auth:
username: user
password: pass
remote_read:
- url: http://host:9363/read
basic_auth:
username: user
password: pass


И все! Долгосрочное хранение в вашем промике у вас в карман - осталось только создать таблицу. А если еще учесть, что кликхаус позволяет сбрасывать холодные партиции на S3 (storage policies) (https://clickhouse.com/docs/integrations/s3#creating-a-storage-policy), то получается совсем хорошо.

Как работает эта штука? Prometheus отправляет все собранные данные по http на remote_write endpoint, а clickhouse складывает их в указанную таблицу. Когда клиент запрашивает у Prometheus период которого локально уже нет, Prometheus сам лезет через remote_read endpoint в clickhouse, а clickhouse возвращает исторические данные. Даже графану перенастраивать не придется.

К сожалению, такая схема никак не решает вопрос отказоустойчивости - тут все равно нужен Thanos. Ну или Victoria Metrics сразу. Но это решение явно более красивое, чем то, которое я использовал лет 7 назад с внешним сервером на golang.
🔥34👍204🙏1🤡1
Всем привет!

Хочу поделиться классной новостью и сделать небольшой подарок. Ну типа, чтобы понедельник не давал повода для грусти.

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

Ну и в общем я точно так же поступил в начале этого года, когда на одном из созвонов мне сказали, что у Yandex Cloud оказывается есть экзамен по облаку. С созвона я вышел сразу. И пошел записываться на сдачу. Я много и часто работаю с облаком, поэтому для подготовки я пробежался по документации, а в частности перечитал все разделы "Концепции", которые там были. Ну и удача мне улыбнулась и я успешно сдал экзамен (именно поэтому я люблю экзамены - чисто когда сдаю).

После этого мы еще запилили совместные вебинары с Яндексом по подготовке к сертификации и нараздавали промо кодов на сдачу. В общем прикольно получилось - мне понравилось.

Экзамен был большой. Реально большой. Там были основы облаков - типа стандартные базовые сервисы - VPC, Compute, IAM и так далее. Там были вопросы ближе к DevOps части - контейнеризация, кубернетесы, registry и так далее. Там было много вопросов про данные - postgresql, opensearch, redis и так далее. И даже serverless с AI не обошли стороной. Короче тем для изучения было достаточно много. Такой универсальный солдат получается.

И вот, ребята из клауда переработали экзамен и выкатывают обновленную версию, ориентированную чисто на DevOps инженеров. Список тем стал более компактным и нацеленным именно на девопсов. Вот тут можно глянуть список компетенций, которые подтверждает экзамен. Я, кстати, чуть-чуть поучаствовал в создании данной сертификации (совсем чуть чуть). Так что мне вдвойне приятно видеть эту новую версию.

И самое главное! Сейчас Yandex проводит пилотные экзамены, которые проходят абсолютно бесплатно! Больше информации можно найти здесь

Рекомендую всем, кто готов принять участие - скорее записываться. Для участия обязательно заполните вот эту форму (берут не всех).

Всем желаю удачи в прохождении! Закидывайте серты, которые вы получали 🙂
🔥19👍43🐳3
👍30🔥176👨‍💻1
День падений. Сегодня не работает Cloudflare. А еще говорят, что понедельник день тяжелый!

На самом деле это второе крупное падение за последнее время. В прошлый раз интернет положил AWS. У них там были хитрые проблемы с гонками, связанные с их внутренними DNS записями в Route53. Подробнее можно почитать вот здесь - https://aws.amazon.com/message/101925/.

Судя по Status Page от Cloudflare (https://www.cloudflarestatus.com/) у них возникли проблемы с WARP сервисом и его даже пришлось отключать в некоторых регионах. Суть сервиса простая - он позволяет защитить клиентские устройства с помощью VPN. Вы ставите WARP клиента, он подрубается к ближайшему дата центру Cloudflare и направляет весь трафик через него. Дальше вы через админку CF можете управлять правилами доступа и фильтрацией контента. Подробнее тут - https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/warp/.

Пока конечно не очень понятно как это связано с глобальным падением если честно. Возможно в деле замешан сервис фильтрации и просто из-за WARP на него пошла большая нагрузка. А возможно еще был затронут Zero Trust. С его помощью можно строить красивые сетевые схемы. В чем суть? Представьте что у вас есть Kubernetes или какой-то закрытый контур. И вы хотите пустить на него трафик из вне. Раньше приходилось получать внешний айпишник, роутить его на свой балансировщик и прокидывать запросы. Даже если вы в облаке - вы все равно создаете какой-нибудь Network Load Balancer и пропускаете трафик.

С Zero Trust все работает наоборот. Вы просто ставите в свой кубер или в свою инфраструктуру cloudflare tunnel (https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/), который подключается к ближайшему дата центру Cloudflare и дальше вы можете роутить трафик через cloudflare на свои внутренние ресурсы. То есть у вас может не быть никаких внешних адресов или чего-то такого. Cloudflare сам примет запрос из вне, затерминирует TLS и дальше по этому внутреннему туннелю отправит запрос к вам. Такой VPN наоборот.

И схема реально выглядела красиво. Ставим какой-нибудь контроллер ingress / gateway api в Kubernetes. Так же ставим cloudflared tunnel (можно через оператор - https://github.com/adyanth/cloudflare-operator). И в cloudflare настраиваем какую-нибудь запись в DNS: "www CNAME <uuid>.cfargotunnel.com". И все! Теперь пользователь, при обращении к www попадет на cloudflare, а тот в свою очередь направит трафик через cloudflare туннль на ваш контроллер в kubernetes. Никаких тебе cert-managerов.

Короче не знаю что там происходит с Cloudflare, но зато я вам рассказал немного про Zero Trust! И ждем итогового постмортема - будет интересно.
👍45🔥15🌚6🫡4
Постмортем от Cloudflare подъехал. Исходники тут - https://blog.cloudflare.com/18-november-2025-outage/. А ниже я сделаю вольный перевод, чисто чтобы понять идею произошедшего.

Итак. Каждый запрос, идущий через Cloudflare, проходит примерно такой путь:

1. HTTP/TLS Layer - обработка запроса на внешнем уровне - сюда подключаются клиенты - браузеры, мобилки и так далее.
2. Core Proxy (FL/FL2) - это ключевой компонент, который Cloudflare называет FL (Frontline), или его новая версия FL2. Здесь отрабатывают все настройки, которые вы добавляете в дашбоард Cloudflare: WAF, DDoS-защита, маршрутизация и, что важно для этого сбоя - Bot Management.
3. Pingora - прокси сервис, который обслуживает кеш и забирает данные с вашего origin.

FL/FL2 - это две версии Frontline сервиса. И в момент инцидента они вели себя по-разному:
- FL2 (Rust) - Вторая версия. Принял на себя основной удар и начал возвращать пятисотые из-за паники (`panic!`)
- FL (Старая версия) - сбой проявился мягче — он не выдавал 5xx, а просто часть функционала не работала. При этом трафик продолжал ходить.

Здесь конечно кажется, что второй вариант с частичным отказом является более логичным решением. Но, возможно, есть какая-то бизнес-логика, которая требует останавливать трафик в случае проблем. В любом случае - тут решать только CF. Кстати, хочется отдельно отметить, что FL2 написан на Rust. И Pingora написана на Rust. Что-то похожее я видел только у Linkerd - https://linkerd.io/ - у них прокси sidecar написан на Rust.

Собственно что происходило дальше. Внутри Core Proxy есть система Bot Management, которая проставляет оценку каждому запросу - бот он или нет. Для принятия решения используется модель машинного обучения. Моделька на вход требует файл конфигурации - feature file, который содержит список признаков, используемых для предсказания. Этот файл обновляется раз в 5 минут.

С ним-то и возникли проблемы. В модуле Bot Management (внутри FL) был установлен жесткий лимит в 200 фич, которые могли содержиться в этом файле. Этот лимит нужен был для предварительной аллокации памяти - короче ради оптимизаций производительности. И вот вдруг этот файл удваивается в размере и FL2 начинает падать с паникой, потому что превышен лимит в 200 строк.

Так почему же этот файл вырос в размере в два раза? Данные для этого файла берутся из Clickhouse базки. Структура базки верхнеуровнево достаточно простая. В базе default лежат distributed таблички, которые смотрят на таблицы в базе r0. Кто не знаком с CH сейчас кратко поясню. В CH есть разные типы движков для таблиц (считайте что разные типы таблиц). Одни - это условно обычные таблички, которые хранят данные. Вторые - это мета-таблицы, которые смотрят на первые таблицы. Они имеют тип - distributed. Это нужно для шардирования. Вы можете сделать один запрос к мета-таблице (distributed), а кликхаус раскидает его на все таблицы с реальными данными во всех шардах. Ну это если очень упрощенно. Главное здесь понимать, что мета-таблица (distributed) и реальная таблица (с данными) имеет одну и ту же структуру - колонки, типы и тд.

А теперь посмотрите вот на такой запрос. Его выполнял bot management раз в 5 минут для формирования файла с фичами (ну не прямо весь запрос - главная его часть):


SELECT
name,
type
FROM system.columns
WHERE
table = 'http_requests_features'
order by name;


Этот запрос вытаскивает информацию об именах и типах колонок для конкретной таблицы. И все было хорошо, пока пользователь имел права только на default базу, а соответственно только к distributed таблице. Таким образом данный запрос возвращал name и type только для одной таблички - http_requests_features в базе default. Ну а дальше ребята из CloudFlare меняли права доступа и у пользователя, под которым выполняется этот запрос появился доступ к реальным таблицам в базе r0. И он тут же начал возвращать name и type для двух идентичных таблиц - мета-таблицы и реальной таблички. Это привело к удвоению данных в feature файле, а потом и к панике, как вы уже знаете.
👍36🔥267
Кстати, прикольно, что в момент раскатки новых прав доступа часть кластера Clickhouse возвращала правильные данные, а часть нет (не везде права обновились). И поэтому иногда feature файл генерировался правильно, а иногда нет. Ну а когда раскатали конфигурацию на весь кластер, то все окончательно и упало.

При этом Cloudflare держался 6 лет без таких критических сбоев, что очень круто. Хотя какие-то небольшие вроде были. Но в любом случае надеюсь без падений в ближайшее время. И на последок закину прикольную статью в их блоге про то как у них все устроено внутри - https://blog.cloudflare.com/20-percent-internet-upgrade/. Почитайте 🙂
👍38
Вот это я новость тут увидел!

Захожу короче в Yandex Cloud чтобы создать кубер кластер и добавить пару узлов для тестов. И тут бах! Раскрывающийся список типа какие узлы ты хочешь - облачные или внешние. Ничего себе заявление.

Пошел искать информацию. И действительно - теперь в Yandex Cloud можно добавлять собственные внешние узлы к облачному куберу. Вот дока - https://yandex.cloud/ru/docs/managed-kubernetes/concepts/external-nodes?utm_referrer=https%3A%2F%2Fwww.google.com%2F. Датирована 5 ноября 2025 года. Дата, кстати, красивая.

Судя по доке надо подключиться к облачной сети yandex'а через interconnect или ipsec/wireguard и получить айпишник из сети клауда. Ну а дальше просто добавляем внешние узлы в наш кластер.

Выглядит супер! На следующей неделе пойду тестировать.
🔥37👀7❤‍🔥4👨‍💻3👍2🤔2🤡2👾21
This media is not supported in your browser
VIEW IN TELEGRAM
🍾59🎄41🤝1311❤‍🔥2🙏1😈1🦄1