DevOps by REBRAIN
Открытые практикумы по DevOps, Linux, Golang, Networks, Security Мы на связи: info@rebrainme.com +7 (499) 116-34-68 https://rebrainme.com/ Зарегистрированы в РКН: https://knd.gov.ru/license?id=674db558d793bc0b0b8845ff®istryType=bloggersPermission
Больше📈 Аналитический обзор Telegram-канала DevOps by REBRAIN
Канал DevOps by REBRAIN (@rebrain_devops) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 28 754 подписчиков, занимая 4 617 место в категории Технологии и приложения и 22 401 место в регионе Россия.
📊 Показатели аудитории и динамика
С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 28 754 подписчиков.
Согласно последним данным от 30 октября, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -102, а за последние 24 часа — -6, при этом общий охват остаётся высоким.
- Статус верификации: Не верифицирован
- Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 8.22%. В первые 24 часа после публикации контент обычно набирает 6.51% реакций от общего числа подписчиков.
- Охват публикаций: В среднем каждый пост получает 2 364 просмотров. В течение первых суток публикация набирает 1 871 просмотров.
- Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 11.
- Тематические интересы: Контент сосредоточен на ключевых темах, таких как dovecot, linux, скрипт, postfix, yandex.
📝 Описание и контентная политика
Автор описывает ресурс как площадку для выражения субъективного мнения:
“Открытые практикумы по DevOps, Linux, Golang, Networks, Security
Мы на связи:
info@rebrainme.com
+7 (499) 116-34-68
https://rebrainme.com/
Зарегистрированы в РКН: https://knd.gov.ru/license?id=674db558d793bc0b0b8845ff®istryType=bloggersPermiss...”
Благодаря высокой частоте обновлений (последние данные получены 31 октября, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.
<source>
@type tail
path /var/log/nginx/access.log
pos_file /var/log/nginx/access.log.pos
tag nginx.access
<parse>
@type nginx
</parse>
</source>
# Фильтруем: исключаем из отправки логи со статус-кодом 200
<filter nginx.access>
@type grep
<exclude>
key code
pattern /^200$/
</exclude>
</filter>
<match nginx.access>
@type elasticsearch_data_stream
host elasticsearch-service
port 9200
# пишем в data stream, а не в датовый индекс. только так работает ILM-rollover
data_stream_name nginx-logs
data_stream_template_name nginx-logs
data_stream_ilm_name logs-policy
<buffer>
flush_interval 5s
</buffer>
</match>
Если приложение сыплет многострочными ошибками (стектрейсами), обычный tail разобьет их на отдельные строки. Чтобы этого не произошло, настраиваем мультилайн-парсер:
<parse>
@type multiline
format_firstline /^\d{4}-\d{2}-\d{2}/
format1 /^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}) (?<level>[A-Z]+) (?<message>.+)/
</parse>
Для контейнеров обязательно включаем обогащение метаданными Kubernetes. Это добавит в каждый лог контекст: namespace, имя пода и лейблы.
<filter kubernetes.**>
@type kubernetes_metadata
</filter>
Шаг 2️⃣ Оптимизация Elasticsearch (ILM)
Без управления индексами Elasticsearch быстро съест весь диск, а поиск станет невыносимо медленным. Настраиваем Index Lifecycle Management (ILM) политику, чтобы вовремя перемещать старые данные на дешевые диски и удалять их:
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_primary_shard_size": "50gb",
"max_age": "7d"
},
"set_priority": { "priority": 100 }
}
},
"warm": {
"min_age": "0ms",
"actions": {
"forcemerge": { "max_num_segments": 1 },
"set_priority": { "priority": 50 }
}
},
"delete": {
"min_age": "90d",
"actions": { "delete": {} }
}
}
}
}
PUT _index_template/nginx-logs
{
"index_patterns": ["nginx-logs*"],
"data_stream": {},
"priority": 200,
"template": {
"settings": {
"index.lifecycle.name": "logs-policy",
"number_of_shards": 1,
"number_of_replicas": 1
}
}
}
update_chart_version:
stage: prepare
image: alpine:3.18
variables:
GIT_DEPTH: 0 # без этого в клоне не будет тегов для git describe
script:
- apk add --no-cache yq git
- |
RAW=$(git describe --tags --always --dirty 2>/dev/null || true)
VERSION=${RAW#v} # убираем префикс v: v1.2.3 -> 1.2.3
# если тега SemVer-вида нет (только хэш) — берём базовую версию
if ! echo "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+'; then
VERSION="0.0.0-${CI_COMMIT_SHORT_SHA}"
fi
echo "Chart version: $VERSION"
yq -i ".version = \"${VERSION}\"" chart/Chart.yaml
- cat chart/Chart.yaml
artifacts:
paths:
- chart/Chart.yaml
Вариант 🔤: Если чарты хранятся в отдельном общем репозитории
Настраиваем автоматический пуш обновлений в репозиторий чартов. Вместо устаревшего gitlab-ci-token для авторизации в GitLab безопаснее и актуальнее использовать oauth2.
update_helm_repo:
stage: deploy
image: alpine/git:2.40.1
script:
# HELM_CHARTS_TOKEN — Project/Group Access Token репозитория helm-charts
# со scope write_repository. Задать в Settings -> CI/CD -> Variables
# (Masked + Protected). Имя пользователя для такого токена — oauth2.
- git clone https://oauth2:${HELM_CHARTS_TOKEN}@gitlab.com/infrastructure/helm-charts.git
- cd helm-charts
- mkdir -p $SERVICE_NAME
- cp -r ../chart/* ./$SERVICE_NAME/
- git config user.email "ci@example.com"
- git config user.name "GitLab CI"
- git add .
# коммитим только при наличии изменений, чтобы не ломать пайплайн пустым коммитом
- git diff-index --quiet HEAD || git commit -m "Update $SERVICE_NAME to $CI_COMMIT_SHORT_SHA"
# -o ci.skip, чтобы пуш не запускал бесконечный пайплайн в репозитории чартов
- git push -o ci.skip origin HEAD:main
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
📌Важно: для кросс-репозиторного пуша CI_JOB_TOKEN не подходит — он даёт клонирование и доступ к API, но не право git push в чужой репозиторий (частичная поддержка появилась только в GitLab 19.1 и требует отдельной настройки allowlist на стороне целевого репозитория). Штатное решение — Project Access Token (или Group/Deploy Token) со scope write_repository, созданный в репозитории helm-charts с ролью не ниже Developer. Токен кладётся в CI/CD-переменную HELM_CHARTS_TOKEN (Masked + Protected). Имя пользователя в URL для access-токена — oauth2 (именно gitlab-ci-token используется только с CI_JOB_TOKEN).
😎 Практический план внедрения
1. Создать отдельный репозиторий для CI-шаблонов. Вынести в него общие этапы сборки, тестирования и деплоя.
2. В каждом сервисе заменить локальный громоздкий .gitlab-ci.yml на подключение шаблонов через include.
3. Унифицировать структуру Helm-чартов во всех сервисах. Использовать общую базу для values.
4. Настроить автоматическое вычисление версии чарта на основе git-тега или хэша коммита.
5. Разделять окружения через переменные: staging деплоится автоматически, а prod — строго вручную через when: manual.
Результат: в каждом сервисе всего 20–30 строк конфигурации вместо 200. Новый сервис добавляется за 5 минут: копируется лаконичный шаблон, меняется название, запускается пайплайн. Изменения в логике деплоя теперь раскатываются на все сотни сервисов одновременно — простым обновлением центрального шаблона.
Хочешь освоить GitLab CI и Helm на практике? 🔥Открывай демодоступы бесплатно🔥:
🔹GitlabCI & Helm & Kubernetes - полный кейс: CI/CD, Helm-чарты, деплой в Kubernetes.
🔹Gitlab CI -пайплайны, артефакты, кэширование, оптимизация и интеграции.
🔹Helm - создание чартов, управление зависимостями, сложная шаблонизация.
.gitlab/
├── templates/
│ ├── build.yml
│ ├── test.yml
│ ├── deploy.yml
│ └── helm.yml
└── jobs/
├── build-job.yml
└── deploy-job.yml
1️⃣ Шаблон для сборки образа (`templates/build.yml`)
Используем современные правила rules:if вместо устаревших конструкций.
.build_template:
stage: build
image: docker:24.0.7
services:
- docker:24.0.7-dind
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_TLS_VERIFY: "1"
# на self-managed раннере в config.toml должен быть volumes = ["/certs/client", "/cache"], иначе клиент не увидит сертификаты и джоба упадёт на TLS. На shared-раннерах GitLab.com это уже настроено.
DOCKER_CERT_PATH: "/certs/client"
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
- docker build --tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: always
2️⃣ Шаблон для деплоя с Helm (`templates/deploy.yml`)
.deploy_template:
stage: deploy
image: alpine/helm:3.12.0
script:
- helm upgrade --install "$CI_PROJECT_NAME" ./chart/ \
--set image.repository=$CI_REGISTRY_IMAGE \
--set image.tag=$CI_COMMIT_SHORT_SHA \
--set environment=$DEPLOY_ENV \
--namespace $DEPLOY_ENV \
--create-namespace \
--wait \
--timeout 5m
environment:
name: $DEPLOY_ENV
url: https://$CI_PROJECT_NAME.$DEPLOY_ENV.example.com
rules:
- if: '$DEPLOY_ENV == "prod" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
when: manual
- if: '$DEPLOY_ENV == "staging" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
when: on_success
3️⃣ Как теперь выглядит .gitlab-ci.yml внутри микросервиса
Каждый сервис определяет только свои переменные и расширяет (`extends`) готовые джобы. Обратите внимание на обязательное объявление стадий (`stages`), включая стадию предварительной подготовки.
include:
- project: 'infrastructure/ci-templates'
ref: main
file: '/templates/build.yml'
- project: 'infrastructure/ci-templates'
ref: main
file: '/templates/deploy.yml'
variables:
SERVICE_NAME: $CI_PROJECT_NAME
stages:
- prepare
- build
- test
- deploy
build:
extends: .build_template
deploy_staging:
extends: .deploy_template
variables:
DEPLOY_ENV: staging
deploy_prod:
extends: .deploy_template
variables:
DEPLOY_ENV: prod