Це стара версія документу!
Jenkins
Автоматизація деплою стеку моніторингу за допомогою Jenkins + Ansible + Git
Ця стаття — шпаргалка з налаштування безпечного CI/CD пайплайну “Push-to-Deploy”.
Мета: Автоматично оновлювати та перезапускати Docker Compose стек моніторингу на сервері щоразу, коли відбувається git push у main гілку.
Архітектура рішення
Ми використовуємо модель із поділом обов'язків для максимальної безпеки та гнучкості:
Git (GitHub): Єдине “джерело правди” для всіх конфігурацій.
Ansible (на хост-сервері): “Виконавець” (CD). Він встановлений на самому сервері sim-serv і єдиний, хто має доступ до Docker та файлів проєкту. Він виконує інструкції (плейбуки).
Jenkins (в Docker): “Оркестратор” (CI). Він ізольований у своєму контейнері без доступу до docker.sock і безroot прав. Його єдина задача — “слухати” GitHub і, у разі змін, “дзвонити” по SSH на хост-сервер, наказуючи Ansible виконати плейбук.
Крок 1: Налаштування Ansible (Виконавець) на хост-сервері
Все це виконується на сервері sim-serv (наприклад, з-під користувача osvex).
Встановлення Ansible та Docker-бібліотек
Встановлення PPA та самого Ansible
sudo apt update sudo apt install -y software-properties-common sudo add-apt-repository --yes --update ppa:ansible/ansible sudo apt install -y ansible
Встановлення Python-бібліотеки для Docker (потрібно для модуля Ansible)
sudo apt install python3-docker
</code>
Створення робочої папки та файлів Ansible
Ми зберігаємо всі конфігурації Ansible у /home/osvex/ansible/.
1. Файл inventory (де виконувати):
Це наш список серверів. Оскільки Ansible керує сам собою, ми використовуємо localhost.
====== /home/osvex/ansible/inventory ====== [monitoring] localhost ansible_connection=local
2. Файл deploy_monitoring.yml (що робити):
Це “плейбук”, або інструкція для Ansible. Він оновлює Git-репозиторій та перезапускає Docker Compose.
====== /home/osvex/ansible/deploy_monitoring.yml ====== ---- * hosts: monitoring become: no # Не отримувати sudo, працювати від імені osvex tasks: * name: 1. Оновити код моніторингу з Git ====== Використовуємо вбудований git модуль ====== git: repo: '[email protected]:osvex/monitoring.git' dest: '/home/osvex/docker/monitoring' # Шлях до проєкту на хості version: 'main' accept_hostkey: yes force: yes * name: 2. Перезапустити стек моніторингу (Docker Compose v2) ====== Використовуємо звичайну команду, оскільки модуль v1 не підтримує v2 ====== ansible.builtin.command: cmd: docker compose up -d --build --remove-orphans chdir: '/home/osvex/docker/monitoring' # Папка, з якої запускати
Крок 2: Налаштування Jenkins (Оркестратор) в Docker
Jenkins запускається у власному ізольованому Docker-контейнері.
docker-compose.yml для Jenkins
Це безпечна конфігурація. Ми НЕ використовуємо user: root і НЕ прокидаємо docker.sock. Єдиний зв'язок зі світом — це “домашня” папка Jenkins.
====== /home/osvex/docker/jenkins/docker-compose.yml ====== version: '3.8' services: jenkins: image: jenkins/jenkins:lts-jdk17 container_name: jenkins restart: unless-stopped <code>''# Секція 'user: root' видалена для безпеки # Порти прокидаються через реверс-проксі (Traefik) # ports: # - "8090:8080" labels: - "traefik.enable=true" - "traefik.http.routers.jenkins.rule=Host(`jenkins.osvex.com`)" - "traefik.http.routers.jenkins.entrypoints=websecure" - "traefik.http.routers.jenkins.tls.certresolver=lets-encrypt" - "traefik.http.services.jenkins.loadbalancer.server.port=8080" # Внутрішній порт Jenkins - "traefik.http.services.jenkins.loadbalancer.server.scheme=http" - "traefik.docker.network=shared_traefik" volumes: # Залишаємо ТІЛЬКИ цей один 'bind mount' для даних Jenkins - /srv/docker/jenkins:/var/jenkins_home # Всі інші volumes (docker.sock, /usr/bin/docker і т.д.) видалені networks: - shared_traefik ''
networks:
shared_traefik:
external: true
</code>
Встановлення прав на папку Jenkins
Оскільки Jenkins тепер працює від імені користувача jenkins (UID 1000), ми повинні надати йому права на “домашню” папку:
sudo chown -R 1000:1000 /srv/docker/jenkins/
Необхідні плагіни Jenkins
У Jenkins (через Manage Jenkins → Plugins) мають бути встановлені:
GitHub Integration (для тригерів та вебхуків)
SSH Agent (для використання SSH-ключів у пайплайнах)
Крок 3: Налаштування "Мосту" (SSH-ключі та Webhook)
Ми створюємо два окремих SSH-ключа для двох різних завдань. Вони зберігаються у /srv/docker/jenkins/.ssh/ (що відповідає /var/jenkins_home/.ssh/ всередині контейнера).
==== Ключ 1: Для підключення до GitHub (id_rsa) ====
Налаштування Jenkins: Перейдіть у Manage Jenkins → Credentials → Global та додайте SSH Username with private key:
ID: github-ssh-key
Username: git
Private Key: (Вміст id_rsa)
Налаштування GitHub: Перейдіть у Репозиторій → Settings → Deploy keys та додайте публічний ключ (вміст id_rsa.pub).
==== Ключ 2: Для підключення до хоста (Ansible) (id_rsa_ansible) ====
Налаштування Jenkins: Перейдіть у Manage Jenkins → Credentials → Global та додайте SSH Username with private key:
ID: ansible-ssh-key
Username: osvex (ваш логін на хост-сервері)
Private Key: (Вміст id_rsa_ansible)
Налаштування хост-сервера: Додайте публічний ключ (вміст id_rsa_ansible.pub) до списку довірених для користувача osvex:
cat /srv/docker/jenkins/.ssh/id_rsa_ansible.pub >> /home/osvex/.ssh/authorized_keys chmod 600 /home/osvex/.ssh/authorized_keys
==== Налаштування known_hosts (у Jenkins) ====
Jenkins повинен “довіряти” серверам, до яких він підключається.
====== На хост-сервері виконайте: ====== ssh-keyscan -t rsa github.com >> /srv/docker/jenkins/.ssh/known_hosts ssh-keyscan -t ed25519 github.com >> /srv/docker/jenkins/.ssh/known_hosts ssh-keyscan -t rsa 172.17.0.1 >> /srv/docker/jenkins/.ssh/known_hosts # IP хоста зсередини Docker
Налаштування GitHub Webhook
У Репозиторій → Settings → Webhooks додайте новий Webhook:
Payload URL: https://jenkins.osvex.com/github-webhook/
Content type: application/json
Крок 4: Фінальний Jenkinsfile (Мозок)
Цей файл лежить у корені вашого Git-репозиторію моніторингу. Він описує всю логіку пайплайну.
====== /home/osvex/docker/monitoring/Jenkinsfile ====== pipeline { agent any // Запускати на будь-якому агенті <code>''stages { // Етап 1: Отримання коду з Git (Jenkins робить це автоматично) stage('Checkout') { steps { echo 'Отримання коду з репозиторію...' checkout scm } } // Етап 2: Запуск розгортання через Ansible stage('Deploy via Ansible') { steps { echo 'Запуск плейбука Ansible на хост-сервері...' // "Обгортаємо" команду в sshagent, // щоб надати їй ключ 'ansible-ssh-key' (де вказано логін 'osvex') sshagent(credentials: ['ansible-ssh-key']) { // Виконуємо SSH-команду // Ми підключаємось до 172.17.0.1 (IP хост-сервера зсередини Docker) // і запускаємо наш плейбук sh ''' ssh -o StrictHostKeyChecking=no [email protected] \ "cd /home/osvex/ansible && ansible-playbook -i inventory deploy_monitoring.yml" ''' } } } } // Блок post-дій post { success { echo 'ЧУДОВО: Пайплайн Ansible успішно виконано.' } failure { echo 'ПОМИЛКА: Пайплайн впав. Перевірте логи.' } } ''
}
</code>
Фінальний потік роботи (Workflow)
Ви робите git push зі змінами у docker-compose.yml або prometheus.yml.
GitHub “ловить” цей push і надсилає Webhook на https://jenkins.osvex.com.
Jenkins “прокидається”, запускає пайплайн, завантажує Jenkinsfile.
Етап “Deploy” підключається по SSH до [email protected] (до вашого хост-сервера).
Jenkins виконує команду: ansible-playbook …
Ansible (на хості) виконує плейбук:
Заходить у /home/osvex/docker/monitoring і робить git pull.
Запускає docker compose up -d …
Jenkins отримує “успішний” статус від Ansible і завершує пайплайн з зеленим кольором.