Розбіжності

Тут показані розбіжності між вибраною ревізією та поточною версією сторінки.

Посилання на цей список змін

Порівняння попередніх версій Попередня ревізія
Наступна ревізія
Попередня ревізія
devops:jenkins [14/11/2025 22:55] osvexdevops:jenkins [14/11/2025 23:00] (поточний) osvex
Рядок 1: Рядок 1:
-======  ====== 
- 
-====== Jenkins  ====== 
- 
 ====== Автоматизація деплою стеку моніторингу за допомогою Jenkins + Ansible + Git ====== ====== Автоматизація деплою стеку моніторингу за допомогою Jenkins + Ansible + Git ======
  
 Ця стаття — шпаргалка з налаштування безпечного CI/CD пайплайну "Push-to-Deploy". Ця стаття — шпаргалка з налаштування безпечного CI/CD пайплайну "Push-to-Deploy".
  
-**Мета:** Автоматично оновлювати та перезапускати Docker Compose стек моніторингу на сервері щоразу, коли відбувається ''git push'' у ''main'' гілку.+**Мета:** Автоматично оновлювати та перезапускати Docker Compose стек моніторингу на сервері щоразу, коли відбувається git push у main гілку.
  
-----+-----
  
 ===== Архітектура рішення ===== ===== Архітектура рішення =====
Рядок 15: Рядок 11:
 Ми використовуємо модель із **поділом обов'язків** для максимальної безпеки та гнучкості: Ми використовуємо модель із **поділом обов'язків** для максимальної безпеки та гнучкості:
  
-   *+**Git (GitHub):** Єдине "джерело правди" для всіх конфігурацій.
  
-**Git (GitHub):** Єдине "джерело правдидля всіх конфігурацій. +* **Ansible (на хост-сервері):** иконавець(CD). Він встановлений на самому сервері sim-serv і єдиний, хто має доступ до Docker та файлів проєкту. Він виконує інструкції (плейбуки).
-  *+
  
-**Ansible (на хост-сервері):** "Виконавець" (CD). Він встановлений на самому сервері ''sim-serv'' і єдиний, хто має доступ до Docker та файлів проєкту. Він виконує інструкції (плейбуки). +* **Jenkins (в Docker):** "Оркестратор" (CI). Він ізольований у своєму контейнері **без** доступу до docker.sock і **без** root прав. Його єдина задача — "слухати" GitHub і, у разі змін, "дзвонити" по SSH на хост-сервер, наказуючи Ansible виконати плейбук.
-  *+
  
-**Jenkins (в Docker):** "Оркестратор" (CI). Він ізольований у своєму контейнері **без** доступу до ''docker.sock'' і **без**''root'' прав. Його єдина задача — "слухати" GitHub і, у разі змін, "дзвонити" по SSH на хост-сервер, наказуючи Ansible виконати плейбук. +-----
-----+
  
 ===== Крок 1: Налаштування Ansible (Виконавець) на хост-сервері ===== ===== Крок 1: Налаштування Ansible (Виконавець) на хост-сервері =====
  
-Все це виконується на сервері ''sim-serv'' (наприклад, з-під користувача ''osvex'').+Все це виконується на сервері sim-serv (наприклад, з-під користувача osvex).
  
 ==== Встановлення Ansible та Docker-бібліотек ==== ==== Встановлення Ansible та Docker-бібліотек ====
  
-====== Встановлення PPA та самого Ansible ======+\<code bash\> 
 + 
 +Встановлення PPA та самого Ansible
  
-<code bash> 
 sudo apt update sudo apt update
  
Рядок 43: Рядок 37:
 sudo apt install -y ansible sudo apt install -y ansible
  
-</code>+# Встановлення Python-бібліотеки для Docker (потрібно для модуля Ansible)
  
-====== Встановлення Python-бібліотеки для Docker (потрібно для модуля Ansible) ====== 
- 
-<code bash> 
 sudo apt install python3-docker sudo apt install python3-docker
  
-</code+\</code\>
- +
-</code>+
  
 ==== Створення робочої папки та файлів Ansible ==== ==== Створення робочої папки та файлів Ansible ====
  
-Ми зберігаємо всі конфігурації Ansible у ''/home/osvex/ansible/''.+Ми зберігаємо всі конфігурації Ansible у /home/osvex/ansible/.
  
-**1. Файл ''inventory'' (де виконувати):**+**1. Файл inventory (де виконувати):**
  
-Це наш список серверів. Оскільки Ansible керує сам собою, ми використовуємо ''localhost''.+Це наш список серверів. Оскільки Ansible керує сам собою, ми використовуємо localhost.
  
-<code ini>+\<code ini\>
  
-====== /home/osvex/ansible/inventory ======+/home/osvex/ansible/inventory
  
 [monitoring] [monitoring]
  
-localhost ansible_connection=local +localhost ansible\_connection=local
  
-</code>+\</code\>
  
-**2. Файл ''deploy_monitoring.yml'' (що робити):**+**2. Файл deploy_monitoring.yml (що робити):**
  
 Це "плейбук", або інструкція для Ansible. Він оновлює Git-репозиторій та перезапускає Docker Compose. Це "плейбук", або інструкція для Ansible. Він оновлює Git-репозиторій та перезапускає Docker Compose.
  
-<code yaml>+\<code yaml\>
  
-====== /home/osvex/ansible/deploy_monitoring.yml ======+/home/osvex/ansible/deploy\_monitoring.yml
  
-----+-----
  
-  *+- hosts: monitoring
  
-hosts: monitoring +become: no \# Не отримувати sudo, працювати від імені osvex
- +
-become: no # Не отримувати sudo, працювати від імені osvex+
  
 tasks: tasks:
  
-      *+- name: 1. Оновити код моніторингу з Git
  
-name: 1. Оновити код моніторингу з Git +Використовуємо вбудований git модуль
- +
-====== Використовуємо вбудований git модуль ======+
  
 git: git:
Рядок 101: Рядок 85:
 repo: '[email protected]:osvex/monitoring.git' repo: '[email protected]:osvex/monitoring.git'
  
-dest: '/home/osvex/docker/monitoring' # Шлях до проєкту на хості+dest: '/home/osvex/docker/monitoring' \# Шлях до проєкту на хості
  
 version: 'main' version: 'main'
  
-accept_hostkey: yes+accept\_hostkey: yes
  
 force: yes force: yes
  
-      * +name: 2. Перезапустити стек моніторингу (Docker Compose v2)
- +
-name: 2. Перезапустити стек моніторингу (Docker Compose v2)+
  
-====== Використовуємо звичайну команду, оскільки модуль v1 не підтримує v2 ======+Використовуємо звичайну команду, оскільки модуль v1 не підтримує v2
  
 ansible.builtin.command: ansible.builtin.command:
Рядок 119: Рядок 101:
 cmd: docker compose up -d --build --remove-orphans cmd: docker compose up -d --build --remove-orphans
  
-chdir: '/home/osvex/docker/monitoring' # Папка, з якої запускати+chdir: '/home/osvex/docker/monitoring' \# Папка, з якої запускати
  
 +\</code\>
  
-</code> +-----
- +
-----+
  
 ===== Крок 2: Налаштування Jenkins (Оркестратор) в Docker ===== ===== Крок 2: Налаштування Jenkins (Оркестратор) в Docker =====
Рядок 132: Рядок 113:
 ==== docker-compose.yml для Jenkins ==== ==== docker-compose.yml для Jenkins ====
  
-Це **безпечна** конфігурація. Ми **НЕ** використовуємо ''user: root'' і **НЕ** прокидаємо ''docker.sock''. Єдиний зв'язок зі світом — це "домашня" папка Jenkins.+Це **безпечна** конфігурація. Ми **НЕ** використовуємо user: root і **НЕ** прокидаємо docker.sock. Єдиний зв'язок зі світом — це "домашня" папка Jenkins.
  
-<code yaml>+\<code yaml\>
  
-====== /home/osvex/docker/jenkins/docker-compose.yml ======+/home/osvex/docker/jenkins/docker-compose.yml
  
 version: '3.8' version: '3.8'
Рядок 146: Рядок 127:
 image: jenkins/jenkins:lts-jdk17 image: jenkins/jenkins:lts-jdk17
  
-container_name: jenkins+container\_name: jenkins
  
 restart: unless-stopped restart: unless-stopped
  
-<code>''# Секція 'user: root' видалена для безпеки+\\ 
 +# Секція 'user: root' видалена для безпеки
  
 # Порти прокидаються через реверс-проксі (Traefik) # Порти прокидаються через реверс-проксі (Traefik)
 +
 # ports: # ports:
-  - "8090:8080"+ 
 +# - "8090:8080"
  
 labels: labels:
-  - "traefik.enable=true" + 
-  - "traefik.http.routers.jenkins.rule=Host(`jenkins.osvex.com`)" +- "traefik.enable=true" 
-  - "traefik.http.routers.jenkins.entrypoints=websecure" + 
-  - "traefik.http.routers.jenkins.tls.certresolver=lets-encrypt" +- "traefik.http.routers.jenkins.rule=Host(jenkins.osvex.com)" 
-  - "traefik.http.services.jenkins.loadbalancer.server.port=8080" # Внутрішній порт Jenkins + 
-  - "traefik.http.services.jenkins.loadbalancer.server.scheme=http" +- "traefik.http.routers.jenkins.entrypoints=websecure" 
-  - "traefik.docker.network=shared_traefik"+ 
 +- "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: volumes:
-  # Залишаємо ТІЛЬКИ цей один 'bind mount' для даних Jenkins 
-  - /srv/docker/jenkins:/var/jenkins_home 
  
-  # Всі інші volumes (docker.sock, /usr/bin/docker і т.д.) видалені+# Залишаємо ТІЛЬКИ цей один 'bind mount' для даних Jenkins 
 + 
 +- /srv/docker/jenkins:/var/jenkins_home 
 + 
 +# Всі інші volumes (docker.sock, /usr/bin/docker і т.д.) видалені
  
 networks: networks:
-  - shared_traefik 
-'' 
  
-</code>+- shared_traefik
  
 +\\
 networks: networks:
  
-shared_traefik:+shared\_traefik:
  
 external: true external: true
  
- +\</code\>
-</code>+
  
 ==== Встановлення прав на папку Jenkins ==== ==== Встановлення прав на папку Jenkins ====
  
-Оскільки Jenkins тепер працює від імені користувача ''jenkins'' (UID 1000), ми повинні надати йому права на "домашню" папку:+Оскільки Jenkins тепер працює від імені користувача jenkins (UID 1000), ми повинні надати йому права на "домашню" папку:
  
-<code bash>+\<code bash\>
  
 sudo chown -R 1000:1000 /srv/docker/jenkins/ sudo chown -R 1000:1000 /srv/docker/jenkins/
  
- +\</code\>
-</code>+
  
 ==== Необхідні плагіни Jenkins ==== ==== Необхідні плагіни Jenkins ====
  
-У Jenkins (через **Manage Jenkins -> Plugins**) мають бути встановлені:+У Jenkins (через **Manage Jenkins -\> Plugins**) мають бути встановлені:
  
-  *+**GitHub Integration** (для тригерів та вебхуків)
  
-**GitHub Integration** (для тригерів та вебхуків) +* **SSH Agent** (для використання SSH-ключів у пайплайнах)
-  *+
  
-**SSH Agent** (для використання SSH-ключів у пайплайнах) +-----
-----+
  
 ===== Крок 3: Налаштування "Мосту" (SSH-ключі та Webhook) ===== ===== Крок 3: Налаштування "Мосту" (SSH-ключі та Webhook) =====
  
-Ми створюємо два окремих SSH-ключа для двох різних завдань. Вони зберігаються у ''/srv/docker/jenkins/.ssh/'' (що відповідає ''/var/jenkins_home/.ssh/'' всередині контейнера).+Ми створюємо два окремих SSH-ключа для двох різних завдань. Вони зберігаються у /srv/docker/jenkins/.ssh/ (що відповідає /var/jenkins_home/.ssh/ всередині контейнера).
  
-==== Ключ 1: Для підключення до GitHub (id_rsa'') ====''+==== Ключ 1: Для підключення до GitHub (id\_rsa) ====
  
-  -+1. **Налаштування Jenkins:** Перейдіть у **Manage Jenkins -\> Credentials -\> Global** та додайте SSH Username with private key:
  
-**Налаштування Jenkins:** Перейдіть у **Manage Jenkins -> Credentials -> Global** та додайте ''SSH Username with private key'': +* **ID:** github-ssh-key
-      *+
  
-**ID:** ''github-ssh-key'' +* **Username:** git
-      *+
  
-**Username:** ''git'' +* **Private Key:** (Вміст id_rsa)
-      *+
  
-**Private Key:** (Вміст ''id_rsa'') +2. **Налаштування GitHub:** Перейдіть у **Репозиторій -\> Settings -\> Deploy keys** та додайте публічний ключ (вміст id_rsa.pub).
-  -+
  
-**Налаштування GitHub:** Перейдіть у **Репозиторій -> Settings -> Deploy keys** та додайте публічний ключ (вміст ''id_rsa.pub''). +==== Ключ 2: Для підключення до хоста (Ansible) (id\_rsa\_ansible) ====
-==== Ключ 2: Для підключення до хоста (Ansible) (id_rsa_ansible'') ====''+
  
-  -+1. **Налаштування Jenkins:** Перейдіть у **Manage Jenkins -\> Credentials -\> Global** та додайте SSH Username with private key:
  
-**Налаштування Jenkins:** Перейдіть у **Manage Jenkins -> Credentials -> Global** та додайте ''SSH Username with private key'': +* **ID:** ansible-ssh-key
-      *+
  
-**ID:** ''ansible-ssh-key'' +* **Username:** osvex (ваш логін на хост-сервері)
-      *+
  
-**Username:** ''osvex'' (ваш логін на хост-сервері) +* **Private Key:** (Вміст id_rsa_ansible)
-      *+
  
-**Private Key:** (Вміст ''id_rsa_ansible'') +2. **Налаштування хост-сервера:** Додайте публічний ключ (вміст id_rsa_ansible.pubдо списку довірених для користувача osvex:
-  -+
  
-Налаштування хост-сервера: Додайте публічний ключ (вміст id_rsa_ansible.pub) до списку довірених для користувача osvex:+\<code bash\>
  
-<code bash>+cat /srv/docker/jenkins/.ssh/id\_rsa\_ansible.pub \>\> /home/osvex/.ssh/authorized\_keys
  
-cat /srv/docker/jenkins/.ssh/id_rsa_ansible.pub >> /home/osvex/.ssh/authorized_keys+chmod 600 /home/osvex/.ssh/authorized\_keys
  
-chmod 600 /home/osvex/.ssh/authorized_keys+\</code\>
  
- +==== Налаштування known\_hosts (у Jenkins) ====
-</code> +
- +
-==== Налаштування known_hosts'' (у Jenkins) ====''+
  
 Jenkins повинен "довіряти" серверам, до яких він підключається. Jenkins повинен "довіряти" серверам, до яких він підключається.
  
-<code bash> +\<code bash\>
- +
-====== На хост-сервері виконайте: ======+
  
-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 github.com \>\> /srv/docker/jenkins/.ssh/known\_hosts
  
-ssh-keyscan -t rsa 172.17.0.1 >> /srv/docker/jenkins/.ssh/known_hosts # IP хоста зсередини Docker+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
  
-</code>+\</code\>
  
 ==== Налаштування GitHub Webhook ==== ==== Налаштування GitHub Webhook ====
  
-У **Репозиторій -> Settings -> Webhooks** додайте новий Webhook:+У **Репозиторій -\> Settings -\> Webhooks** додайте новий Webhook:
  
-  *+**Payload URL:** https://jenkins.osvex.com/github-webhook/
  
-**Payload URL:** ''https://jenkins.osvex.com/github-webhook/'' +* **Content type:** application/json
-  *+
  
-**Content type:** ''application/json'' +-----
-----+
  
 ===== Крок 4: Фінальний Jenkinsfile (Мозок) ===== ===== Крок 4: Фінальний Jenkinsfile (Мозок) =====
Рядок 290: Рядок 263:
 Цей файл лежить у корені вашого Git-репозиторію моніторингу. Він описує всю логіку пайплайну. Цей файл лежить у корені вашого Git-репозиторію моніторингу. Він описує всю логіку пайплайну.
  
-<code groovy>+\<code groovy\>
  
-====== /home/osvex/docker/monitoring/Jenkinsfile ======+/home/osvex/docker/monitoring/Jenkinsfile
  
 pipeline { pipeline {
Рядок 298: Рядок 271:
 agent any // Запускати на будь-якому агенті agent any // Запускати на будь-якому агенті
  
-<code>''stages {+\\ 
 +stages {
  
-    // Етап 1: Отримання коду з Git (Jenkins робить це автоматично) +// Етап 1: Отримання коду з Git (Jenkins робить це автоматично)
-    stage('Checkout') { +
-   steps { +
-            echo 'Отримання коду з репозиторію...' +
-            checkout scm +
-        } +
-    }+
  
-    // Етап 2: Запуск розгортання через Ansible +stage('Checkout') {
-    stage('Deploy via Ansible') { +
-        steps { +
-            echo 'Запуск плейбука Ansible на хост-сервері...'+
  
-            // "Обгортаємо" команду в sshagent, +steps { 
-            // щоб надати їй ключ 'ansible-ssh-key' (де вказано логін 'osvex') + 
-            sshagent(credentials: ['ansible-ssh-key']) {+echo 'Отримання коду з репозиторію...
 + 
 +checkout scm
  
-                // Виконуємо 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>+// Етап 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" 
 + 
 +'''
  
 } }
  
-</code>+}
  
-----+}
  
-===== Фінальний потік роботи (Workflow) =====+}
  
-  -+// Блок post-дій
  
-Ви робите ''git push'' зі змінами у ''docker-compose.yml'' або ''prometheus.yml''.+post {
  
-  -+success {
  
-GitHub "ловить" цей push і надсилає Webhook на ''https://jenkins.osvex.com''.+echo 'ЧУДОВО: Пайплайн Ansible успішно виконано.'
  
-  -+}
  
-Jenkins "прокидається", запускає пайплайн, завантажує ''Jenkinsfile''.+failure {
  
-  -+echo 'ПОМИЛКА: Пайплайн впав. Перевірте логи.' 
 + 
 +
 + 
 +
 + 
 +\\ 
 +
 + 
 +\</code\> 
 + 
 +----- 
 + 
 +===== Фінальний потік роботи (Workflow) =====
  
-Етап "Deploy" підключається по SSH до ''osvex@172.17.0.1'' (до вашого хост-сервера).+1. Ви робите git push зі змінами у docker-compose.yml або prometheus.yml.
  
-  -+2. GitHub "ловить" цей push і надсилає Webhook на https://jenkins.osvex.com.
  
-Jenkins виконує команду: ''ansible-playbook ...'' +3. Jenkins "прокидається", запускає пайплайн, завантажує Jenkinsfile.
-  -+
  
-Ansible (на хості) виконує плейбук:+4. Етап "Deploy" підключається по SSH до [email protected] (до вашого хост-сервера).
  
-      *+5. Jenkins виконує команду: ansible-playbook ...
  
-Заходить у ''/home/osvex/docker/monitoring'' і робить ''git pull''.+6. Ansible (на хості) виконує плейбук:
  
-      *+Заходить у /home/osvex/docker/monitoring і робить git pull.
  
-Запускає ''docker compose up -d ...'' +Запускає docker compose up -d ...
-  -+
  
-Jenkins отримує "успішний" статус від Ansible і завершує пайплайн з зеленим кольором.+7. Jenkins отримує "успішний" статус від Ansible і завершує пайплайн з зеленим кольором.
  
  • devops/jenkins.1763160902.txt.gz
  • Востаннє змінено: 14/11/2025 22:55
  • повз osvex