Azalio_tech
525 subscribers
8 photos
1 video
3 files
46 links
Разные заметки о kubernetes, linux и IT
https://www.linkedin.com/in/azalio/
Download Telegram
А что, если в действительности написать такую программу, которая содержит в себе сравнение всех uint32 чисел? Какие сложности нас ожидают?

(hint: компилятор скомпилировать такую программу не смог и пришлось выкручиваться…

hint2: превосходство питона над другими жалкими языками программирования, но не так как вы подумали)



https://andreasjhkarlsson.github.io//jekyll/update/2023/12/27/4-billion-if-statements.html
🔥3
Сегодня мне задали интересный вопрос: как обнаружить ситуацию, когда YAML-файл синтаксически корректен, но его содержимое некорректно для Kubernetes, и сделать это до попытки его применения в кластере?

https://gist.github.com/azalio/f2e2859258c5d1768131623775ad369c

#kubernetes #lint
👍6
#cilium #external_nodes #kubernetes

Начальные условия: Есть кластер(а) kubernetes с cilium в режиме VxVLAN. Мастер ноды никак не входят в кластер k8s.

Надо: Настроить control plane так, чтобы kube-apiserver мог общаться с k8s node(s), вебхуками и расширенным апи (например, метрик сервер), но не был нодой kubernetes.

Сколько вариантов это сделать вы можете придумать используя стандартные средства (без написания чего-то своего)?

Я пока вижу 3 нормальных.

1. VTEP (Virtual Tunnel Endpoint)

https://docs.cilium.io/en/stable/network/vtep/

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

   - Плюсы: Легко настроить.

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

2. Cilium External Workloads
https://docs.cilium.io/en/stable/network/external-workloads/

   - Как работает: Создаётся vxvlan интерфейс для Cilium сети и подключается Cilium Agent на внешней ноде с clustermesh API.

   - Плюсы: Позволяет настраивать L3-связь без broadcast, а Cilium управляет всей связностью.

   - Минусы: Требуется LoadBalancer или NodePort для clustermesh API, что может добавить сложности и расходы. Требуется надежное хранение в etcd.

3. Konnectivity Service
https://kubernetes.io/docs/tasks/extend-kubernetes/setup-konnectivity/

   - Как работает: Konnectivity сервер разворачивается на мастер-ноде и позволяет контроллеру взаимодействовать с ресурсами нод через прокси.

   - Плюсы: Работает и через NAT, поддерживает любые CNI.

   - Минусы: Требуются дополнительные ресурсы на агенты и сервер Konnectivity, а также балансировщик для отказоустойчивости.

Есть еще вариант с выносом вебхуков и расширенного апи на хостовую сеть, но это не удобно.
2
Я перед сном смотрю разные видео и это видео я посмотрел судя по истории 11 октября, но идея этого видео не отпускает меня до сих пор.
Как вам такая мысль:

В нашей вселенной время и расстояние квантуются.

То есть есть минимальные единицы, меньше которых нельзя либо переместиться, либо измерить время?
То есть, например, нельзя переместиться на произвольное расстояние, а только на минимальное или больше него.

Именно о таких понятиях это видео и оно весьма интересно.
4🤔2
#AI #opensource

Как с помощью генеративного ИИ улучшить PR в open source проект.

## Введение

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

## Проблема

При настройке отправки логов в Amazon Kinesis через Fluent Bit я столкнулся с ограничением - плагин не позволял указать нестандартный порт для подключения. Это было критично в нашей инфраструктуре, где из-за особенностей сетевой архитектуры мы используем нестандартные порты для доступа к kinesis.

## Первоначальное решение

Мой коллега предложил простой патч, который решал проблему:
Было:


ctx->kinesis_client->port = 443;
struct flb_upstream *upstream = flb_upstream_create(config, ctx->endpoint,
443, FLB_IO_TLS,
ctx->client_tls);



Стало:


ctx->kinesis_client->port = ctx->port;
struct flb_upstream *upstream = flb_upstream_create(config, ctx->endpoint,
ctx->port, FLB_IO_TLS,
ctx->client_tls);


Патч работал, но для долгосрочного решения нужно было внести изменения в апстрим проекта. Пересборка Fluent Bit при каждом обновлении не самый удобный вариант.

## Работа с ИИ

Для работы я использовал cursor.com - форк VSCode с интегрированным Claude AI. Главное преимущество этого редактора в том, что он "понимает" всю кодовую базу проекта.

Вот как проходила работа с ИИ:

1. Сначала я показал ему существующий патч и попросил предложить улучшения. ИИ самостоятельно:
- Обнаружил существующие в кодовой базе механизмы логирования (flb_plg_debug и flb_plg_error)
- Предложил добавить информативные сообщения о выбранном порте
- Добавил валидацию входных данных после моей просьбы.

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

3. Когда возникли проблемы с подхватыванием порта, ИИ предложил пошаговую отладку через gdb:

# Сборка с отладочной информацией
cmake .. -DCMAKE_BUILD_TYPE=Debug -DFLB_DEV=On

# Запуск отладчика
gdb --args ./bin/fluent-bit -c /etc/fluent-bit/fluent-bit.conf

# Команды отладки
(gdb) break cb_kinesis_init
(gdb) run
(gdb) print flb_output_get_property("port", ins)
(gdb) print *ins


## Результат

Итоговый PR был вмержен в основную ветку проекта. На всю работу ушло около 6 часов, включая время на знакомство с кодовой базой Fluent Bit.

Теперь изменение конфигурации Fluent Bit для работы с нестандартным портом Kinesis выглядит так:


[OUTPUT]
Name kinesis
Match *
region us-east-1
port 4443 # Новый параметр
stream my-stream


Я надеюсь в версии fluent-bit 3.2 оно уже будет работать.

P.S. Я пробовал копилот от гитхаба для этой задачи - он мне показался несколько бесполезым и не шел ни в какое сравнение с sonnet 3.5.
👍41
Собирали вручную Kubernetes-кластер без всяких там kubeadm?

Я разрабатываю курс по Kubernetes и решил: что может быть лучше для практики, чем собрать кластер своими руками? Это не только помогает понять, как работает Kubernetes, но и учит не бояться его сломать.

Kubernetes the Hard Way от легендарного Келси Высокая Башня — лучший туториал для этой задачи. Но вот что странно: в репозитории нет быстрого способа поднять виртуалки для начала работы.

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

```bash
brew tap hashicorp/tap
brew install hashicorp/tap/hashicorp-vagrant
vagrant plugin install vagrant-vmware-desktop

vagrant up
```

P.S. В репозиторий я также добавил файл, без которого пройти упражнение на сегодняшний день невозможно.

---
Ставьте лайки, пробуйте запустить и делитесь фидбеком! А еще будет интересно узнать ваши идеи, как решить подобную задачу. 👨‍💻
👍72🔥1
#это_база #kubelet #kubernetes

Дело было вечером, делать было нечего, да много дел было!

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

Так и получилась небольшая статейка.

---
Понравилось? Поставь лайк! Они улучшают мне настроение.
Есть что добавить - велком в комменты!
👍6🔥4🦄3
#AI

Я часто слышу, что генеративные ИИ скоро заменят разработчиков...

Поэтому у меня тут возникла идея попробовать разобраться можно ли написать проект полностью с помощью генеративного ИИ.
Решил написать мем-бота, который использует YandexGPT для улучшения или придумывания промпта и для генерации картинок взял YandexART и Kandinsky.

И оно работает! Вот, положила: @meme_ydx_bot

Для генерации API внешних сервисов я копировал страницу с сайта в чат и говорил: "Вот тебе дока, напиши код".
Ну и для всего остального я только выдавал текстовые команды.

Итого я написал всего около 1% кода. Все остальное сделал Deepseek v3 с помощью плагинов Continue.dev и Aider.chat.

Continue.dev - это плагин для VS Code. А Aider.chat - клевый инструмент для работы в терминале.

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

Мемы получаются так себе, правда... 🙂 Надо будет дообучить на каком-нибудь корпусе мемов ИИшку.

P.S. Кстати, пробовал Sonnet 3.5 - он хорош, но очень дорогой по сравнению с Deepseek.
P.S. ЯндексАрт более щепетильно относится к промпту и, например, не будет генерировать картику по запросу "Гроб, кладбище, пидор".
P.S. Более крутые товарищи уже написали сервис @AIMemeArenaBot.

---
Если есть мысли как улучшить бота или промпт - напишите, пожалуйста :)
👍1
#cilium #l2 #kubernetes

Разбирался я тут с опциями цилиума и наткнулся на опцию --agent-liveness-update-interval и что-то из описания опции в документации яснее не стало.

Полез разбираться и внезапно почувствовал себя мужчиной из ролика, который решил поменять лампочку (скину в комменты).

Встречайте L2 анонсы в Cilium для доступа к сервисам LoadBalancer в bare-metal Kubernetes.

Все как вы любите, код на go, код на C, bpf-maps, bpftrace и прочие потроха цилиума и немножко линукс ядра.

---
Понравилось? Поставь лайк!
👍16🔥4
Kubernetes Network Policies Done the Right Way by Isovalent.pdf
7.9 MB
Прочитал новую книжку от #cilium про то как надо делать сетевые политики в #kubernetes.
Сначала дают теорию, рассказывают как с 0 организовать сетевые политики, дают пошаговое руководство, потом переходят к практике, но практике сильно урезанной.
Захватывают все свои фишки типа:
- свое переосмысление на чем надо основываться при выборе эндпоинтов (identities)
- избирательный defaultDeny
- hubble UI и cli
- генерацию политик в редакторе
- L3/L4, L7 политики
В целом если вы давно в этой теме - вам эта книжка ничего не даст, если же вы не работали или работали эпизодически с сетевыми политиками (особенно с сетевыми политиками cilium), то рекомендую эту книжку - отличный старт.
👍20
Говорят, в этом канале собрались очень умные люди.
Поэтому поступило предложение рассказать про митап, который устраивает Магнит OMNI и я не нашел поводов отказаться.


23 апреля встречаемся на митапе в Магнит OMNI!

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

🔸 Что будет:
— Спикеры из Магнит OMNI, Лаборатории Касперского, Авито, Cloud.ru и других компаний
— Разбор болей, кейсов и решений, которые работают.
— Розыгрыш призов от Магнит OMNI.
— Живой нетворкинг.

Митап можно посетить:
— Офлайн в московском офисе Магнита,
— Онлайн

📅 Дата: 23 апреля
🕔 Время: 17:30

Не упускайте возможность узнать новое и пообщаться с профессионалами!

Подробности и регистрация — по ссылке.

#OMNI_events

@magnit_omni_team
5🔥3🤩1
🔒 Отключаем анонимный доступ к kube-apiserver, но оставляем health checks!

Привет! Недавно ко мне пришел коллега-безопасник (Дима привет!) с интересным вопросом: как полностью отключить анонимный доступ к API-серверу Kubernetes, но оставить рабочими проверки /livez, /readyz и /healthz? 🤔 Сходу не ответил, полез копаться в исходниках и KEPах.

Проблема в том, что по умолчанию (`--anonymous-auth=true`) любой может дернуть эндпоинты health-чеков и не только health-чеков:

curl -k https://<API_SERVER_IP>:6443/livez
# Output: ok

Это удобно, но создает потенциальный вектор атаки, если RBAC настроен не идеально или найдется уязвимость. Безопасники такое не любят. 😟

К счастью, в KEP-4633 сообщество Kubernetes предложило решение! Теперь можно тонко настроить, к каким путям разрешен анонимный доступ, даже если глобально он выключен.

Сделать это можно так:

Сначала выключаем глобальный анонимный доступ в манифесте kube-apiserver:

spec:
containers:
- command:
- kube-apiserver
# ... другие флаги ...
- --anonymous-auth=false # <--- Выключаем!
- --authentication-config=/etc/kubernetes/auth-config.yaml # <--- Указываем конфиг


Затем создаем файл конфигурации /etc/kubernetes/auth-config.yaml на control plane нодах и монтируем его в под kube-apiserver:

# /etc/kubernetes/auth-config.yaml
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
anonymous:
enabled: true # Включаем анонимный доступ *только* для указанных путей
conditions:
- path: /livez
- path: /readyz
- path: /healthz

*(Не забудьте добавить volume и volumeMount в манифест kube-apiserver для этого файла)*

В итоге получаем:
- Запросы к /livez, /readyz, /healthz проходят как system:anonymous.
- Запросы к другим путям (например, /apis) без аутентификации получают 401 Unauthorized.

Кстати, эта функциональность появилась как Alpha в Kubernetes 1.31 и стала Beta в 1.32.

Теперь можно спать спокойнее, зная, что анонимный доступ под контролем!

#kubernetes #k8s #security #authentication #kubeadm #devops #infosec
👍20🔥3💋1
😠 Агент-лимитер “слепнет” после появления новых PV? Раз и навсегда разбираемся с `mountPropagation` в Kubernetes!

Недавно писал I/O-лимитер для LVM-томов: агент читает маунты подов, чтобы вычислить MAJOR:MINOR для добавления в io.max, и всё ок… пока на узел не приедет новый Pod. Его маунта агент уже не видит. Перезапуск помогает, но это же костыль!

Почему так происходит

* Каждый контейнер стартует в своём *privаte* mount-namespace -> изменения на хосте туда не пролетают.
* В Kubernetes это равно mountPropagation: None.


Как починить?

Параметр mountPropagation у volumeMounts имеет 3 режима:

* None - полная изоляция (`rprivate`), дефолт.
* HostToContainer - маунты летят *с хоста -> в контейнер* (`rslave`). Нам нужен именно он.
* Bidirectional - маунты ходят в обе стороны (`rshared`). Работает *только* в `privileged`-контейнере, иначе Pod не стартует.


Спека


spec:
containers:
- name: my-agent
image: my-agent-image
volumeMounts:
- name: kubelet-pods
mountPath: /var/lib/kubelet/pods
mountPropagation: HostToContainer
volumes:
- name: kubelet-pods
hostPath:
path: /var/lib/kubelet/pods
type: Directory


Теперь каждое *новое* bind-mount событие внутри /var/lib/kubelet/pods мгновенно видно агенту - без рестартов.


Что происходит под капотом

1. Kubelet видит HostToContainer и пишет в CRI PROPAGATION_HOST_TO_CONTAINER.
2. CRI-shim (containerd/CRI-O) делает каталог rslave.
3. Все будущие маунты, созданные kubelet’ом на хосте, автоматически “проливаются” в контейнер.


На заметку

* Bidirectional опасен в мульти-тенант окружениях: контейнер может пролить маунты *на хост*.
* В Kubernetes 1.10 было краткое время, когда дефолтом неожиданно стал HostToContainer. Если админите древний кластер - проверьте (хотя боюсь вам уже ничего не поможет...).
* Cilium тоже использует этот трюк чтобы следить за bpf мапами.


Полезные ссылки
Документация
• CRI интерфейс
• man mount

#kubernetes #k8s #mountPropagation #linux #devops #storage
👍12
GKE metadata-proxy: элегантный способ получения JWT без дыр в RBAC

Недавно беседовали с коллегой про Workload Identity Federation в GKE и выяснилось, что не все знают, как metadata-proxy получает JWT токен от имени пода.

А вы знаете, как это работает под капотом?

Что такое WIF?
Простая идея: токен пода обменивается на cloud token для доступа к облачным API. Никаких статических ключей!

Два подхода к безопасности:

Небезопасный подход (как в эмуляторе):


rules:
- apiGroups: [""]
resources: [serviceaccounts/token]
verbs: [create]


Критическая уязвимость! Такая роль позволяет получить JWT токен от ЛЮБОГО ServiceAccount в кластере!

Элегантное решение GKE:

1. Использует kubeconfig от kubelet (у него есть права только на поды своей ноды)
2. Запрашивает токен с указанием реально существующего объекта в кубере, который к тому же привязан к конкренной ноде:


kubectl create token azalio-meta-sa \
--namespace azalio-meta \
--bound-object-kind Pod \
--bound-object-name test-pod \
--bound-object-uid 5094d128-8f9b-463d


Почему это безопасно?

- metadata-proxy может получить токен только для подов на своей ноде
- Токен привязан к конкретному поду через UID
- Нет доступа к ServiceAccount подов других нод

**Как работает весь процесс:**
(картинка в комментариях)

1. Pod → metadata-proxy: GET /computeMetadata/.../token
2. proxy → K8s API: create token (ограничен нодой + Pod UID)
3. proxy → Google STS: обмен JWT → Access Token
4. STS → proxy → Pod: Access Token
5. Pod → Google API: работа с нужными сервисами


Полезные ссылки:

- Официальная документация GKE Workload Identity
- Детальный разбор безопасности WIF
- Пример настройки WI в GKE
- Bound service account tokens.

Что запомнить:

Прав выдаваемых kubeconfig'у kubelet хватает чтобы выписать токен от имени SA пода запущенного на ноде.

Вопрос: у какого российского облачного провайдера есть WIF? 😉

#kubernetes #security #gke #workloadidentity #cloudsecurity
2👍9🦄21
This media is not supported in your browser
VIEW IN TELEGRAM
Я думаю вас никогда так не рикролили :)
Рассказываю сегодня про l2 анонсы в #cilium.
13
Вряд ли я это произнесу со сцены, но мне нравится шутка.

CNI chaining — как секс у подростков:

все про него говорят, но на деле почти никто не пробовал.

И самое смешное - те, кто пробовал, сделали это неправильно.
😁117👎1👏1
azalio-cni-chain.pdf
15.6 MB
Моя презентация с KuberConf 2025 по ^
(В комменты закину версию с видео слайдами)
👍197👏3