Make. Build. Break. Reflect.
907 subscribers
115 photos
1 video
119 links
Полезные советы, всратые истории, странные шутки и заметки на полях от @kruchkov_alexandr
Download Telegram
#aws #eks #kubernetes #bottlerocket #troubleshooting

Case:
AWS EKS, Bottlerocket AMI. Случайно уронили коллектор логов, сбора не было несколько часов, но логи нужны прям сейчас. Если коллектор починить, то ждать долго(кстати какого фига долго я хз).
Нужных логов в поде нет, в ArgoCD их тоже нет(логично же).
Как быть?

Можно слить с EKS node(s), но этот путь не очевидный, ведь у нас Bottlerocket.

Для начала нужно быть уверен, что вы включали админ доступ в TOML конфиге.*
# Доступ к системным логам, получению root-оболочки (sheltie), запуску journalctl, logdog и пр.
[settings.host-containers.admin]
enabled = true

# Доступ к Bottlerocket API для настроек и диагностики, но без глубокого доступа к логам и файловой системе ноды.
[settings.host-containers.control]
enabled = true

Ок, админ доступ включён.
Смотрим на какой ноде запущен наш под.
kubectl get pods -o wide | grep podname
... ip-10-1-114-226.ec2.internal ...

Узнаем айди инстанса.
kubectl get node -o yaml ip-10-1-114-226.ec2.internal | grep -A4 -i "nodeid"
... "i-09cd72826bee50209" ...

Подключаемся к инстансу через SSM
aws ssm start-session --target i-09cd72826bee50209

Сейчас нет никаких прав, переходим в админа.
enter-admin-container

Ок, мы стали админами(через контейнер), теперь нам нужен шелл - шелти.
[root@admin]# sudo sheltie

Дальше просто смотрим в /var/log/
ls /var/log/containers/
argo-cd-argocd-application-controller-0_argo-cd_application-controller-dfb4d12f601e71ac373b30bfaad8d02b56141218e7bcc5f1358f3a7d8f7df7f7.log
...

Ну и смотрим логи
cat argo-cd-argocd-application-controller-0_argo-cd_application-controller-dfb4d12f601e71ac373b30bfaad8d02b56141218e7bcc5f1358f3a7d8f7df7f7.log


"но Алекс, нам нужны все логи, как их слить к себе локально?"

Ок, запускаем сборку логов в шелти
bash-5.1# logdog

После коллекции у нас логи хранятся на ноде в
logs are at: /var/log/support/bottlerocket-logs.tar.gz

Теперь со своей локальной машины дёргаем их к себе через k8s API (да-да, я тоже не знал)
kubectl get --raw "/api/v1/nodes/ip-10-1-114-226.ec2.internal/proxy/logs/support/bottlerocket-logs.tar.gz" > ./bottlerocket-logs.tar.gz

У нас локально теперь все логи в bottlerocket-logs.tar.gz
Задача решена.**


* Если изначально админ доступ не включён, то всё не ок. По идее если его включаешь в момент задачи, то ноды пересоздаются и старые логи с нод исчезают в пучине небытия и бездны. Тогда уж лучше ждать окончания работы починенного коллектора логов.

** При необходимости повторить для других нод, если исторически старый под был запущен на других нодах.
👍85🔥3
#пятница #всратость

Интервью где-то в параллельной вселенной.


- Переходим к следующему вопросу. Что происходит, когда вы вводите команду kubectl apply -f file.yaml?
-
kubectl: command not found

- А, ладно, допустим установлен. Попробуем снова.
-
error: the path "file.yaml" does not exist

- (Раздражённо) Нет-нет, файл точно есть.
-
error: You must be logged in to the server (Unauthorized)

- (Устало) Так, у нас есть все бинари, ямл и контекст
-
Unable to connect to the server: dial tcp 10.0.0.1:443: i/o timeout

- (обречённо) Да что же вы мне всё путаете, ок, есть файлы и контекст и доступ по сетке с VPN и с RBAC проблем нет
- Хорошо,
kubectl apply по умолчанию использует Server-Side Apply, если не ошибаюсь с Kubernetes 1.23, где сервер разрешает конфликты полей через field managers. На клиенте YAML конвертируется в JSON для отправки на API-сервер. В случае client-side apply добавляется аннотация last-applied-configuration для 3-way merge. После получения запроса API-сервером объект проходит через mutating admission controllers и затем validating admission controllers, прежде чем сохраняется в etcd. В etcd данные хранятся в protobuf, а каждый write увеличивает resourceVersion - счётчик версий, который контроллеры используют для optimistic concurrency control, избегая race conditions.
Затем...

- (удивлённо прерывая) Стоп-стоп, эээ... я вообще думал про шедулер и поды с кублетом..
- До этого мы ещё даже не дошли. Могу предложить перейти сразу к продакшн-кейсам по вашей вакансии для ведущего инженера, а не к тесту на внимательность и глубокое ныряние в омут, в котором, порой, можно потонуть всем и сразу?
- Да-да, пожалуй вы правы, мне стоит пересмотреть точность и корректность вопросов практикующим инженерам..
👏22😁153
#байки #troubleshooting #kubernetes #openshift

В далёком уже 2020-2021 я пилил обучающие онлайн видео для компании, где работал.
Ну типа внутренние онлайн видео встречи "что такое кубернетес/опеншифт" на минималках для ВНЕШНЕЙ компании-партнёра из другой страны. От моей компании передача знаний другой компании-партнёру.
Ничего интересного там не было, общий концепт куба, общие уровни абстракции и так далее.
Помимо этого были куски про CICD и так далее от коллег по компании.
В общем "DevOps онлайн уроки на минималках", галопам по европам skill-опам.

Одна из частей уроков была подготовка стенда во внутренней сети компании для студентов, чтобы они вживую всё это потыкали и сделали ДЗ.
Этим занимались системные администраторы(крутые ребята, между прочим!) внутри компании.
Установили GitLab, OpenShift, TeamCity, Nexus OSS etc.
Мы, "преподаватели", лишь дали указания, что нам надо, количество нод, версии и всё.
Когда админы всё подготовили, нам дали лишь эндпойнты и креды.
Нам лишь надо было подготовить домашки и всё проверить самостоятельно.

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

Сидим, оба "преподавателя" и хлопаем глазами*, как сельские дурачки🤡.
Признаться над своей некомпетентностью стыдно. Даже самому себе.

Потом, меня, внезапно, осеняет. Говорю:
- "а как ты проверял от себя локально? Какие команды вводил?"
- "ну докер билд, докер пуш, докер пулл для проверки"
- "а какой рантайм у опеншифта?"
- "ну cri-o
вроде"
Ага, проверяли-то мы по-разному.

Иду к админам, тихонечко спрашиваю:
- "а случаем нет ли какого балансёра перед реджистри?
- "ну как нет, конечно же есть, у нас по регламенту должен быть балансёр"

Бегу в github, качаю нужные бинари крио, канико, докера, подмана и так далее.
Запускаю пулл с каждой из них, в фоне гоню tcpdump.
У всех разный user-agent 🐒. Сука.

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

Зачем нужен был балансёр перед реджистри внутри закрытой корпоративной сети, с фильтрацией по юзер агенту, я так и не узнал, сперва забыл спросить, а потом и вовсе тот админ покинул компанию, а спустя год и я ушёл.🤷🏽‍♂️

* да, вот такие "преподаватели" порой участвуют в преподавании.
Ради лишнего гроша участвуешь и не в такой активности компании
😭.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁13👍1
#troubleshooting #aws #ssh #retool #paranoia #linux

Есть такая штука, называется retool https://retool.com/
Какая-то платформа для менеджеров, я ей не пользовался никогда в бизнес уровне.
В UI интерфейсе мышкой подключаются resource и на их базе могут строятся какие-то таблички, панели и прочая не интересная мне информация для менеджеров и сейлзов(наверное).
Resources чаще всего это база данных. Например MySQL или PostgreSQL. У retool тысячи их для любых интеграций.
Это всё, что надо знать для начала, идём дальше.

В основном Retool из интернета подключается к вашим ресурсам либо напрямую по hostname, либо к AWS через IAM credentials, либо через SSH bastion host.
Первый случай я не знаю для кого, у меня пока не было опыта публичных БД, второй способ мне не нравится, да и не пройти с ним SOC2 аудит, так что у нас только третий вариант - через ssh tunnel.

У них есть вполне годный гайд https://docs.retool.com/data-sources/guides/connections/ssh-tunnels, который подойдёт для 99% случаев.
Создаётся пользователь на бастион хосте(например через ansible или руками), добавляется их ssh public key, раскидываются права - всё готово. В общем всё по инструкции.
При подключении ресурса вы в UI указываете ваш bastion хост, порт и прожимаете test connection.
Если всё ок- ошибки нет. Не ок - ошибка.
Ошибка чаще всего дурацкая, потому что открывается какой-то аналог developer tool и показывает длинный стактрейс.

С retool я уже работал, подключал на проект много лет назад.
В то время в качестве бастион хоста была убунту 18 вроде и мне пришлось промучить весь стакоферфлоу, чтобы найти решение для себя при ошибке, мне не хватало
PubkeyAcceptedKeyTypes +ssh-rsa

Ровно после этого в официальной документации и появился этот совет, если коннекта нет.
Написал им в поддержку, чтобы поправили мануал для глупеньких я.
Тогда подключили какие-то бд, я сидел дальше ковырялся с конфигами, безопасностью, со временем обложил всё секьюрити группами типа
resource "aws_security_group" "bastion" {
...
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
# https://docs.retool.com/data-sources/reference/ip-allowlist-cloud-orgs
# retool ip ranges only
# tfsec:ignore:aws-ec2-no-public-ingress-sgr
cidr_blocks = [
"35.90.103.132/30",
"44.208.168.68/30",
"3.77.79.248/30"
]
description = "SSH access from allowed IP ranges"
}
...

Потом добавились секюрити группы по MySQL/PostgreSQL типа
resource "aws_security_group_rule" "this" {
type = "ingress"
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = ["*********"]
security_group_id = aws_security_group.rds.id
description = "Allow PostgreSQL access from ***** VPC"
}

Так же сразу сделал отдельного пользователя в БД с чётко обрезанными правами.
Делал что-то ещё, и в целом был удовлетворён, что тварь какая-то ходит в мои сети.

Прошло много лет.

Ко мне приходят ребята инженеры, говорят хотят добавить новую БД для retool.
Уже подключена монга, mysql и всякое, а теперь надо и PostgreSQL.
Ок, говорю, ну там всё уже настроено - все ssh ключи, секьюрити группы и прочее - всё должно работать - другие то ресурсы(БД) работает до сих пор.
Берите креды и сами настраиваете, мы же договорились, что не должно быть боттлнека -девопса.
Они высылают скрин, что ошибка подключения. Я само собой не верю (бл, когда я научусь думать, что другие люди не глупее меня 🐒, баран самоуверенный).
Иду сам в retool, копирую все креды, создаю ресурс, но у меня тоже ошибка.
Извиняюсь перед ребятами, пилю тикет, начинаю разбираться.😭
Please open Telegram to view this post
VIEW IN TELEGRAM
😱3
#troubleshooting #aws #ssh #retool #paranoia #linux

Ок, что же говорит ошибка. Текст типа
Test connection failed (120.327s):(SSH) Channel open failure: open failed
{query: "Connect Request", error: Object}
query: "Connect Request"
error: Object
message: "(SSH) Channel open failure: open failed"
data: Object
reason: 1
name: "Error"
message: "(SSH) Channel open failure: open failed"

и дальше огромная простыня трейса.
А ничего она не говорит, и так понятно, ясно понятно, нет подключения.
Прохожу снова по инструкции - всё ок.
Проверяю не менялся ли паблик ключ? Не менялся.
Не менялся ли пул публичных адресов? Не менялся.
Блин, ну я же не дурак.
Добавляю руками свой IP на секьюрити группу, подключаюсь на бастион хост и оттуда делаю телнет и подключение через cli к PostgreSQL.
Сетевая связность есть, коннект.
Проверяю ещё раз все секьюрити группы, поиск по коммитам, всё отлично.
Так, стоп, а предыдущие то ресурсы работают?
Захожу в retool, в давно созданные ресурсы - тест проходит ок.

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

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

Спустя время дошёл до конца файла /etc/ssh/sshd_config перебирая по одному все включённые параметры, а там.... а там парам-пам-пам!
А там паранойя, ну прям рили паранойя.
# bastion host 1.2.3.4

cat /etc/ssh/sshd_config |grep -v "^#"
...
Match User retool
PermitTTY no
AllowTcpForwarding yes
PermitOpen mysql.amazonaws.com:3306 docdb.amazonaws.com:27017
ForceCommand /bin/echo "Shell disabled!"

Я даже сам забыл про эту паранойю!

В общем добавляю очевидное
...
PermitOpen mysql.amazonaws.com:3306 docdb.amazonaws.com:27017 postgresql.amazonaws.com:5432
...

Перезапускаю
sudo systemctl restart ssh

и Voilà! - коннект от retool есть.

Описываюсь ребятам, они подтверждают, закрываю задачу.

Какая же мораль? Как обычно:
- не думай, что остальные глупее тебя, если пишут ошибка есть - значит она есть!
- вспоминай о своих параноидальных привычках, прежде, чем тратить время
- держи конфиг sshd в IaC (ansible например), а не руками заполняй, баран. Поиском по iac я быстро увидел бы причину

* адреса endpoints к БД само собой должны быть полными и длинными, короткие URL лишь для примера
2🔥10
#troubleshooting #billing #CostOptimization #newrelic

Внезапно вырос ценник на newrelic.
Заметили не сразу, не было настроены алерты по биллингу.
Увидели лишь в начале месяца, при выставлении счёта.

Я не сильно тогда был знаком с newrelic, этой штукой обычно пользовались коллеги-разработчики, я больше по инфре и стеку с VM/Prometheus/Grafana, но деньги есть деньги, надо разбираться.

Поковырявшись в интерфейсе и немного документации, обнаружил, что деньги начали списываться в раздел логирования.
А ведь это странно, все логи у нас пишутся в ELK стек в самом кубе, зачем ещё и в newrelic писать, а там за каждый чих деньги просят.

Первым делом смотрю в ньюрелике кто именно пишет логи - ага, одно единственное приложение.
Иду в git, захожу в раздел PR, вижу там миллиард PR, закрываю, ибо даже с поиском ничего не найти.
Клонирую репозиторий, смотрю локально.
Ага, у нас агент newrelic ставится через Dockerfile
ENV NEWRELIC_VERSION 11.6.0.19
...
ADD https://download.newrelic.com/php_agent/archive/${NEWRELIC_VERSION}/newrelic-php5-${NEWRELIC_VERSION}-linux.tar.gz /tmp/
RUN export NR_INSTALL_USE_CP_NOT_LN=1 NR_INSTALL_SILENT=1 \
&& tar -xf /tmp/newrelic-php5-${NEWRELIC_VERSION}-linux.tar.gz -C /tmp \
&& /tmp/newrelic-php5-*/newrelic-install install \
&& rm -rf /tmp/*
...

Дальше ковыряюсь в конфигах самого приложения, но там ничего интересного.
Нет в явном виде "логирование енаблед тру" или подобного. Странно.
Ладно, ну поехали, смотрим через git кто когда вносил изменения в докерфайлэ, всё равно другой зацепки нет.
git log Dockerfile

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

Ладно, иду в POD, смотрю конфиг, а что внутри
cat /usr/local/etc/php/conf.d/newrelic.ini

и поиском вижу там нечто типа
newrelic.application_logging.enabled = true

Пилю себе ветку, в этой ветке делаю даунгрейд до старой версии newrelic, собираю имадж, смотрю в нём конфиг
newrelic.application_logging.enabled = false

Да бл.

Бегу в документацию и нахожу
https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/
PHP agent version 10.1.0 lets you forward your PHP logs with APM logs in context. As of version 10.3.0, the logging metrics and agent log forwarding features are enabled by default. The value newrelic.application_logging.enabled controls whether or not the logs in context feature is active or inactive.

От суки, ладно, пилю быстрофикс (не удивлюсь, если он до сих пор там в докерфайле, лол).
RUN sed "s/^.*;newrelic.application_logging.enabled.*/newrelic.application_logging.enabled = false/" \
-i /usr/local/etc/php/conf.d/newrelic.ini

Качу PR, аппрув, мерж, логи перестали идти в newrelic, прайс не растёт.

Ну а дальше как обычно: оповещение коллегам, ата-та так не делайте плиз, читайте доки перед апдейтом(да ладно, кому я вру, я бы тоже не читал), вот рут коз, вот фикс, вот ссылки, вот пруфы.
Все виновато покивали и сделали вид, что запомнили и не повторят ошибок. Да.

Потеря денег всего $460 за пару недель.
Идём работать дальше.
5👍191
Make. Build. Break. Reflect.
#пятница #байки #troubleshooting Задолго до работы в айти я был простым советским инженером спутниковой связи. Тарелки, антенны, модемы, кабели, бесконечные командировки. В то время случалось масса странных историй. Мы разрабатывали спутниковое оборудование…
#пятница #байки #troubleshooting

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

Приезжаю. Место знакомое. Смотрю на антенну: стоит та же, что и пять лет назад. Только вот когда её ставили - перед ней было чистое поле. А теперь в нескольких метрах перед приёмником выросло почти дерево.
Сначала были слабые ростки, ветер шатал - появлялись помехи на канале, потом выросли кустики - помех стало чуть больше при ветре, а потом почти полноценный ствол с кроной. И он, как назло, при ветре и шатании кроны в самый азимут упирается. Догадаться, что спутниковая антенна должна видеть спутник напрямую, никто не удосужился. Стоит же железка - пусть работает сама по себе. Раньше же всегда работало. Они то сами ничего не меняли, да.

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

Иногда проблема не в людях, железках и кабелях, а в природе, которая растёт где хочет.
Без разрешения начальства и согласования с отделом связи.
Наверное, считает себя самым главным интегратором на объекте.
2😁32
#grafana

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

Где взять дашборды Grafana в 2025, как и с чего начать с нуля.


1) Скачать любой stack helm chart
aenix, victoria metrics, prometheus
- просто установить в миникуб/кубер, зайти в графану и откуда слить интересующие дашборды
- удалить stack

Если не хочется установить, то просто слить сразу директории и файлы. Пример:
helm pull oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack --untar

Все дашборды лежат в
kube-prometheus-stack/templates/grafana/dashboards-1.14
├── alertmanager-overview.yaml
├── apiserver.yaml
├── cluster-total.yaml
├── controller-manager.yaml
├── etcd.yaml
...

Внутри YAML лежит JSON.
Минус варианта:
надо будет ещё и records за собой утащить - большая часть дашбордов используют не стандартные метрики.

2) Официальные и community репозитории:
- https://grafana.com/grafana/dashboards
- https://play.grafana.org/dashboards (всякие demo, поиском искать по ключевым словам)
- https://grafana.com/orgs/victoriametrics/dashboards
- https://github.com/monitoring-mixins/website/tree/master/assets
- https://github.com/dotdc/grafana-dashboards-kubernetes
- https://github.com/voidquark/grafana-dashboards

3) Специфик репозитории. Само собой их больше, тут как пример.
- https://github.com/tarantool/grafana-dashboard
- https://github.com/cloudnative-pg/grafana-dashboards
- https://github.com/percona/grafana-dashboards
- https://github.com/temporalio/dashboards

4) Просто по тегам гитхаба (обычно по звёздам сортировать и брать нужное)
- https://github.com/topics/grafana-dashboards

5) GitHub поиск:
- Поиск по метрике (например, nginx_ingress_controller_requests, node_load5, trino_failuredetector_HeartbeatFailureDetector_ActiveCount etc.)
- Фильтрация по "dashboard" и "json"
- Сортировка по звёздам, дате, популярности
- Вытаскивать нужные .json и импорт к себе
Пример: https://github.com/search?q=rate%28nginx_ingress_controller_requests+language%3AJSON&type=code&l=JSON

6) Для новых/непопулярных проектов можно делать так.
Сделать port-forward на сервис, скопировать все метрики(обычно по пути /metrics), вставить в любую нейронку, попросить нечто типа "вот все метрики по %продуктнейм%, сделай мне общую графана борду, типовые сценарии использования, дальше поправлю сам".

Бонус-инфа:
7) Необычный проект для синка clickops/IaC по бордам
- https://github.com/grafana/grafana-git-sync-demo
🔥24311👍1🤡1🤝1
If you upgraded to macOS Tahoe and it feels super slow, you can disable transparency by going to System Preferences > Accessibility > Display and checking "Reduce transparency"

My mac had been terrible since I upgraded, but after doing this it improved a lot.

Why did I even update the fckng OS?😭
Please open Telegram to view this post
VIEW IN TELEGRAM
1😁6💯6
#aws #azure #gcp #kubernetes

Допустим вы сменили место работы.
На новом месте GCP, Azure, AWS. Миллионы куберов.
Разные тенанты, разные сабскрипшны, разные профили, разные аккаунты, разные регионы.

Ваше железо с нуля, в нём пока нет ничего (а зачем старое со старых работ тащить?)
Надо установить утилиты, Надо обновить кубконфиг.
Чтобы видеть сразу всё и сразу (из доступного по правам).

Первым делом ставим asdf.
https://github.com/asdf-vm/asdf/releases
Затем добавляем тулзы.
cat ~/.tool-versions

kubelogin 0.1.4
helm 3.17.0
dive 0.12.0
sops 3.9.4
terragrunt 0.54.15
terraform 1.5.3
kubectl 1.29.0
awscli 2.31.6
aws-sso-cli 2.0.3
kubectx 0.9.5
eksctl 0.215.0
azure-cli 2.77.0
jq 1.8.1

Апплаим (у меня это алиас asdfu)
cut -d' ' -f1 ~/.tool-versions | xargs -I{} asdf plugin add {} && asdf install

Теперь у нас есть все необходимые утилиты

Затем конфигурируем один раз профили(если есть).
aws configure sso 
# или
aws configure sso --profile profilename
az login


Теперь нам надо один раз залогиниться в ажур и амазон.
Где-то достаточно
az login и aws sso login
где-то разово надо попрыгать по профилям
aws sso login --profile profilename

Мы залогинились во все тенанты, все подписки, все аккаунты.
Как теперь в автоматике собрать все кубконфиги?
На помощь нам приходит любимый bash ❤️.

AWS (пример)
account_id=$(aws sts get-caller-identity --query Account --output text)
eksctl get cluster --all-regions -o json | jq -r '.[] | [.Name, .Region] | @tsv' | while read -r name region; do
aws eks update-kubeconfig \
--name "$name" \
--region "$region" \
--alias "${account_id}_${name}-${region}"
done

Azure (пример)
origin_context=$(kubectl config current-context)
original_subscription_info=$(az account show --query '{id:id, name:name}' --output json)
original_subscription_id=$(echo "$original_subscription_info" | jq -r '.id')

subscriptions=$(az account list --query "[].id" --output tsv)
for subscription in $subscriptions; do
az account set --subscription "$subscription"
clusters=$(az aks list --query "[].{name:name, resourceGroup:resourceGroup}" --output json)
for cluster in $(echo "$clusters" | jq -c '.[]'); do
cluster_name=$(echo "$cluster" | jq -r '.name')
resource_group=$(echo "$cluster" | jq -r '.resourceGroup')
az aks get-credentials \
--resource-group "$resource_group" \
--name "$cluster_name" \
--overwrite-existing \
--context "${subscription}_${cluster_name}"
kubelogin convert-kubeconfig -l azurecli
done
done
kubectl config use-context "$origin_context"
az account set --subscription "$original_subscription_id"

Это пример логики скриптов.
Можно изменять под любые цели, мне в целом удобнее формат алиасов кластеров
# AWS
<account_id>_<cluster_name>-<region>
# Azure
<subscription_id>_<cluster_name>-<region>

Алиасы каждый пилит сам под себя - как кому удобнее.
Можно даже добавлять суффикс, что за кластера
# AWS
eks-<account_id>_<cluster_name>-<region>
# Azure
aks-<subscription_id>_<cluster_name>-<region>

Очевидно, что если аккаунт один, подписка одна и регион один - сложный нейминг не нужен.

Теперь наше рабочее место настроено и в любой момент времени можно обновить актуальные кластера всех провайдеров, всех тенантов, подписок, аккаунтов и даже всех регионов.

Вводим kubectx, видим огромный список всего.
> kubectx

aks-98765-98765-98765_stage-fake-centralus
aks-54321-54321-54321_dev-fake-eastus2
aks-12345-12345-12345_uat-fake-germanywestcentral
eks-123456789_dev-project1-us-east-1
eks-123456789_stage-project2-us-east-2
...

Cвичимся в нужное и поехали работать.

* в условиях разных SSO и корпоративных политик некоторые способы могут отличаться. Это лишь общий паттерн.

А доступ в GCP вам так и не дали 😀
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍16🔥4
#aws #opensearch #elasticsearch

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

Было три классических окружений(dev, stage, prod), все одинаковые по конфигу терраформ модуля, но отличающиеся по размеру стораджа, типу инстансов, шардам и количеству инстансов, на деве вроде был всего один.

Ну задача-то не сложная:
- обновил поля в индекс паттерне если есть конфликты (опционально, будет не у всех).
Если есть конфликты, то обновление на какую-то из версий опенсёрч не пройдёт
- обновить руками в UI на последнюю версию (раньше не даёт сразу обновить на опенсёрч) эластиксерч
- обновить руками в UI с эластик на опенсёрч
- обновить руками в UI одну или две версии опенсёрча до последней
UI‑апгрейт AWS OpenSearch происходит пошагово, без возможности пропуска промежуточных версий.
- поменять ресурс терраформа с
resource "aws_elasticsearch_domain" "elasticsearch"

на
resource "aws_opensearch_domain" "opensearch"

- выполнить удаление старого ресурса
terraform state rm aws_elasticsearch_domain.elasticsearch

- добавить новый ресурс импортом
terraform import aws_opensearch_domain.opensearch %domainname%

- прогнать терраформ план и поправить, где чего упущено (ну там новые названия переменных для .tfvars файла и типа того, не помню уже).
- проверить все дашборды в графане(есть ли метрики и не поменялись ли они), поправить если надо
- проверить все метрики для алертов и алерты, поправить если надо
- коммит и отправить MR

Не сложно, не правда ли?
Пока без каких проблем.

Однако в процессе миграции кто-то решил "а давайте ещё и SSO включим! Ну всё равно же апдейт!" 🤩.
SSO так SSO, правила диктуют боссы и стейкхолдеры.
К текущему плану добавляем новый ресурс нечто типа (могут быть опечатки, пишу на память и примерам)
resource "aws_opensearch_domain" "opensearch"
...
advanced_security_options {
enabled = true
internal_user_database_enabled = true
master_user_options {
...
}

и
resource "aws_opensearch_domain_saml_options" "saml"
...

- ну ещё там добавились всякие политики, роли и так далее. Я думаю это и так очевидно. Перечислять не буду.
- со стороны коллектора логов (Vector/VMlogs/fluentbit/Fluentd etc - выбор у каждого свой) добавилась ещё и авторизация - если УЖЕ включили SAML/SSO на OpenSearch, то для банальной отправки логов в хранилище будет авторизация.
- добавить 3 Azure enterprise application - на каждый из энвов, ведь Reply URL (Assertion Consumer Service URL) везде разный. Если был бы один опенсёрч на все энвы - был бы один аппликейшн.
- коммит и отправить MR, получить аппрув

Внесли в код, начали апплаить - а всё работает!
Коллектор логов шуршит, собирает логи, асьюмит роль, монтирует токен, цепляется к опенсёрчу, проходит авторизацию, аутентификацию и успешно делает PUT логов.
Пользователи отлично заходят на OpenSearch UI через SSO и всё работает.
На всё ушло около 4 часов чтения доков и вроде полутора-двух часов для апплая и отладки.

Ок, идём к Stage окружение, там повторяем примерно всё, что написано выше, правим мелкие недочёты если есть.
Почти не было кода, лишь просто выполнять команды в порядке, описанном в тикете.
На всё ушло вроде меньше 2 часов.
Всё так же работает.
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍3
#aws #opensearch #elasticsearch

Поехали к проду 🍷
Объявили время на апдейт, утвердили даты на выходные, ну а когда же.
Время апдейта? А время апдейта я написал, что "да за 6 часа управимся!"🐒🐒🐒
О, как же я ошибался в сроках.😭

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

Пристегните ремни, а теперь объявляем реальное время апгрейда😁:
- первый этап обновления до последней версии эластиксёрча - 12 часов.
- обновление до опенсёрча - 19 часов.
- обновление до последней на тот момент времени версии опенсёрча - 15 часов.
- включение SAML и авторизации - 18 часов.
- переиндексация (а потому что смотри первый пункт) - 49 часов.
На стейдже и деве не было конфликтов, а на проде не хватало полей и после апдейта просто рефреш не помогал, помогла только реиндексация всего. Поиндексно.

Подводим итоги:
вместо "да тут приключения на 20 минут", миграция заняла больше недели.
Я же не могу постоянно быть у ПК, а значит процесс запущенный днём, мог завершиться в 2 ночи, но я у ПК только в 10.00 утра, на этом тоже потеря времени.
Всю неделю логи были то доступны, то нет, во время обновления SAML вообще не было ничего доступно - доступ без пароля УЖЕ не работал, но доступ по SSO ЕЩЁ не работал.

Написание плана и кода вообще - не сложно.
Адекватно оценить сроки апгрейда прода - сложно.
П - планирование. 🚬

- - - - - - -

"К чему эта заметка, Алекс?" - спросите вы.
А всё просто: календарь напомнил, что через месяц заканчивается стандартная поддержка - самое время обновляться.
Ссылка на детали тут: https://aws.amazon.com/blogs/big-data/amazon-opensearch-service-announces-standard-and-extended-support-dates-for-elasticsearch-and-opensearch-versions/
Там расписано всё и по OpenSearch, и по Elasticsearch.

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

РЕБЯТА, У ВАС ОСТАЛСЯ ВСЕГО МЕСЯЦ НА ТО, ЧТОБЫ ЗАПРЫГНУТЬ В ЭТО УВЛЕКАТЕЛЬНОЕ ПУТЕШЕСТВИЕ МИГРАЦИИ ВСЕГО НА 6 ЧАСОВ! 😀
Please open Telegram to view this post
VIEW IN TELEGRAM
1😁14🔥51🫡1
#delimiter #separator

Заметка для самых-самых маленьких.

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

Итак, Delimiter. Separators. Разделители.
Наверняка вы замечали, что в консоли/редакторе можно выделить по разному слова:
- выделив мышкой от начала слова до конца
- двойной клик (или хоткеи клавишами в редакторе)

Но при двойном клике в разных случаях и разных слов поведение разное.
Даже тут, в Telegram, с ПК, при двойном клике будет разное выделение.
Попробуйте!
asdf-qwer
asd—1234 (а вот тут уже выделяется всё)
asdf/fdsa
1234.4321
asdf_1234 (да, и тут будет выделено всё)
as 1234a
as␣2345 (и снова выделяется всё)

Всё зависит какой есть delimiter в том месте, где вы это выделяете.

Он имеет право быть разным везде:
- в editor VSCode
- в console VSCode
- в terminal Windows 11
- в WSL terminal
- в SQL console
Да где угодно на самом деле. И настройки у всех могут быть разными, не зависящими от других.

В случае, если ваc не устраивает то, что выделяется в вашем рабочем пространстве, можно просто поискать в гугле или документации про delimiter или separator.

Например в Terminal Windows 11 дефолтный делиметр
 /\-()"'.,:;<>~!@#$%^&*|+=[]{}~?│

и он находится в пункте
Windows Terminal → Settings → Interaction → Word delimiters
Можно поменять, удалив символ дефиса (-), на
 /\()"'.,:;<>~!@#$%^&*|+=[]{}~?│

И после этого в вашем терминале, например в WSL Ubuntu, будут выделяться слова типа
eks-cluster-one  # тут, в телеграм, конечно же, не сработает, это ж пример для WSL


В VSCode, если мне не изменяет память, два пункта.
- один для editor
`~!@#$%^&*()-=+[{]}\|;:'",.<>/?

- второй для terminal
 ()[]{}',"`─‘’“”|


Не стоит стесняться: кастомизируйте рабочее место так, как вам удобнее.
Значения по-умолчанию не всегда удобны.

Для чего важно знать, что такое delimiter?
Потому что это напрямую влияет на скорость и удобство редактирования текста и кода.
Если изменить границы слова через настройку разделителей, то двойной клик мышью или сочетания клавиш вроде Ctrl + Shift + ←/→ начинают работать именно так, как удобно вам.
👍205🔥3👀3
#DNS #cloudflare

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

Надо было для одной задачи проверить кое-что.
Я в своём личном аккаунте CloudFlare купил домен, арендовал VPS на linode, создал рутовую A запись, поднял Nginx на 80 порту - всё ок.
Задача усложнилась, мне надо было 443 порт, а это сертификаты.

Очевидно нужно сгенерить, на ум приходит cert-bot, acme.sh.
Сперва я промучался с одним, потом с вторым, эти падлы не хотели генерировать мне серты.
Просидев с логами я понял, что конфликт в TXT записи _acme-challenge.<domain>.
Всмыыысле, подумал я, какие TXT, у меня ничего нет в DNS записях, только A.
Иду в UI, в DNS там только A record.
Но логи говорят об обратном.

Ладно, идём в dig.
dig _acme-challenge.domain.com +answer TXT 8.8.8.8

А там, бл, я правда есть TXT записи.
;; ANSWER SECTION:
_acme-challenge.domain.com. 297 IN TXT "blabla"

Гугл, изучение админки CloudFlare приводят меня в и к документации.

❗️Дефолтное поведение Cloudflare при покупке домена включает Universal SSL/Edge Certificate.
Cloudflare автоматически выписывает вайлдкард сертификат на 3 месяца.
Для подтверждения владения Cloudflare сам автоматически создает собственные TXT-записи с префиксом _acme-challenge.*. Эти TXT записи не отображаются в стандартном интерфейсе DNS-записей Cloudflare.
Их наличие можно подтвердить только через внешний DNS-запрос, например dig.
Айдишник от Cloudflare не совпадает с айдишником другой утилиты, вываливается ошибка, конфликт, нет серта.

Решение очевидное: отключить Universal SSL/Edge Certificate Cloudflare:
Перейти в раздел SSL/TLS → Edge Certificates .
Найти блок Disable Universal SSL(в самом низу) и нажать кнопку Disable Universal SSL
Подождать около 15 минут. Он ревоукнет сертификат и уберёт все не редактируемые неявные TXT записи.

Теперь можно работать с любыми генераторами сертов, кто челленджит владение DNS зоной через создание _acme-challenge.domain.

Тех, кто челленджит DNS через HTTP-01 Challenge, это поведение не аффектит.

* а бектики я не поставил, потому как телеграм глючит и любой код в этой заметке превращает в мусор из спецсимволов и тайский алфавит. Как, например, превращает TXT в TXT. Fixed.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍111👎1🤡1
#linux

Самое сложное это переступить свои привычки и стереотипы.

Начал карьеру с VSCode/vim/IDEA - привыкаешь с хоткеям, интерфейсу, удобству.
С браузером так же. Пересесть на другое - неудобно, непривычно, неохота.

По Linux утилитам тоже самое, одни плюсы: часть уже есть в операционной системе по умолчанию, часть ты знаешь так, что даже без нейронки и хелпа на память помнишь синтаксис.
cat, sed, ping, du, df, grep, awk

Зачем переходить на другое?
- Его надо отдельно ставить. Фу.
- Снова учить синтаксис. Больно, да.

Однако причины перейти всё же есть.
Скорость работы, удобство и новые фичи.
Конкретно для меня это user/human-friendly.

Для себя я нашёл эти и даже успел к ним привыкнуть:
cat ~/.tool-versions
...
jq 1.8.1
direnv 2.37.1
duf 0.9.1
dust 1.2.3
bat 0.25.0
yq 4.48.1
delta 0.18.2
...

Остальное тоже пробовал, но не прижилось.
Фигня для rustаманов-зумеров 😁.
Шучу, просто не зашло по задачам
🤡.

Ниже список репозиториев, где есть несколько современных утилит - замена/альтернатива привычных всем:
- https://github.com/ibraheemdev/modern-unix
- https://github.com/johnalanwoods/maintained-modern-unix

Как бонус (не замена, а просто общий список):
- https://github.com/agarrharr/awesome-cli-apps
- https://terminaltrove.com/list/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16
#troubleshooting #alertmanager

Заметка для самых маленьких.

Прилетает алерт "KubernetesStatefulsetDown".
Брр, ну ок, смотрю что не так.
А, понял! Судя по названию приложения statefulset, это же наш новый тестовый неймспейс test-project.
Там сейчас на пару месяцев будут тесты, нам не нужны эти алерты.
Можно добавить и сайленс, но сайленс работает лишь до первого рестарта алертменеджера и не хранит стейт.
Хочу полностью отключить все алерты на этом неймспейсе.

Иду в алертменеджер, добавляю рут в начале типа
      routes:
...
- receiver: 'null'
matchers:
- namespace = "test-project"
continue: false
....
тут дальше остальные руты на нормальные ресиверы

Применяю, всё ок.
Проходит час - снова этот же алёрт.

Может опечатка? Может конфиг поломанный?
Смотрим что у нас в логах vmalert/alertmanager.
kubectl logs vmalert-podname
...
... Rules reloaded successfully from ... yaml
...

Да не, время совпадает - применилось недавно мной.

Ладно. Идём в git к алёрту, смотрим что там у него в expr.
expr: kube_statefulset_replicas != kube_statefulset_status_replicas_ready > 0

Ну всё эээ понятно. Всё просто. Никаких вопросов.
Пока ковырялся, пришёл ещё алерт, такой же.

Не понял, иду в https://prometheus.io/webtools/alerting/routing-tree-editor/
Копирую туда часть конфига алертменеджера с рутами.
Дальше проверяю на namespace {namespace="test-project").
Матчинг, идёт в null, как и должно.

Бред, возвращаюсь в git к алерту.
Копирую expr
kube_statefulset_replicas != kube_statefulset_status_replicas_ready > 0

иду в prometheus/VM/grafana explore, вставляю:
Да, вижу респонс метрики с лейблами.
kube_statefulset_replicas
{
container="kube-state-metrics",
endpoint="http",
instance="10.0.115.164:8080",
job="kube-state-metrics",
namespace="test-project",
pod="kube-state-metrics-6794d79b55-sf879",
service="kube-state-metrics",
statefulset="fake-app"
}

Хм, всё есть - лейбл namespace и он не пустой.
По второй метрике так же есть лейбл namespace.
Но ведь магии не бывает (ну кроме тех случаях, когда руководство постоянно забывает про наши просьбы поднять зарплату, там точно магия поработала, не иначе)

В третий раз, словно старик закидывает невод в море, иду к алёртам. Теперь смотрю всё и сразу.
- alert: KubernetesStatefulsetDown
expr: kube_statefulset_replicas != kube_statefulset_status_replicas_ready > 0
for: 1m
labels:
...
severity: critical
namespace: '{{ $labels.namespac }}'
statefulset: '{{ $labels.statefulset }}'
...
annotations:
summary: ...

Сразу же видна причина, можно было бы и раньше увидеть🤡.

Зачем-то, скорее всего копипастой, был добавлен лейбл неймспейса. Дубль. С опечаткой в названии.
Лейбла namespac у нас нет в метрике, а значит пустым значением от namespac перетирается значение namespace.
В итоге до алёртменеджера алёрт приходил с пустым значением namespace и все рулсы рутов игнорировались(ведь нет матчинга).
Я такие случаи называю "broken downstream-routing".

Поиском поискал ещё опечатки, нашёл ещё три шутки, поправил(конкретно в этом алерте я просто удалил, он совсем тут не нужен), проверил в ВМ и отправил MR.
Наступила тишина в слак канале и можно попить кофе.☕️
.
..
...
....
А не, хер мне, а не отдых.
Теперь при верном неймспейсе заработали другие три алерта и прилетела новая проблема, ранее не замеченная из-за кривого лейбла. И это уже прод.
Эх, ну значит потом кофе попью😭.
Поехали чинить..
Please open Telegram to view this post
VIEW IN TELEGRAM
14😁12
#TIL

Бестолково листая бесконечные телеграм каналы, на которые подписан, наткнулся на репост репоста репоста любопытной заметки.

Стало интересно, пришлось копнуть дальше.
Думаю все это знали, но я, как обычно, к своему стыду не знал🤡.

Есть такая функция inet_aton(). https://linux.die.net/man/3/inet_aton
Функция обработки адреса интерпретирует входные данные не только как четыре октета, но и как 1, 2, или 3 числа. Если указано меньше четырёх чисел, недостающие биты адреса "добираются" из последнего указанного числа, а не просто заполняются нулями (хотя в некоторых случаях это выглядит так, как будто они заполнились нулями).

И эта функция используется утилитой ping.
Что это значит?
- можно пинговать localhost вот так
ping 127.1
PING 127.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.028 ms

- или даже пинговать DNS от CloudFlare https://www.whois.com/whois/1.0.0.1
>ping 1.1
PING 1.1 (1.0.0.1) 56(84) bytes of data.
64 bytes from 1.0.0.1: icmp_seq=1 ttl=58 time=5.85 ms

- ну или вообще вот так
ping 0
PING 0 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.030 ms


Так же и у curl (на самом деле там собственный host парсер).
curl -i https://1.1
HTTP/2 301
date:
content-length: 0
location: https://one.one.one.one/
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=TXp9lzhnM4jO3U47uy7caHHtaOGB5P%2FiVVgdhCuuaxklboKrkVlRH0at%2BwLL5kall9an%2FdkawG%2FoU7aRBxAABe2Ux52GTldnNm%2F%2F9EpxGNvKdtyJi5BQPcE%3D"}],"group":"cf-nel","max_age":604800}
nel: {"report_to":"cf-nel","max_age":604800}
server: cloudflare
cf-ray:

и
curl -i http://0
HTTP/1.1 308 Permanent Redirect
Connection: close
Location: https://0.0.0.0/
Server: Caddy
Date:
Content-Length: 0

# и даже с портом

curl -i http://0:8081
HTTP/1.1 302 Found
Cache-Control: no-store
Content-Type: text/html; charset=utf-8
Location: /login
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-Xss-Protection: 1; mode=block
Date:
Content-Length: 29

<a href="/login">Found</a>.


Зачем это надо?
А чёрт его знает.
Прикольно, не более.
Думаю это лишь историческая особенность, а не функциональность, предназначенная для практического применения.

Кому это надо?
Ну вдруг кто-то спешит и нет времени печатать полностью адрес 😀
Please open Telegram to view this post
VIEW IN TELEGRAM
😁143👍2👏1
17 октября 2025 года человек уходит из AWS.
https://nekrolm.github.io/blog.html

20 октября 2025 года сразу же крупнейший инцидент.
https://health.aws.amazon.com/health/status
😁22👍3
Make. Build. Break. Reflect.
#пятница #байки #troubleshooting Задолго до работы в айти я был простым советским инженером спутниковой связи. Тарелки, антенны, модемы, кабели, бесконечные командировки. В то время случалось масса странных историй. Мы разрабатывали спутниковое оборудование…
#пятница #байки #всратость

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


Помимо производства и продажи наземного спутникового оборудования, компания хотела занять и другие ниши на рынке. Одна из ниш была продажа спутниковой ёмкости.
Компания закупала целый транспондер или широкую полосу на спутнике и продавала маленькие кусочки/полосы желающим. Купили оптом одно, нарубили на кусочки, продавать их, но уже по розничной цене.
Ведь для клиентов ты либо арендуешь на месяц/год небольшую полосу и платишь невероятно сумасшедшие деньги, либо арендуешь пару мегагерц на месяц/год. Конечно рынок сбыта был, не у всех есть деньги на большие полосы и надо было лишь узкую полосу.

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

В общем компания решила войти в эту новую нишу: в мир автоматизации и продажи программного обеспечения, которое позволит на время арендовать канал телевизионщикам.

Какая была основная идея:
- мы пилим некий heatmap по дате/времени/календарю/частотам/полосам/спутникам, где отображены цветами полоса занята или нет
- у компании-оператора есть эта панель
- клиенты заходят на сайт, при помощи планировщика запрашивают полосу, допустим 0.5МГц, на два часа на четверг днём
- компания-оператор даёт согласие
- нужный кусок конфигурации(частота, ширина полосы, модуляция и тп) попадает на спутниковый модем от этого планировщика
- съёмочная бригада выезжает на место, просто включает оборудование, смотрит на свою собственную панель, на которой он видит ОК или НЕ ОК, можно выходить на связь или нет, убеждается, что всё ок, снимают репортаж, сворачивают антенну
- компания-оператор выставляет счёт клиенту-телеканалу за использование полосы

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

Задача всем понятна, выкатываем первый релиз.
Первый релиз - первая всратость. 😭

Разработчики из компании подошли к разработке интерфейса для клиентов максимально логично, с их стороны.
- Зеленый цвет - всё ок, можете выходить в эфир. Всё работает. 👍
- Красный цвет - всё не ок, полоса занята/оборудование не работает, конфиг не получен, выходить на связь нельзя. 👎
Ну всё же логично!

Логично, но не для мира телевещания.
Оказывается в мире съёмок и студий красный это ON AIR.
- Красный цвет - всё ок. Можно выходить в эфир.
- Зелёный цвет - standby. Ждите, пока можно выйти в эфир.

Ну вы поняли, да? 😁

Приезжает одна съёмочная бригада на место, открывает интерфейс софта, там красный индикатор (не получен конфиг, баг на релизе), думает "ну красный же! Можно выходить в эфир!", выходит в эфир, вываливаясь в чужую частоту, ни сами сигнал не передают, да и другим глушат. Красота.

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

И так далее.

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

Хорошо, что для медицины ничего не начали поставлять на старте 😀
Please open Telegram to view this post
VIEW IN TELEGRAM
😁17🫡10🔥7🥰2🤣1