Azalio_tech
525 subscribers
8 photos
1 video
3 files
46 links
Разные заметки о kubernetes, linux и IT
https://www.linkedin.com/in/azalio/
Download Telegram
Собирали вручную 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