Обновить readme.md
This commit is contained in:
1 parent
a6899fe71e
commit
b2447b6ea8
1 file changed
+112
-90
@@ -1,8 +1,10 @@
|
|||||||
# Документация проекта: Развертывание резервной конфигурации HAProxy по требованию
|
# Документация проекта: Развертывание конфигурации HAProxy по событию через systemd path
|
||||||
|
|
||||||
## 1. Архитектурное описание
|
## 1. Архитектурное описание
|
||||||
|
|
||||||
Комплекс предназначен для контролируемого применения резервной конфигурации балансировщика **HAProxy** по клику оператора с рабочей станции Windows.
|
Комплекс предназначен для мгновенного и контролируемого отката/применения резервной конфигурации балансировщика **HAProxy** по клику оператора с рабочей станции Windows.
|
||||||
|
|
||||||
|
Вместо периодического опроса через cron система использует событийную модель ядра Linux (**inotify**) через связку **systemd path** + **systemd service**, что обеспечивает нулевую задержку реакции и отсутствие холостых запусков скрипта.
|
||||||
|
|
||||||
```
|
```
|
||||||
[ Рабочая станция Windows ]
|
[ Рабочая станция Windows ]
|
||||||
@@ -11,56 +13,34 @@
|
|||||||
|
|
|
|
||||||
deployfile.exe (.NET 4.8)
|
deployfile.exe (.NET 4.8)
|
||||||
|
|
|
|
||||||
| (1. SSH connection: ed25519)
|
| (1. SSH-сессия: ed25519)
|
||||||
| (2. Генерация status/change.me + status/sha256.hash)
|
| (2. Запись status/change.me + status/sha256.hash)
|
||||||
v
|
v
|
||||||
[ Linux-сервер (HAProxy) ]
|
[ Linux-сервер (HAProxy) ]
|
||||||
/var/lib/depfile/ (Домашний каталог depfile)
|
/var/lib/depfile/status/change.me
|
||||||
├── .ssh/authorized_keys
|
|
||||||
├── status/
|
|
||||||
│ ├── change.me
|
|
||||||
│ └── sha256.hash
|
|
||||||
└── deployment/
|
|
||||||
└── success.me
|
|
||||||
|
|
|
|
||||||
(cron: раз в минуту)
|
(Событие inotify: IN_CLOSE_WRITE)
|
||||||
v
|
v
|
||||||
deploy_haproxy.sh (Bash)
|
depfile-watcher.path (systemd)
|
||||||
|
| (Активирует однократный сервис)
|
||||||
|
v
|
||||||
|
depfile-watcher.service (systemd: oneshot)
|
||||||
|
| (Запуск /usr/local/bin/deploy_haproxy.sh)
|
||||||
|
|
|
||||||
|-- 1. Валидация SHA-256 суммы файла change.me
|
|-- 1. Валидация SHA-256 суммы файла change.me
|
||||||
|-- 2. Валидация синтаксиса backup/haproxy.cfg (haproxy -c)
|
|-- 2. Проверка синтаксиса backup/haproxy.cfg (haproxy -c)
|
||||||
|-- 3. Подмена /etc/haproxy/haproxy.cfg
|
|-- 3. Подмена боевого /etc/haproxy/haproxy.cfg
|
||||||
|-- 4. Перезапуск службы haproxy (systemctl restart)
|
|-- 4. Перезапуск службы haproxy (systemctl restart)
|
||||||
|-- 5. Удаление каталога status/
|
|-- 5. Удаление директории status/
|
||||||
`-- 6. Запись метки в deployment/success.me
|
`-- 6. Запись отчета в deployment/success.me
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Принцип работы
|
|
||||||
|
|
||||||
1. **Windows-клиент (`deployfile.exe`):**
|
|
||||||
* Разработан на .NET Framework 4.8 без внешних библиотек.
|
|
||||||
* Вызывает встроенный клиент Windows OpenSSH (`ssh.exe`) с автоопределением путей (включая обход WOW64-редиректа `Sysnative` для 32-битных процессов) и автоматической установкой OpenSSH через PowerShell при его отсутствии.
|
|
||||||
* Генерирует случайный текстовый блок, подключается к серверу по SSH под пользователем `depfile` с использованием ED25519-ключа и записывает данные в `/var/lib/depfile/status/change.me`.
|
|
||||||
* На стороне сервера генерирует файл контрольной суммы `/var/lib/depfile/status/sha256.hash`.
|
|
||||||
|
|
||||||
|
|
||||||
2. **Серверный обработчик (`deploy_haproxy.sh`):**
|
|
||||||
* Выполняется по cron от имени `root`.
|
|
||||||
* Проверяет наличие файла `/var/lib/depfile/status/change.me`. Если файл отсутствует — завершает работу без нагрузки на систему.
|
|
||||||
* Валидирует целостность `change.me` через `sha256sum -c`.
|
|
||||||
* Выполняет проверку синтаксиса резервного файла (`haproxy -c -f /etc/haproxy/backup/haproxy.cfg`). При обнаружении ошибок применение отменяется.
|
|
||||||
* Копирует резервную конфигурацию в боевой файл `/etc/haproxy/haproxy.cfg`.
|
|
||||||
* Перезапускает службу `haproxy`.
|
|
||||||
* Удаляет временную директорию `/var/lib/depfile/status`.
|
|
||||||
* Фиксирует статус и метку времени в файле `/var/lib/depfile/deployment/success.me`.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Настройка Linux-сервера
|
## 2. Настройка Linux-сервера
|
||||||
|
|
||||||
### 2.1. Создание сервисного пользователя и директорий
|
### 2.1. Создание сервисного пользователя и рабочих каталогов
|
||||||
|
|
||||||
Подключитесь к серверу с правами `root` или через `sudo`:
|
Подключитесь к серверу с правами `root` или через `sudo`:
|
||||||
|
|
||||||
@@ -68,11 +48,11 @@
|
|||||||
# 1. Создаем системного пользователя с домашним каталогом /var/lib/depfile
|
# 1. Создаем системного пользователя с домашним каталогом /var/lib/depfile
|
||||||
sudo useradd -m -d /var/lib/depfile -s /bin/bash -c "File deploment service" depfile
|
sudo useradd -m -d /var/lib/depfile -s /bin/bash -c "File deploment service" depfile
|
||||||
|
|
||||||
# 2. Выставляем права доступа на домашнюю директорию
|
# 2. Назначаем права доступа на домашний каталог
|
||||||
sudo chown -R depfile:depfile /var/lib/depfile
|
sudo chown -R depfile:depfile /var/lib/depfile
|
||||||
sudo chmod 750 /var/lib/depfile
|
sudo chmod 750 /var/lib/depfile
|
||||||
|
|
||||||
# 3. Создаем каталог резервных конфигураций HAProxy и копируем текущий рабочий конфиг
|
# 3. Создаем каталог резервных конфигураций HAProxy и размещаем эталонный конфиг
|
||||||
sudo mkdir -p /etc/haproxy/backup
|
sudo mkdir -p /etc/haproxy/backup
|
||||||
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/backup/haproxy.cfg
|
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/backup/haproxy.cfg
|
||||||
sudo chown -R root:root /etc/haproxy/backup
|
sudo chown -R root:root /etc/haproxy/backup
|
||||||
@@ -82,7 +62,7 @@ sudo chmod 750 /etc/haproxy/backup
|
|||||||
|
|
||||||
### 2.2. Подготовка каталога SSH-ключей
|
### 2.2. Подготовка каталога SSH-ключей
|
||||||
|
|
||||||
Так как домашний каталог пользователя расположен в `/var/lib/depfile`, файл доверенных ключей находится по пути `/var/lib/depfile/.ssh/authorized_keys`:
|
Домашняя директория пользователя — `/var/lib/depfile`, соответственно путь к файлу доверенных ключей: `/var/lib/depfile/.ssh/authorized_keys`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo -u depfile mkdir -p /var/lib/depfile/.ssh
|
sudo -u depfile mkdir -p /var/lib/depfile/.ssh
|
||||||
@@ -94,77 +74,129 @@ sudo chmod 600 /var/lib/depfile/.ssh/authorized_keys
|
|||||||
|
|
||||||
### 2.3. Создание скрипта развертывания
|
### 2.3. Создание скрипта развертывания
|
||||||
|
|
||||||
Создайте файл `/usr/local/bin/deploy_haproxy.sh`:
|
Создайте исполняемый файл `/usr/local/bin/deploy_haproxy.sh`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo nano /usr/local/bin/deploy_haproxy.sh
|
sudo nano /usr/local/bin/deploy_haproxy.sh
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Вставьте следующий код:
|
Содержимое скрипта:
|
||||||
|
|
||||||
[deploy_haproxy.sh](deploy_haproxy.sh)
|
[deploy_haproxy.sh](deploy_haproxy.sh)
|
||||||
|
|
||||||
Назначьте права на запуск:
|
Назначьте права на выполнение:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo chmod +x /usr/local/bin/deploy_haproxy.sh
|
sudo chmod +x /usr/local/bin/deploy_haproxy.sh
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.4. Настройка периодического запуска в cron
|
---
|
||||||
|
|
||||||
Откройте планировщик суперпользователя:
|
### 2.4. Настройка связки systemd (Path + Service)
|
||||||
|
|
||||||
|
Для мгновенного реагирования создаются два системных юнита.
|
||||||
|
|
||||||
|
#### Шаг 1: Юнит сервиса (`depfile-watcher.service`)
|
||||||
|
|
||||||
|
Создайте файл описания процесса:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo crontab -e
|
sudo nano /etc/systemd/system/depfile-watcher.service
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Добавьте задачу запуска раз в минуту:
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=HAProxy Config Rollback Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
```cron
|
[Service]
|
||||||
* * * * * /usr/local/bin/deploy_haproxy.sh >> /var/log/deploy_haproxy.log 2>&1
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/bin/deploy_haproxy.sh
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Шаг 2: Юнит отслеживания файловой системы (`depfile-watcher.path`)
|
||||||
|
|
||||||
|
Создайте файл монитора событий:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo nano /etc/systemd/system/depfile-watcher.path
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Watch for deployment trigger file change.me
|
||||||
|
|
||||||
|
[Path]
|
||||||
|
# PathChanged срабатывает в момент, когда запись в файл завершена и дескриптор закрыт (IN_CLOSE_WRITE)
|
||||||
|
PathChanged=/var/lib/depfile/status/change.me
|
||||||
|
Unit=depfile-watcher.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Шаг 3: Активация и запуск монитора
|
||||||
|
|
||||||
|
Примените конфигурацию и включите монитор в автозагрузку:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now depfile-watcher.path
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверьте статус наблюдателя:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status depfile-watcher.path
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
*(Должен быть в статусе `active (waiting)`).*
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Настройка рабочей станции Windows
|
## 3. Настройка рабочей станции Windows
|
||||||
|
|
||||||
### 3.1. Генерация SSH-ключа
|
### 3.1. Генерация SSH-ключа
|
||||||
|
|
||||||
В командной строке (`cmd`) или PowerShell выполните:
|
В командной строке (`cmd`) или PowerShell на рабочей станции:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
ssh-keygen -t ed25519 -f "D:\sys\C-Sharp\deployfile\key\test_key.key" -N ""
|
ssh-keygen -t ed25519 -f "D:\sys\C-Sharp\deployfile\key\test_key.key" -N ""
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Создаются:
|
Будут созданы:
|
||||||
|
|
||||||
* `test_key.key` — закрытый ключ (хранится строго локально).
|
* `test_key.key` — приватный ключ (остается на машине оператора).
|
||||||
* `test_key.key.pub` — открытый ключ для передачи на сервер.
|
* `test_key.key.pub` — открытый ключ.
|
||||||
|
|
||||||
### 3.2. Добавление открытого ключа на сервер
|
### 3.2. Экспорт открытого ключа на сервер
|
||||||
|
|
||||||
Передайте содержимое открытого ключа в `authorized_keys` пользователя `depfile`:
|
Выполните команду передачи публичного ключа (потребуется однократный ввод пароля пользователя `depfile`):
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
type "D:\sys\C-Sharp\deployfile\key\test_key.key.pub" | ssh depfile@10.228.48.110 "cat >> /var/lib/depfile/.ssh/authorized_keys"
|
type "D:\sys\C-Sharp\deployfile\key\test_key.key.pub" | ssh depfile@10.228.48.110 "cat >> /var/lib/depfile/.ssh/authorized_keys"
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
*(При первом подключении введите пароль пользователя `depfile` на сервере).*
|
Проверьте вход по ключу:
|
||||||
|
|
||||||
Проверьте беспарольный вход:
|
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
ssh -i "D:\sys\C-Sharp\deployfile\key\test_key.key" depfile@10.228.48.110 "whoami && pwd"
|
ssh -i "D:\sys\C-Sharp\deployfile\key\test_key.key" depfile@10.228.48.110 "whoami && pwd"
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
*Вывод должен вернуть:*
|
Ожидаемый ответ:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
depfile
|
depfile
|
||||||
@@ -176,23 +208,19 @@ depfile
|
|||||||
|
|
||||||
## 4. Клиентское приложение C# (.NET Framework 4.8)
|
## 4. Клиентское приложение C# (.NET Framework 4.8)
|
||||||
|
|
||||||
### 4.1. Исходный код
|
### 4.1. Исходный код (`Program.cs`)
|
||||||
[Program.cs](Program.cs)
|
|
||||||
|
|
||||||
|
Код утилиты запускает встроенный клиент Windows OpenSSH, автоматически обрабатывает 32/64-битные системные пути и при необходимости устанавливает OpenSSH Client.
|
||||||
|
|
||||||
|
[Program.cs](Program.cs)
|
||||||
|
|
||||||
### 4.2. Сборка и создание ярлыка на рабочем столе
|
### 4.2. Сборка и создание ярлыка на рабочем столе
|
||||||
|
|
||||||
1. В Visual Studio в свойствах проекта (**Свойства** -> **Сборка** / **Build**) рекомендуется выставить целевую платформу **x64** (или снять флаг *Prefer 32-bit*).
|
1. В Visual Studio в свойствах проекта (**Build** / **Сборка**) установите платформу **x64** (или снимите флаг *Prefer 32-bit*).
|
||||||
2. Скомпилируйте проект в конфигурации **Release** (результирующий бинарник: `D:\sys\C-Sharp\deployfile\bin\Release\deployfile.exe`).
|
2. Скомпилируйте проект в конфигурации **Release** (`D:\sys\C-Sharp\deployfile\bin\Release\deployfile.exe`).
|
||||||
3. Создайте ярлык на рабочем столе:
|
3. Создайте ярлык на рабочем столе:
|
||||||
* **Расположение объекта:**
|
* **Объект:** `"D:\sys\C-Sharp\deployfile\bin\Release\deployfile.exe"`
|
||||||
```cmd
|
* **Название:** `Откатить конфигурацию HAProxy`.
|
||||||
"D:\sys\C-Sharp\deployfile\bin\Release\deployfile.exe"
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
* **Имя ярлыка:** `Откатить конфигурацию HAProxy`.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -200,9 +228,8 @@ depfile
|
|||||||
|
|
||||||
## 5. Проверка работы комплекса
|
## 5. Проверка работы комплекса
|
||||||
|
|
||||||
1. **Запуск с клиента:**
|
1. Нажмите на ярлык на рабочем столе Windows.
|
||||||
* Дважды кликните по созданному ярлыку на рабочем столе.
|
2. В консоли отобразится успешный статус:
|
||||||
* Консоль отобразит процесс подключения и результат:
|
|
||||||
```text
|
```text
|
||||||
Используется ключ: D:\sys\C-Sharp\deployfile\key\test_key.key
|
Используется ключ: D:\sys\C-Sharp\deployfile\key\test_key.key
|
||||||
Подключение к depfile@10.228.48.110:22...
|
Подключение к depfile@10.228.48.110:22...
|
||||||
@@ -211,24 +238,19 @@ depfile
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
3. Реакция сервера происходит **мгновенно** (без задержек таймера cron). Проверьте журнал выполнения сервиса:
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u depfile-watcher.service -n 25 --no-pager
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
2. **Проверка на сервере (в пределах 1 минуты):**
|
4. Убедитесь в результатах развертывания:
|
||||||
* Каталог `/var/lib/depfile/status` удален.
|
* Каталог `/var/lib/depfile/status` удален.
|
||||||
* Файл конфигурации `/etc/haproxy/haproxy.cfg` перезаписан из `/etc/haproxy/backup/haproxy.cfg`.
|
* Конфигурация `/etc/haproxy/haproxy.cfg` обновлена из бэкапа.
|
||||||
* Статус HAProxy: `systemctl status haproxy` в состоянии `active (running)`.
|
* Служба активна: `systemctl status haproxy`.
|
||||||
* Проверка фиксации развертывания:
|
* Метка времени зафиксирована в `/var/lib/depfile/deployment/success.me`:
|
||||||
```bash
|
```bash
|
||||||
cat /var/lib/depfile/deployment/success.me
|
cat /var/lib/depfile/deployment/success.me
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
*Вывод:*
|
|
||||||
```text
|
|
||||||
deploment success {2026-10-13 12:45:00}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
* Журнал работы скрипта доступен в `/var/log/deploy_haproxy.log`.
|
|
||||||
Reference in new issue
Block a user