Розбіжності
Тут показані розбіжності між вибраною ревізією та поточною версією сторінки.
| Порівняння попередніх версій Попередня ревізія Наступна ревізія | Попередня ревізія | ||
| devops:jenkins [14/11/2025 22:56] – osvex | devops:jenkins [14/11/2025 23:00] (поточний) – osvex | ||
|---|---|---|---|
| Рядок 1: | Рядок 1: | ||
| - | Гаразд, це чудова | + | ====== Автоматизація деплою стеку моніторингу за допомогою Jenkins + Ansible + Git ====== |
| - | Оскільки ви будете використовувати DokuWiki, | + | Ця стаття |
| - | Ось готова | + | **Мета: |
| ----- | ----- | ||
| - | ## (Скопіюйте цей | + | ===== Архітектура рішення ===== |
| - | `====== Автоматизація | + | Ми використовуємо модель із **поділом обов'язків** |
| - | Ця стаття — шпаргалка з налаштування безпечного CI/CD пайплайну " | + | * **Git (GitHub):** Єдине " |
| - | **Мета:** Автоматично оновлювати та перезапускати Docker Compose стек | + | * **Ansible (на хост-сервері):** " |
| - | + | ||
| - | ----- | + | |
| - | + | ||
| - | `===== Архітектура рішення =====` | + | |
| - | + | ||
| - | Ми використовуємо модель із **поділом обов' | + | |
| - | * **Git (GitHub):** Єдине " | + | * **Jenkins (в Docker):** " |
| - | * **Ansible (на хост-сервері): | + | |
| - | | + | |
| ----- | ----- | ||
| - | `===== Крок 1: Налаштування Ansible (Виконавець) на хост-сервері =====` | + | ===== Крок 1: Налаштування Ansible (Виконавець) на хост-сервері ===== |
| - | Все це виконується на сервері | + | Все це виконується на сервері sim-serv (наприклад, |
| - | `==== Встановлення Ansible та Docker-бібліотек ====` | + | ==== Встановлення Ansible та Docker-бібліотек ==== |
| \<code bash\> | \<code bash\> | ||
| Рядок 38: | Рядок 30: | ||
| sudo apt update | sudo apt update | ||
| + | |||
| sudo apt install -y software-properties-common | sudo apt install -y software-properties-common | ||
| + | |||
| sudo add-apt-repository --yes --update ppa: | sudo add-apt-repository --yes --update ppa: | ||
| + | |||
| sudo apt install -y ansible | sudo apt install -y ansible | ||
| Рядок 45: | Рядок 40: | ||
| sudo apt install python3-docker | sudo apt install python3-docker | ||
| + | |||
| \</ | \</ | ||
| - | `==== Створення робочої папки та файлів Ansible ====` | + | ==== Створення робочої папки та файлів Ansible ==== |
| - | Ми зберігаємо всі конфігурації Ansible у `/ | + | Ми зберігаємо всі конфігурації Ansible у / |
| - | **1. Файл | + | **1. Файл inventory (де виконувати): |
| - | Це наш список серверів. Оскільки Ansible керує сам собою, ми використовуємо | + | Це наш список серверів. Оскільки Ansible керує сам собою, ми використовуємо localhost. |
| \<code ini\> | \<code ini\> | ||
| Рядок 60: | Рядок 56: | ||
| [monitoring] | [monitoring] | ||
| + | |||
| localhost ansible\_connection=local | localhost ansible\_connection=local | ||
| + | |||
| \</ | \</ | ||
| - | **2. Файл | + | **2. Файл deploy_monitoring.yml (що робити): |
| Це " | Це " | ||
| Рядок 73: | Рядок 71: | ||
| ----- | ----- | ||
| - | | + | - hosts: monitoring |
| - | become: no \# Не отримувати sudo, працювати від імені osvex | + | |
| - | tasks: | + | become: no \# Не отримувати sudo, працювати від імені osvex |
| - | - name: 1. Оновити код моніторингу з Git | + | tasks: |
| - | # Використовуємо вбудований git модуль | + | - name: 1. Оновити код моніторингу з Git |
| - | git: | + | # Використовуємо вбудований git модуль |
| - | repo: ' | + | |
| - | dest: '/ | + | |
| - | version: ' | + | |
| - | accept\_hostkey: | + | |
| - | force: yes | + | |
| - | - name: 2. Перезапустити стек моніторингу (Docker Compose v2) | + | git: |
| - | # Використовуємо звичайну команду, | + | repo: ' |
| - | | + | dest: '/ |
| - | cmd: docker compose up -d --build --remove-orphans | + | |
| - | chdir: '/ | + | version: ' |
| + | |||
| + | accept\_hostkey: | ||
| + | |||
| + | force: yes | ||
| + | |||
| + | - name: 2. Перезапустити стек моніторингу (Docker Compose v2) | ||
| + | |||
| + | # Використовуємо звичайну команду, | ||
| + | |||
| + | ansible.builtin.command: | ||
| + | |||
| + | cmd: docker compose up -d --build --remove-orphans | ||
| + | |||
| + | chdir: '/ | ||
| \</ | \</ | ||
| Рядок 101: | Рядок 107: | ||
| ----- | ----- | ||
| - | `===== Крок 2: Налаштування Jenkins (Оркестратор) в Docker =====` | + | ===== Крок 2: Налаштування Jenkins (Оркестратор) в Docker ===== |
| Jenkins запускається у власному ізольованому Docker-контейнері. | Jenkins запускається у власному ізольованому Docker-контейнері. | ||
| - | ` ==== `docker-compose.yml` | + | ==== docker-compose.yml для Jenkins ==== |
| - | Це **безпечна** конфігурація. Ми **НЕ** використовуємо | + | Це **безпечна** конфігурація. Ми **НЕ** використовуємо user: root і **НЕ** прокидаємо docker.sock. Єдиний зв' |
| \<code yaml\> | \<code yaml\> | ||
| Рядок 116: | Рядок 122: | ||
| services: | services: | ||
| + | |||
| jenkins: | jenkins: | ||
| + | |||
| image: jenkins/ | image: jenkins/ | ||
| + | |||
| container\_name: | container\_name: | ||
| + | |||
| restart: unless-stopped | restart: unless-stopped | ||
| - | ``` | + | \\ |
| # Секція 'user: root' видалена для безпеки | # Секція 'user: root' видалена для безпеки | ||
| # Порти прокидаються через реверс-проксі (Traefik) | # Порти прокидаються через реверс-проксі (Traefik) | ||
| + | |||
| # ports: | # ports: | ||
| - | # | + | |
| - | + | # - " | |
| labels: | labels: | ||
| - | | + | |
| - | - " | + | - " |
| - | - " | + | |
| - | - " | + | - " |
| - | - " | + | |
| - | - " | + | - " |
| - | - " | + | |
| + | - " | ||
| + | |||
| + | - " | ||
| + | |||
| + | - " | ||
| + | |||
| + | - " | ||
| volumes: | volumes: | ||
| - | | + | |
| - | - / | + | # Залишаємо ТІЛЬКИ цей один 'bind mount' для даних Jenkins |
| - | + | ||
| - | # Всі інші volumes (docker.sock, | + | - / |
| + | |||
| + | # Всі інші volumes (docker.sock, | ||
| networks: | networks: | ||
| - | - shared_traefik | ||
| - | ``` | ||
| + | - shared_traefik | ||
| + | |||
| + | \\ | ||
| networks: | networks: | ||
| + | |||
| shared\_traefik: | shared\_traefik: | ||
| + | |||
| external: true | external: true | ||
| + | |||
| \</ | \</ | ||
| - | `==== Встановлення прав на папку Jenkins ====` | + | ==== Встановлення прав на папку Jenkins ==== |
| - | Оскільки Jenkins тепер працює від імені користувача | + | Оскільки Jenkins тепер працює від імені користувача jenkins (UID 1000), ми повинні надати йому права на " |
| \<code bash\> | \<code bash\> | ||
| + | |||
| sudo chown -R 1000:1000 / | sudo chown -R 1000:1000 / | ||
| + | |||
| \</ | \</ | ||
| - | `==== Необхідні плагіни Jenkins ====` | + | ==== Необхідні плагіни Jenkins ==== |
| У Jenkins (через **Manage Jenkins -\> Plugins**) мають бути встановлені: | У Jenkins (через **Manage Jenkins -\> Plugins**) мають бути встановлені: | ||
| - | | + | * **GitHub Integration** (для тригерів та вебхуків) |
| - | * **SSH Agent** (для використання SSH-ключів у пайплайнах) | + | |
| + | * **SSH Agent** (для використання SSH-ключів у пайплайнах) | ||
| ----- | ----- | ||
| - | `===== Крок 3: Налаштування " | + | ===== Крок 3: Налаштування " |
| - | Ми створюємо два окремих SSH-ключа для двох різних завдань. Вони зберігаються у `/ | + | Ми створюємо два окремих SSH-ключа для двох різних завдань. Вони зберігаються у / |
| - | `==== Ключ 1: Для підключення до GitHub (`id\_rsa`) ====` | + | ==== Ключ 1: Для підключення до GitHub (id\_rsa) ==== |
| - | 1. **Налаштування Jenkins:** Перейдіть у **Manage Jenkins -\> Credentials -\> Global** та додайте | + | 1. **Налаштування Jenkins:** Перейдіть у **Manage Jenkins -\> Credentials -\> Global** та додайте SSH Username with private key: |
| - | * **ID:** `github-ssh-key` | + | |
| - | * **Username: | + | |
| - | * **Private Key:** (Вміст `id_rsa`) | + | |
| - | 2. **Налаштування GitHub:** Перейдіть у **Репозиторій -\> Settings -\> Deploy keys** та додайте публічний ключ (вміст `id_rsa.pub`). | + | |
| - | `==== Ключ 2: Для підключення до хоста (Ansible) (`id\_rsa\_ansible`) ====` | + | * **ID:** github-ssh-key |
| - | 1. | + | * **Username: |
| - | | + | |
| - | * **Username: | + | |
| - | * **Private Key:** (Вміст `id_rsa_ansible`) | + | |
| - | 2. **Налаштування хост-сервера: | + | |
| - | \<code bash\> | + | |
| - | cat / | + | |
| - | chmod 600 / | + | |
| - | \</ | + | |
| - | ` ==== Налаштування | + | * **Private Key:** (Вміст id_rsa) |
| + | |||
| + | 2. **Налаштування GitHub:** Перейдіть у **Репозиторій -\> Settings -\> Deploy keys** та додайте публічний ключ (вміст id_rsa.pub). | ||
| + | |||
| + | ==== Ключ 2: Для підключення до хоста (Ansible) (id\_rsa\_ansible) ==== | ||
| + | |||
| + | 1. **Налаштування Jenkins:** Перейдіть у **Manage Jenkins -\> Credentials -\> Global** та додайте SSH Username with private key: | ||
| + | |||
| + | * **ID:** ansible-ssh-key | ||
| + | |||
| + | * **Username: | ||
| + | |||
| + | * **Private Key:** (Вміст id_rsa_ansible) | ||
| + | |||
| + | 2. **Налаштування хост-сервера: | ||
| + | |||
| + | \<code bash\> | ||
| + | |||
| + | cat / | ||
| + | |||
| + | chmod 600 / | ||
| + | |||
| + | \</ | ||
| + | |||
| + | ==== Налаштування known\_hosts (у Jenkins) ==== | ||
| Jenkins повинен " | Jenkins повинен " | ||
| Рядок 202: | Рядок 242: | ||
| ssh-keyscan -t rsa github.com \>\> / | ssh-keyscan -t rsa github.com \>\> / | ||
| + | |||
| ssh-keyscan -t ed25519 github.com \>\> / | ssh-keyscan -t ed25519 github.com \>\> / | ||
| + | |||
| ssh-keyscan -t rsa 172.17.0.1 \>\> / | ssh-keyscan -t rsa 172.17.0.1 \>\> / | ||
| + | |||
| \</ | \</ | ||
| - | `==== Налаштування GitHub Webhook ====` | + | ==== Налаштування GitHub Webhook ==== |
| У **Репозиторій -\> Settings -\> Webhooks** додайте новий Webhook: | У **Репозиторій -\> Settings -\> Webhooks** додайте новий Webhook: | ||
| - | | + | * **Payload URL:** https:// |
| - | * **Content type: | + | |
| + | * **Content type:** application/ | ||
| ----- | ----- | ||
| - | ` ===== Крок 4: Фінальний | + | ===== Крок 4: Фінальний Jenkinsfile (Мозок) ===== |
| Цей файл лежить у корені вашого Git-репозиторію моніторингу. Він описує всю логіку пайплайну. | Цей файл лежить у корені вашого Git-репозиторію моніторингу. Він описує всю логіку пайплайну. | ||
| Рядок 224: | Рядок 268: | ||
| pipeline { | pipeline { | ||
| + | |||
| agent any // Запускати на будь-якому агенті | agent any // Запускати на будь-якому агенті | ||
| - | ``` | + | \\ |
| stages { | stages { | ||
| - | | ||
| - | // Етап 1: Отримання коду з Git (Jenkins робить це автоматично) | ||
| - | stage(' | ||
| - | steps { | ||
| - | echo ' | ||
| - | checkout scm | ||
| - | } | ||
| - | } | ||
| - | | + | // Етап 1: Отримання коду з Git (Jenkins робить це автоматично) |
| - | stage(' | + | |
| - | steps { | + | stage(' |
| - | echo ' | + | |
| - | + | steps { | |
| - | // " | + | |
| - | // щоб надати їй ключ ' | + | echo ' |
| - | sshagent(credentials: | + | |
| - | + | checkout scm | |
| - | // Виконуємо SSH-команду | + | |
| - | // Ми підключаємось до 172.17.0.1 (IP хост-сервера зсередини Docker) | + | } |
| - | // і запускаємо наш плейбук | + | |
| - | sh ''' | + | } |
| - | ssh -o StrictHostKeyChecking=no [email protected] \ | + | |
| - | "cd / | + | // Етап 2: Запуск розгортання через Ansible |
| - | ''' | + | |
| - | } | + | stage(' |
| - | } | + | |
| - | } | + | steps { |
| + | |||
| + | echo ' | ||
| + | |||
| + | // " | ||
| + | |||
| + | // щоб надати їй ключ ' | ||
| + | |||
| + | sshagent(credentials: | ||
| + | |||
| + | // Виконуємо SSH-команду | ||
| + | |||
| + | // Ми підключаємось до 172.17.0.1 (IP хост-сервера зсередини Docker) | ||
| + | |||
| + | // і запускаємо наш плейбук | ||
| + | |||
| + | sh ''' | ||
| + | |||
| + | ssh -o StrictHostKeyChecking=no [email protected] \ | ||
| + | |||
| + | "cd / | ||
| + | |||
| + | ''' | ||
| + | |||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | } | ||
| } | } | ||
| // Блок post-дій | // Блок post-дій | ||
| + | |||
| post { | post { | ||
| - | | + | |
| - | echo ' | + | success { |
| - | } | + | |
| - | failure { | + | echo ' |
| - | echo ' | + | |
| - | } | + | |
| } | } | ||
| - | ``` | + | |
| + | failure { | ||
| + | |||
| + | echo ' | ||
| } | } | ||
| + | |||
| + | } | ||
| + | |||
| + | \\ | ||
| + | } | ||
| + | |||
| \</ | \</ | ||
| ----- | ----- | ||
| - | `===== Фінальний потік роботи (Workflow) =====` | + | ===== Фінальний потік роботи (Workflow) ===== |
| + | |||
| + | 1. Ви робите git push зі змінами у docker-compose.yml або prometheus.yml. | ||
| + | |||
| + | 2. GitHub " | ||
| + | |||
| + | 3. Jenkins " | ||
| + | |||
| + | 4. Етап " | ||
| + | |||
| + | 5. Jenkins виконує команду: | ||
| + | |||
| + | 6. Ansible (на хості) виконує плейбук: | ||
| + | |||
| + | * Заходить у / | ||
| + | |||
| + | * Запускає docker compose up -d ... | ||
| + | |||
| + | 7. Jenkins отримує " | ||
| - | 1. Ви робите `git push` зі змінами у `docker-compose.yml` або `prometheus.yml`. | ||
| - | 2. GitHub " | ||
| - | 3. Jenkins " | ||
| - | 4. Етап " | ||
| - | 5. Jenkins виконує команду: | ||
| - | 6. Ansible (на хості) виконує плейбук: | ||
| - | * Заходить у `/ | ||
| - | * Запускає `docker compose up -d ...` | ||
| - | 7. Jenkins отримує " | ||