From:To:
11¶ **k8sgpt** — инструмент, который смотрит на кластер Kubernetes, находит поломки и отправляет их объяснять языковой модели. Описание в шапке репозитория без скромности: *Giving Kubernetes Superpowers to everyone*.
22
33 Заведён **21 марта 2023 года**. На сегодня — 8140 звёзд, 1045 форков, больше сотни людей, вложивших код, девяносто одна открытая задача. Go, Apache-2.0, отдельная организация `k8sgpt-ai` — то есть не репозиторий одного человека, а команда с процессом.
44
55 ### Повадки, видные с первого захода
66
77 **Задача открывается по шаблону** — с галочками «искал похожие задачи», полями для версий K8sGPT, Kubernetes и операционной системы. В разборе ниже человек оставит их пустыми — `_No response_` — и это не небрежность: у него не поломка, у него вопрос.
88
99 **Отвечают по существу и быстро.** Мейнтейнер — через шесть дней и со ссылкой на конкретные строки в `pod.go`. Основатель — в тот же день, когда вопрос стал неудобным.
1010
1111 **Спрашивающего не отправляют читать код.** Ему отвечают списком — и он остаётся в проекте писать документацию.
1212
1313 Анонимизация появилась у них **на третьей неделе жизни проекта**: репозиторий заведён 21 марта, флаг приехал 10 апреля. О том, что данные чужого кластера уезжают к постороннему поставщику, здесь подумали сразу.
1414
1515 Именно поэтому разбор ниже — не про небрежность.
1616¶ **10 апреля 2023.** Приезжает PR [#242 «feat: add anonymize option»](https://github.com/k8sgpt-ai/k8sgpt/pull/242) от `matthisholleville`. Влит через два дня — [`fb75434`](https://github.com/k8sgpt-ai/k8sgpt/commit/fb7543418b3905aee4aedb102c36691d3ddffbcd).
1717
1818 Флаг обещает простое: перед отправкой модели чувствительное заменят.
1919
2020 В README появляется строка среди ключевых возможностей: **Anonymization**. Строка короткая и успокаивающая.
2121¶ **14 апреля, через два дня после вливания.** Приезжает коммит [`fe52951`](https://github.com/k8sgpt-ai/k8sgpt/commit/fe529510b68ac5fbd39c147c7719abe2e7d20894) от `Alex Jones` — того самого основателя, который через три месяца будет отвечать на неудобный вопрос.
2222
2323 Название приводится как есть, с опечаткой:
2424
2525 > feat: anoymization based on pr feedback
2626
2727 Анонимизацию переделывают **по замечаниям в ревью** — через два дня после того, как её влили. Здесь не добавили флаг и забыли: над ним ещё поработали чужими руками и глазами.
2828¶ **5 июля, три месяца спустя.** `jatinmehrotra` открывает [issue #541](https://github.com/k8sgpt-ai/k8sgpt/issues/541). Заголовок звучит вежливо и настораживающе одновременно: «Что означает KEY FEATURE[Anonymization] в README?»
2929
3030 В поле «шаги воспроизведения» — одна строка:
3131
3232 > Searched the entire REPO for the meaning of events where anonymization would not apply.
3333 >
3434 > *Искал по всему репозиторию, что означают события, к которым анонимизация не применяется.*
3535
3636 Он не сообщает об ошибке. Он сообщает, что **не нашёл границы**.
3737¶ Но ещё раньше, **19 апреля** — через девять дней после того, как анонимизация появилась, — в `pod.go` приезжает коммит [`3c7e0bb`](https://github.com/k8sgpt-ai/k8sgpt/commit/3c7e0bba1d4cc8247d248756dcfef884bc406992) от `Peter Pan`:
3838
3939 > chore: analyze Pod ReadinessProbe faliure
4040
4141 Он учит анализатор разбирать отказ проверки готовности — и вместе с полезным делом приносит в этот файл первый `Sensitive: []common.Sensitive{}`.
4242
4343 Это не небрежность автора и не повод искать виноватого. Это **форма структуры**: чтобы сообщить о поломке, надо заполнить оба поля, а что класть во второе, если текст пришёл извне и ты о нём ничего не знаешь? Пустой список — единственный ответ, который компилируется.
4444¶ **11 июля.** Отвечает `arbreezy`, мейнтейнер. Ответ занимает абзац, и в нём есть предложение, ради которого стоит читать весь разбор:
4545
4646 > In a few analysers like Pod, we feed to the AI backend the event messages which are not known beforehand thus we are not masking them for the time being.
4747 >
4848 > *В нескольких анализаторах, например Pod, мы отдаём модели тексты событий, которые заранее неизвестны, — и поэтому пока их не маскируем.*
4949
5050 Перечитайте, что именно не маскируется. Не «сложное» и не «редкое», а то, что **заранее неизвестно**.
5151
5252 Маскировка накрывает предсказуемое: имена подов и пространств имён — их придумал сам проект, он же знает, как они выглядят. И не накрывает то, что в кластер написал кто-то другой.
5353¶ **12 июля.** `jatinmehrotra` возвращается с четырьмя вопросами подряд: какие анализаторы маскируют, какие нет, что именно заменяется и когда починят остальное. А потом задаёт тот, ради которого всё и затевалось:
5454
5555 > In the docs it was mentioned that k8sgpt is being used in production for customer projects… does it not pose a security risk to the customer sensitive information?
5656 >
5757 > *В документации сказано, что k8sgpt используют в продакшене на клиентских проектах… не создаёт ли это риска для чувствительных данных клиента?*
5858
5959 Вопрос неудобный. Человек собирается ставить инструмент в проект и спрашивает прямо, чем это ему обойдётся.
6060¶ **В тот же день** отвечает `AlexsJones` — один из основателей проекта.
6161
6262 Он не уходит в общие слова и не обещает «безопасность на уровне предприятия». Он выкладывает **список**: маскируется у Statefulset, Service, PodDisruptionBudget, Node, NetworkPolicy, Ingress, HPA, Deployment, Cronjob. Не маскируется у ReplicaSet и PersistentVolumeClaim — и тут же объясняет почему: оттуда не уходит ничего опознающего, только сам факт, что штука сломана.
6363
6464 Список, названный вслух, — это и есть честно названная цена. Он же показывает, что границу до этого разговора никто не записывал: её пришлось собирать в ответе на вопрос.
6565¶ **19 июля.** Приезжает PR [#559 «docs: fix readme for anonymization»](https://github.com/k8sgpt-ai/k8sgpt/pull/559) — [`70bec05`](https://github.com/k8sgpt-ai/k8sgpt/commit/70bec050d854be6f559065278d6a583d8e0e333b).
6666
6767 Автор — **тот же `jatinmehrotra`**, который две недели назад пришёл с вопросом. Спросил, получил ответ, написал документацию сам.
6868
6969 От вопроса до правки — четырнадцать дней.
7070¶ **Сегодня.** Тот же файл, [строки 130–133](https://github.com/k8sgpt-ai/k8sgpt/blob/731a6c90749e8e62b9325e41712c39c0d72510c4/pkg/analyzer/pod.go#L130-L133):
7171
7272 ```go
7373 failures = append(failures, common.Failure{
7474 Text: evt.Message,
7575 Sensitive: []common.Sensitive{},
7676 })
7777 ```
7878
7979 Сообщение события отправляется как есть, список чувствительного при нём — **пустой**. Сорока строками ниже, в соседней ветке условия, — точно такой же.
8080
8181 А всего в дереве сегодня **сорок** таких мест: анализаторы подов, хранилища, конфигов, интеграции с keda и kyverno. Дописывали их разные люди в 2023, 2025 и 2026 годах.
8282
8383 «Пока» из июля 2023-го идёт третий год — и разошлось по сорока местам.
8484¶ ### Хвост про себя
8585
8686 В тот же день та же болезнь нашлась у меня — и не чтением, а прогоном.
8787
8888 Пятнадцать моих агентов устроены как k8sgpt: скрипт собирает факты о машине, факты уезжают в модель. Разбор журнала отдаёт двадцать самых частых предупреждений **дословно** — а журнал пишут службы, и пишут в него что угодно.
8989
9090 Подставил сорок пять предупреждений nginx с токеном в пути запроса. В исходящих фактах:
9191
9292 ```
93− 45 open() "/srv/www/media?token=tk_ldVDfCbPVWlS2knHNQjSxOLuu5" failed
93+ 45 open() "/srv/www/media?token=tk_…" failed (2: No such file or directory)
9494 ```
9595
96+ Токен здесь обрезан нарочно: он был проверочный и ничего не открывал, но дословный вид в разборе про утечки учит ровно противоположному — да и чужие сканеры секретов он споткнёт.
97+
9698 Мой список чувствительного был так же пуст и ровно по той же причине: заранее неизвестно, что служба напишет в журнал. Починено маскировкой в запускателе агентов — одно место на пятнадцать сборщиков; проверка после правки: «вырезано фрагментов: 1».
9799
98100 Разница между нами и k8sgpt только в масштабе последствий. А формулировка «то, что заранее неизвестно, мы пока не маскируем» — честная ровно настолько, насколько точно описывает дыру.
99101## Что это значит для нас
1001021. Выписать, что уходит наружу ДОСЛОВНО
101103 По каждому сборщику фактов ответить: какие разделы передают чужой текст без изменений, а какие отдают только счётчики и имена, придуманные вами.
102104 $ grep -nE 'journalctl|cat |curl |-o cat' сборщики/*.sh
103105 why: Маскировка всегда накрывает предсказуемое — то, что проект придумал сам. Опасно ровно обратное: текст, который написал кто-то другой.
104106 - [ ] По каждому сборщику названы разделы с дословным чужим текстом
105107 - [ ] Для каждого такого раздела сказано, кто пишет этот текст на самом деле
106108 - [ ] Найден хотя бы один раздел, о котором вспомнили только при составлении списка
1071092. Резать в одном месте, а не в каждом сборщике
108110 Маскировка ставится на общем пути — там, где факты передаются модели, — а не в каждом скрипте по отдельности.
109111 why: Пятнадцать сборщиков — это пятнадцать мест, где можно забыть, и один запускатель, где нельзя. Шестнадцатый сборщик напишут через месяц и про маскировку не вспомнят.
110112 - [ ] Резка стоит на общем пути, а не в отдельных сборщиках
111113 - [ ] Новый сборщик получает маскировку, ничего не делая
112114 - [ ] При недоступности детектора остаётся запасной слой, а не тишина
1131153. Доказать подставленным секретом, а не чтением
114116 Положить в источник фактов заведомо узнаваемую строку и посмотреть, дойдёт ли она до исходящих фактов — и в той же форме, в какой её ищете.
115117 why: Моя первая проверка сказала «чисто» дважды и оба раза соврала: сначала проба шла не того уровня, потом сборщик переписывал цифры, и греп по целому токену промахивался.
116118 - [ ] Проба попадает в тот же канал, который читает сборщик (уровень, единица, частота)
117119 - [ ] Искали в той форме, в какой строка выходит после обработки, а не в исходной
118120 - [ ] До правки проба находит секрет, после — не находит