Initial commit: interview prep repo (resume, legend, stack cases, Kubernetes course)

This commit is contained in:
Tot Maxim
2026-07-18 00:37:41 +03:00
commit 9bb7f6263f
47 changed files with 3548 additions and 0 deletions

100
stack/elk/CASE.md Normal file
View File

@@ -0,0 +1,100 @@
# Кейс: Elastic Stack (ELK)
Связь с легендой: [../../legend/LEGEND.md](../../legend/LEGEND.md) — раздел «АО ТНИИС», централизованный сбор и анализ логов в дополнение к метрикам из Prometheus.
## Что нужно реально сделать (домашний стенд)
Docker Compose стенд Elasticsearch + Kibana + Filebeat, собирающий логи уже готового кейса [../nginx/CASE.md](../nginx/CASE.md) — реальная связка «есть логи → собрали → увидели в Kibana», а не абстрактный пример.
### 1. docker-compose.yml
```yaml
version: "3.8"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.13.0
container_name: elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
kibana:
image: docker.elastic.co/kibana/kibana:8.13.0
container_name: kibana
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
ports:
- "5601:5601"
depends_on:
- elasticsearch
filebeat:
image: docker.elastic.co/beats/filebeat:8.13.0
container_name: filebeat
user: root
volumes:
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- nginx_logs:/var/log/nginx:ro
depends_on:
- elasticsearch
volumes:
nginx_logs:
```
Чтобы подключить реальные логи из кейса [../nginx/CASE.md](../nginx/CASE.md), в его `docker-compose.yml` у сервиса `proxy` нужно смонтировать тот же named volume `nginx_logs` на `/var/log/nginx` — тогда Filebeat читает те же файлы логов, что пишет живой nginx.
### 2. filebeat.yml
```yaml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
fields:
service: nginx-lab
output.elasticsearch:
hosts: ["elasticsearch:9200"]
index: "nginx-logs-%{+yyyy.MM.dd}"
setup.template.name: "nginx-logs"
setup.template.pattern: "nginx-logs-*"
```
### 3. Шаги воспроизведения
1. В [../nginx/CASE.md](../nginx/CASE.md) настроить `access_log` в формате, откуда легко выделить статус-код (стандартный combined-формат nginx это уже делает).
2. `docker compose up -d` для обоих стендов (или объединить в один docker-compose.yml).
3. Сгенерировать трафик через nginx-стенд (`curl` в цикле из шагов [../nginx/CASE.md](../nginx/CASE.md)), чтобы появились строки в access.log.
4. Проверить, что данные дошли: `curl http://localhost:9200/nginx-logs-*/_search?pretty`.
5. В Kibana (`localhost:5601`) создать index pattern `nginx-logs-*`, зайти в Discover — увидеть живые записи логов.
6. Построить простую визуализацию: количество запросов по HTTP-статус-коду (парсинг статуса из строки лога через встроенный `nginx` module Filebeat или простой grok-подобный dissect-фильтр).
### 4. Простой parse-фильтр для нестандартных логов
```yaml
processors:
- dissect:
tokenizer: '%{client_ip} - - [%{@timestamp}] "%{method} %{url} %{http_version}" %{status_code} %{bytes}'
field: "message"
target_prefix: ""
```
`dissect` — более простой и быстрый аналог `grok` для логов со стабильным, предсказуемым форматом (не требует регулярных выражений, работает через явные разделители) — здесь разбирает стандартную строку access-лога nginx на отдельные поля (`status_code`, `method`, `url`), которые дальше можно фильтровать и агрегировать в Kibana.
## Что это даёт в разговоре с интервьюером
- Реально собранная связка «источник логов (nginx) → shipper (Filebeat) → хранилище/поиск (Elasticsearch) → визуализация (Kibana)».
- Понимание, зачем нужен index pattern и что такое shard/index на базовом уровне (см. [QUESTIONS.md](QUESTIONS.md)).
- Понимание разницы Filebeat (лёгкий shipper, просто пересылает строки/файлы) vs Logstash (тяжёлый обработчик с богатыми фильтрами — grok, mutate, конвертация форматов).
- Практика простого dissect/parse-фильтра для структурирования сырых текстовых логов.
## Как это ложится в легенду
ELK упоминается в стеке отдела АО ТНИИС как часть инфраструктуры сопровождения, дополняющая метрики. Кейс замыкает цепочку с уже проработанным Nginx-кейсом — те же логи, которые нужно было бы разбирать вручную, теперь централизованно собираются и доступны для поиска и визуализации.

35
stack/elk/QUESTIONS.md Normal file
View File

@@ -0,0 +1,35 @@
# Вопросы: Elastic Stack (ELK)
Опираются на кейс: [CASE.md](CASE.md). Источники — [Реалист банк.md](../../interview/Реалист%20банк.md), [Bi.Zone.md](../../interview/Bi.Zone.md).
### Зачем нужен централизованный сбор логов?
Без централизации при инциденте пришлось бы вручную заходить на каждый сервер и грепать локальные файлы — на масштабе больше пары серверов это нереально быстро. Централизованный сбор (Filebeat/Logstash → Elasticsearch → Kibana) даёт единую точку поиска по всем источникам сразу, с фильтрами, временными диапазонами и агрегациями — я это прочувствовал даже на своём мини-стенде: логи одного nginx-контейнера искать через Kibana удобнее, чем `docker logs | grep` вручную, а на масштабе десятков сервисов разница становится критичной.
### Что такое index и shard в Elasticsearch на базовом уровне?
Index — логическая единица хранения данных в Elasticsearch, аналог таблицы/базы в привычных СУБД (у меня — `nginx-logs-2026.07.17`, с ротацией по дням). Shard — физическая часть индекса: Elasticsearch разбивает индекс на несколько shard'ов, которые могут распределяться по разным нодам кластера — это даёт горизонтальное масштабирование (шардов больше — можно параллельно обрабатывать запросы/индексацию на нескольких машинах) и отказоустойчивость через replica-шарды (копии основных шардов на других нодах). На однонодовом dev-стенде я это не мог продемонстрировать в полную силу (реплики некуда класть при single-node), но структуру index → shards видел через `_cat/indices` и `_cat/shards`.
### В чём разница между Logstash и Filebeat?
Filebeat — лёгкий shipper: минимум ресурсов, задача — надёжно прочитать файл/поток и переслать данные дальше (в Elasticsearch напрямую или через Logstash), с минимальной трансформацией (у меня — простой `dissect` для разбора строки access-лога). Logstash — тяжёлый обработчик с богатым набором фильтров (`grok`, `mutate`, `date`, конвертация форматов, обогащение из внешних источников) — уместен, когда нужна серьёзная трансформация/нормализация разнородных логов перед индексацией. Типичная практика — Filebeat на источнике (лёгкий агент на каждом хосте) → опционально Logstash в середине для тяжёлой обработки → Elasticsearch. В своём стенде обошёлся без Logstash, потому что формат nginx access-лога стабильный и `dissect` в самом Filebeat справился.
### Чем отличается ELK от OpenSearch?
OpenSearch — форк Elasticsearch и Kibana (под открытой лицензией, после того как Elastic сменил лицензирование части своего стека) — архитектурно и по API очень близок к Elasticsearch на момент форка, дальше эти проекты развиваются раздельно и постепенно расходятся в фичах. С точки зрения повседневной эксплуатации на базовом уровне (индексация, поиск, дашборды) отличия для рядового пользователя минимальны — выбор между ними чаще определяется лицензионной политикой компании (открытая лицензия OpenSearch vs текущее лицензирование Elastic), а не техническими возможностями на базовом уровне.
### Ты мониторил стандартными службами мониторинга сам стек ELK? Если да, то как?
Elasticsearch отдаёт собственные метрики (использование JVM heap, длина очередей индексации, состояние шардов, задержки запросов) через встроенный API (`_cluster/health`, `_nodes/stats`) — это можно собирать тем же Prometheus через `elasticsearch_exporter` и визуализировать в Grafana, аналогично стенду [../monitoring/CASE.md](../monitoring/CASE.md). Сам ELK-стек — это тоже сервис, которому нужен мониторинг (не только логи снаружи собирает, но и сам может деградировать — например, при переполнении диска или нехватке heap), поэтому в проде разумно смотреть на него теми же инструментами, что и на остальную инфраструктуру, а не только через собственный Kibana Stack Monitoring.
### Разворачивал ELK с нуля с агентами?
Да, стенд в [CASE.md](CASE.md) — Elasticsearch + Kibana + Filebeat с нуля через Docker Compose, с Filebeat, читающим реальные логи работающего nginx-контейнера из отдельного кейса, а не тестовые/синтетические данные. Настроил index pattern в Kibana и простую визуализацию по статус-кодам запросов nginx.
### Сколько Гб данных логов будет в ELK, если в Prometheus уже 15 Гб метрик?
Однозначного числа тут нет — вопрос проверяет понимание порядка и природы различия между логами и метриками, а не конкретную формулу. Метрики — компактные числовые ряды с фиксированной структурой (timestamp + значение + лейблы), которые к тому же хорошо сжимаются за счёт повторяемости паттернов (Prometheus TSDB использует специальное сжатие временных рядов). Логи — произвольный текст, часто многословный (стектрейсы, JSON с вложенностью, человекочитаемые сообщения), без такой плотной структуры — при сопоставимом количестве событий объём логов обычно на порядок (иногда на два) больше объёма метрик. Отсюда и практический вывод, который я бы озвучил на этом вопросе: если стоит выбор, что мониторить в первую очередь при ограниченных ресурсах хранения — метрики обычно дешевле держать долго и по ним быстрее строить алерты по порогам, а логи — глубже для расследования причины конкретного инцидента, но дороже в хранении; поэтому разумная схема — метрики для алертинга и трендов + логи с более коротким retention для расследований (см. также [../monitoring/QUESTIONS.md](../monitoring/QUESTIONS.md) про выбор между логами и метриками для конкретного инцидента).
### Что такое retention логов и зачем он нужен?
Retention — период, в течение которого логи хранятся, прежде чем автоматически удаляются/архивируются. Нужен, потому что логи растут в объёме быстрее метрик (см. вопрос выше) и бесконечное хранение экономически и технически нецелесообразно — retention настраивают через Index Lifecycle Management в Elasticsearch (например, hot-фаза несколько дней на быстрых дисках для активного поиска, потом warm/cold фазы на более дешёвом хранилище, потом delete). Конкретный срок — компромисс между стоимостью хранения и требованиями (иногда регуляторными) держать историю логов для расследования инцидентов задним числом.