Compare commits
129 Commits
19e7e7bb3b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 98004bcb67 | |||
| f7e0663d3e | |||
| 756607fbb9 | |||
| ce9454d518 | |||
| 038d71be6e | |||
| 039eeb40e5 | |||
| cd480c69a9 | |||
| 34d17c9c9b | |||
| 351d80d3ff | |||
| 5a017ac47a | |||
| f438203912 | |||
| ce0d02d0b0 | |||
| caf80d3c20 | |||
| 17f6f8ac98 | |||
| 902ee9d5fb | |||
| 3905acf5b1 | |||
| 92a2df6b73 | |||
| 5118268045 | |||
| a9c1d87b38 | |||
| 3310c3143e | |||
| 91e73ffbef | |||
| 3f10edf636 | |||
| 5d7f0eb094 | |||
| 6864921ba2 | |||
| 695d095133 | |||
| f8c68fc017 | |||
| 24027d9d7c | |||
| ca2c0ecb0d | |||
| 3c01fb220c | |||
| 7813c906b6 | |||
| 54e0280d36 | |||
| 8291eabd96 | |||
| 5f53344c8d | |||
| fffbc19277 | |||
| 5eab9c24f8 | |||
| 82f1fe3ebe | |||
| 8b96c3784f | |||
| ad86c1410a | |||
| 52ea4eb4c8 | |||
| d56d13dfa4 | |||
| ec880e8d5d | |||
| 49c3a582f1 | |||
| a400048ef3 | |||
| 672a33d6f9 | |||
| e5977484af | |||
| 62fe0e0ca1 | |||
| 1ea6770013 | |||
| 8047021a44 | |||
| 198d6d22a7 | |||
| 17f4d4caf2 | |||
| 3cee2b82ac | |||
| e9e886bd5d | |||
| 3e4620a388 | |||
| f1bfc53bb5 | |||
| 83d57cfc36 | |||
| 5351b235dc | |||
| ddace8434d | |||
| e771369149 | |||
| 05c40b0ee6 | |||
| 92fac48655 | |||
| a5726a2d72 | |||
| 0b2f00cbb4 | |||
| 7c8dd413c3 | |||
| bae611e68d | |||
| 5fd2d3ae93 | |||
| f9bbb41e70 | |||
| 2871dc4b22 | |||
| 1831e7f03a | |||
| 12fca342c5 | |||
| 1551ebccaa | |||
| 70ca44f15d | |||
| 6af90cffb7 | |||
| 43a4d24f27 | |||
| 073a7ca4b8 | |||
| 2976e88ea5 | |||
| 96eb57c703 | |||
| 4b103f90c3 | |||
| 1fae23d524 | |||
| 63761558b2 | |||
| ca97ec782f | |||
| e5d791d144 | |||
| 11edd56fc8 | |||
| aab0e2fd4d | |||
| 2b95597c26 | |||
| 1b8965971a | |||
| f9c37af160 | |||
| c872d859e6 | |||
| 17b384693d | |||
| 25fdf07e26 | |||
| 2376c96197 | |||
| 29d72e9c76 | |||
| 2a65169168 | |||
| ce500cc31b | |||
| fed2a92b79 | |||
| c00a2e2460 | |||
| 8cb35e0009 | |||
| 6eddf40b7c | |||
| 8aa65149df | |||
| fade8ecdcf | |||
| 3cc9e28b3a | |||
| 76e7277186 | |||
| 83bebf1836 | |||
| 42e74764b3 | |||
| 7dd332b9ed | |||
| 561c277646 | |||
| 15e2783cb3 | |||
| 8730ac5fba | |||
| 481404b050 | |||
| 59389a9d4f | |||
| b6f3925b2e | |||
| 716014a704 | |||
| 5899a62772 | |||
| 0279c2067b | |||
| c4a124f043 | |||
| c3a61631d6 | |||
| d813f4a043 | |||
| 299937d418 | |||
| 233cb48188 | |||
| d83565202c | |||
| c3f5a1ebc1 | |||
| f87057d69a | |||
| d2faf0c62f | |||
| 1005f589eb | |||
| ac5ebaa626 | |||
| 27a7baa660 | |||
| 3cc2b962b0 | |||
| 706cd6dcae | |||
| 5434303ab1 | |||
| 50285ff6a9 |
18
Apple/MacOS/Create-flash-on-m3.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!--
|
||||
title: Создание загрузочной флешки с macOS
|
||||
description:
|
||||
published: true
|
||||
date: 2025-02-14T16:47:57.135Z
|
||||
tags: macos, m3, flash
|
||||
editor: ckeditor
|
||||
dateCreated: 2025-02-14T16:47:57.135Z
|
||||
-->
|
||||
|
||||
<h1>Установка на ноуте с arm процессорами</h1>
|
||||
<p><code>cd /Applications/Install\ macOS\ High\ Sierra.app/Contents/Resources/</code></p>
|
||||
<p><code>codesign -s - -f createinstallmedia</code></p>
|
||||
<p>с результатом<br>createinstallmedia: replacing existing signature</p>
|
||||
<p>После этого повторяем команду для создания и все идет.</p>
|
||||
<p><code>sudo /Applications/Install\ macOS\ High\ Sierra.app/Contents/Resources/createinstallmedia --volume /Volumes/macos</code></p>
|
||||
<h1>Установка High Sierra</h1>
|
||||
<p>Делал на новой ОС - "Секвойя"(MacBook Air M1), там дополнительно перед командами пришлось в настройках безопаности разрешить выполнение программы:<br>Настройки - конфиденциальности и безопасность-управление приложениями. Здес нужно добавить из раздела "программы" появившуюся там программу установки "Установка MacOS High Sierra" (!Важно, для тех кто не знает(если что то я не знал - не часто вожусьс МакОС) - в раздел "Программы" "Установка MacOS High Sierra" - добавляется простым копированием из подмонтированного .dmg-файла образа установочного.<br>Только после этого сработали команды что выше и флэшка создалась.<br>Также не забывам, что потом при загрузке с нее на старом Мак-е и попытке установки, можем получить ошибку: "Экземпляр программы "установка macOS high sierra" поврежден и не может быть использован для установки". Решается просто отключением Wi-Fi и заданием даты в терминале. И только потом жмем установку ОС.</p>
|
||||
164
DevOps/Clickhouse/Cluster/0-Bases-and-query.md
Normal file
@@ -0,0 +1,164 @@
|
||||
---
|
||||
title: 0. Основы и запросы
|
||||
description:
|
||||
published: true
|
||||
date: 2025-05-15T20:02:37.600Z
|
||||
tags: clickhouse
|
||||
editor: markdown
|
||||
dateCreated: 2025-05-15T20:01:45.285Z
|
||||
---
|
||||
|
||||
## Структура кластера
|
||||
|
||||
### Найдено на просторах инета:
|
||||
##### Выбор решения:
|
||||
- Если **диск загружен на запись (INSERT)** → **шардирование (Distributed)**.
|
||||
- Если **диск загружен на чтение (SELECT)** → **репликация (Replicated)**.
|
||||
- Если **один сервер, но много дисков** → **JBOD или RAID 0/10**.
|
||||
|
||||
#### Реализуем такую структуру тестового кластера:
|
||||
- сервер clickhouse-1
|
||||
- сервер clickhouse-2
|
||||
- сервер clickhouse-keeper
|
||||
Для того, чтобы это было надежно и работало быстро с записью в БД, необходимо сделать репликацию (Replicated) таблиц и распределенный (Distributed) доступ к таблицам.
|
||||
Если делать несколько шардов (shard) в настройках кластера, то это значит, что часть данных будет находится на одном сервере, другая часть на другом. При выходе из строя сервера мы потеряем всю базу.
|
||||
Поэтому настраиваем shard1 на обоих серверах, а также replica1 и replica2 для дублирования данных на серверах.
|
||||
|
||||
### Репликация поддерживается только для таблиц семейства MergeTree:
|
||||
https://clickhouse.com/docs/ru/engines/table-engines/mergetree-family/replication
|
||||
- ReplicatedMergeTree
|
||||
- ReplicatedSummingMergeTree
|
||||
- ReplicatedReplacingMergeTree
|
||||
- ReplicatedAggregatingMergeTree
|
||||
- ReplicatedCollapsingMergeTree
|
||||
- ReplicatedVersionedCollapsingMergeTree
|
||||
- ReplicatedGraphiteMergeTree
|
||||
|
||||
### Для одиночного сервера и кластера
|
||||
#### Получение списка всех баз данных на сервере
|
||||
```sql
|
||||
SHOW DATABASES;
|
||||
```
|
||||
#### Просмотр всех таблиц в конкретной базе default
|
||||
```sql
|
||||
SHOW TABLES FROM default;
|
||||
```
|
||||
#### Получить запрос на создание таблицы из существующей
|
||||
```sql
|
||||
show create table default.event;
|
||||
```
|
||||
#### Создание базы данных
|
||||
```sql
|
||||
CREATE DATABASE IF NOT EXISTS my_database ENGINE = Atomic;
|
||||
```
|
||||
Создает новую базу данных с именем `my_database`. Если такая база уже существует, ничего не произойдет благодаря условию `IF NOT EXISTS`.
|
||||
Параметр `ENGINE = Atomic` используется для новых версий ClickHouse и позволяет создавать транзакционно безопасные базы данных. В ранних версиях использовался простой синтаксис без указания движка.
|
||||
#### Создание таблицы
|
||||
```sql
|
||||
CREATE TABLE my_table (
|
||||
event_date Date,
|
||||
user_id UInt32,
|
||||
page_views Int32,
|
||||
revenue Float64
|
||||
)
|
||||
ENGINE = MergeTree()
|
||||
ORDER BY (event_date);
|
||||
```
|
||||
##### Вставка данных
|
||||
```sql
|
||||
INSERT INTO my_table VALUES ('2023-08-01', 1, 10, 100.5), ('2023-08-02', 2, 15, 150.75);
|
||||
```
|
||||
##### Выборка данных
|
||||
```sql
|
||||
SELECT * FROM my_table WHERE event_date >= '2023-08-01' AND event_date <= '2023-08-31';
|
||||
```
|
||||
#### Показ структуры таблицы
|
||||
```sql
|
||||
DESCRIBE TABLE my_database.my_table;
|
||||
```
|
||||
или подробнее:
|
||||
```sql
|
||||
SELECT * FROM system.columns WHERE table='my_table' AND database='my_database';
|
||||
```
|
||||
### Узнать сколько занимают места базы
|
||||
```sql
|
||||
SELECT
|
||||
database,
|
||||
formatReadableSize(sum(bytes_on_disk)) AS total_size
|
||||
FROM system.parts
|
||||
WHERE active
|
||||
GROUP BY database
|
||||
ORDER BY sum(bytes_on_disk) DESC;
|
||||
```
|
||||
#### Узнать сколько занимают места таблицы в базе
|
||||
default
|
||||
```sql
|
||||
SELECT
|
||||
name AS table_name,
|
||||
formatReadableSize(total_bytes) AS size_readable,
|
||||
total_rows AS rows_count
|
||||
FROM system.tables
|
||||
WHERE database = 'default'
|
||||
ORDER BY total_bytes DESC;
|
||||
```
|
||||
system
|
||||
```sql
|
||||
SELECT
|
||||
name AS table_name,
|
||||
formatReadableSize(total_bytes) AS size_readable,
|
||||
total_rows AS rows_count
|
||||
FROM system.tables
|
||||
WHERE database = 'system'
|
||||
ORDER BY total_bytes DESC;
|
||||
```
|
||||
#### Очистка базы event_replicated
|
||||
```sql
|
||||
TRUNCATE TABLE default.event_replicated;
|
||||
```
|
||||
#### Очистка старых данных от определенной даты
|
||||
```sql
|
||||
ALTER TABLE my_table DELETE WHERE event_date < '2023-08-01';
|
||||
```
|
||||
#### Безопасное удаление таблицы
|
||||
```sql
|
||||
DROP TABLE IF EXISTS my_database.my_table;
|
||||
```
|
||||
Безопасно удаляет указанную таблицу, если она существует.
|
||||
|
||||
|
||||
### Для кластера
|
||||
|
||||
#### Вывести список серверов в кластере
|
||||
```sql
|
||||
SELECT hostName() FROM clusterAllReplicas('smvu2_cluster', 'system', 'one')
|
||||
```
|
||||
#### Получение списка Replicated таблиц
|
||||
```sql
|
||||
SELECT
|
||||
database,
|
||||
name AS table,
|
||||
engine
|
||||
FROM system.tables
|
||||
WHERE engine LIKE 'Replicated%';
|
||||
```
|
||||
#### Получение списка Distributed таблиц
|
||||
```sql
|
||||
SELECT
|
||||
database,
|
||||
name AS table,
|
||||
engine
|
||||
FROM system.tables
|
||||
WHERE engine LIKE 'Distributed%';
|
||||
```
|
||||
#### Проверить распределение данных базы event на серверах кластера
|
||||
```sql
|
||||
SELECT
|
||||
hostName() AS host,
|
||||
count() AS count
|
||||
FROM clusterAllReplicas(smvu2_cluster, default.event)
|
||||
GROUP BY host;
|
||||
```
|
||||
#### Удалить таблицу в кластере
|
||||
```sql
|
||||
DROP TABLE event_replicated ON CLUSTER smvu2_cluster SYNC;
|
||||
```
|
||||
228
DevOps/Clickhouse/Cluster/1-Install-Clickhouse-cluster.md
Normal file
@@ -0,0 +1,228 @@
|
||||
---
|
||||
title: 1. Создание кластера Clickhouse
|
||||
description:
|
||||
published: true
|
||||
date: 2025-05-15T20:11:12.215Z
|
||||
tags: clickhouse, cluster
|
||||
editor: markdown
|
||||
dateCreated: 2025-05-15T18:04:57.423Z
|
||||
---
|
||||
|
||||
https://clickhouse.com/docs/guides/sre/keeper/clickhouse-keeper
|
||||
## Установка и настройка clickhouse, clickhouse-keeper
|
||||
### Установка clickhouse-keeper
|
||||
```bash
|
||||
apt-get install -y apt-transport-https ca-certificates curl gnupg
|
||||
curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' | sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg arch=${ARCH}] https://packages.clickhouse.com/deb stable main" | sudo tee /etc/apt/sources.list.d/clickhouse.list
|
||||
apt-get update
|
||||
apt-get install -y clickhouse-keeper
|
||||
```
|
||||
|
||||
#### Готовим конфиг clickhouse-keeper
|
||||
```
|
||||
nano /etc/clickhouse-keeper/keeper_config.xml
|
||||
```
|
||||
|
||||
```xml
|
||||
<clickhouse>
|
||||
<logger>
|
||||
<level>warning</level>
|
||||
<log>/var/log/clickhouse-keeper/clickhouse-keeper.log</log>
|
||||
<errorlog>/var/log/clickhouse-keeper/clickhouse-keeper.err.log</errorlog>
|
||||
<size>1000M</size>
|
||||
<count>10</count>
|
||||
<!-- <console>1</console> --> <!-- Default behavior is autodetection (log to console if not daemon mode and is tty) -->
|
||||
</logger>
|
||||
|
||||
<max_connections>4096</max_connections>
|
||||
<listen_host>0.0.0.0</listen_host>
|
||||
<listen_host>::1</listen_host>
|
||||
|
||||
<keeper_server>
|
||||
<tcp_port>9181</tcp_port>
|
||||
<server_id>1</server_id>
|
||||
|
||||
<log_storage_path>/var/lib/clickhouse/coordination/logs</log_storage_path>
|
||||
<snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
|
||||
|
||||
<coordination_settings>
|
||||
<operation_timeout_ms>10000</operation_timeout_ms>
|
||||
<session_timeout_ms>30000</session_timeout_ms>
|
||||
<raft_logs_level>warning</raft_logs_level>
|
||||
<compress_logs>true</compress_logs>
|
||||
</coordination_settings>
|
||||
|
||||
<!-- enable sanity hostname checks for cluster configuration (e.g. if localhost is used with remote endpoints) -->
|
||||
<hostname_checks_enabled>false</hostname_checks_enabled>
|
||||
<raft_configuration>
|
||||
<server>
|
||||
<id>1</id>
|
||||
<hostname>localhost</hostname>
|
||||
<port>9234</port>
|
||||
</server>
|
||||
</raft_configuration>
|
||||
</keeper_server>
|
||||
</clickhouse>
|
||||
```
|
||||
|
||||
#### Пароль пользователя
|
||||
```
|
||||
nano /etc/clickhouse-server/users.d/default-password.xml
|
||||
```
|
||||
|
||||
```xml
|
||||
<yandex>
|
||||
<users>
|
||||
<default>
|
||||
<password>SuperPass</password>
|
||||
<networks>
|
||||
<ip>::/0</ip>
|
||||
<ip>127.0.0.1</ip>
|
||||
<ip>172.16.212.0/24</ip>
|
||||
</networks>
|
||||
</default>
|
||||
</users>
|
||||
</yandex>
|
||||
```
|
||||
|
||||
### Готовим конфиги clickhouse на серверах SMVU2-DEV14 и SMVU2-Click-DEV
|
||||
|
||||
```bash
|
||||
nano /etc/clickhouse-server/config.d/remote_servers.xml
|
||||
```
|
||||
##### server 1
|
||||
```xml
|
||||
<yandex>
|
||||
<display_name>smvu2_cluster node 1</display_name>
|
||||
<remote_servers replace="true">
|
||||
<smvu2_cluster>
|
||||
<!--<secret>mysecretphrase</secret> -->
|
||||
<shard>
|
||||
<internal_replication>true</internal_replication>
|
||||
<replica>
|
||||
<host>172.16.212.14</host>
|
||||
<port>9000</port>
|
||||
<priority>1</priority>
|
||||
<secure>0</secure>
|
||||
<user>default</user>
|
||||
<password>SuperPass</password>
|
||||
</replica>
|
||||
<replica>
|
||||
<host>172.16.212.42</host>
|
||||
<port>9000</port>
|
||||
<priority>2</priority>
|
||||
<secure>0</secure>
|
||||
<user>default</user>
|
||||
<password>SuperPass</password>
|
||||
</replica>
|
||||
</shard>
|
||||
</smvu2_cluster>
|
||||
</remote_servers>
|
||||
</yandex>
|
||||
```
|
||||
|
||||
```
|
||||
nano /etc/clickhouse-server/config.d/shard.xml
|
||||
```
|
||||
|
||||
```xml
|
||||
<yandex>
|
||||
<macros>
|
||||
<shard>1</shard>
|
||||
<replica>replica1</replica>
|
||||
</macros>
|
||||
</yandex>
|
||||
```
|
||||
|
||||
##### server 2
|
||||
```xml
|
||||
<yandex>
|
||||
<display_name>smvu2_cluster node 2</display_name>
|
||||
<remote_servers replace="true">
|
||||
<smvu2_cluster>
|
||||
<!--<secret>mysecretphrase</secret> -->
|
||||
<shard>
|
||||
<internal_replication>true</internal_replication>
|
||||
<replica>
|
||||
<host>172.16.212.42</host>
|
||||
<port>9000</port>
|
||||
<priority>2</priority>
|
||||
<secure>0</secure>
|
||||
<user>default</user>
|
||||
<password>SuperPass</password>
|
||||
</replica>
|
||||
<replica>
|
||||
<host>172.16.212.14</host>
|
||||
<port>9000</port>
|
||||
<priority>1</priority>
|
||||
<secure>0</secure>
|
||||
<user>default</user>
|
||||
<password>SuperPass</password>
|
||||
</replica>
|
||||
</shard>
|
||||
</smvu2_cluster>
|
||||
</remote_servers>
|
||||
</yandex>
|
||||
```
|
||||
|
||||
```
|
||||
nano /etc/clickhouse-server/config.d/shard.xml
|
||||
```
|
||||
|
||||
```xml
|
||||
<yandex>
|
||||
<macros>
|
||||
<shard>1</shard>
|
||||
<replica>replica2</replica>
|
||||
</macros>
|
||||
</yandex>
|
||||
```
|
||||
|
||||
```
|
||||
nano /etc/clickhouse-server/config.d/keeper.xml
|
||||
```
|
||||
|
||||
```xml
|
||||
<yandex>
|
||||
<zookeeper>
|
||||
<node>
|
||||
<host>172.16.212.41</host>
|
||||
<port>9181</port>
|
||||
</node>
|
||||
</zookeeper>
|
||||
</yandex>
|
||||
```
|
||||
|
||||
```
|
||||
nano /etc/clickhouse-server/config.d/distributed_ddl.xml
|
||||
```
|
||||
|
||||
```xml
|
||||
<yandex>
|
||||
<distributed_ddl>
|
||||
<task_max_lifetime>86400</task_max_lifetime>
|
||||
<profile>default</profile>
|
||||
<cleanup_delay>60</cleanup_delay>
|
||||
<max_workers>16</max_workers>
|
||||
</distributed_ddl>
|
||||
</yandex>
|
||||
```
|
||||
|
||||
### Проверить сервера, что они в кластере
|
||||
|
||||
#### Показать кластер
|
||||
```sql
|
||||
SHOW clusters;
|
||||
```
|
||||
|
||||
#### Вывести список серверов в кластере
|
||||
```sql
|
||||
SELECT hostName() FROM clusterAllReplicas('smvu2_cluster', 'system', 'one')
|
||||
```
|
||||
|
||||
#### Keeper status
|
||||
```sql
|
||||
SELECT * FROM system.zookeeper WHERE path = '/';
|
||||
```
|
||||
646
DevOps/Clickhouse/Cluster/3-Create-manual.md
Normal file
@@ -0,0 +1,646 @@
|
||||
---
|
||||
title: 3. Создание таблиц вручную
|
||||
description:
|
||||
published: true
|
||||
date: 2025-05-15T20:07:34.738Z
|
||||
tags: clickhouse
|
||||
editor: markdown
|
||||
dateCreated: 2025-05-15T20:07:34.738Z
|
||||
---
|
||||
|
||||
Можно создать все таблицы для кластера вручную.
|
||||
Запрашиваем структуру каждой таблицы, создаем под другим именем и копируем данные с исходника.
|
||||
|
||||
##### Может возникнуть проблема, что таблицы содержат много данных, поэтому внизу статьи будет решение
|
||||
|
||||
## Создаем реплицированные таблицы
|
||||
|
||||
**Разберем первую таблицу подробно**
|
||||
### 1. api_request_log_replicated
|
||||
|
||||
Запрашиваем структуру
|
||||
```sql
|
||||
show create table default.api_request_log
|
||||
```
|
||||
|
||||
Выход:
|
||||
```sql
|
||||
CREATE TABLE default.api_request_log
|
||||
(
|
||||
`uuid` UUID DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`ver` UInt8,
|
||||
`request_ts` DateTime64(3) DEFAULT '0000000000.000',
|
||||
`duration` Float64,
|
||||
`endpoint` String,
|
||||
`method` FixedString(5),
|
||||
`status_code` UInt32,
|
||||
`remote_addr` String,
|
||||
`username` Nullable(String),
|
||||
`error` Nullable(String),
|
||||
`request_body` Nullable(String) TTL toDateTime(request_ts) + toIntervalMonth(1),
|
||||
`query_params` Nullable(String) TTL toDateTime(request_ts) + toIntervalMonth(1),
|
||||
`response_body` Nullable(String) TTL toDateTime(request_ts) + toIntervalMonth(1)
|
||||
)
|
||||
ENGINE = MergeTree(ver)
|
||||
PARTITION BY toYYYYMM(request_ts)
|
||||
ORDER BY uuid
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
|
||||
Дорабатываем запрос, чтобы получилась на выходе реплицируемая таблица
|
||||
```sql
|
||||
CREATE TABLE default.api_request_log_replicated ON CLUSTER smvu2_cluster
|
||||
(
|
||||
`uuid` UUID DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`ver` UInt8,
|
||||
`request_ts` DateTime64(3) DEFAULT '0000000000.000',
|
||||
`duration` Float64,
|
||||
`endpoint` String,
|
||||
`method` FixedString(5),
|
||||
`status_code` UInt32,
|
||||
`remote_addr` String,
|
||||
`username` Nullable(String),
|
||||
`error` Nullable(String),
|
||||
`request_body` Nullable(String) TTL toDateTime(request_ts) + toIntervalMonth(1),
|
||||
`query_params` Nullable(String) TTL toDateTime(request_ts) + toIntervalMonth(1),
|
||||
`response_body` Nullable(String) TTL toDateTime(request_ts) + toIntervalMonth(1)
|
||||
)
|
||||
ENGINE = ReplicatedReplacingMergeTree(
|
||||
'/clickhouse/tables/{shard}/default/api_request_log_replicated',
|
||||
'{replica}',
|
||||
ver
|
||||
)
|
||||
PARTITION BY toYYYYMM(request_ts)
|
||||
ORDER BY uuid
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
Копируем данные
|
||||
```sql
|
||||
INSERT INTO default.api_request_log_replicated
|
||||
SELECT * FROM default.api_request_log
|
||||
```
|
||||
|
||||
### 2. event_replicated
|
||||
```sql
|
||||
show create table default.event
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.event_replicated ON CLUSTER smvu2_cluster
|
||||
(
|
||||
`event_id` UUID,
|
||||
`unipoll_id` UUID,
|
||||
`sensor_id` UUID,
|
||||
`sensor_type_id` UUID,
|
||||
`sensor_type_name` String,
|
||||
`sensor_activation_status_name` String,
|
||||
`sensor_logic_status_id` UUID,
|
||||
`sensor_logic_status_name` String,
|
||||
`sensor_comment` Nullable(String),
|
||||
`command` String,
|
||||
`priority_name` String,
|
||||
`pub_ts` DateTime,
|
||||
`sub_ts` DateTime64(3, 'Europe/Moscow'),
|
||||
`state_id` UInt8,
|
||||
`state_name` String,
|
||||
`status_id` UInt8,
|
||||
`status_name` String,
|
||||
`unitype_id` UInt16,
|
||||
`unitype_name` String,
|
||||
`system_id` UInt16,
|
||||
`system_short_name` String,
|
||||
`system_name` String,
|
||||
`checked` UInt8,
|
||||
`object_id` UUID,
|
||||
`object_type_name` String,
|
||||
`data_id` UInt8,
|
||||
`value` Nullable(String),
|
||||
`raw_value` Nullable(String),
|
||||
`data` String,
|
||||
`region_id` UUID,
|
||||
`region_name` String,
|
||||
`complex_id` UUID,
|
||||
`complex_name` String,
|
||||
`collector_id` Nullable(UUID),
|
||||
`collector_name` Nullable(String),
|
||||
`control_room_id` Nullable(UUID),
|
||||
`control_room_name` Nullable(String),
|
||||
`picket_id` Nullable(UUID),
|
||||
`picket_name` Nullable(String),
|
||||
`picket_n` Nullable(UInt32),
|
||||
`cstate_id` UUID,
|
||||
`cstate_name` String,
|
||||
`cstate_color_id` UInt8,
|
||||
`sub_ms` UInt64,
|
||||
`linked_channel_state` Nullable(String),
|
||||
`on_guard` Nullable(UInt8),
|
||||
`internal_id` Nullable(String),
|
||||
`floor_number` Nullable(Int32)
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse/tables/{shard}/default/event_replicated',
|
||||
'{replica}'
|
||||
)
|
||||
PARTITION BY toYYYYMM(pub_ts)
|
||||
ORDER BY (priority_name, sensor_type_id, cstate_id, object_id, sensor_id, pub_ts, sub_ts, event_id)
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
Копируем данные
|
||||
```sql
|
||||
INSERT INTO default.event_replicated
|
||||
SELECT * FROM default.event
|
||||
```
|
||||
|
||||
### 3. event_automation_replicated
|
||||
```sql
|
||||
show create table default.event_automation
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.event_automation_replicated ON CLUSTER smvu2_cluster
|
||||
(
|
||||
`event_id` UUID DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`unipoll_id` UUID DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`automation_id` UUID DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`automation_name` String,
|
||||
`automation_mode` UInt8,
|
||||
`pub_ts` DateTime DEFAULT '0000000000',
|
||||
`sub_ts` DateTime64(3) DEFAULT '0000000000.000',
|
||||
`sub_ms` UInt64,
|
||||
`state_id` UInt8,
|
||||
`state_name` String,
|
||||
`status_id` UInt8,
|
||||
`unitype_id` UInt8,
|
||||
`unitype_name` String,
|
||||
`group_id` UUID DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`group_name` String,
|
||||
`data` String,
|
||||
`cstate_id` UUID DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`cstate_name` String,
|
||||
`cstate_color_id` UInt8
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse/tables/{shard}/default/event_automation_replicated',
|
||||
'{replica}'
|
||||
)
|
||||
PARTITION BY toYYYYMMDD(pub_ts)
|
||||
ORDER BY (event_id, pub_ts, sub_ts)
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
Копируем данные
|
||||
```sql
|
||||
INSERT INTO default.event_automation_replicated
|
||||
SELECT * FROM default.event_automation
|
||||
```
|
||||
|
||||
### 4. event_confirmation_replicated
|
||||
```sql
|
||||
show create table default.event_confirmation
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.event_confirmation_replicated ON CLUSTER smvu2_cluster
|
||||
(
|
||||
`uuid` UUID,
|
||||
`event_id` UUID,
|
||||
`reason` String DEFAULT '',
|
||||
`event_checked` Int8,
|
||||
`username` String,
|
||||
`datetime` DateTime,
|
||||
`confirmation_group` String,
|
||||
`node_id` UUID
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse/tables/{shard}/default/event_confirmation_replicated',
|
||||
'{replica}'
|
||||
)
|
||||
PARTITION BY toYYYYMM(datetime)
|
||||
ORDER BY datetime
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
Копируем данные
|
||||
```sql
|
||||
INSERT INTO default.event_confirmation_replicated
|
||||
SELECT * FROM default.event_confirmation
|
||||
```
|
||||
|
||||
### 5. event_objects_replicated
|
||||
```sql
|
||||
show create table default.event_objects
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.event_objects_replicated ON CLUSTER smvu2_cluster
|
||||
(
|
||||
`event_id` UUID,
|
||||
`node_id` UUID,
|
||||
`pub_ts` DateTime,
|
||||
`sub_ts` DateTime64(3, 'UTC'),
|
||||
`cstate_id` UUID,
|
||||
`source_id` UUID,
|
||||
`source_name` String DEFAULT '',
|
||||
`source_type_id` UUID,
|
||||
`event_data` String,
|
||||
`complex_id` UUID
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse/tables/{shard}/default/event_objects_replicated',
|
||||
'{replica}'
|
||||
)
|
||||
PARTITION BY toYYYYMM(pub_ts)
|
||||
PRIMARY KEY event_id
|
||||
ORDER BY (event_id, pub_ts, sub_ts)
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
Копируем данные
|
||||
```sql
|
||||
INSERT INTO default.event_objects_replicated
|
||||
SELECT * FROM default.event_objects
|
||||
```
|
||||
### 6. infi_clickhouse_orm_migrations_replicated
|
||||
|
||||
```sql
|
||||
show create table default.infi_clickhouse_orm_migrations
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.infi_clickhouse_orm_migrations_replicated ON CLUSTER smvu2_cluster
|
||||
(
|
||||
`package_name` String,
|
||||
`module_name` String,
|
||||
`applied` Date DEFAULT '1970-01-01'
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse/tables/{shard}/default/infi_clickhouse_orm_migrations_replicated',
|
||||
'{replica}'
|
||||
)
|
||||
PARTITION BY toYYYYMM(applied)
|
||||
ORDER BY (package_name, module_name)
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
Копируем данные
|
||||
```sql
|
||||
INSERT INTO default.infi_clickhouse_orm_migrations_replicated
|
||||
SELECT * FROM default.infi_clickhouse_orm_migrations
|
||||
```
|
||||
|
||||
### 7. unchecked_event_replicated
|
||||
|
||||
```sql
|
||||
show create table default.unchecked_event
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.unchecked_event_replicated ON CLUSTER smvu2_cluster
|
||||
(
|
||||
`event_id` UUID,
|
||||
`unipoll_id` Nullable(UUID),
|
||||
`sensor_id` Nullable(UUID),
|
||||
`sensor_type_id` Nullable(UUID),
|
||||
`sensor_type_name` Nullable(String),
|
||||
`sensor_activation_status_name` Nullable(String),
|
||||
`sensor_logic_status_id` Nullable(UUID),
|
||||
`sensor_logic_status_name` Nullable(String),
|
||||
`sensor_comment` Nullable(String),
|
||||
`command` Nullable(String),
|
||||
`priority_name` Nullable(String),
|
||||
`pub_ts` Nullable(DateTime),
|
||||
`sub_ts` DateTime64(3),
|
||||
`state_id` Nullable(UInt8),
|
||||
`state_name` Nullable(String),
|
||||
`status_id` Nullable(UInt8),
|
||||
`status_name` Nullable(String),
|
||||
`unitype_id` Nullable(UInt16),
|
||||
`unitype_name` Nullable(String),
|
||||
`system_id` Nullable(UInt16),
|
||||
`system_short_name` Nullable(String),
|
||||
`system_name` Nullable(String),
|
||||
`checked` Nullable(UInt8),
|
||||
`object_id` Nullable(UUID),
|
||||
`object_type_name` Nullable(String),
|
||||
`data_id` Nullable(UInt8),
|
||||
`data` Nullable(String),
|
||||
`region_id` Nullable(UUID),
|
||||
`region_name` Nullable(String),
|
||||
`complex_id` Nullable(UUID),
|
||||
`complex_name` Nullable(String),
|
||||
`collector_id` Nullable(UUID),
|
||||
`collector_name` Nullable(String),
|
||||
`control_room_id` Nullable(UUID),
|
||||
`control_room_name` Nullable(String),
|
||||
`picket_id` Nullable(UUID),
|
||||
`picket_name` Nullable(String),
|
||||
`picket_n` Nullable(UInt32),
|
||||
`cstate_id` Nullable(UUID),
|
||||
`cstate_name` Nullable(String),
|
||||
`cstate_color_id` Nullable(UInt8),
|
||||
`sub_ms` Nullable(UInt64),
|
||||
`linked_channel_state` Nullable(String),
|
||||
`on_guard` Nullable(UInt8),
|
||||
`internal_id` Nullable(String),
|
||||
`floor_number` Nullable(Int32),
|
||||
`sign` Int8,
|
||||
`value` Nullable(String),
|
||||
`raw_value` Nullable(String)
|
||||
)
|
||||
ENGINE = ReplicatedCollapsingMergeTree(
|
||||
'/clickhouse/tables/{shard}/default/unchecked_event_replicated',
|
||||
'{replica}',
|
||||
sign
|
||||
)
|
||||
PARTITION BY toYYYYMM(sub_ts)
|
||||
PRIMARY KEY event_id
|
||||
ORDER BY event_id
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
Копируем
|
||||
```sql
|
||||
INSERT INTO default.unchecked_event_replicated
|
||||
SELECT * FROM default.unchecked_event;
|
||||
```
|
||||
|
||||
### 8. unchecked_objects_event_replicated
|
||||
```sql
|
||||
show create table default.unchecked_objects_event;
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.unchecked_objects_event_replicated ON CLUSTER smvu2_cluster
|
||||
(
|
||||
`event_id` UUID,
|
||||
`node_id` Nullable(UUID),
|
||||
`complex_id` Nullable(UUID),
|
||||
`pub_ts` Nullable(DateTime),
|
||||
`sub_ts` DateTime64(3, 'UTC'),
|
||||
`cstate_id` Nullable(UUID),
|
||||
`source_id` Nullable(UUID),
|
||||
`source_name` Nullable(String),
|
||||
`source_type_id` Nullable(UUID),
|
||||
`event_data` Nullable(String),
|
||||
`sign` Int8
|
||||
)
|
||||
ENGINE = ReplicatedCollapsingMergeTree(
|
||||
'/clickhouse/tables/{shard}/default/unchecked_objects_event_replicated',
|
||||
'{replica}',
|
||||
sign
|
||||
)
|
||||
PARTITION BY toYYYYMM(sub_ts)
|
||||
PRIMARY KEY event_id
|
||||
ORDER BY event_id
|
||||
SETTINGS index_granularity = 8192;
|
||||
```
|
||||
Копируем
|
||||
```sql
|
||||
INSERT INTO default.unchecked_objects_event_replicated
|
||||
SELECT * FROM default.unchecked_objects_event;
|
||||
```
|
||||
|
||||
|
||||
### Проверка состояния репликации после создания:
|
||||
```sql
|
||||
SELECT database, table, is_leader, total_replicas, active_replicas
|
||||
FROM system.replicas
|
||||
WHERE database = 'default'
|
||||
```
|
||||
### Узнаем и сравниваем сколько занимают места таблицы в базе default
|
||||
```sql
|
||||
SELECT
|
||||
name AS table_name,
|
||||
formatReadableSize(total_bytes) AS size_readable,
|
||||
total_rows AS rows_count
|
||||
FROM system.tables
|
||||
WHERE database = 'default'
|
||||
ORDER BY total_bytes DESC;
|
||||
```
|
||||
|
||||
### Переименовываем исходные таблицы
|
||||
```sql
|
||||
rename table api_request_log to api_request_log_old;
|
||||
rename table event to event_old;
|
||||
rename table event_objects to event_objects_old;
|
||||
rename table event_confirmation to event_confirmation_old;
|
||||
rename table audit_new to audit_new_old;
|
||||
rename table event_automation to event_automation_old;
|
||||
rename table infi_clickhouse_orm_migrations to infi_clickhouse_orm_migrations_old;
|
||||
rename table unchecked_event to unchecked_event_old;
|
||||
rename table unchecked_objects_event to unchecked_objects_event_old;
|
||||
```
|
||||
|
||||
### Создаем Distributed-таблицы
|
||||
```sql
|
||||
CREATE TABLE default.event ON CLUSTER smvu2_cluster AS default.event_replicated
|
||||
ENGINE = Distributed(smvu2_cluster, default, api_request_log_replicated, rand());
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.event ON CLUSTER smvu2_cluster AS default.event_replicated
|
||||
ENGINE = Distributed(smvu2_cluster, default, event_replicated, rand());
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.audit_new ON CLUSTER smvu2_cluster AS default.audit_new_replicated
|
||||
ENGINE = Distributed(smvu2_cluster, default, audit_new_replicated, rand());
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.event_objects ON CLUSTER smvu2_cluster AS default.event_objects_replicated
|
||||
ENGINE = Distributed(smvu2_cluster, default, event_objects_replicated, rand());
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.event_automation ON CLUSTER smvu2_cluster AS default.event_automation_replicated
|
||||
ENGINE = Distributed(smvu2_cluster, default, event_automation_replicated, rand());
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.event_confirmation ON CLUSTER smvu2_cluster AS default.event_confirmation_replicated
|
||||
ENGINE = Distributed(smvu2_cluster, default, event_confirmation_replicated, rand());
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.infi_clickhouse_orm_migrations ON CLUSTER smvu2_cluster AS default.infi_clickhouse_orm_migrations_replicated
|
||||
ENGINE = Distributed(smvu2_cluster, default, infi_clickhouse_orm_migrations_replicated, rand());
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.unchecked_event ON CLUSTER smvu2_cluster AS default.unchecked_event_replicated
|
||||
ENGINE = Distributed(smvu2_cluster, default, unchecked_event_replicated, rand());
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE default.unchecked_objects_event ON CLUSTER smvu2_cluster AS default.unchecked_objects_event_replicated
|
||||
ENGINE = Distributed(smvu2_cluster, default, unchecked_objects_event_replicated, rand());
|
||||
```
|
||||
|
||||
|
||||
### Решение проблемы размера таблицы
|
||||
#### 1. Используя ограничение отправляемых строк, прикладываю скрипт, который делает в автоматическом режиме
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Список таблиц для репликации
|
||||
TABLES=(
|
||||
api_request_log
|
||||
audit_new
|
||||
event
|
||||
event_automation
|
||||
event_confirmation
|
||||
event_objects
|
||||
infi_clickhouse_orm_migrations
|
||||
)
|
||||
|
||||
PASSWORD="q1"
|
||||
BATCH_SIZE=100000 # Размер порции для вставки
|
||||
MAX_THREADS=4 # Максимальное количество потоков для вставки
|
||||
|
||||
for table in "${TABLES[@]}"; do
|
||||
replicated_table="${table}_replicated"
|
||||
echo "Processing $table to $replicated_table"
|
||||
|
||||
# 1. Получаем общее количество строк
|
||||
total_rows=$(clickhouse-client --password "$PASSWORD" --query="
|
||||
SELECT count() FROM remote('localhost', 'default', '$table')")
|
||||
|
||||
echo "Total rows to copy: $total_rows"
|
||||
|
||||
# 2. Копируем данные порциями
|
||||
for ((offset=0; offset<total_rows; offset+=BATCH_SIZE)); do
|
||||
echo "Copying rows $((offset+1))-$((offset+BATCH_SIZE))..."
|
||||
|
||||
clickhouse-client --password "$PASSWORD" --query="
|
||||
INSERT INTO default.$replicated_table
|
||||
SELECT * FROM remote('localhost', 'default', '$table')
|
||||
LIMIT $BATCH_SIZE OFFSET $offset
|
||||
SETTINGS
|
||||
max_insert_threads=$MAX_THREADS,
|
||||
max_memory_usage='10Gi'"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error copying batch $((offset/BATCH_SIZE+1))"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 3. Проверяем количество скопированных строк
|
||||
copied_rows=$(clickhouse-client --password "$PASSWORD" --query="
|
||||
SELECT count() FROM default.$replicated_table")
|
||||
|
||||
echo "Successfully copied $copied_rows/$total_rows rows from $table to $replicated_table"
|
||||
done
|
||||
```
|
||||
|
||||
#### 2. Копирование с помощью программы clickhouse-copier
|
||||
Создается конфиг подключения к кластеру (keeper)
|
||||
config.xml
|
||||
```xml
|
||||
<yandex>
|
||||
<logger>
|
||||
<level>warning</level>
|
||||
<log>/var/log/clickhouse-server/clickhouse-copier.log</log>
|
||||
<errorlog>/var/log/clickhouse-server/clickhouse-copier.err.log</errorlog>
|
||||
</logger>
|
||||
|
||||
<zookeeper>
|
||||
<!-- Для ClickHouse Keeper (рекомендуется) -->
|
||||
<node>
|
||||
<host>172.16.212.41</host>
|
||||
<port>9181</port>
|
||||
</node>
|
||||
</zookeeper>
|
||||
|
||||
<distributed_ddl>
|
||||
<path>/clickhouse/task_queue/ddl</path>
|
||||
</distributed_ddl>
|
||||
|
||||
<http_port>9999</http_port>
|
||||
</yandex>
|
||||
```
|
||||
|
||||
Создается папка tasks и там размещаются файлы для каждой таблицы, например api_request_log.xml
|
||||
```xml
|
||||
<yandex>
|
||||
<!-- Configuration of clusters as in an ordinary server config -->
|
||||
<remote_servers>
|
||||
<source_cluster>
|
||||
<shard>
|
||||
<internal_replication>true</internal_replication>
|
||||
<replica>
|
||||
<host>172.16.212.14</host>
|
||||
<port>9000</port>
|
||||
<user>default</user>
|
||||
<password>q1</password>
|
||||
<secure>0</secure>
|
||||
</replica>
|
||||
</shard>
|
||||
</source_cluster>
|
||||
|
||||
<destination_cluster>
|
||||
<shard>
|
||||
<internal_replication>true</internal_replication>
|
||||
<replica>
|
||||
<host>172.16.212.14</host>
|
||||
<port>9000</port>
|
||||
<user>default</user>
|
||||
<password>q1</password>
|
||||
<secure>0</secure>
|
||||
</replica>
|
||||
</shard>
|
||||
</destination_cluster>
|
||||
</remote_servers>
|
||||
|
||||
<!-- How many simultaneously active workers are possible. If you run more workers superfluous workers will sleep. -->
|
||||
<max_workers>2</max_workers>
|
||||
|
||||
<!-- Setting used to fetch (pull) data from source cluster tables -->
|
||||
<settings_pull>
|
||||
<readonly>1</readonly>
|
||||
</settings_pull>
|
||||
|
||||
<!-- Setting used to insert (push) data to destination cluster tables -->
|
||||
<settings_push>
|
||||
<readonly>0</readonly>
|
||||
</settings_push>
|
||||
|
||||
<!-- Common setting for fetch (pull) and insert (push) operations. Also, copier process context uses it.
|
||||
They are overlaid by <settings_pull/> and <settings_push/> respectively. -->
|
||||
<settings>
|
||||
<connect_timeout>3</connect_timeout>
|
||||
<!-- Sync insert is set forcibly, leave it here just in case. -->
|
||||
<insert_distributed_sync>1</insert_distributed_sync>
|
||||
</settings>
|
||||
|
||||
<tables>
|
||||
<!-- A table task, copies one table. -->
|
||||
<event>
|
||||
<!-- Source cluster name (from <remote_servers/> section) and tables in it that should be copied -->
|
||||
<cluster_pull>source_cluster</cluster_pull>
|
||||
<database_pull>default</database_pull>
|
||||
<table_pull>api_request_log</table_pull>
|
||||
|
||||
<!-- Destination cluster name and tables in which the data should be inserted -->
|
||||
<cluster_push>destination_cluster</cluster_push>
|
||||
<database_push>default</database_push>
|
||||
<table_push>api_request_log_replicated</table_push>
|
||||
|
||||
<engine>
|
||||
ENGINE = ReplicatedReplacingMergeTree(
|
||||
'/clickhouse/tables/{shard}/default/api_request_log_replicated',
|
||||
'{replica}',
|
||||
ver
|
||||
)
|
||||
PARTITION BY toYYYYMM(request_ts)
|
||||
ORDER BY uuid
|
||||
SETTINGS index_granularity = 8192;
|
||||
</engine>
|
||||
<sharding_key>rand()</sharding_key>
|
||||
</event>
|
||||
</tables>
|
||||
</yandex>
|
||||
```
|
||||
|
||||
В каждом файле меняется название базы в разделе **tables**
|
||||
После этого запускается копирование, где --task-path должен быть уникальным для каждой таблицы
|
||||
```bash
|
||||
clickhouse-copier --config config.xml --task-file ./tasks/api_request_log.xml --task-path /clickhouse/copier/task1
|
||||
```
|
||||
44
DevOps/Docker/converter.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Конвертация строки в compose
|
||||
description:
|
||||
published: true
|
||||
date: 2025-06-17T09:20:55.103Z
|
||||
tags: docker
|
||||
editor: markdown
|
||||
dateCreated: 2025-06-17T09:20:07.483Z
|
||||
---
|
||||
|
||||
Я попал на сайт к какому-то девопсу, где были материалы по Playwright. Я немного походил по нему и набрёл на раздел DevTools (https://ray.run/tools). Он там собрал то ли свои, то ли просто open source инструменты для решения простых прикладных задач. Вроде ничего особенного, но некоторые вещи я просто не знал, что вообще существуют. Всегда их делал вручную.
|
||||
|
||||
Покажу сразу на примерах, что мне показалось полезным:
|
||||
|
||||
- Docker Run to Docker Compose Converter (https://ray.run/tools/docker-run-to-docker-compose)
|
||||
Отправляем в форму однострочник с docker run и получаем файл для docker compose. Вроде мелочь, но я всегда это делал вручную. Не думал, что кому-то придёт в голову написать конвертер.
|
||||
|
||||
- Docker Compose to Docker Run Converter (https://ray.run/tools/docker-compose-to-docker-run)
|
||||
И соответственно в обратную сторону преобразование из docker compose в однострочник для docker run. Не припоминаю, чтобы мне приходилось такие преобразования делать, но в тему к первому упоминаю.
|
||||
|
||||
- Bash Command Formatter (https://ray.run/tools/bash-command-formatter)
|
||||
Эта штука тоже очень понравилась. Она длинный однострочник разбивает на строки с переходами через \ То есть вот такую колбасу:
|
||||
```
|
||||
curl -v --url "smtp://mail.server.ru:25" --mail-from "root@server.ru" --mail-rcpt "user@gmail.com" --user 'root@server.ru:password123' --upload-file ~/mail.txt
|
||||
```
|
||||
Нарезает на кусочки:
|
||||
```
|
||||
curl -v \
|
||||
--url "smtp://mail.server.ru:25" \
|
||||
--mail-from "root@server.ru" \
|
||||
--mail-rcpt "user@gmail.com" \
|
||||
--user 'root@server.ru:password123' \
|
||||
--upload-file ~/mail.txt
|
||||
```
|
||||
Я тоже всегда это вручную делал, особенно для публикации сюда. Можно упростить себе задачу.
|
||||
|
||||
- URL Extractor (https://ray.run/tools/url-extractor)
|
||||
Просто кидаешь сюда любой текст, а на выходе получаешь набор ссылок, если они в нём присутствуют.
|
||||
|
||||
Там много всяких конвертеров и анализаторов синтаксиса для json, yaml, toml, csv. Не стал обращать на них внимание, так как их существует десятки. Обычно просто в гугле ищут что-то подобное, когда надо преобразовать. Посмотрите список, может вам что-то ещё приглянётся. Меня впечатлили только эти четыре штуки.
|
||||
|
||||

|
||||

|
||||
.jpg)
|
||||
49
DevOps/ELK/EFK-rotate.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: EFK - ротация логов fluent-bit
|
||||
description:
|
||||
published: true
|
||||
date: 2025-03-13T16:02:22.898Z
|
||||
tags: elk, efk, fluent-bit, rotate
|
||||
editor: markdown
|
||||
dateCreated: 2025-03-13T16:02:22.898Z
|
||||
---
|
||||
|
||||
# Ротация логов fluent-bit
|
||||
Не получилось сделать ротацию логов, если индекс имеет текущую дату, получилось с помощью порядокового номера
|
||||
|
||||
> Нужно в конфиге флюента в разделе [OUTPUT] сделать такие параметры:
|
||||
Logstash_Format Off
|
||||
Index smvu2-test-stand-docker
|
||||
|
||||
## Запросы в EFK:
|
||||
После запуска контейнера лог уже отправляется в EFK и создается индекс, поэтому нужно сначала его удалить
|
||||
```json
|
||||
DELETE /smvu2-test-stand-docker
|
||||
```
|
||||
Создаем шаблон
|
||||
```json
|
||||
PUT _index_template/smvu2-test-stand-docker-template
|
||||
{
|
||||
"index_patterns": [
|
||||
"smvu2-test-stand-docker-*"
|
||||
],
|
||||
"composed_of": ["smvu2-common-settings"],
|
||||
"template": {
|
||||
"settings": {
|
||||
"index.lifecycle.name": "smvu2-policy",
|
||||
"index.lifecycle.rollover_alias": "smvu2-test-stand-docker"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Ну и создаем индекс с алиасом, куда будет прилетать лог
|
||||
```json
|
||||
PUT smvu2-test-stand-docker-000001
|
||||
{
|
||||
"aliases": {
|
||||
"smvu2-test-stand-docker": {
|
||||
"is_write_index": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
146
DevOps/ELK/Rotation-logs-ILM.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
title: Ротация логов с помощью Lificycle
|
||||
description: ILM
|
||||
published: true
|
||||
date: 2025-03-13T08:16:59.504Z
|
||||
tags: ilm, elk, efk
|
||||
editor: markdown
|
||||
dateCreated: 2025-03-13T08:16:59.504Z
|
||||
---
|
||||
|
||||
# Ротация логов в ELK
|
||||
Конечно! Давайте разберем настройку ротации логов с помощью ILM (Index Lifecycle Management) в Elasticsearch простым языком. Это пошаговая инструкция, которая поможет вам настроить автоматическое управление жизненным циклом индексов (логов).
|
||||
|
||||
---
|
||||
|
||||
### **1. Что такое ротация логов с ILM?**
|
||||
Ротация логов — это процесс автоматического создания новых индексов (например, когда текущий индекс становится слишком большим или старым) и удаления старых индексов, чтобы освободить место. ILM помогает автоматизировать этот процесс.
|
||||
|
||||
---
|
||||
|
||||
### **2. Основные шаги настройки ILM для ротации логов:**
|
||||
|
||||
#### **Шаг 1: Создайте алиас для индексов**
|
||||
Алиас — это "псевдоним", который будет указывать на текущий активный индекс. Все новые данные будут писаться в индекс, на который указывает этот алиас.
|
||||
|
||||
Пример:
|
||||
```bash
|
||||
PUT _aliases
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"add": {
|
||||
"index": "logs-2023.10.01-000001", # текущий индекс
|
||||
"alias": "logs-alias" # алиас
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **Шаг 2: Создайте политику ILM**
|
||||
Политика ILM определяет, что делать с индексами на разных этапах их жизни (например, когда переходить на новый индекс, когда удалять старые данные).
|
||||
|
||||
Пример политики:
|
||||
```bash
|
||||
PUT _ilm/policy/logs-policy
|
||||
{
|
||||
"policy": {
|
||||
"phases": {
|
||||
"hot": { # этап "горячих" данных
|
||||
"actions": {
|
||||
"rollover": { # ротация индекса
|
||||
"max_size": "50gb", # ротация при достижении 50 ГБ
|
||||
"max_age": "7d" # или через 7 дней
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": { # этап удаления
|
||||
"min_age": "30d", # удалить через 30 дней
|
||||
"actions": {
|
||||
"delete": {} # действие — удалить индекс
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **Шаг 3: Создайте шаблон индекса**
|
||||
Шаблон индекса автоматически применяет настройки (например, политику ILM и алиас) к новым индексам, которые соответствуют определенному шаблону имени.
|
||||
|
||||
Пример шаблона:
|
||||
```bash
|
||||
PUT _index_template/logs-template
|
||||
{
|
||||
"index_patterns": ["logs-*"], # шаблон имени индекса
|
||||
"template": {
|
||||
"settings": {
|
||||
"index.lifecycle.name": "logs-policy", # применяем политику ILM
|
||||
"index.lifecycle.rollover_alias": "logs-alias" # указываем алиас
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **Шаг 4: Создайте начальный индекс**
|
||||
Создайте первый индекс, который будет использоваться для записи данных. Убедитесь, что он соответствует шаблону и имеет алиас.
|
||||
|
||||
Пример:
|
||||
```bash
|
||||
PUT logs-2023.10.01-000001
|
||||
{
|
||||
"aliases": {
|
||||
"logs-alias": {} # назначаем алиас
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **Шаг 5: Настройте сбор логов**
|
||||
Убедитесь, что ваши логи (например, из Filebeat, Logstash или другого источника) пишутся в алиас `logs-alias`. Это гарантирует, что данные будут попадать в текущий активный индекс.
|
||||
|
||||
---
|
||||
|
||||
#### **Шаг 6: Проверка работы ILM**
|
||||
- Когда текущий индекс достигнет 50 ГБ или пройдет 7 дней, ILM создаст новый индекс (например, `logs-2023.10.08-000002`) и перенаправит запись на него.
|
||||
- Старые индексы будут автоматически удаляться через 30 дней.
|
||||
|
||||
---
|
||||
|
||||
### **3. Как проверить, что все работает?**
|
||||
- Проверьте статус ILM:
|
||||
```bash
|
||||
GET _ilm/status
|
||||
```
|
||||
- Посмотрите информацию по конкретному индексу:
|
||||
```bash
|
||||
GET logs-2023.10.01-000001/_ilm/explain
|
||||
```
|
||||
- Убедитесь, что новые индексы создаются, а старые удаляются.
|
||||
|
||||
---
|
||||
|
||||
### **4. Пример полного цикла:**
|
||||
1. Создаете алиас `logs-alias` и первый индекс `logs-2023.10.01-000001`.
|
||||
2. Данные начинают писаться в `logs-2023.10.01-000001`.
|
||||
3. Через 7 дней или при достижении 50 ГБ создается новый индекс `logs-2023.10.08-000002`, и данные начинают писаться туда.
|
||||
4. Через 30 дней индекс `logs-2023.10.01-000001` автоматически удаляется.
|
||||
|
||||
---
|
||||
|
||||
### **5. Частые ошибки:**
|
||||
- **Алиас не указан:** Убедитесь, что алиас указан в шаблоне индекса и в самом индексе.
|
||||
- **Политика не применяется:** Проверьте, что политика ILM указана в шаблоне индекса.
|
||||
- **Нет данных для ротации:** Убедитесь, что данные пишутся в алиас.
|
||||
|
||||
---
|
||||
|
||||
Если все настроено правильно, ILM будет автоматически управлять вашими индексами, и вам не придется вручную заниматься ротацией логов. 😊
|
||||
103
DevOps/Gitlab/Minimal-install.md
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Gitlab minimal install
|
||||
description:
|
||||
published: true
|
||||
date: 2025-03-25T18:40:52.824Z
|
||||
tags: gitlab
|
||||
editor: markdown
|
||||
dateCreated: 2025-03-25T18:39:58.350Z
|
||||
---
|
||||
|
||||
Популярный open source продукт, который можно развернуть на своём оборудовании, Gitlab требует для своей работы приличное количество ресурсов. Для того, чтобы он в установке по умолчанию работал бодрячком лучше всего начать с 4 CPU и 8 GB оперативной памяти. Можно выделить 4 GB, но будет заметно тормозить, иногда 500-е ошибки выдавать.
|
||||
|
||||
Для того, чтобы иметь возможность использовать Gitlab для единоличного использования, либо очень небольшого коллектива, многие из стандартных компонентов и настроек программного комплекса можно безболезненно отключить. В документации есть отдельная статья на этот счёт:
|
||||
|
||||
⇨ Running GitLab in a memory-constrained environment (https://docs.gitlab.com/omnibus/settings/memory_constrained_envs.html) (Запуск GitLab в среде с ограниченным объемом памяти)
|
||||
|
||||
Следуя этим рекомендация, можно заставить работать систему с использованием всего 2 GB оперативной памяти. Если вы запускаете его для себя на арендованном железе, то можно получить существенную экономию ресурсов.
|
||||
|
||||
Я взял виртуальную машину с 1 CPU и 2 GB памяти и попробовал на ней запустить Gitlab. Что для этого нужно сделать?
|
||||
|
||||
1️⃣ Подключаем 1 GB свопа.
|
||||
|
||||
```
|
||||
# dd if=/dev/zero of=/swap bs=1024 count=1000000
|
||||
# mkswap /swap
|
||||
# chmod 0600 /swap
|
||||
# swapon /swap
|
||||
```
|
||||
|
||||
Добавляем в /etc/fstab:
|
||||
`/swap swap swap defaults 0 0`
|
||||
|
||||
2️⃣ Меняем параметр swappiness:
|
||||
|
||||
`# sysctl vm.swappiness=10`
|
||||
|
||||
Добавляем в /etc/sysctl.conf:
|
||||
|
||||
`vm.swappiness=10`
|
||||
|
||||
3️⃣ Устанавливаем Gitlab.
|
||||
```
|
||||
# curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | bash
|
||||
# EXTERNAL_URL="http://10.20.1.36" apt-get install gitlab-ce
|
||||
````
|
||||
|
||||
4️⃣ Отключаем службу puma, которая помогает обрабатывает конкурентные запросы. Без большой нагрузки можно обойтись без неё. В /etc/gitlab/gitlab.rb добавляем:
|
||||
|
||||
`puma['worker_processes'] = 0`
|
||||
|
||||
5️⃣ Уменьшаем число фоновых процессов Sidekiq:
|
||||
|
||||
`sidekiq['concurrency'] = 10`
|
||||
|
||||
6️⃣ Оптимизируем Gitaly. Туда же в конфиг добавляем:
|
||||
```json
|
||||
gitaly['configuration'] = {
|
||||
concurrency: [
|
||||
{
|
||||
'rpc' => "/gitaly.SmartHTTPService/PostReceivePack",
|
||||
'max_per_repo' => 3,
|
||||
}, {
|
||||
'rpc' => "/gitaly.SSHService/SSHUploadPack",
|
||||
'max_per_repo' => 3,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
gitaly['env'] = {
|
||||
'GITALY_COMMAND_SPAWN_MAX_PARALLEL' => '2'
|
||||
}
|
||||
```
|
||||
|
||||
❗️Обращаю ваше внимание, что я убрал из этого раздела настройки, касающиеся cgroups. В инструкции судя по всему какая-то ошибка. Если их оставить, то сокет gitaly не поднимается. А в интерфейсе при создании каких-либо сущностей, например, нового проекта, вылетает 502 ошибка. И это не зависит от выделенных ресурсов.
|
||||
|
||||
7️⃣ Отключаем мониторинг:
|
||||
|
||||
`prometheus_monitoring['enable'] = false`
|
||||
|
||||
8️⃣ Уменьшаем потребление памяти процессам GitLab:
|
||||
```
|
||||
gitlab_rails['env'] = {
|
||||
'MALLOC_CONF' => 'dirty_decay_ms:1000,muzzy_decay_ms:1000'
|
||||
}
|
||||
|
||||
gitaly['env'] = {
|
||||
'MALLOC_CONF' => 'dirty_decay_ms:1000,muzzy_decay_ms:1000'
|
||||
}
|
||||
```
|
||||
|
||||
9️⃣ Перезапускаем Gitlab:
|
||||
|
||||
`# gitlab-ctl reconfigure`
|
||||
|
||||
🔟 Идём в веб интерфейс и отключаем в настройках мониторинга метрики Prometheus: Admin Area ⇨ Settings ⇨ Metrics and profiling ⇨ Metrics - Prometheus ⇨ отключаем Enable Prometheus Metrics.
|
||||
|
||||
После перезапуска Gitlab будет очень долго подниматься. Но в итоге заработает. Смотрим потребление памяти и проверяем, как всё работает:
|
||||
|
||||
`# free -h`
|
||||
|
||||
Более подробно всё это описано по ссылке в статье из начала заметки. Для комфортной работы лучше всё же добавить до 2CPU и 3GB памяти. Тогда всё это будет бодро работать с предложенными параметрами. Если этого не сделать, то иногда будете видеть 500-е ошибки.
|
||||
|
||||
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
|
||||
196
DevOps/Hashicorp-Vault/Gitlab-with-vault.md
Normal file
@@ -0,0 +1,196 @@
|
||||
---
|
||||
title: Vault через GitLab CI - Аутентификация и чтение секретов
|
||||
description:
|
||||
published: true
|
||||
date: 2024-08-01T14:48:58.749Z
|
||||
tags: vault, gitlab
|
||||
editor: markdown
|
||||
dateCreated: 2024-07-31T12:59:36.391Z
|
||||
---
|
||||
|
||||
|
||||
Источник: https://habr.com/ru/companies/nixys/articles/512754/
|
||||
Этот туториал демонстрирует пример аутентификации, конфигурации и чтения секретов с HashiCorp’s Vault через GitLab CI/CD.
|
||||
|
||||
**Требования**
|
||||
|
||||
Туториал предполагает, что вы знакомы с GitLab CI/CD и Vault.
|
||||
|
||||
Чтобы ему последовать, вам понадобятся:
|
||||
|
||||
- Аккаунт в GItLab
|
||||
- Запущенный Vault сервер и доступ для настройки аутентификации и создания ролей и политик.
|
||||
Для каждой задачи (job) генерируется свой уникальный токен JSON Web Token (JWT), доступный только как значение переменной окружения CI_JOB_JWT конкретной задачи. Данный JWT может быть использован для аутентификации в Vault при помощи метода JWT Auth.
|
||||
Пример того, как выглядит JWT в дешифрованном виде:
|
||||
```json
|
||||
{
|
||||
"jti": "c82eeb0c-5c6f-4a33-abf5-4c474b92b558", # Уникальный идентификатор токена
|
||||
"iss": "gitlab.example.com", # Issuer, т.е. домен вашего инстанса GitLab
|
||||
"iat": 1585710286, # Время выдачи
|
||||
"nbf": 1585798372, # Не валиден до
|
||||
"exp": 1585713886, # Не велиден после
|
||||
"sub": "22", # Subject (project id)
|
||||
"namespace_id": "1",
|
||||
"namespace_path": "mygroup",
|
||||
"project_id": "22",
|
||||
"project_path": "mygroup/myproject",
|
||||
"user_id": "42",
|
||||
"user_login": "myuser",
|
||||
"user_email": "myuser@example.com"
|
||||
"pipeline_id": "1212",
|
||||
"job_id": "1212",
|
||||
"ref": "auto-deploy-2020-04-01", # Название Git-refs для этой задачи
|
||||
"ref_type": "branch", # Тип Git-refs, это либо(branch) либо тег(tag)
|
||||
"ref_protected": "true" # true, если это ветка protected, иначе false
|
||||
}
|
||||
```
|
||||
|
||||
Токен кодируется по стандарту RS256 и подписывается приватным ключом OpenID Connect вашего GitLab инстанса, причем этот ключ периодически изменяется без вашего ведома. И, если приватный ключ был изменен, при cледующем запуске задания новый JWT будет подписан с новым ключом. Срок валидности токена будет устанавливаться в соотвествии с таймаутом вашего задания, а если он не задан, то срок валидности будет 5 минут.
|
||||
|
||||
Вы можете использовать этот JWT-токен и URL (https://gitlab.example.com/-/jwks) как конечную точку JWKS для аутентификации на Vault сервере, если для него настроен соответствующий метод JWT-аутентификации.
|
||||
|
||||
При настройке ролей в Vault, вы можете задавать значения bound_claims для сопоставления их с полями из JWT и, таким образом, дополнительно ограничить то, к каким секретам какой процесс CI будет иметь доступ.
|
||||
|
||||
Для получения доступа к Vault можно использовать либо его CLI, либо выполнять запросы к API (через curl или другой клиент).
|
||||
|
||||
**Пример**
|
||||
Предположим, у вас есть пароли для ваших баз данных, отличающиеся для production и staging окружений и они хранятся в Vault, который доступен по адресу http://vault.example.com:8200. Ваш пароль для stage это pa$$w0rd и real-pa$$w0rd для prod:
|
||||
```
|
||||
$ vault kv get -field=password secret/myproject/staging/db
|
||||
pa$$w0rd
|
||||
|
||||
$ vault kv get -field=password secret/myproject/production/db
|
||||
real-pa$$w0rd
|
||||
```
|
||||
Разрешим для нашего Vault-сервера метод аутентификации через JWT:
|
||||
```
|
||||
$ vault auth enable jwt
|
||||
Success! Enabled jwt auth method at: jwt/
|
||||
```
|
||||
Создаем policy, которые дают доступ на чтение к нужным нам секретам:
|
||||
```bash
|
||||
$ vault policy write myproject-staging - <<EOF
|
||||
# Policy name: myproject-staging
|
||||
#
|
||||
# Read-only permission on 'secret/data/myproject/staging/*' path
|
||||
path "secret/data/myproject/staging/*" {
|
||||
capabilities = [ "read" ]
|
||||
}
|
||||
EOF
|
||||
Success! Uploaded policy: myproject-staging
|
||||
|
||||
$ vault policy write myproject-production - <<EOF
|
||||
# Policy name: myproject-production
|
||||
#
|
||||
# Read-only permission on 'secret/data/myproject/production/*' path
|
||||
path "secret/data/myproject/production/*" {
|
||||
capabilities = [ "read" ]
|
||||
}
|
||||
EOF
|
||||
Success! Uploaded policy: myproject-production
|
||||
```
|
||||
Теперь нам нужны роли, которые будут связывать созданные политики с JWT-токенами.
|
||||
|
||||
Для stage под названием myproject-staging:
|
||||
```json
|
||||
$ vault write auth/jwt/role/myproject-staging - <<EOF
|
||||
{
|
||||
"role_type": "jwt",
|
||||
"policies": ["myproject-staging"],
|
||||
"token_explicit_max_ttl": 60,
|
||||
"user_claim": "user_email",
|
||||
"bound_claims": {
|
||||
"project_id": "22",
|
||||
"ref": "master",
|
||||
"ref_type": "branch"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
````
|
||||
И для production под названием myproject-production:
|
||||
```json
|
||||
$ vault write auth/jwt/role/myproject-production - <<EOF
|
||||
{
|
||||
"role_type": "jwt",
|
||||
"policies": ["myproject-production"],
|
||||
"token_explicit_max_ttl": 60,
|
||||
"user_claim": "user_email",
|
||||
"bound_claims_type": "glob",
|
||||
"bound_claims": {
|
||||
"project_id": "22",
|
||||
"ref_protected": "true",
|
||||
"ref_type": "branch",
|
||||
"ref": "auto-deploy-*"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
В этом примере использовались bound_claims указывающие, что только JWT-токены с соответствующими значениями смогут пройти аутентификацию.
|
||||
|
||||
В сочетании с GitLab protected branches, можно разграничивать тех, кто может проходить аутентификацию и читать секреты.
|
||||
|
||||
Token_explicit_max_ttl определяет, что выпущенный Vault токен, после аутентификации имеет время жизни 60 секунд.
|
||||
|
||||
User_claim определяет имя пользователя, которое будет использовать Vault при успешной авторизации. (Прим. переводчика — В нашем случае "user_claim" = "user_email", то есть имя пользователя будет иметь значение user_email из JWT-токена. То есть определяться как (известный GitLab) email пользователя, запустившего задание.)
|
||||
|
||||
Параметр bound_claims_type задает формат значений bound_claims. Если он установлен в “glob”, то значения будут интерпретироваться в формате glob и * будет означать любое количество символов. (Прим. переводчика — Также доступно значение “string”, в этом случае данные будут хранится в формате строк и * будет означать только *.)
|
||||
Полный лист опций можно посмотреть в Vault’s Create Role documentation.
|
||||
|
||||
Предупреждение: обязательно устанавливайте либо project_id либо namespace_id, иначе любой токен, сгенерированный этим инстансом GitLab, сможет использовать эту роль.
|
||||
|
||||
Теперь зададим метод аутентификации через JWT:
|
||||
```
|
||||
$ vault write auth/jwt/config \
|
||||
jwks_url="https://gitlab.example.com/-/jwks" \
|
||||
bound_issuer="gitlab.example.com"
|
||||
```
|
||||
bound_issuer определяет, что только токены, выпущенные от имени домена gitlab.example.com (iss claim) могут использовать этот метод аутентификации, и в качестве точки валидации токена JWKS должна использоваться страница https://gitlab.example.com/-/jwks .
|
||||
|
||||
Полный список доступных опций можно посмотреть в Vault’s API documentation.
|
||||
|
||||
Теперь создадим джобу для master-ветки, у которой будут права на чтение secret/myproject/staging/, но при этом не будет прав на чтение secret/myproject/production/:
|
||||
```yaml
|
||||
read_secrets:
|
||||
script:
|
||||
# Проверяем имя ref джобы
|
||||
- echo $CI_COMMIT_REF_NAME
|
||||
# и является ли она protected
|
||||
- echo $CI_COMMIT_REF_PROTECTED
|
||||
# Адрес Vault может быть передан через переменную в CI
|
||||
- export VAULT_ADDR=http://vault.example.com:8200
|
||||
# Проходим аутентификацию и получаем токен. Время истечения жизни токена и другие
|
||||
# его параметры можно задать при конфигурации
|
||||
# JWT Auth - https://www.vaultproject.io/api/auth/jwt#parameters-1
|
||||
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-staging jwt=$CI_JOB_JWT)"
|
||||
# Теперь используем VAULT_TOKEN для чтения секретов и сохранения их в перемнных окружения
|
||||
- export PASSWORD="$(vault kv get -field=password secret/myproject/staging/db)"
|
||||
# Используем секрет
|
||||
- echo $PASSWORD
|
||||
# Здесь получить секрет не получится, потому что роль myproject-staging не может
|
||||
# читать секреты из secret/myproject/production/*
|
||||
- export PASSWORD="$(vault kv get -field=password secret/myproject/production/db)"
|
||||
```
|
||||

|
||||
Следующее задание сможет пройти аутентификацию через роль myproject-production и прочитать секрет в /secret/myproject/production/:
|
||||
```yaml
|
||||
read_secrets:
|
||||
script:
|
||||
# Проверяем имя ref джобы
|
||||
- echo $CI_COMMIT_REF_NAME
|
||||
# и является ли она protected
|
||||
- echo $CI_COMMIT_REF_PROTECTED
|
||||
# Адрес Vault может быть передан через переменную в CI
|
||||
- export VAULT_ADDR=http://vault.example.com:8200
|
||||
# Проходим аутентификацию и получаем токен. Время истечения жизни токена и другие
|
||||
# его параметры можно задать при конфигурации
|
||||
# JWT Auth - https://www.vaultproject.io/api/auth/jwt#parameters-1
|
||||
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-production jwt=$CI_JOB_JWT)"
|
||||
# Теперь используем VAULT_TOKEN для чтения секретов и сохранения их в перемнных окружения
|
||||
- export PASSWORD="$(vault kv get -field=password secret/myproject/production/db)"
|
||||
# Используем секрет
|
||||
- echo $PASSWORD
|
||||
```
|
||||

|
||||
На этом все, надеюсь данный туториал окажется вам полезен!
|
||||
|
||||
|
||||
338
DevOps/Hashicorp-Vault/vault-postgresql-users.md
Normal file
@@ -0,0 +1,338 @@
|
||||
---
|
||||
title: PostgreSQL через Vault - управление динамическими учетными записями
|
||||
description:
|
||||
published: true
|
||||
date: 2024-08-01T15:52:14.268Z
|
||||
tags: vault, postgresql
|
||||
editor: markdown
|
||||
dateCreated: 2024-08-01T14:55:31.582Z
|
||||
---
|
||||
|
||||
# Управление динамическими учетными записями в PostgreSQL через Hashicorp Vault
|
||||
|
||||
>В инструкции мы рассмотрим процесс хранения учетной записи PostgreSQL в хранилище секретов Hashicorp Vault, используя механизм database, с возможностью автоматической смены секрета в СУБД при его смене в Vault. Также мы настроим Vault для создания временных учетных записей в PostgreSQL.
|
||||
|
||||
|
||||
## Настройка прав PostgreSQL
|
||||
|
||||
На сервере PostgreSQL нам необходимо:
|
||||
|
||||
- Задать пароль для пользователя postgres.
|
||||
- Создать пользователя, пароль для которого мы будем хранить в Vault.
|
||||
- Разрешить подключение к базе данных для postgres и созданного пользователя.
|
||||
- Открыть порт 5432 для удаленного подключения.
|
||||
- Проверить доступы.
|
||||
|
||||
Рассмотрим действия по шагам.
|
||||
|
||||
### Задаем пароль для postgres
|
||||
Данные действия необходимы, если мы не задавали пароль для пользователя postgres или мы не знаем данный пароль.
|
||||
>Стоит иметь ввиду, что данный пользователь может использоваться другими приложениями — таким образом, смена пароля приведет к потере их работоспособности. В этом случае, стоит уточнить текущий пароль и использовать его.
|
||||
|
||||
Заходим под пользователем postgres и подключаемся к СУБД:
|
||||
```
|
||||
su - postgres
|
||||
$ psql
|
||||
```
|
||||
|
||||
Вводим:
|
||||
```
|
||||
=# ALTER USER postgres PASSWORD 'qwerty123';
|
||||
```
|
||||
*в данном примере мы задаем пароль qwerty123 для пользователя postgres.*
|
||||
|
||||
### Создаем нового пользователя
|
||||
На данном шаге мы создадим пользователя, для которого и будем хранить секрет в Vault. В рамках примера мы не будем его предоставлять никаких доступов. Для нас достаточно, чтобы мы могли подключиться и удостовериться, что пароль будет меняться.
|
||||
|
||||
В той же командной оболочке postgresql вводим:
|
||||
```
|
||||
=# CREATE USER ksu WITH PASSWORD 'qwerty123';
|
||||
```
|
||||
*с помощью данной команды мы создадим пользователя ksu с паролем qwerty123.*
|
||||
|
||||
### Разрешаем подключение к СУБД
|
||||
Нам необходимо разрешить подключаться к базе данных пользователю ksu (создали на шаге 2) с локального компьютера и пользователю postgres с сервера Vault. Это делается посредством редактирования файла pg_hba.conf.
|
||||
|
||||
Но размещение этого файла может быть разным — это зависит от версии установленного PostgreSQL. Вводим команду:
|
||||
```
|
||||
=# SHOW config_file;
|
||||
```
|
||||
Данная команда нам покажет место размещения конфигурационного файла postgresql.conf — в этом же каталоге находятся и другие конфигурационные файлы. Например, если команда показала:
|
||||
```
|
||||
----------------------------------------
|
||||
/etc/postgresql/11/main/postgresql.conf
|
||||
(1 row)
|
||||
```
|
||||
... то значит нужный нам файл в каталоге /etc/postgresql/11/main/.
|
||||
|
||||
Выходим из командной оболочки psql:
|
||||
```
|
||||
=# \q
|
||||
```
|
||||
Разлогиниваемся из-под пользователя postgres:
|
||||
```
|
||||
$ exit
|
||||
```
|
||||
И вводим:
|
||||
```
|
||||
vi /etc/postgresql/11/main/pg_hba.conf
|
||||
```
|
||||
*где /etc/postgresql/11/main/ — путь, который мы получили с помощью sql-команды SHOW config_file.*
|
||||
|
||||
В данном файле мы должны добавить 2 строки:
|
||||
```
|
||||
...
|
||||
# "local" is for Unix domain socket connections only
|
||||
local all ksu md5
|
||||
...
|
||||
# IPv4 local connections:
|
||||
host all postgres 172.30.5.19/32 md5
|
||||
...
|
||||
```
|
||||
|
||||
*где 172.30.5.19 — IP-адрес предполагаемого сервера Vault, с которого мы будем подключаться под пользователем postgres.*
|
||||
|
||||
Открываем конфигурационный файл:
|
||||
```
|
||||
vi /etc/postgresql/11/main/postgresql.conf
|
||||
```
|
||||
Приводим опцию listen_addresses к виду:
|
||||
```
|
||||
listen_addresses = '*'
|
||||
```
|
||||
*в данном примере мы настроили, чтобы postgresql слушал запросы на всех сетевых интерфейсах. При необходимости. мы можем ограничить их число вводом конкретного адреса.*
|
||||
|
||||
Перезапускаем службу СУБД:
|
||||
```
|
||||
systemctl restart postgresql
|
||||
```
|
||||
*команда для перезапуска PostgreSQL может отличаться и зависит от версии СУБД.*
|
||||
|
||||
### Настраиваем межсетевой экран
|
||||
Для подключения к серверу баз данных по сети, нам необходимо открыть порт 5432.
|
||||
|
||||
Как правило, в CentOS используется firewalld, как средство управления брандмауэром. Вводим:
|
||||
```
|
||||
firewall-cmd --permanent --add-port=5432/tcp
|
||||
|
||||
firewall-cmd --reload
|
||||
```
|
||||
5. Делаем проверку
|
||||
Убедимся, что наши учетные записи имеют права для подключения к базе данных.
|
||||
|
||||
На сервере с СУБД вводим:
|
||||
```
|
||||
psql -Uksu -W template1
|
||||
```
|
||||
* в данном примере мы подключаемся к локальному хосту под пользователем ksu.
|
||||
|
||||
Система запросит пароль — вводим тот, что задали при создании нашего пользователя. Мы должны попасть в оболочку psql.
|
||||
|
||||
Теперь подключаемся по SSH на сервер Vault. Нам придется установить на него клиента postgresql.
|
||||
|
||||
На Deb (Ubuntu, Debian):
|
||||
```
|
||||
apt install postgresql
|
||||
```
|
||||
После установки можно подключаться к нашему серверу с помощью команды psql.
|
||||
|
||||
Вводим:
|
||||
```
|
||||
psql -h172.30.30.87 -Upostgres -W
|
||||
```
|
||||
*в данном примере мы подключимся к серверу 172.30.30.87 под учетной записью postgres.*
|
||||
|
||||
Консоль у нас запросит пароль — вводим тот, что задали для пользователя postgres. В итоге мы должны подключиться к серверу:
|
||||
```
|
||||
postgres=#
|
||||
```
|
||||
Выходим из SQL-оболочки:
|
||||
```
|
||||
postgres=# \q
|
||||
```
|
||||
... и переходим к настройке Vault.
|
||||
|
||||
### Настройка Vault
|
||||
На стороне хранилища паролей необходимо:
|
||||
|
||||
Включить механизм хранения database.
|
||||
Создать конфигурацию для подключения к СУБД и привязать ее к роли.
|
||||
Выполним настройки по шагам.
|
||||
|
||||
Включаем механизм database
|
||||
Для включения механизма database вводим:
|
||||
```
|
||||
vault secrets enable database
|
||||
```
|
||||
Мы должны получить ответ:
|
||||
```
|
||||
Success! Enabled the database secrets engine at: database/
|
||||
```
|
||||
... или:
|
||||
```
|
||||
Error enabling: Error making API request.
|
||||
...
|
||||
* path is already in use at database/
|
||||
```
|
||||
Второй ответ говорит нам о том, что механизм database уже работает по пути database/. Так или иначе, идем дальше.
|
||||
### Настройка подключения к postgresql
|
||||
Создаем конфигурацию с опциями подключения к базе данных:
|
||||
```
|
||||
vault write database/config/postgresql \
|
||||
plugin_name=postgresql-database-plugin \
|
||||
allowed_roles="postgresql-rotate,postgresql-create" \
|
||||
connection_url=postgresql://{{username}}:{{password}}@172.30.30.87:5432/postgres?sslmode=disable \
|
||||
username="postgres" \
|
||||
password="qwerty123"
|
||||
```
|
||||
где:
|
||||
|
||||
- **database/config/postgresql** — путь в системе Vault к секрету.
|
||||
- **plugin_name** — плагин, который будем использоваться конфигурацией.
|
||||
- **allowed_roles** — для каких ролей будет использоваться данная конфигурация. Ниже по инструкции мы создадим 2 роли — для ротации паролей и для создания временных пользователей.
|
||||
- **connection_url** — строка подключения к базе данных. В данном примере 172.30.30.87 — сервер PostgreSQL.
|
||||
- **username** — пользователь, под которым выполняется подключение к СУБД.
|
||||
- **password** — пароль для пользователя, под которым выполняем подключение.
|
||||
|
||||
Наш Vault подготовлен для работы с базой PostgreSQL.
|
||||
|
||||
## Настройка ротации паролей
|
||||
Данная настройка позволит автоматически по таймеру менять пароли в СУБД PostgreSQL для определенных учетных записей.
|
||||
|
||||
На стороне хранилища паролей необходимо:
|
||||
|
||||
- Создать роль, которая будет менять пароль в базе данных.
|
||||
- Проверить настройки, создав новый пароль и подключившись к базе данных.
|
||||
|
||||
Переходим к настройке.
|
||||
|
||||
### Создаем роль для смены пароля
|
||||
Настройка задается с помощью static-roles. В нашем Vault вводим команду:
|
||||
```
|
||||
vault write database/static-roles/postgresql-rotate \
|
||||
db_name=postgresql \
|
||||
rotation_statements="ALTER USER \"{{name}}\" WITH PASSWORD '{{password}}';" \
|
||||
username="ksu" \
|
||||
rotation_period=720h
|
||||
```
|
||||
|* обратите внимание, что запрос rotation_statements важно написать именно так — первая кавычка двойная, вторая одинарная.
|
||||
|** в данном примере:
|
||||
|
||||
- Мы создадим роль с названием **postgresql-rotate** (с тем названием, которое мы использовали в allowed_roles, когда создавали конфигурацию).
|
||||
- Опция **db_name** должна называться как настройка, которую мы создали на предыдущем шаге (database/config/postgresql).
|
||||
- Наша роль будет выполнять команду **rotation_statements** (менять пароль для пользователя).
|
||||
- Каждые 720 часов (30 дней) пароль будет меняться автоматически.
|
||||
|
||||
Мы должны увидеть что-то на подобие:
|
||||
```
|
||||
Success! Data written to: database/static-roles/postgresql-rotate
|
||||
```
|
||||
Готово.
|
||||
|
||||
### Меняем пароль и проверяем доступ
|
||||
Давайте посмотрим текущий пароль:
|
||||
```
|
||||
vault read database/static-creds/postgresql-rotate
|
||||
```
|
||||
Мы получим что-то на подобие:
|
||||
```
|
||||
Key Value
|
||||
--- -----
|
||||
last_vault_rotation 2024-08-01T17:08:42.837263316+03:00
|
||||
password O-Zl1M15Ze1FWzTtPZN1
|
||||
rotation_period 720h
|
||||
ttl 719h39m58s
|
||||
username ksu
|
||||
|
||||
```
|
||||
Где **O-Zl1M15Ze1FWzTtPZN1** — наш пароль от учетной записи ksu.
|
||||
|
||||
Перейдем на сервер с PostgreSQL и попробуем войти в СУБД с использованием этих данных:
|
||||
```
|
||||
psql -Uksu -W template1
|
||||
```
|
||||
Мы должны подключиться с использованием пароля, который получили от Vault.
|
||||
|
||||
## Создание временных пользователей в PostgreSQL
|
||||
Давайте теперь рассмотрим настройку, при которой Vault будет создавать временных пользователей.
|
||||
Для этого мы:
|
||||
|
||||
- Создадим роль в Vault, которая будет создавать учетную запись в базе PostgreSQL.
|
||||
- Настроим файл pg_hba.conf для возможности подключаться к базе пользователям по паролю.
|
||||
- Проверим настройки, создав учетную запись и подключившись к СУБД.
|
||||
|
||||
Приступим.
|
||||
|
||||
### Создаем роль для создания нового пользователя
|
||||
Настройка задается с помощью roles. На сервере Vault вводим команду:
|
||||
```
|
||||
vault write database/roles/postgresql-create \
|
||||
db_name=postgresql \
|
||||
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
|
||||
default_ttl="1h" \
|
||||
max_ttl="24h"
|
||||
```
|
||||
|* обратите внимание, что запрос creation_statements важно написать именно так — первая кавычка двойная, остальные одинарные.
|
||||
|** в данном примере:
|
||||
- Мы создадим роль с названием **postgresql-create** (с тем названием, которое мы использовали в allowed_roles, когда создавали конфигурацию).
|
||||
- Опция **db_name** должна называться как настройка, которую мы создали на шаге создания конфига (database/config/**postgresql**).
|
||||
- Наша роль будет выполнять команду **creation_statements** — создавать пользователя и задавать ему права. Нужно переписать запрос, чтобы права выдавались такими, какими нужны именно вам. Для тестовых целей можно поставить как в данном примере.
|
||||
- **default_ttl** — время, в течение которого будет действовать пароль.
|
||||
- **max_ttl** — время, в течение которого пользователю можно будет обновлять пароль.
|
||||
|
||||
Мы должны увидеть что-то на подобие:
|
||||
```
|
||||
Success! Data written to: database/roles/postgresql-create
|
||||
```
|
||||
Готово.
|
||||
|
||||
### Настраиваем файл pg_hba.conf
|
||||
Ранее в инструкции мы настраивали данный файл, чтобы обеспечить возможность подключения к базе пользователям ksu и postgresql. Но при создании динамических учетных записей, логины будут разные — необходимо разрешить парольный вход для всех пользователей.
|
||||
|
||||
Открываем файл:
|
||||
```
|
||||
vi /etc/postgresql/11/main/pg_hba.conf
|
||||
```
|
||||
* напомню, что путь до нашего файла может быть другим — это зависит от операционной системы и версии postgresql. Посмотреть расположение конфигурационных файлов можно sql-командой **SHOW config_file**;
|
||||
|
||||
В открывшемся редакторе необходимо внести изменения:
|
||||
```
|
||||
...
|
||||
# "local" is for Unix domain socket connections only
|
||||
local all ksu md5
|
||||
local all postgres peer
|
||||
local all all md5
|
||||
##local all all peer
|
||||
...
|
||||
```
|
||||
|* мы добавили строку, разрешающую пользователю postgres логин с локального хоста (local) без запроса пароля; также мы закомментировали строку, которая позволяет вход всем пользователям с локального хоста без пароля и добавили новую, почти, такую же, но требующую ввода логина и пароля.
|
||||
|** это, всего лишь, пример настройки. В вашем случае необходимо руководствоваться политикой безопасности, принятой в компании и требованиями приложения.
|
||||
|
||||
Перезапускаем сервис СУБД:
|
||||
```
|
||||
systemctl restart postgresql
|
||||
```
|
||||
* также напомню, что название сервиса может отличаться и это зависит от версии PostgreSQL.
|
||||
|
||||
### Создаем нового пользователя и проверяем доступ
|
||||
Создаем временного пользователя командой:
|
||||
```
|
||||
vault read database/creds/postgresql-create
|
||||
```
|
||||
Мы должны увидеть что-то на подобие:
|
||||
```
|
||||
Key Value
|
||||
--- -----
|
||||
lease_id database/creds/postgresql-create/dluf4Zt8DUn28jsEhAv6tqmE
|
||||
lease_duration 1h
|
||||
lease_renewable true
|
||||
password SREUIRWI2D-IyGi5npN9
|
||||
username v-ldap-dfe-postgres-73SnRsVbtmVw86CAAlPy-1722523328
|
||||
```
|
||||
Наши логин и пароль соответственно — **v-root-postgres-0VO0sWprjEuCPZkZpu62-1631008720** и **9oAhg1VIEhleeRA7EU-U**.
|
||||
|
||||
Перейдем на сервер с PostgreSQL и попробуем войти в СУБД с использованием этих данных:
|
||||
```
|
||||
psql -U'v-ldap-dfe-postgres-73SnRsVbtmVw86CAAlPy-1722523328' -W template1
|
||||
```
|
||||
Мы должны подключиться с использованием пароля, который получили от Vault.
|
||||
82
DevOps/PostgreSQL/instruments.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Инструменты для обслуживания postgresql
|
||||
description:
|
||||
published: true
|
||||
date: 2025-06-17T09:33:07.672Z
|
||||
tags: postgresql
|
||||
editor: markdown
|
||||
dateCreated: 2025-06-17T09:33:07.672Z
|
||||
---
|
||||
|
||||
Расскажу про парочку инструментов, которые упростят обслуживание сервера PostgreSQL. Начну с наиболее простого - pgBadger (https://pgbadger.darold.net/examples/sample.html). Это анализатор лога, который на его основе генерирует отчёты в формате html. На выходе получаются одиночные html файлы, которые можно просто открыть в браузере. Сделано всё аккуратно и добротно, легко настраивается, отчёты наглядные и информационные.
|
||||
|
||||
🔹Чтобы было что анализировать, необходимо включить логирование интересующих вас событий. Для разовой отладки это всё можно включать на ходу, либо постоянно через файл конфигурации `postgresql.conf` и перезапуск сервера. Он обычно хорошо прокомментирован. Вас будут интересовать параметры, начинающие с log_*. Они собраны все в отдельном блоке. Для примера я включил почти всё:
|
||||
```
|
||||
log_min_duration_statement = 0
|
||||
log_checkpoints = on
|
||||
log_connections = on
|
||||
log_disconnections = on
|
||||
log_duration = on
|
||||
log_line_prefix = '%m [%p] %q%u@%d '
|
||||
log_lock_waits = on
|
||||
log_temp_files = 0
|
||||
log_timezone = 'Europe/Moscow'
|
||||
```
|
||||
Вся включенная статистика стала писаться в общий лог-файл `/var/log/postgresql/postgresql-17-main.log`. С ним и будем работать. Устанавливаем pgBadger:
|
||||
```
|
||||
# wget https://github.com/darold/pgbadger/archive/refs/tags/v13.1.tar.gz
|
||||
# tar xzvf v13.1.tar.gz
|
||||
# cd pgbadger-*
|
||||
# apt install make
|
||||
# make && make install
|
||||
```
|
||||
Анализируем лог файл:
|
||||
```
|
||||
# pgbadger /var/log/postgresql/postgresql-17-main.log
|
||||
```
|
||||
Тут же в директории, где его запускали, увидите файл out.html. Забирайте его к себе и смотрите. Там будет информация с общей статистикой сервера, информация по запросам и их типам, времени исполнения, подключениям, по пользователям, базам и хостам откуда подключались и много всего остального.
|
||||
|
||||
PgBadger удобен тем, что по сути это одиночный скрипт на Perl. Можно включить логирование в конфигурации, применить её через `SELECT pg_reload_conf();` без перезапуска сервера СУБД. Пособирать некоторое время данные, забрать лог и анализировать его. Логирование отключить и снова перечитать конфиг. В итоге всё будет сделано без перезапуска сервера.
|
||||
|
||||
🔹Второй инструмент - PgHero (https://github.com/ankane/pghero), он показывает примерно то же самое, только в режиме реального времени и работает в виде веб сервиса. Для него уже надо создавать пользователя, настраивать доступ, отдельную базу. Немного другой подход. Надо будет дёргать сервер с СУБД.
|
||||
|
||||
Надо перейти в консоль и создать необходимые сущности:
|
||||
```sql
|
||||
# su postgres
|
||||
# psql
|
||||
> CREATE USER pghero WITH PASSWORD 'pgheropass';
|
||||
> CREATE DATABASE pgherodb OWNER pghero;
|
||||
> \q
|
||||
```
|
||||
Разрешаем этому пользователю подключаться. Добавляем в `pg_hba.conf` строку:
|
||||
```
|
||||
host pgherodb pghero 172.17.0.0/24 md5
|
||||
```
|
||||
`172.17.0.0/24` - подсеть, из которой будет подключаться PgHero. В данном случае это Docker контейнер, запущенный на этом же хосте. PostgreSQL должен принимать запросы с локального IP адреса, к которому будет доступ из Docker сети. Можно добавить в конфиг `postgresql.conf` параметр:
|
||||
```
|
||||
listen_addresses = 'localhost,172.17.0.1'
|
||||
```
|
||||
Перезапускаем PotgreSQL:
|
||||
```
|
||||
# systemctl restart postgresql
|
||||
```
|
||||
Запускаем PgHero в Docker контейнере:
|
||||
```
|
||||
# docker run -ti -e DATABASE_URL=postgres://pghero:pgheropass@172.17.0.1:5432/pgherodb -p 8080:8080 ankane/pghero
|
||||
```
|
||||
Идём на порт севера 8080, где запущен контейнер и смотрим информацию о PostgreSQL. Если у вас не настроено расширение **pg_stat_statements**, которое использует PgHero для сбора статистики, то установите его. Для этого в конфигурацию `postgresql.conf` добавьте параметры:
|
||||
```
|
||||
shared_preload_libraries = 'pg_stat_statements'
|
||||
pg_stat_statements.track = all
|
||||
pg_stat_statements.max = 10000
|
||||
track_activity_query_size = 2048
|
||||
```
|
||||
Перезапустите Postgresql и выполните в консоли СУБД:
|
||||
```sql
|
||||
> CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
|
||||
> GRANT pg_read_all_stats TO pghero;
|
||||
```
|
||||
Теперь можно возвращаться в веб интерфейс и смотреть информацию. По умолчанию, пользователь pghero не будет видеть запросы других пользователей, если ему не дать права superuser. Это можно исправить, выдав ему набор прав и ролей из этой инструкции (https://github.com/ankane/pghero/blob/master/guides/Permissions.md).
|
||||
|
||||

|
||||
.jpg)
|
||||
BIN
DevOps/attachments/photo_2025-05-16_16-20-53.jpg
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
DevOps/attachments/photo_2025-05-16_16-20-54.jpg
Normal file
|
After Width: | Height: | Size: 81 KiB |
BIN
DevOps/attachments/photo_2025-05-16_16-20-54_(2).jpg
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
DevOps/attachments/photo_2025-05-21_20-48-32.jpg
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
DevOps/attachments/photo_2025-05-21_20-48-32_(2).jpg
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
DevOps/img/vault-gitlab.png
Normal file
|
After Width: | Height: | Size: 291 KiB |
BIN
DevOps/img/vault-gitlab2.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
131
Funny/Jaecoo/Jcartools.html
Normal file
@@ -0,0 +1,131 @@
|
||||
<!--
|
||||
title: Jcartools
|
||||
description:
|
||||
published: true
|
||||
date: 2024-10-24T18:34:35.072Z
|
||||
tags: jaecoo
|
||||
editor: ckeditor
|
||||
dateCreated: 2024-10-24T06:25:44.217Z
|
||||
-->
|
||||
|
||||
<h1>APK</h1>
|
||||
<p>Предоставление прав apk установленным из rustore:</p>
|
||||
<blockquote>
|
||||
<p>запись<br>adb shell pm grant название пакета android.permission.WRITE_EXTERNAL_STORAGE<br><br>чтение<br>все тоже самое, но в конце после последней точки READ_EXTERNAL_STORAGE<br><br>доступ к хранилищу(полный)<br>после последней точки MANAGE_EXTERNAL_STORAGE</p>
|
||||
</blockquote>
|
||||
<p>а как узнать название пакета?</p>
|
||||
<blockquote>
|
||||
<p>Через adb прибуду какую нибудь типа adb app control (как то так вроде бы) </p>
|
||||
<p>Или же узнать уже с машины (установленные программы) через командную строку adb shell pm list packages -3</p>
|
||||
</blockquote>
|
||||
<h1><strong>Iphone</strong></h1>
|
||||
<p>Нестабильно работает wifi на iphone</p>
|
||||
<blockquote>
|
||||
<p>На айфоне максимальную совместимость и пароль не замудреный поставить</p>
|
||||
</blockquote>
|
||||
<p>Утилита для прошивки (установка приложений) на Jaecoo j7. Новая версия. <a href="https://www.youtube.com/watch?v=mVRuAvgRIEI">https://www.youtube.com/watch?v=mVRuAvgRIEI</a></p>
|
||||
<p> </p>
|
||||
<p>Подскажите, что надо сделать что бы во время работы ЯН на ГУ или приборке, показывало стрелки на проекции?</p>
|
||||
<blockquote>
|
||||
<p>Проверить Включено ли в настройках проекционного дисплея отображение ассистентов вождения.</p>
|
||||
</blockquote>
|
||||
<p>Подскажите. Как сделать так что бы вместо ЯК включался ЯН?</p>
|
||||
<blockquote>
|
||||
<p>переписать имя пакета на ru.yandex.yandexnavi</p>
|
||||
</blockquote>
|
||||
<p>woha с версии 7.3 и продолжилось в 7.4 перестали выводиться на проекцию данные с антирадар Стрелка при проложенном маршруте як, стрелки як выводятся.</p>
|
||||
<blockquote>
|
||||
<p>Это сделано намерено, так как по практике Як, камер много и перекрывались маневры в самый неподходящий момент. Думаю сделать настройкой, но будет или то или то скорее всего. Или вариант с перекрытием маневров то же рассматривать?</p>
|
||||
</blockquote>
|
||||
<p>Прошу прощения, можно поподробнее пояснить. В настоящий момент, чтобы вместо стрелок навигации на проекцию выводились уведомления от приложения стрелка то необходимо отключить выведение навигации в HUD?</p>
|
||||
<blockquote>
|
||||
<p>Когда не выводятся стрелки от навигации, отображаются камеры со стрелки</p>
|
||||
</blockquote>
|
||||
<p>Подскажите зачем нужна стрелка дублирующая камеры из ЯН?</p>
|
||||
<blockquote>
|
||||
<p>В як нужно для этого маршрут строить, а антирадар работает постоянно</p>
|
||||
</blockquote>
|
||||
<h1>Youtube и аналоги</h1>
|
||||
<p>Для тех, кто спрашивал про Revanced Youtube</p>
|
||||
<p>1. Старые, если были, снести</p>
|
||||
<p>2. Эти два новых apk установить</p>
|
||||
<p>3. выполнить в adb shell </p>
|
||||
<pre><code class="language-plaintext">#разрешить microg поверх всех окон
|
||||
appops set app.revanced.android.gms SYSTEM_ALERT_WINDOW allow
|
||||
|
||||
#добавить в белый список (отключить оптимизацию батареи) для microg
|
||||
dumpsys deviceidle whitelist +app.revanced.android.gms </code></pre>
|
||||
<p>4. Зайти в настройки Microg и в разделе проверок протыкать разрешения у которых не стоит галочка. </p>
|
||||
<p>5. Зайти в настройках Microg в список аккаунтов, и перед добавлением своего аккаунта - поставить ползунки как на фото ниже. </p>
|
||||
<p>6. Добавить свой гугл аккаунт. </p>
|
||||
<p>7. Радоваться. А чтобы не пропадала История просмотров - в настройках Revanced в настройках General Layout включить Enable Tablet Layout.</p>
|
||||
<p> </p>
|
||||
<h1>Wifi</h1>
|
||||
<p>Всем привет! Перестал вай фай подключаться</p>
|
||||
<blockquote>
|
||||
<p>в инженерке удалите, перезагрузите ГУ и снова в инженерке подключите</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>Для стабильного подключения ГУ к WiFi вашего мобильного устройства или модема необходимо отключить автоматическое включение Android Auto. Удалить все настройки подключения AA в самом ГУ и в приложении Android Auto вашего мобильного устройства. Зайдите в приложения на телефоне, найдите там приложение android auto и отключите.</p>
|
||||
<p>AA работает по принципу точки доступа. Ваше ГУ становится точкой доступа и в этот же момент отключает поиск и подключение к WiFi-сети находящейся поблизости.</p>
|
||||
</blockquote>
|
||||
<h3> </h3>
|
||||
<h1><strong>Стрелка</strong></h1>
|
||||
<p>Подскажите пожалуйста, в стрелке как настроить расстояние до камеры, в плане оповещения ?) </p>
|
||||
<blockquote>
|
||||
<p>В объектах выбираете нужную камеру, там же есть 3 раздела трасса, город, мегаполис. И 3 уровня уведомления(дистанции):</p>
|
||||
<p>1 уровень это самый дальний - от 1км до 2км.</p>
|
||||
<p>2 уровень от 300м до 1км.</p>
|
||||
<p>3 уровень от 50м до 300м.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>Вот и настраиваете как вам удобно, себе всё настроил с 2мя уведомлениями</p>
|
||||
<p>1 уведомление естественно отключено.</p>
|
||||
<p>2 уведомление за 700м.</p>
|
||||
<p>3 уведомление за 300м.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>Ну Вам нужно знать только о камерах или о всех событиях по пути.? Стрелка все может показывать. От лежачих , переходах , перекрёстках..... в незнакомом городе очень удобно и безопасно .</p>
|
||||
</blockquote>
|
||||
<h3> </h3>
|
||||
<h1><strong>Звук</strong></h1>
|
||||
<p>Звук почему то только английский (2 голоса), но звук есть. </p>
|
||||
<blockquote>
|
||||
<p>У меня вначале был английский, переключил в настройках на русский. Появилась Алиса вместо джона. Но Алиса тоже болтала по английски. Еще в настройках нашел язык "как в системе", переключил его на русский и все пошло норм</p>
|
||||
</blockquote>
|
||||
<p> В последней версии говорили же, что обязательно ставить эту настройку - фиксированные подсказки</p>
|
||||
<blockquote>
|
||||
<p>А если в картах поставите «закрепить указатель манёвра» будет ещё лучше</p>
|
||||
</blockquote>
|
||||
<p> </p>
|
||||
<h1>Яндекс карта</h1>
|
||||
<blockquote>
|
||||
<p>Приборку нужно перевести в режим отображения навигации. Нажать на левом джойстике руля по центру о и выбрать влево-вправо значок стрелки. Только после этого кидать на приборку.</p>
|
||||
<p>На руле "о" один раз, стрелка влево, чтобы режим карт появился, и зажать "о". Или в приложении "открыть на приборке".</p>
|
||||
</blockquote>
|
||||
<figure class="image image_resized" style="width:21.6%;"><img src="/jaecoo/{30a2bdf4-b137-4cf1-bf8e-94721aa1c8c0}.png"></figure>
|
||||
<figure class="image image_resized" style="width:21.51%;"><img src="/jaecoo/{26c4849a-5094-4662-ac6b-205e2d230e66}.png"></figure>
|
||||
<p>у всех оповещение при движении по маршруту на английском произносит или это только у меня. как это исправить. в настройках навигатора русский стоит.</p>
|
||||
<blockquote>
|
||||
<p>язык аннотаций на русский поменяйте. И даже если стоит язык "как в системе" и вы уверены, что в системе у вас русский, то все равно надо ставить русский.</p>
|
||||
</blockquote>
|
||||
<p>Приходится яндекс навигатор каждый раз открывать</p>
|
||||
<blockquote>
|
||||
<p>Включите настройку в як "переходить в навигатор при движении"</p>
|
||||
</blockquote>
|
||||
<p> </p>
|
||||
<h1>Обновление</h1>
|
||||
<p>А есть ссылка на пост с обновлением по воздуху тут?)</p>
|
||||
<blockquote>
|
||||
<p>Все просто. Три точки сверху справа "обновить приложение" и "обновить карты". При появлении новой версии приложения при его открытии будет уведомление.</p>
|
||||
</blockquote>
|
||||
<p>На проекцию не выводится ограничение скорости</p>
|
||||
<blockquote>
|
||||
<p>Ну когда навигатор работает над стрелками на проекции в бегущей строке вместе с названием улицы есть ещё что-то типа Lim 40 km/h. В настройках навистарт нужно вкл</p>
|
||||
</blockquote>
|
||||
<h1>Шторка-люк</h1>
|
||||
<p>Ну что бы шторка срабатывала нормально а не произвольно и очень редко :)</p>
|
||||
<blockquote>
|
||||
<p>Надо поставить галку для всех водителей</p>
|
||||
<p>В списке выбрать водитель один и поставить галку шторки например</p>
|
||||
</blockquote>
|
||||
20
Hypervisors/Proxmox/Cluster/DestroyCluster.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
title: Удаление кластера Proxmox
|
||||
description:
|
||||
published: true
|
||||
date: 2025-05-21T11:31:51.721Z
|
||||
tags: proxmox, cluster
|
||||
editor: ckeditor
|
||||
dateCreated: 2025-05-21T11:31:51.721Z
|
||||
-->
|
||||
|
||||
<p>systemctl stop pve-cluster.service</p>
|
||||
<p>systemctl stop corosync.service</p>
|
||||
<p>pmxcfs -l</p>
|
||||
<p>rm -rf /etc/pve/corosync.conf</p>
|
||||
<p>rm -rf /etc/corosync/</p>
|
||||
<p>killall pmxcfs</p>
|
||||
<p>systemctl restart pve-cluster.service</p>
|
||||
<p>cd /etc/pve/nodes</p>
|
||||
<p>ls</p>
|
||||
<p>rm -rf /etc/pve/nodes/pve-01/</p>
|
||||
68
Hypervisors/Proxmox/Cluster/DestroyCluster.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: Как удалить ноду из кластера Proxmox?
|
||||
description:
|
||||
published: true
|
||||
date: 2025-05-22T09:28:25.522Z
|
||||
tags: proxmox, cluster
|
||||
editor: markdown
|
||||
dateCreated: 2025-05-21T11:31:51.721Z
|
||||
---
|
||||
|
||||
|
||||
Перед удалением ноды важно убедиться в том, что все виртуальные машины и данные безопасно мигрированы или созданы резервные копии, чтобы избежать потери данных и поддерживать целостность кластера.
|
||||
1. Остановите службу "pve-cluster" на изолируемой ноде
|
||||
```
|
||||
systemctl stop pve-cluster.service
|
||||
systemctl stop corosync.service
|
||||
```
|
||||
2. Запустите команду для перевода файловой системы кластера на изолируемой ноде в локальный режим
|
||||
```
|
||||
pmxcfs -l
|
||||
```
|
||||
3. Запустите команду для удаления файлов конфигурации Corosync:
|
||||
```
|
||||
rm -rf /etc/pve/corosync.conf
|
||||
rm -rf /etc/corosync/*
|
||||
```
|
||||
4. Запустите команду для перезапуска службы файловой системы кластера:
|
||||
```
|
||||
killall pmxcfs
|
||||
systemctl start pve-cluster.service
|
||||
```
|
||||
5. Удалите файлы неисправной ноды:
|
||||
```
|
||||
cd /etc/pve/nodes
|
||||
ls
|
||||
rm -rf /etc/pve/nodes/pve2 # Path corresponding to the faulty node
|
||||
```
|
||||
6. Очистите остаточную информацию о кластере:
|
||||
```
|
||||
pvecm delnode NodeName
|
||||
```
|
||||
Здесь приведена информация по устранению распространенных проблем, с которыми вы можете столкнуться.
|
||||
|
||||
Нода не отвечает: Если нода, которую вы хотите удалить, не отвечает из-за проблем с сетью или по другим причинам, вы можете использовать опцию Force для принудительного удаления ее из кластера:
|
||||
```
|
||||
pvecm delnode <NODE_NAME> --force
|
||||
```
|
||||
Застревание процесса удаления: В случае возникновения проблем с выполнением команды или застревания процесса во время удаления, вы можете диагностировать проблему, просмотрев системный журнал:
|
||||
```
|
||||
journalctl -xe
|
||||
```
|
||||
После устранения потенциальной проблемы попробуйте удалить ноду еще раз.
|
||||
|
||||
```
|
||||
systemctl stop pve-cluster.service
|
||||
systemctl stop corosync.service
|
||||
pmxcfs -l
|
||||
rm -rf /etc/pve/corosync.conf
|
||||
rm -rf /etc/corosync/
|
||||
killall pmxcfs
|
||||
systemctl restart pve-cluster.service
|
||||
cd /etc/pve/nodes
|
||||
ls
|
||||
rm -rf /etc/pve/nodes/pve-01/
|
||||
pvecm delnode pve-01
|
||||
pvecm delnode pve-01 --force
|
||||
systemctl restart corosync.service
|
||||
```
|
||||
14
Hypervisors/Proxmox/Disable-ProxMox-Subscription-Notice.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: Disable ProxMox Subscription Notice
|
||||
description:
|
||||
published: true
|
||||
date: 2025-04-11T07:57:37.999Z
|
||||
tags: proxmox
|
||||
editor: markdown
|
||||
dateCreated: 2025-04-11T07:53:49.776Z
|
||||
---
|
||||
|
||||
Proxmox 8.3
|
||||
```bash
|
||||
sed -Ezi.bak "s/(function\(orig_cmd\) \{)/\1\n\torig_cmd\(\);\n\treturn;/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service
|
||||
```
|
||||
123
Monitoring/Gatus.md
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
title: Gatus - просто мониторинг
|
||||
description:
|
||||
published: true
|
||||
date: 2024-08-08T14:54:22.568Z
|
||||
tags: мониторинг, gatus
|
||||
editor: markdown
|
||||
dateCreated: 2024-08-08T14:47:57.868Z
|
||||
---
|
||||
|
||||
У меня было очень много заметок про различные мониторинги. Кажется, что я уже про всё более-менее полезное что-то да писал. Оказалось, что нет. Расскажу про очередной небольшой и удобный мониторинг, который позволяет очень просто и быстро создать дашборд с зелёными и красными кнопками. Если зелёные, то всё ОК, если красные, то НЕ ОК.
|
||||
|
||||
Речь пойдёт про Gatus (https://github.com/TwiN/gatus). С его помощью очень удобно создавать Status Page. Сразу покажу, как это будет выглядеть:
|
||||
|
||||
⇨ [https://status.twin.sh](https://status.twin.sh)
|
||||
|
||||
И сразу же простой пример, как это настраивается. Там всё максимально просто и быстро. Мы будем проверять следующие условия:
|
||||
|
||||
◽️Подключение к сайту [zabbix.com](https://zabbix.com) проходит успешно, а его IP равен 188.114.99.224. Так как этот домен резолвится в разные IP, можно будет увидеть, как срабатывает проверка.
|
||||
|
||||
◽️Сайт [github.com](https://github.com) отдаёт код 200 при подключении и содержит заголовок страницы GitHub: Let’s build from here · GitHub.
|
||||
|
||||
◽️Сайт ya.ru отдаёт код 200 и имеет отклик менее 10 мс. На практике он будет больше, посмотрим, как срабатывает триггер. По этой проверке будет уведомление в Telegram.
|
||||
|
||||
◽️Домен [vk.com](https://vk.com) имеет сертификат со сроком истечения не менее 48 часов и делегирование домена не менее 720 часов.
|
||||
|
||||
Специально подобрал разнообразные примеры, чтобы вы оценили возможности мониторинга. Я просто открыл документацию и сходу по ней всё сделал. Всё очень просто и понятно, особо разбираться не пришлось. Создаём конфигурационный файл для этих проверок:
|
||||
|
||||
```bash
|
||||
mkdir gatus && cd gatus
|
||||
touch config.yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
alerting:
|
||||
telegram:
|
||||
token: "1393668911:AAHtEAKqxUH7ZpyX28R-wxKfvH1WR6-vdNw"
|
||||
id: "210806260"
|
||||
|
||||
endpoints:
|
||||
- name: Zabbix Connection
|
||||
url: "https://zabbix.com"
|
||||
interval: 30s
|
||||
conditions:
|
||||
- "[CONNECTED] == true"
|
||||
- "[IP] == 188.114.99.224"
|
||||
|
||||
- name: Github Title
|
||||
url: "https://github.com"
|
||||
interval: 30s
|
||||
conditions:
|
||||
- "[STATUS] == 200"
|
||||
- "[BODY] == pat(*<title>GitHub: Let’s build from here · GitHub</title>*)"
|
||||
|
||||
- name: Yandex response
|
||||
url: "https://ya.ru"
|
||||
interval: 30s
|
||||
conditions:
|
||||
- "[STATUS] == 200"
|
||||
- "[RESPONSE_TIME] < 10"
|
||||
alerts:
|
||||
- type: telegram
|
||||
send-on-resolved: true
|
||||
|
||||
- name: VK cert & domain
|
||||
url: "https://vk.com"
|
||||
interval: 5m
|
||||
conditions:
|
||||
- "[CERTIFICATE_EXPIRATION] > 48h"
|
||||
- "[DOMAIN_EXPIRATION] > 720h"
|
||||
```
|
||||
|
||||
Запускаем Docker контейнер и цепляем к нему этот файл:
|
||||
|
||||
```bash
|
||||
docker run -p 8080:8080 -d \
|
||||
--mount type=bind,source="$(pwd)"/config.yaml,target=/config/config.yaml \
|
||||
--name gatus twinproduction/gatus
|
||||
```
|
||||
|
||||
Идём по IP адресу сервера на порт 8080 и смотрим на свой мониторинг. Данные могут храниться в оперативной памяти, sqlite или postgresql базе. Если выберите последнее, то вот готовый [docker-compose](https://github.com/TwiN/gatus/blob/master/.examples/docker-compose-postgres-storage/docker-compose.yml) для этого. По умолчанию данные хранятся в оперативной памяти и после перезапуска контейнера пропадают.
|
||||
|
||||
```yaml
|
||||
version: "3.9"
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
volumes:
|
||||
- ./data/db:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
- POSTGRES_DB=gatus
|
||||
- POSTGRES_USER=username
|
||||
- POSTGRES_PASSWORD=password
|
||||
networks:
|
||||
- web
|
||||
|
||||
gatus:
|
||||
image: twinproduction/gatus:latest
|
||||
restart: always
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- POSTGRES_USER=username
|
||||
- POSTGRES_PASSWORD=password
|
||||
- POSTGRES_DB=gatus
|
||||
volumes:
|
||||
- ./config:/config
|
||||
networks:
|
||||
- web
|
||||
depends_on:
|
||||
- postgres
|
||||
|
||||
networks:
|
||||
web:
|
||||
```
|
||||
|
||||
Штука простая и удобная. Меня не раз просили посоветовать что-то для простого дашборда с зелёными кнопками, когда всё нормально и красными, когда нет. Вот это идеальный вариант под такую задачу.
|
||||
|
||||
Также с помощью этого мониторинга удобно сделать дашборд для мониторинга мониторингов, чтобы понимать, живы они или нет.
|
||||
|
||||

|
||||
80
Monitoring/VictoriaLogs-setup.md
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: VictoriaLogs - установка и настройка
|
||||
description:
|
||||
published: true
|
||||
date: 2025-04-28T07:27:29.722Z
|
||||
tags: victorialogs
|
||||
editor: markdown
|
||||
dateCreated: 2025-04-28T07:25:56.957Z
|
||||
---
|
||||
|
||||
Пару лет назад у VictoriaMetrics вышел продукт, который является частью именного стека, – VictoriaLogs. Руки не доходили раньше на него посмотреть и вот дошли. Сразу скажу, что всё очень понравилось за простоту, функциональность и удобство. Покажу сразу с примерами.
|
||||
|
||||
Отдельно перечислю особенности VictoriaLogs:
|
||||
|
||||
▪️По своей сути это одиночный бинарник, который можно сконфигурировать ключами запуска, не нужен даже конфигурационный файл.
|
||||
▪️В бинарнике есть всё, что надо для сбора и просмотра логов: веб интерфейс, метрики для мониторинга за системой, все типы приёмников логов.
|
||||
▪️Для бэкапа достаточно скопировать директорию с данными, например, с помощью rsync. То есть вообще никаких проблем и заморочек с бэкапом.
|
||||
▪️Есть плагин для datasource в Grafana, чтобы делать оттуда запросы к логам, а также готовый дашборд для визуализации метрик хранилища.
|
||||
▪️Простая, короткая документация, где есть всё необходимое для запуска и настройки.
|
||||
|
||||
Покажу примеры сбора логов в VictoriaLogs от Journald, Syslog и Vector. Для этого подготовил небольшой docker-compose.yml с некоторыми параметрами:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
victoria-logs:
|
||||
image: victoriametrics/victoria-logs:latest
|
||||
volumes:
|
||||
- ./victoria-logs-data:/victoria-logs-data
|
||||
command:
|
||||
- --storageDataPath=/victoria-logs-data
|
||||
- --retentionPeriod=90d
|
||||
- --syslog.listenAddr.tcp=:514
|
||||
ports:
|
||||
- 9428:9428
|
||||
- 514:514
|
||||
restart: always
|
||||
```
|
||||
Запускаем проект, переходим на порт 9428, чтобы убедиться в том, что всё запустилось. По умолчанию открывается страница с некоторыми ссылками на Web UI, Метрики и ключи запуска.
|
||||
|
||||
Отправим в VictoriaLogs логи от systemd от любого сервера, локального или внешнего. Для этого понадобится служба systemd-journal-remote (https://t.me/srv_admin/3136). Ставим её:
|
||||
|
||||
`# apt install systemd-journal-remote`
|
||||
|
||||
Редактируем конфиг /etc/systemd/journal-upload.conf, добавляя один параметр:
|
||||
```
|
||||
[Upload]
|
||||
URL=http://localhost:9428/insert/journald
|
||||
```
|
||||
URL, соответственно, измените, если у вас сбор логов не с локального сервера, а удалённого. Запускаем службу и проверяем, что она успешно начала отправку логов:
|
||||
|
||||
`# systemctl start systemd-journal-upload`
|
||||
`# systemctl status systemd-journal-upload`
|
||||
|
||||
Идём в веб интерфейс VictoriaLogs - http://212.193.59.87:9428/select/vmui и смотрим там логи.
|
||||
|
||||
Переходим к Syslog. Я уже добавил параметр syslog.listenAddr.tcp=:514. Убедитесь, что указанный порт прослушивается:
|
||||
|
||||
`# ss -tulnp | grep 514`
|
||||
|
||||
Если у вас этот порт уже занят syslog сервером, то измените порт для VictoriaLogs. В общем-то настраивать больше ничего не надо. Теперь в любом софте, который умеет отправлять данные в формате syslog, укажите в качестве сервера IP вашего VictoriaLogs. Например, в том же Микротике: System ⇨ Logging ⇨ Actions ⇨ Add Type Remote.
|
||||
|
||||
Для сбора логов от всех популярных агентов, типа Filebeat, Fluentd, Vector (https://t.me/srv_admin/2388) и т.д. тоже ничего специально настраивать не надо. Делаете всё точно так же, как для отправки логов в Elasticsearch, только в качестве endpoint указываете URL от вашего сервера VictoriaLogs. Вот пример для Vector:
|
||||
|
||||
```yaml
|
||||
sinks:
|
||||
vlogs:
|
||||
inputs:
|
||||
- nginx_access_logs
|
||||
type: elasticsearch
|
||||
endpoints:
|
||||
- http://212.193.59.87:9428/insert/elasticsearch/
|
||||
api_version: v8
|
||||
compression: gzip
|
||||
```
|
||||
Решение очень понравилось своей простотой, универсальностью и скоростью настройки. Буквально за час со всем разобрался и настроил. Никаких затруднений. Отдельно нужно решать вопрос доступа к приёмнику логов и веб интерфейсу. С уровня приложения никаких решений нет. Нужно либо firewall, либо proxy использовать.
|
||||
|
||||
Отдельно отмечу, что те же логи syslog и journald сразу парсятся по основным полям, типа hostname, time, cmdline и т.д. Ничего для этого настраивать не надо. Сразу в веб интерфейсе можно поиск и группировку по ним делать. Получается очень функциональное решение по простоте и скорости настройки на уровне обычного syslog сервера, но с гораздо большими возможностями.
|
||||

|
||||

|
||||

|
||||
11
NAS/Synology/Disable-check-hdd.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: Отключение проверки совместимости дисков в Synology
|
||||
description:
|
||||
published: true
|
||||
date: 2025-04-21T09:51:56.904Z
|
||||
tags: synology, check, hdd
|
||||
editor: markdown
|
||||
dateCreated: 2025-04-21T09:51:56.903Z
|
||||
---
|
||||
|
||||
https://github.com/007revad/Synology_HDD_db?tab=readme-ov-file
|
||||
19
NAS/Synology/Qemu-for-Synology.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!--
|
||||
title: Qemu agent for Synology
|
||||
description:
|
||||
published: true
|
||||
date: 2024-09-26T22:10:34.314Z
|
||||
tags:
|
||||
editor: ckeditor
|
||||
dateCreated: 2024-09-26T22:10:34.314Z
|
||||
-->
|
||||
|
||||
<p>Для того, чтобы была возможность управлять перезагрузкой и выключение в Proxmox нужно поставить дополнение</p>
|
||||
<p>Нужно добавить репозиторий: <a href="https://spk7.imnks.com">https://spk7.imnks.com</a></p>
|
||||
<figure class="image image_resized" style="width:52.45%;"><img src="/nas/qemu-1.png"></figure>
|
||||
<p><strong>Install it and don't start at first.</strong> Then you need to ssh in your Xpeno and run this command, as described:</p>
|
||||
<p>sudo sed -i 's/package/root/g' /var/packages/qemu-ga/conf/privilege</p>
|
||||
<p>After that you need to stop Xpeno VM, turn on Qemu Guest Agent in VM options at Proxmox console:</p>
|
||||
<figure class="image image_resized" style="width:52.32%;"><img src="/nas/qemu-2.png"></figure>
|
||||
<p>В Proxmox нужно включить агента.</p>
|
||||
<figure class="image image_resized" style="width:52.59%;"><img src="/nas/qemu-3.png"></figure>
|
||||
@@ -2,14 +2,19 @@
|
||||
title: Synology-support-HEVC
|
||||
description:
|
||||
published: true
|
||||
date: 2024-07-09T09:49:40.393Z
|
||||
date: 2024-09-26T22:26:34.511Z
|
||||
tags: hevc, synology
|
||||
editor: ckeditor
|
||||
dateCreated: 2024-04-01T15:15:52.913Z
|
||||
-->
|
||||
|
||||
<p>В synology photo не показывает пиктограммы и ролики формата HEVC.</p>
|
||||
<p>Решение проблемы:</p>
|
||||
<p><a href="https://xpenology.com/forum/topic/65643-ame-30-patcher/page/3/">https://xpenology.com/forum/topic/65643-ame-30-patcher/page/3/</a></p>
|
||||
<p><a href="https://github.com/wirgen/synocodectool-patch?tab=readme-ov-file">https://github.com/wirgen/synocodectool-patch?tab=readme-ov-file</a></p>
|
||||
<p> </p>
|
||||
<p>В synology photo не показывает пиктограммы и ролики формата HEVC.</p>
|
||||
<p>Решение проблемы:</p>
|
||||
<p><a href="https://xpenology.com/forum/topic/65643-ame-30-patcher/page/3/">https://xpenology.com/forum/topic/65643-ame-30-patcher/page/3/</a></p>
|
||||
<p><a href="https://github.com/wirgen/synocodectool-patch?tab=readme-ov-file">https://github.com/wirgen/synocodectool-patch?tab=readme-ov-file</a></p>
|
||||
<p><a href="https://bafista.ru/xpenology-ustanovka-ame-3-1-patch-dlya-dsm-7-2/">https://bafista.ru/xpenology-ustanovka-ame-3-1-patch-dlya-dsm-7-2/</a></p>
|
||||
<pre><code class="language-plaintext">#DSM7.1 AMУ 3.0.1-2004
|
||||
curl http://code.imnks.com/ame3patch/ame71-2004.sh | bash
|
||||
#DSM7.2 AME 3.1.0-3005
|
||||
curl http://code.imnks.com/ame3patch/ame72-3005.sh | bash
|
||||
wget http://code.imnks.com/ame3patch/ame72-3005.sh && sh ame72-3005.sh</code></pre>
|
||||
48
NAS/Synology/brtfs-or-ext-for-synology.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: Какую файловую систему выбрать brtfs или ext4 для synology ?
|
||||
description:
|
||||
published: true
|
||||
date: 2025-04-05T10:07:48.849Z
|
||||
tags: brtfs, ext4
|
||||
editor: markdown
|
||||
dateCreated: 2025-04-05T10:07:48.849Z
|
||||
---
|
||||
|
||||
Выбор между **Btrfs** и **ext4** для Synology зависит от ваших потребностей в функциональности, надёжности и производительности.
|
||||
|
||||
### **1. Btrfs (Рекомендуется для Synology)**
|
||||
**Плюсы:**
|
||||
✅ **Снимки (snapshots)** – возможность создавать мгновенные копии файлов для защиты от случайного удаления или ransomware.
|
||||
✅ **Самовосстановление данных** – проверка целостности данных и автоматическое исправление ошибок (если используется SHR-1/SHR-2 или RAID с избыточностью).
|
||||
✅ **Эффективное сжатие** – экономия места без потери производительности (особенно полезно для текстовых файлов, логов, баз данных).
|
||||
✅ **Дедупликация** (вручную или через сторонние утилиты) – экономия места при дублировании файлов.
|
||||
✅ **Поддержка копирования при записи (CoW)** – уменьшает риск повреждения данных.
|
||||
|
||||
**Минусы:**
|
||||
❌ **Требует больше ресурсов** (CPU, RAM) – на слабых моделях (например, DS220j) может работать медленнее.
|
||||
❌ **Не поддерживается на всех моделях** (старые или бюджетные Synology могут не иметь Btrfs).
|
||||
❌ **Чувствителен к внезапному отключению питания** (но Synology использует журналирование для минимизации рисков).
|
||||
|
||||
---
|
||||
|
||||
### **2. ext4 (Классический вариант)**
|
||||
**Плюсы:**
|
||||
✅ **Высокая скорость** – особенно на слабом железе.
|
||||
✅ **Стабильность** – проверенная временем файловая система.
|
||||
✅ **Меньше накладных расходов** – не требует много оперативной памяти.
|
||||
|
||||
**Минусы:**
|
||||
❌ **Нет снимков (snapshots)** – нельзя быстро откатить изменения.
|
||||
❌ **Нет самовосстановления данных** – при повреждении файлов потребуется проверка вручную (fsck).
|
||||
❌ **Нет сжатия и дедупликации** – занимает больше места.
|
||||
|
||||
---
|
||||
|
||||
### **Вывод: что выбрать?**
|
||||
- **Btrfs** – если у вас **NAS с двухдисковой (или более) конфигурацией (SHR-1/SHR-2, RAID 1/5/6)** и вы хотите **защиту от повреждения данных, снимки и сжатие**.
|
||||
- **ext4** – если у вас **однодисковый NAS** или **очень слабое железо** (например, серия **"j"**), и вам важна **максимальная скорость без дополнительных функций**.
|
||||
|
||||
#### **Рекомендация для большинства пользователей:**
|
||||
**Btrfs** – лучший выбор для Synology, если ваша модель его поддерживает. Он даёт больше возможностей для защиты данных и экономии места.
|
||||
|
||||
Если сомневаетесь, выбирайте **Btrfs**, но убедитесь, что у вас **достаточно оперативной памяти** (минимум **1-2 ГБ** для комфортной работы).
|
||||
70
NAS/Synology/cupsd.md
Normal file
@@ -0,0 +1,70 @@
|
||||
---
|
||||
title: Подключение принтера в Synology
|
||||
description:
|
||||
published: true
|
||||
date: 2024-10-29T09:04:59.553Z
|
||||
tags: synology, cups
|
||||
editor: markdown
|
||||
dateCreated: 2024-10-29T09:04:59.553Z
|
||||
---
|
||||
|
||||
# Подключение принтера по usb
|
||||
https://github.com/ziwork/synology-airprint
|
||||
|
||||
Когда подключил принтер по usb к synology, то не получилось распечатать удаленно, вполне возможно что малая поддержка устройств.
|
||||
Нашел на просторах интернета проект synology-airprint с помощью которого получилось завести.
|
||||

|
||||
|
||||
Так как принтер не определяется с нормальным именем, например как /dev/ttyUSB0
|
||||
Поэтому пришлось делать символьную ссылку через планировщик
|
||||
`ln -s /dev/usb/04e8:3413:8J66BAAY331838K /dev/ttyUSB0`
|
||||
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
Создаем docker-compose с таким содержимым
|
||||
```
|
||||
nano docker-compose.yml
|
||||
|
||||
```
|
||||
```yaml
|
||||
version: '3.5'
|
||||
|
||||
services:
|
||||
airprint:
|
||||
container_name: airprint
|
||||
image: znetwork/synology-airprint:latest
|
||||
restart: always
|
||||
# network_mode: "bridge"
|
||||
network_mode: "host"
|
||||
devices:
|
||||
# - "/dev/bus/usb/001/001:/dev/ttyUSB0"
|
||||
- "/dev/ttyUSB0:/dev/ttyUSB0"
|
||||
# ports:
|
||||
# - "9631:631"
|
||||
environment:
|
||||
CUPSADMIN: admin
|
||||
CUPSPASSWORD: admin
|
||||
```
|
||||
Нужно по странице проекта остановить и выключить службы
|
||||
```
|
||||
sudo synosystemctl stop cupsd
|
||||
sudo synosystemctl stop cups-lpd
|
||||
sudo synosystemctl stop cups-service-handler
|
||||
sudo synosystemctl disable cupsd
|
||||
sudo synosystemctl disable cups-lpd
|
||||
sudo synosystemctl disable cups-service-handler
|
||||
```
|
||||
|
||||
И поднимаем контейнер (нужно перед этим через центр пакетов поставить Container Manager)
|
||||
```
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Заходим на страницу и там добавляем принтер
|
||||
http://192.168.88.250:631/
|
||||
|
||||
И потом добавляем принтер на компьютере:
|
||||
через ipip http://192.168.88.250:631/printers/samsung
|
||||
@@ -2,7 +2,7 @@
|
||||
title: Установка XPEnology
|
||||
description:
|
||||
published: true
|
||||
date: 2024-07-09T09:49:44.068Z
|
||||
date: 2024-09-24T14:13:07.116Z
|
||||
tags: xpenology
|
||||
editor: ckeditor
|
||||
dateCreated: 2023-11-15T16:50:54.856Z
|
||||
@@ -63,10 +63,11 @@ sudo ./rploader.sh identifyusb now
|
||||
<pre><code class="language-plaintext">sudo ./rploader.sh build bromolow-7.0.1-42218</code></pre>
|
||||
<p>После завершения сборки загрузите файл *.pat через WinSCP по указанному пути и скачивайте на вашу локальную машину.</p>
|
||||
<pre><code class="language-plaintext">Found /home/tc/redpill-load/cache/ds3615xs_42218.pat, copying to cache directory : /mnt/sdc3/auxfiles</code></pre>
|
||||
<p> </p>
|
||||
<p>Можно скачать <a href="https://archive.synology.com/download/Os/DSM">тут</a></p>
|
||||
<figure class="image"><img src="/attachments/xpenology/10.png"></figure>
|
||||
<p> </p>
|
||||
<p>Перезагрузите свой компьютер (оставьте USB включенным), и запустится новый загрузчик, и вы сможете установить dsm или снова запустить tinycore.</p>
|
||||
<p><mark class="pen-red">Нашел инфу, что нужно </mark><a href="https://xpenology.com/forum/topic/57525-%D0%BF%D0%B5%D1%80%D0%B5%D1%85%D0%BE%D0%B4-%D0%BD%D0%B0-7xx-%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E-tinycore-redpill/"><mark class="pen-red">отключать </mark></a><mark class="pen-red">интернет синолоджи перед тем как устанавливать dsm.</mark></p>
|
||||
<p>Начните с <a href="http://find.synology.com">find.synology.com</a> в веб-браузере (или в программе <strong>Synology Assistant</strong>) и найдите свое хранилище dsm 7. Загрузите файл pat, который вы скачали, и будьте довольны своей версией DSM 7.</p>
|
||||
<figure class="image"><img src="/attachments/xpenology/11.png"></figure>
|
||||
<p> </p>
|
||||
142
NAS/Synology/scrutiny.html
Normal file
@@ -0,0 +1,142 @@
|
||||
<!--
|
||||
title: Просмотр атрибутов SMART в DSM 7.2.1 и новее
|
||||
description: scrutiny
|
||||
published: true
|
||||
date: 2025-03-12T10:21:29.816Z
|
||||
tags: scrutiny, smart
|
||||
editor: ckeditor
|
||||
dateCreated: 2025-03-12T10:21:29.816Z
|
||||
-->
|
||||
|
||||
<p>Источник: https://bafista.ru/prosmotr-atributov-smart-v-dsm-7-2-1-i-novee/</p>
|
||||
<h2><strong>Введение</strong></h2>
|
||||
<p>В самой лучшей на данный момент ОС DSM для NAS от компании Synology было все необходимое для работы с дисками. Но 26.09.2023 вышло <a href="https://www.synology.com/ru-ru/releaseNote/DSM"><u>обновление DSM 7.2.1</u></a> и вместе с ним обновление для <a href="https://www.synology.com/ru-ru/releaseNote/StorageManager"><u>диспетчера хранения</u></a> 1.0.0-0017. В этом обновлении произошло невероятное: <i><strong>Атрибуты S.M.A.R.T. больше не записываются и не отображаются.</strong></i></p>
|
||||
<p>При проверке опасения подтвердились. Кнопка просмотров атрибутов SMART пропала со своего места и теперь ее нигде нет. Очень печальная ситуация.</p>
|
||||
<p><a href="https://github.com/AnalogJ/scrutiny"><u>Scrutiny </u></a>– это инструмент, который собирает данные SMART с жесткого диска и отображает их через веб-интерфейс. Дополнительно ведется логирование полученных данных и есть возможность настроить уведомления.</p>
|
||||
<figure class="image image_resized" style="width:47.66%;"><img src="https://bafista.ru/wp-content/uploads/2023/09/scr-20230930-iwuw.png"></figure>
|
||||
<p> </p>
|
||||
<figure class="image image_resized" style="width:47.81%;"><img src="https://bafista.ru/wp-content/uploads/2023/09/scr-20230930-jdtv.png"></figure>
|
||||
<h2><strong>Установка Scrutiny</strong></h2>
|
||||
<p>Для установки нам понадобится Container Manager. Поэтому перед началом найдите его в центре пакетов и установите. Если в центре пакетов его нет, значит ваше устройство его не поддерживает и дальше вам можно не читать данную инструкцию.</p>
|
||||
<p>Откройте File station и перейдите в папку docker. В этой папке создайте пустой каталог с именем <strong>scrutiny</strong>, а внутри еще один пустой с именем <strong>influxdb</strong> как показано на картинке ниже.</p>
|
||||
<figure class="image image_resized" style="width:46.87%;"><img src="https://bafista.ru/wp-content/uploads/2023/09/image-180-1024x594.png"></figure>
|
||||
<p>Так тут же нужно создать файл <strong>collector.yaml</strong> следующего содержимого:</p>
|
||||
<pre><code class="language-plaintext">version: 1
|
||||
host:
|
||||
id: "NAS"
|
||||
devices:
|
||||
- device: /dev/sata1
|
||||
type: 'sat'
|
||||
# - device: /dev/sata2
|
||||
# type: 'sat'
|
||||
# - device: /dev/sata3
|
||||
# type: 'sat'
|
||||
- device: /dev/nvme0n1
|
||||
type: 'nvme'
|
||||
# - device: /dev/nvme1n1
|
||||
# type: 'nvme'</code></pre>
|
||||
<p>Разберем что в этом файле и зачем.</p>
|
||||
<ul>
|
||||
<li>ИмяСервера – замените на ваше, желательно латинскими буквами</li>
|
||||
<li>sata1 sata2 sata3 – это все ваши диски. Укажите тут точное количество ваших дисков в Synology и где они установлены. Номер 1 2 и 3 совпадает с номеров диска в слотах устройства. В некоторых случаях вместо sata1 sata2 sata3 и т.д. нужно указывать sda sdb sdc и т.д.</li>
|
||||
<li>nvme0m1 и nvme1n1 – это ssd диски установленные в M2 слоты, если у вас их нет, то просто удалите их.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p><i>Так же можно добавить диски подключенные по USB, подробнее в комментарии по </i><a href="https://bafista.ru/prosmotr-atributov-smart-v-dsm-7-2-1-i-novee/#comment-2692"><i><u>ссылке</u></i></a></p>
|
||||
</blockquote>
|
||||
<p>Теперь открываем Container Manager, переходим в проекты и нажимаем создать проект. В открывшемся окне придумываем имя, задаем путь, который мы ранее создали и выбираем создать docker-compose.yml как показано на картинке ниже.</p>
|
||||
<figure class="image"><img src="https://bafista.ru/wp-content/uploads/2023/09/image-181-1024x617.png"></figure>
|
||||
<p>В тактовое поле вставляем такой текст заранее его подредактировав:</p>
|
||||
<pre><code class="language-plaintext">services:
|
||||
scrutiny:
|
||||
container_name: scrutiny
|
||||
image: ghcr.io/analogj/scrutiny:master-omnibus
|
||||
cap_add:
|
||||
- SYS_RAWIO
|
||||
- SYS_ADMIN
|
||||
ports:
|
||||
- "8095:8080" # webapp
|
||||
- "8096:8086" # influxDB admin
|
||||
volumes:
|
||||
- /run/udev:/run/udev:ro
|
||||
- ./:/opt/scrutiny/config
|
||||
- ./influxdb:/opt/scrutiny/influxdb
|
||||
- ./scrutiny.yaml:/opt/scrutiny/config/scrutiny.yaml
|
||||
devices:
|
||||
- /dev/sata1:/dev/sata1
|
||||
# - /dev/sata2:/dev/sata2
|
||||
# - /dev/sata3:/dev/sata3
|
||||
- /dev/nvme0n1:/dev/nvme0n1
|
||||
# - /dev/nvme1n1:/dev/nvme1n1
|
||||
environment:
|
||||
- COLLECTOR_CRON_SCHEDULE='*/5 * * * *'
|
||||
- SCRUTINY_WEB_INFLUXDB_TOKEN=ANYLONGSTRING
|
||||
- SCRUTINY_WEB_INFLUXDB_INIT_USERNAME=sadmin
|
||||
- SCRUTINY_WEB_INFLUXDB_INIT_PASSWORD=6lise-shorter-Direct0
|
||||
- TZ=Europe/Moscow
|
||||
restart: unless-stopped</code></pre>
|
||||
<p>Разберем что в этом файле и зачем.</p>
|
||||
<ul>
|
||||
<li>Порт 8095 – это порт для web интерфейса scrutiny. Порт 8096 для web интерфейса influxDB. Порты после двоеточия 8080 и 8086 менять нельзя.</li>
|
||||
<li>sata1 sata2 sata3 – это все ваши диски. Укажите тут точное количество ваших дисков в Synology и где они установлены. Номер 1 2 и 3 совпадает с номеров диска в слотах устройства. В некоторых случаях вместо sata1 sata2 sata3 и т.д. нужно указывать sda sdb sdc и т.д.</li>
|
||||
<li>nvme0m1 и nvme1n1 – это ssd диски установленные в M2 слоты, если у вас их нет, то просто удалите их.</li>
|
||||
<li>Токен, логин и пароль устанавливайте на свое усмотрение, но не менее 8 символов иначе не будет работать.</li>
|
||||
</ul>
|
||||
<p>По умолчанию сбор данных в scrutiny выполняется раз в сутки и этого вполне достаточно почти всегда, но это можно переопределить вставив такую переменную:</p>
|
||||
<blockquote>
|
||||
<p><i>Спешу напомнить, что если вы хотите переопределить частоту запуска коллектора, то нужно заново создавать проект с контейнером.</i></p>
|
||||
<p style="text-align:center;"><i>!!! Не делайте часто, это не есть хорошо !!!</i></p>
|
||||
</blockquote>
|
||||
<pre><code class="language-plaintext">- COLLECTOR_CRON_SCHEDULE='*/1 * * * *'</code></pre>
|
||||
<p>Где:</p>
|
||||
<ul>
|
||||
<li>‘*/1 * * * *’ – запуск коллектора каждую минуту</li>
|
||||
<li>‘*/5 * * * *’ – запуск коллектора каждые 5 минут</li>
|
||||
<li>‘*/10 * * * *’ – запуск коллектора каждые 10 минут</li>
|
||||
<li>‘0 * * * *’ – запуск коллектора каждый час</li>
|
||||
</ul>
|
||||
<p>Далее нигде ничего менять не нужно, просто на заключительном этапе жмите выполнено для создания и запуска проекта scrutiny</p>
|
||||
<figure class="image"><img src="https://bafista.ru/wp-content/uploads/2023/09/image-182-1024x554.png"></figure>
|
||||
<p>Процесс этот весьма небыстрый. Будет скачен образ контейнера docker, затем распакован и создан сам контейнер. Если все сделано правильно, то увидите Exit Code 0, что означает успешное создание проекта с контейнером. Если нет, то увидите в чем проблема, ее нужно будет устранить и начать заново.</p>
|
||||
<figure class="image"><img src="https://bafista.ru/wp-content/uploads/2023/09/image-183-1024x559.png"></figure>
|
||||
<p> </p>
|
||||
<p>Теперь в браузере открываете новую вкладку и вбиваете http://IP-NAS:8095. Естественно, что IP адрес и порт вы вставляете свои.</p>
|
||||
<blockquote>
|
||||
<p><i>При создании проекта для него создается отдельная сеть bridge, которую нужно разрешить на фаерволе Synology, если он у вас включен</i></p>
|
||||
</blockquote>
|
||||
<figure class="image"><img src="https://bafista.ru/wp-content/uploads/2023/09/image-184-1024x674.png"></figure>
|
||||
<p>Для просмотра атрибутов SMART щелкните три точки у нужного диска и нажмите Detail</p>
|
||||
<figure class="image"><img src="https://bafista.ru/wp-content/uploads/2023/09/image-185-1024x674.png"></figure>
|
||||
<p>Тут нужно отметить, что данные обновляются раз в сутки в 6:00 утра или после старта контейнера scrunity.</p>
|
||||
<p><i>За образец была взята эта </i><a href="https://drfrankenstein.co.uk/2023/05/29/scrutiny-in-container-manager-on-a-synology-nas/"><i><u>инструкция</u></i></a><i>, но сделано по моему.</i></p>
|
||||
<p>Добавочные файлы config.yml</p>
|
||||
<pre><code class="language-plaintext">bolt-path: /opt/scrutiny/influxdb/influxd.bolt
|
||||
engine-path: /opt/scrutiny/influxdb/engine
|
||||
http-bind-address: ":8086"
|
||||
reporting-disabled: true
|
||||
</code></pre>
|
||||
<p>Уведомление через Gotify scrutiny.yml</p>
|
||||
<pre><code class="language-plaintext">version: 1
|
||||
|
||||
web:
|
||||
listen:
|
||||
port: 8080
|
||||
host: 0.0.0.0
|
||||
basepath: ''
|
||||
database:
|
||||
location: /opt/scrutiny/config/scrutiny.db
|
||||
src:
|
||||
frontend:
|
||||
path: /opt/scrutiny/web
|
||||
influxdb:
|
||||
host: 0.0.0.0
|
||||
port: 8086
|
||||
retention_policy: true
|
||||
log:
|
||||
file: '' #absolute or relative paths allowed, eg. web.log
|
||||
level: INFO
|
||||
notify:
|
||||
urls:
|
||||
# - "telegram://token@telegram?channels=channel-1[,channel-2,...]"
|
||||
- "gotify://prodik.ddns.net:8880/token"
|
||||
</code></pre>
|
||||
90
NAS/Synology/syn-console-command.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Synology - reindex photo
|
||||
description:
|
||||
published: true
|
||||
date: 2025-04-05T10:09:59.015Z
|
||||
tags: ssh, synology, reindex, photo
|
||||
editor: markdown
|
||||
dateCreated: 2024-11-27T08:35:34.807Z
|
||||
---
|
||||
|
||||
# Зависла индексация
|
||||
Попытки исправить проблему с зависшей индексацией ни к чему не привели.
|
||||
Пытался с помощью консольных команд, но ругался на битую таблицу в postgresql.
|
||||
Пробовал исправить таблицу, но не получилось.
|
||||
В итоге нашел решение, которое помогло, хотя очень кординальным методом, гроханием базы данных.
|
||||
|
||||
```
|
||||
sudo rm -rf /volume1/@database/pgsql
|
||||
reboot
|
||||
```
|
||||
После этого сделать реиндексацию фоток и видео.
|
||||
Источник https://community.synology.com/enu/forum/17/post/103120
|
||||
|
||||
## Перезапуск synology photo
|
||||
```bash
|
||||
synopkgctl stop SynologyPhotos && synopkgctl start SynologyPhotos
|
||||
```
|
||||
|
||||
## Реиндексация фото и видео
|
||||
```
|
||||
synoindex -a /volume3/photo/PhotoLibrary/2024/11/
|
||||
synoindex -R all
|
||||
```
|
||||
|
||||
Help:
|
||||
```
|
||||
bash-4.4# synoindex --help
|
||||
Usage:
|
||||
synoindex [OPTIONS]
|
||||
|
||||
Index Options:
|
||||
-h, --help
|
||||
this help text
|
||||
-A dirpath
|
||||
add a dir
|
||||
-a filepath
|
||||
add a file
|
||||
-D dirpath
|
||||
delete a dir
|
||||
-d filepath
|
||||
delete a file
|
||||
-N new_dirpath old_dirpath
|
||||
rename a dir
|
||||
-n new_filepath old_filepath
|
||||
rename a file
|
||||
-R [all|media|photo|music|video|thumb|dirpath]
|
||||
all: reindex all dirpath that registered in each package
|
||||
media: reindex dirpath that registered in MediaIndex package
|
||||
photo: reindex photo dirpath
|
||||
music: reindex music dirpath
|
||||
video: reindex video dirpath
|
||||
thumb: check converted video of each video file
|
||||
dirpath: reindex this specific dirpath
|
||||
-R user:{user_name}
|
||||
reindex personal photo dirpath
|
||||
-R share:{share_name}
|
||||
reindex share dirpath
|
||||
-R [type_music|type_video|type_photo]
|
||||
reindex dirpath that registered with specific type in MediaIndex
|
||||
|
||||
Package Index Options:
|
||||
-P [MediaIndex|{package_name}] {index_option}
|
||||
index operation only apply on this package
|
||||
-p [MediaIndex|{package_name}] {index_option}
|
||||
index operation apply all packages except for this package
|
||||
|
||||
File Index Options:
|
||||
-f {index_option}
|
||||
index operation apply on file index
|
||||
-U photo
|
||||
update photo images
|
||||
```
|
||||
|
||||
```
|
||||
/var/packages/SynologyPhotos/target/usr/bin/synofoto-bin-clear-index-task -t thumbnail
|
||||
```
|
||||
|
||||
```
|
||||
/var/packages/SynologyPhotos/target/usr/bin/synofoto-bin-index-tool -t basic -i /volume3/photo/PhotoLibrary/2024/ -t basic_reindex
|
||||
```
|
||||
11
NAS/Synology/synology_app_mover.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!--
|
||||
title: Перенос приложений на другой том
|
||||
description:
|
||||
published: true
|
||||
date: 2025-04-05T12:08:46.013Z
|
||||
tags: synology, app, move
|
||||
editor: ckeditor
|
||||
dateCreated: 2025-04-05T12:08:46.013Z
|
||||
-->
|
||||
|
||||
<p>https://github.com/007revad/Synology_app_mover</p>
|
||||
BIN
jaecoo/{26c4849a-5094-4662-ac6b-205e2d230e66}.png
Normal file
|
After Width: | Height: | Size: 150 KiB |
BIN
jaecoo/{30a2bdf4-b137-4cf1-bf8e-94721aa1c8c0}.png
Normal file
|
After Width: | Height: | Size: 117 KiB |
BIN
monitoring/victorialogs-1.png
Normal file
|
After Width: | Height: | Size: 314 KiB |
BIN
monitoring/victorialogs-2.png
Normal file
|
After Width: | Height: | Size: 217 KiB |
BIN
monitoring/victorialogs-3.png
Normal file
|
After Width: | Height: | Size: 191 KiB |
BIN
nas/cups1.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
nas/cups2.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
nas/cups3.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
nas/cups4.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
nas/qemu-1.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
nas/qemu-2.png
Normal file
|
After Width: | Height: | Size: 195 KiB |
BIN
nas/qemu-3.png
Normal file
|
After Width: | Height: | Size: 146 KiB |
28
sysadmin/Linux/Base-znaniy/Disk-limit.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: Ограничение использования диска
|
||||
description:
|
||||
published: true
|
||||
date: 2024-08-09T07:39:28.081Z
|
||||
tags: limit, disk
|
||||
editor: markdown
|
||||
dateCreated: 2024-08-09T07:39:28.081Z
|
||||
---
|
||||
|
||||
Стал регулярно сталкиваться с одной проблемой. Есть сервер с бюджетными SSD дисками. Они для многих задач вполне подходят, несмотря на низкую стоимость и скорость записи. Последнее как раз их узкое место. Но если у вас в основном с дисков чтение, то можно существенно экономить, используя десктопные диски.
|
||||
|
||||
У меня как раз такой случай. Несколько виртуалок под веб сервера, где в основном чтение из кэшей на дисках. По производительности никаких нареканий, кроме одного момента. Когда дампишь для бэкапов базы данных, весь гипервизор начинает прилично тормозить, а в мониторинг сыпятся уведомления о медленном ответе веб сервера и увеличении отклика дисков. Обычно это происходит ночью и особых проблем не доставляет. Но тем не менее, решил это исправить.
|
||||
|
||||
Самый простой способ в лоб - ограничить скорость пайпа, через который данные с mysqldump записываются в файл. По умолчанию всё читается и пишется параллельными потоками с одних и тех же SSD. Десктопные диски такой режим очень не любят и заметно тормозят при выполнении.
|
||||
|
||||
Я использовал утилиту pv:
|
||||
```
|
||||
# apt install pv
|
||||
# mysqldump --opt -v --single-transaction --databases db01 | pv -L 20m > /mnt/backup/db01.sql
|
||||
```
|
||||
Ограничил скорость записи в 20 MiB/s через ключ -L. Для того, чтобы посмотреть текущую скорость записи, используйте pv без ограничения:
|
||||
```
|
||||
# mysqldump --opt -v --single-transaction --databases db01 | pv > /mnt/backup/db01.sql
|
||||
............................
|
||||
1319MiB 0:00:06 [ 205MiB/s]
|
||||
```
|
||||
Вообще pv интересная утилита. Стоит написать о ней отдельно. Если знаете ещё какие-то способы решения этой задачи, поделитесь в комментариях. Если дампишь сразу по сети, то можно скорость сетевой передачи ограничивать. А вот так, чтобы локально, больше ничего в голову не приходит. Разве что жать сразу на лету с сильной компрессией, чтобы медленно было. Но это как-то муторно подбирать подходящую скорость.
|
||||
71
sysadmin/Linux/Base-znaniy/Disk-limit2.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: Ограничение использования диска, вариант 2
|
||||
description:
|
||||
published: true
|
||||
date: 2024-08-09T07:42:49.725Z
|
||||
tags: limit, disk
|
||||
editor: markdown
|
||||
dateCreated: 2024-08-09T07:42:49.725Z
|
||||
---
|
||||
|
||||
Первый вариант - [Disk-limit](/sysadmin/Linux/Base-znaniy/Disk-limit)
|
||||
|
||||
Недавно делал заметку (https://t.me/srv_admin/3817) про ограничение использования диска при создании дампов базы данных, чтобы не вызывать замедление всех остальных процессов в системе. Использовал утилиту pv (https://t.me/srv_admin/3823). Способ простой и рабочий, я его внедрил и оставил. Поставленную задачу решает.
|
||||
|
||||
Тем не менее, захотелось сделать это более изящно через использование приоритетов. Если диск не нагружен, то неплохо было бы его использовать с максимальной производительностью. А если нагружен, то отдать приоритет другим процесса. Это был бы наиболее рациональный и эффективный способ.
|
||||
|
||||
Я знаю утилиту ionice, которая в большинстве дистрибутивов есть по умолчанию. Она как раз существует для решения именно этой задачи. У неё не так много параметров, так что пользоваться ей просто. Приоритет можно передать через ключи. Для этого нужно задать режим работы:
|
||||
|
||||
◽️Idle - идентификатор 1, процесс работает с диском только тогда, когда он не занят
|
||||
◽️Best effort - идентификатор 2, стандартный режим работы с возможностью выставления приоритета от 0 до 7 (0 - максимальный)
|
||||
◽️Real time - режим работы реального времени тоже с возможностью задавать приоритет от 0 до 7
|
||||
|
||||
На практике это выглядит примерно так:
|
||||
```
|
||||
# ionice -c 3 cp tempfile ~/
|
||||
```
|
||||
Скопировали tempfile в домашний каталог в режиме idle. По идее, это то, что нужно. На практике этот приоритет не работает. Провёл разные тесты и убедился в том, что в Debian 12 ionice не работает вообще. Стал копать, почему так.
|
||||
|
||||
В Linux системах существуют разные планировщики процессов в отношении ввода-вывода. Раньше использовался Cfq, и ionice работает только с ним. В современных системах используется более эффективный планировщик Deadline. Проверить планировщик можно так:
|
||||
```
|
||||
# cat /sys/block/sda/queue/scheduler
|
||||
[none] mq-deadline
|
||||
```
|
||||
Принципиальная разница этих планировщиков в том, что cfq равномерно распределяет процессы с операциями ввода-вывода, и это нормально подходит для hdd, а deadline отдаёт приоритет чтению в ущерб записи, что в целом уменьшает отклик для ssd дисков. С ними использовать его более рационально. Можно заставить работать ionice, но тогда придётся вернуть планировщик cfq, что не хочется делать, если у вас ssd диски.
|
||||
|
||||
Для планировщика deadline не смог найти простого и наглядного решения приоритизации процессов записи на диск. Стандартным решением по ограничению скорости, по типу того, что делает pv, является использование параметров systemd:
|
||||
|
||||
- **IOReadBandwidthMax** - объём данных, который сервису разрешается прочитать с блочных устройств за одну секунду;
|
||||
- **IOWriteBandwidthMax** - объём данных, который сервису разрешается записать на блочные устройства за одну секунду.
|
||||
|
||||
Причём у него есть также параметр IODeviceWeight, что является примерно тем же самым, что и приоритет. Но работает он тоже только с cfq.
|
||||
|
||||
Для того, чтобы ограничить скорость записи на диск с помощью systemd, необходимо создать юнит для этого. Покажу на примере создания тестового файла с помощью dd с ограничением скорости записи в 20 мегабайт в секунду.
|
||||
```
|
||||
[Unit]
|
||||
Description=Create file with dd
|
||||
[Service]
|
||||
IOWriteBandwidthMax=/dev/sda 20M
|
||||
ExecStart=/usr/bin/dd if=/dev/zero of=/tempfile bs=1M count=1000 oflag=sync
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
Запускаем:
|
||||
```
|
||||
# systemctl start createfile.service
|
||||
```
|
||||
Проверяем:
|
||||
```
|
||||
# systemctl status createfile.service
|
||||
systemd[1]: Started createfile.service - Create file with dd.
|
||||
dd[1423]: 1000+0 records in
|
||||
dd[1423]: 1000+0 records out
|
||||
dd[1423]: 1048576000 bytes (1.0 GB, 1000 MiB) copied, 52.417 s, 20.0 MB/s
|
||||
systemd[1]: createfile.service: Deactivated successfully.
|
||||
```
|
||||
Это можно использовать как заготовку для реального задания. Если хочется потестировать в консоли, то запускайте так:
|
||||
```
|
||||
# systemd-run --scope -p IOWriteBandwidthMax='/dev/sda 20M' dd status=progress if=/dev/zero of=/tempfile bs=1M count=1000 oflag=sync
|
||||
```
|
||||
Простое рабочее решение без использования дополнительных утилит. Обращаю внимание, что если сработает кэширование записи, то визуально ограничение можно не увидеть. Я это наблюдал. И только с флагом sync её хорошо сразу же видно.
|
||||

|
||||
81
sysadmin/Linux/Base-znaniy/Memory-limit.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: Ограничение потребления памяти процессу
|
||||
description:
|
||||
published: true
|
||||
date: 2024-08-09T07:34:35.655Z
|
||||
tags: memory, limit
|
||||
editor: markdown
|
||||
dateCreated: 2024-08-09T07:34:35.655Z
|
||||
---
|
||||
|
||||
Если вам нужно ограничить процессу потребление памяти, то с systemd это сделать очень просто. Причём там есть гибкие варианты настройки. Вообще, все варианты ограничения ресурсов с помощью systemd описаны в [документации](https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html). Там внушительный список. Покажу на примере памяти, какие настройки за что отвечают.
|
||||
|
||||
◽️MemoryAccounting=1
|
||||
Включение подсчёта памяти (Turn on process and kernel memory accounting for this unit)
|
||||
|
||||
◽️MemoryHigh=16G
|
||||
Это основной механизм ограничения потребления памяти (This is the main mechanism to control memory usage of a unit). Указанный лимит может быть превышен, если это необходимо, но процесс при этом будет замедляться, а память у него активно забираться назад.
|
||||
|
||||
◽️MemoryMax=20G
|
||||
Жёсткий лимит по потреблению памяти. Если процесс до него дойдет, то он будет завершён OOM Killer. В общем случае этот лимит лучше не использовать, только в крайних случаях, чтобы сохранить работоспособность системы.
|
||||
|
||||
◽️MemorySwapMax=3G
|
||||
Ограничение по использованию swap.
|
||||
|
||||
◽️Restart=on-abnormal
|
||||
Параметр не имеет отношения к потреблению памяти, но добавил сюда для справки. Если хотите, чтобы процесс перезапускался автоматически после того, как его прибьют по превышению MemoryMax, то используйте этот параметр.
|
||||
|
||||
◽️OOMPolicy=stop
|
||||
Тоже косвенный параметр, который устанавливает то, как OOM Killer будет останавливать процесс. Либо это будет попытка корректно остановить процесс через stop, либо он его просто прибьёт через kill. Выбирайте в зависимости от того, что ограничиваете. Если у процесса жор памяти означает, что он завис и его надо прибить, то ставьте kill. А если он ещё живой и может быть остановлен, тогда stop.
|
||||
|
||||
Параметры эти описываются в секции юнита [Service] примерно так:
|
||||
```
|
||||
[Unit]
|
||||
Description=Python Script
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/opt/run
|
||||
ExecStart=/opt/run/scrape.py
|
||||
Restart=on-abnormal
|
||||
|
||||
MemoryAccounting=1
|
||||
MemoryHigh=16G
|
||||
MemoryMax=20G
|
||||
MemorySwapMax=3G
|
||||
OOMPolicy=stop
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Потестировать лимиты можно в консоли. Для примера возьмём python и съедим гигабайт памяти:
|
||||
```
|
||||
# python3 -c 'a="a"*1024**3; input()'
|
||||
```
|
||||
Команда будет висеть без ошибок, по По ps или free -m будет видно, что скушала 1G оперативы.
|
||||
|
||||
Теперь зажимаем её:
|
||||
```
|
||||
# systemd-run --scope -p MemoryMax=256M -p MemoryHigh=200M python3 -c 'a="a"*1024**3; input()'
|
||||
```
|
||||
Процесс работает, но потребляет разрешённые ему 200M. На практике чуть меньше. Смотрим через pmap:
|
||||
```
|
||||
# ps ax | grep python
|
||||
767 pts/0 S+ 0:00 /usr/bin/python3 -c a="a"*1024**3; input()
|
||||
|
||||
# pmap 767 -x | grep total
|
||||
total kB 1065048 173992 168284
|
||||
```
|
||||
Значения в килобайтах. Первое - виртуальная память (VSZ), сколько процесс запросил, столько получил. Занял весь гигабайт. Второе значение - RSS, что условно соответствует реальному потреблению физической памяти, и тут уже работает лимит. Реальной памяти процесс потребляет не больше лимита.
|
||||
|
||||
RSS можно ещё вот так быстро глянуть:
|
||||
```
|
||||
# ps -e -o rss,args --sort -rss
|
||||
```
|
||||
Вообще, с памятью у Linux всё непросто. Кому интересно, я как-то пытался в этом разобраться и [рассказать простым языком] (https://t.me/srv_admin/2859).
|
||||
|
||||
Systemd удобный инструмент в плане управления лимитами процессов. Легко настраивать и управлять.
|
||||
|
||||
Считаю, что эта заметка достойна того, чтобы быть сохранённой в избранном.
|
||||

|
||||
190
sysadmin/MikroTik/Youtube.md
Normal file
@@ -0,0 +1,190 @@
|
||||
---
|
||||
title: Обход блокировок Youtube для Mikrotik
|
||||
description:
|
||||
published: true
|
||||
date: 2024-08-06T17:07:15.519Z
|
||||
tags: youtube, mikrotik
|
||||
editor: markdown
|
||||
dateCreated: 2024-08-06T17:02:20.248Z
|
||||
---
|
||||
|
||||
Нужен VPN за границей
|
||||
|
||||
Нужно настроить Mangle на MikroTik для маркировки трафика и роутинг настроить
|
||||
|
||||
### Для примера
|
||||
|
||||
  
|
||||
|
||||
### Вот address-list
|
||||
|
||||
```
|
||||
/ip firewall address-list
|
||||
|
||||
|
||||
add list=Google address=34.0.48.0/24
|
||||
add list=Google address=34.1.68.0/23
|
||||
add list=Google address=34.1.70.0/24
|
||||
add list=Google address=34.1.76.0/24
|
||||
add list=Google address=34.1.80.0/24
|
||||
add list=Google address=34.1.83.0/24
|
||||
add list=Google address=34.1.84.0/22
|
||||
add list=Google address=34.1.88.0/24
|
||||
add list=Google address=34.1.90.0/23
|
||||
add list=Google address=34.1.97.0/24
|
||||
add list=Google address=34.1.98.0/24
|
||||
add list=Google address=34.1.128.0/20
|
||||
add list=Google address=34.1.192.0/20
|
||||
add list=Google address=34.3.3.0/24
|
||||
add list=Google address=34.4.4.0/24
|
||||
add list=Google address=34.143.64.0/21
|
||||
add list=Google address=34.143.88.0/21
|
||||
add list=Google address=34.144.0.0/20
|
||||
add list=Google address=34.152.64.0/18
|
||||
add list=Google address=34.156.0.0/15
|
||||
add list=Google address=34.158.4.0/22
|
||||
add list=Google address=34.158.8.0/21
|
||||
add list=Google address=34.158.16.0/20
|
||||
add list=Google address=34.158.32.0/19
|
||||
add list=Google address=34.158.64.0/18
|
||||
add list=Google address=34.158.128.0/18
|
||||
add list=Google address=34.158.192.0/19
|
||||
add list=Google address=34.158.224.0/20
|
||||
add list=Google address=34.158.240.0/21
|
||||
add list=Google address=34.158.248.0/22
|
||||
add list=Google address=34.167.0.0/16
|
||||
add list=Google address=34.177.24.0/21
|
||||
add list=Google address=34.177.32.0/19
|
||||
add list=Google address=34.177.64.0/19
|
||||
add list=Google address=34.177.96.0/20
|
||||
add list=Google address=34.177.112.0/21
|
||||
add list=Google address=34.177.120.0/22
|
||||
add list=Google address=34.179.0.0/16
|
||||
add list=Google address=34.180.0.0/14
|
||||
add list=Google address=34.184.0.0/15
|
||||
add list=Google address=34.186.0.0/17
|
||||
add list=Google address=34.187.0.0/16
|
||||
add list=Google address=35.186.192.0/18
|
||||
add list=Google address=35.187.128.0/20
|
||||
add list=Google address=35.190.0.0/17
|
||||
add list=Google address=35.190.248.0/21
|
||||
add list=Google address=35.191.0.0/16
|
||||
add list=Google address=35.206.2.0/24
|
||||
add list=Google address=35.206.4.0/24
|
||||
add list=Google address=35.206.192.0/18
|
||||
add list=Google address=35.213.0.0/17
|
||||
add list=Google address=35.213.128.0/18
|
||||
add list=Google address=35.215.64.0/18
|
||||
add list=Google address=35.215.128.0/17
|
||||
add list=Google address=35.216.0.0/17
|
||||
add list=Google address=35.217.0.0/16
|
||||
add list=Google address=35.219.0.0/17
|
||||
add list=Google address=35.219.128.0/18
|
||||
add list=Google address=35.219.193.0/24
|
||||
add list=Google address=35.219.224.0/19
|
||||
add list=Google address=35.220.0.0/17
|
||||
add list=Google address=35.242.0.0/17
|
||||
add list=Google address=35.243.16.0/20
|
||||
add list=Google address=57.140.196.0/23
|
||||
add list=Google address=57.140.211.0/24
|
||||
add list=Google address=57.140.224.0/22
|
||||
add list=Google address=57.140.228.0/24
|
||||
add list=Google address=57.140.240.0/23
|
||||
add list=Google address=57.140.242.0/24
|
||||
add list=Google address=64.233.160.0/19
|
||||
add list=Google address=66.22.228.0/23
|
||||
add list=Google address=66.102.0.0/20
|
||||
add list=Google address=66.249.64.0/19
|
||||
add list=Google address=70.32.128.0/21
|
||||
add list=Google address=70.32.136.0/22
|
||||
add list=Google address=70.32.141.0/24
|
||||
add list=Google address=70.32.142.0/23
|
||||
add list=Google address=70.32.144.0/21
|
||||
add list=Google address=70.32.158.0/24
|
||||
add list=Google address=72.14.192.0/18
|
||||
add list=Google address=74.125.0.0/18
|
||||
add list=Google address=74.125.67.0/24
|
||||
add list=Google address=74.125.68.0/22
|
||||
add list=Google address=74.125.72.0/21
|
||||
add list=Google address=74.125.80.0/20
|
||||
add list=Google address=74.125.96.0/19
|
||||
add list=Google address=74.125.128.0/17
|
||||
add list=Google address=104.154.124.0/23
|
||||
add list=Google address=104.196.72.0/21
|
||||
add list=Google address=104.196.80.0/20
|
||||
add list=Google address=108.170.196.0/23
|
||||
add list=Google address=108.170.216.0/24
|
||||
add list=Google address=108.170.220.0/23
|
||||
add list=Google address=108.170.224.0/19
|
||||
add list=Google address=108.177.0.0/17
|
||||
add list=Google address=136.22.160.0/20
|
||||
add list=Google address=136.22.176.0/21
|
||||
add list=Google address=136.22.184.0/23
|
||||
add list=Google address=136.22.186.0/24
|
||||
add list=Google address=142.250.0.0/15
|
||||
add list=Google address=146.148.0.0/23
|
||||
add list=Google address=152.65.227.0/24
|
||||
add list=Google address=152.65.229.0/24
|
||||
add list=Google address=152.65.230.0/24
|
||||
add list=Google address=152.65.237.0/24
|
||||
add list=Google address=152.65.238.0/23
|
||||
add list=Google address=152.65.242.0/23
|
||||
add list=Google address=152.65.245.0/24
|
||||
add list=Google address=152.65.246.0/23
|
||||
add list=Google address=152.65.249.0/24
|
||||
add list=Google address=152.65.250.0/24
|
||||
add list=Google address=152.65.253.0/24
|
||||
add list=Google address=152.65.254.0/23
|
||||
add list=Google address=162.120.128.0/20
|
||||
add list=Google address=162.120.144.0/24
|
||||
add list=Google address=162.120.146.0/23
|
||||
add list=Google address=162.120.148.0/22
|
||||
add list=Google address=162.120.152.0/21
|
||||
add list=Google address=162.120.160.0/19
|
||||
add list=Google address=162.120.192.0/18
|
||||
add list=Google address=172.110.32.0/21
|
||||
add list=Google address=172.217.0.0/19
|
||||
add list=Google address=172.217.32.0/20
|
||||
add list=Google address=172.217.48.0/21
|
||||
add list=Google address=172.217.64.0/18
|
||||
add list=Google address=172.217.128.0/17
|
||||
add list=Google address=172.253.0.0/20
|
||||
add list=Google address=172.253.32.0/19
|
||||
add list=Google address=172.253.64.0/18
|
||||
add list=Google address=172.253.128.0/17
|
||||
add list=Google address=173.194.0.0/16
|
||||
add list=Google address=192.178.0.0/15
|
||||
add list=Google address=193.186.4.0/24
|
||||
add list=Google address=199.36.154.0/23
|
||||
add list=Google address=199.36.156.0/24
|
||||
add list=Google address=199.192.112.0/24
|
||||
add list=Google address=199.223.238.0/23
|
||||
add list=Google address=207.223.160.0/20
|
||||
add list=Google address=208.68.108.0/22
|
||||
add list=Google address=209.85.128.0/17
|
||||
add list=Google address=216.58.192.0/19
|
||||
add list=Google address=216.73.80.0/20
|
||||
add list=Google address=216.239.32.0/20
|
||||
add list=Google address=216.239.48.0/21
|
||||
add list=Google address=216.239.56.0/22
|
||||
add list=Google address=216.239.61.0/24
|
||||
add list=Google address=216.239.62.0/23
|
||||
add address=35.186.232.0/24 comment=youtube list=Google
|
||||
add address=74.125.8.0/24 comment=youtube list=Google
|
||||
add address=74.125.100.0/24 comment=youtube list=Google
|
||||
add address=74.125.131.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=74.125.205.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=64.233.161.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=64.233.162.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=64.233.163.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=64.233.164.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=64.233.165.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=108.177.14.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=142.250.150.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=142.251.1.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=172.217.133.0/24 comment=youtube list=Google
|
||||
add address=173.194.222.0/24 comment=yt4.ggpht.com list=Google
|
||||
add address=173.194.221.0/24 comment=yt4.ggpht.com list=Google
|
||||
add address=173.194.220.0/24 comment=yt4.ggpht.com list=Google
|
||||
add address=209.85.233.0/24 comment=yt3.ggpht.com list=Google
|
||||
add address=209.85.226.0/24 comment=youtube list=Google
|
||||
107
sysadmin/Monitoring/Gatus.html
Normal file
@@ -0,0 +1,107 @@
|
||||
<!--
|
||||
title: Gatus - просто мониторинг
|
||||
description:
|
||||
published: true
|
||||
date: 2024-08-08T14:53:32.993Z
|
||||
tags: мониторинг, gatus
|
||||
editor: ckeditor
|
||||
dateCreated: 2024-08-08T14:47:57.868Z
|
||||
-->
|
||||
|
||||
<p>У меня было очень много заметок про различные мониторинги. Кажется, что я уже про всё более-менее полезное что-то да писал. Оказалось, что нет. Расскажу про очередной небольшой и удобный мониторинг, который позволяет очень просто и быстро создать дашборд с зелёными и красными кнопками. Если зелёные, то всё ОК, если красные, то НЕ ОК. </p>
|
||||
<p> </p>
|
||||
<p>Речь пойдёт про Gatus (https://github.com/TwiN/gatus). С его помощью очень удобно создавать Status Page. Сразу покажу, как это будет выглядеть:</p>
|
||||
<p> </p>
|
||||
<p>⇨ <a href="https://status.twin.sh">https://status.twin.sh</a></p>
|
||||
<p> </p>
|
||||
<p>И сразу же простой пример, как это настраивается. Там всё максимально просто и быстро. Мы будем проверять следующие условия:</p>
|
||||
<p> </p>
|
||||
<p>◽️Подключение к сайту <a href="https://zabbix.com">zabbix.com </a>проходит успешно, а его IP равен 188.114.99.224. Так как этот домен резолвится в разные IP, можно будет увидеть, как срабатывает проверка.</p>
|
||||
<p>◽️Сайт <a href="https://github.com">github.com</a> отдаёт код 200 при подключении и содержит заголовок страницы GitHub: Let’s build from here · GitHub. </p>
|
||||
<p>◽️Сайт ya.ru отдаёт код 200 и имеет отклик менее 10 мс. На практике он будет больше, посмотрим, как срабатывает триггер. По этой проверке будет уведомление в Telegram.</p>
|
||||
<p>◽️Домен <a href="https://vk.com">vk.com</a> имеет сертификат со сроком истечения не менее 48 часов и делегирование домена не менее 720 часов. </p>
|
||||
<p> </p>
|
||||
<p>Специально подобрал разнообразные примеры, чтобы вы оценили возможности мониторинга. Я просто открыл документацию и сходу по ней всё сделал. Всё очень просто и понятно, особо разбираться не пришлось. Создаём конфигурационный файл для этих проверок:</p>
|
||||
<pre><code class="language-plaintext"># mkdir gatus && cd gatus
|
||||
# touch config.yaml
|
||||
</code></pre>
|
||||
<pre><code class="language-plaintext">alerting:
|
||||
telegram:
|
||||
token: "1393668911:AAHtEAKqxUH7ZpyX28R-wxKfvH1WR6-vdNw"
|
||||
id: "210806260"
|
||||
|
||||
endpoints:
|
||||
- name: Zabbix Connection
|
||||
url: "https://zabbix.com"
|
||||
interval: 30s
|
||||
conditions:
|
||||
- "[CONNECTED] == true"
|
||||
- "[IP] == 188.114.99.224"
|
||||
|
||||
- name: Github Title
|
||||
url: "https://github.com"
|
||||
interval: 30s
|
||||
conditions:
|
||||
- "[STATUS] == 200"
|
||||
- "[BODY] == pat(*<title>GitHub: Let’s build from here · GitHub</title>*)"
|
||||
|
||||
- name: Yandex response
|
||||
url: "https://ya.ru"
|
||||
interval: 30s
|
||||
conditions:
|
||||
- "[STATUS] == 200"
|
||||
- "[RESPONSE_TIME] < 10"
|
||||
alerts:
|
||||
- type: telegram
|
||||
send-on-resolved: true
|
||||
|
||||
- name: VK cert & domain
|
||||
url: "https://vk.com"
|
||||
interval: 5m
|
||||
conditions:
|
||||
- "[CERTIFICATE_EXPIRATION] > 48h"
|
||||
- "[DOMAIN_EXPIRATION] > 720h"
|
||||
</code></pre>
|
||||
<p>Запускаем Docker контейнер и цепляем к нему этот файл:</p>
|
||||
<pre><code class="language-plaintext"># docker run -p 8080:8080 -d \
|
||||
--mount type=bind,source="$(pwd)"/config.yaml,target=/config/config.yaml \
|
||||
--name gatus twinproduction/gatus
|
||||
</code></pre>
|
||||
<p>Идём по IP адресу сервера на порт 8080 и смотрим на свой мониторинг. Данные могут храниться в оперативной памяти, sqlite или postgresql базе. Если выберите последнее, то вот готовый <a href="https://github.com/TwiN/gatus/blob/master/.examples/docker-compose-postgres-storage/docker-compose.yml">docker-compose</a> для этого. По умолчанию данные хранятся в оперативной памяти и после перезапуска контейнера пропадают. </p>
|
||||
<pre><code class="language-plaintext">version: "3.9"
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
volumes:
|
||||
- ./data/db:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
- POSTGRES_DB=gatus
|
||||
- POSTGRES_USER=username
|
||||
- POSTGRES_PASSWORD=password
|
||||
networks:
|
||||
- web
|
||||
|
||||
gatus:
|
||||
image: twinproduction/gatus:latest
|
||||
restart: always
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- POSTGRES_USER=username
|
||||
- POSTGRES_PASSWORD=password
|
||||
- POSTGRES_DB=gatus
|
||||
volumes:
|
||||
- ./config:/config
|
||||
networks:
|
||||
- web
|
||||
depends_on:
|
||||
- postgres
|
||||
|
||||
networks:
|
||||
web:</code></pre>
|
||||
<p>Штука простая и удобная. Меня не раз просили посоветовать что-то для простого дашборда с зелёными кнопками, когда всё нормально и красными, когда нет. Вот это идеальный вариант под такую задачу.</p>
|
||||
<p>Также с помощью этого мониторинга удобно сделать дашборд для мониторинга мониторингов, чтобы понимать, живы они или нет.</p>
|
||||
<figure class="image"><img src="/sysadmin/img/gatus.png"></figure>
|
||||
<p> </p>
|
||||
BIN
sysadmin/img/disk-limit.png
Normal file
|
After Width: | Height: | Size: 689 KiB |
BIN
sysadmin/img/gatus.png
Normal file
|
After Width: | Height: | Size: 595 KiB |
BIN
sysadmin/img/memory-limit.png
Normal file
|
After Width: | Height: | Size: 889 KiB |
BIN
sysadmin/img/mkrt1.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
sysadmin/img/mkrt2.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
sysadmin/img/mkrt3.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
39
sysadmin/supermicro/fan.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: Регулировка скорости вращения вентиляторов
|
||||
description:
|
||||
published: true
|
||||
date: 2025-05-19T09:26:33.340Z
|
||||
tags: ipmi, fan
|
||||
editor: markdown
|
||||
dateCreated: 2025-05-19T08:49:19.082Z
|
||||
---
|
||||
|
||||
https://forums.servethehome.com/index.php?resources/supermicro-x9-x10-x11-fan-speed-control.20/
|
||||
https://forums.servethehome.com/index.php?threads/supermicro-x9-x10-x11-fan-speed-control.10059/page-8
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# IPMI settings
|
||||
IPMI_IP="192.168.88.221" # Replace with your BMC IP
|
||||
IPMI_USER="ADMIN" # Replace with your IPMI username
|
||||
IPMI_PASS="JYGEABVVCV" # Replace with your IPMI password
|
||||
|
||||
# Fan settings (for FAN3)
|
||||
FAN_ID="0x02" # 0x02 = FAN3 (0x00=FAN1, 0x01=FAN2, etc.)
|
||||
FAN_SPEED="0x32" # 0x32 = 50% (0x01=FULL, 0x24=37%, 0x16=25%)
|
||||
|
||||
# Set FULL
|
||||
ipmitool -I lanplus -H $IPMI_IP -U $IPMI_USER -P $IPMI_PASS raw 0x30 0x45 0x01 0x01
|
||||
|
||||
sleep 3
|
||||
|
||||
# Set manual control mode
|
||||
ipmitool -I lanplus -H $IPMI_IP -U $IPMI_USER -P $IPMI_PASS raw 0x30 0x70 0x66 0x01 0x00 0x16
|
||||
|
||||
# Set fan speed
|
||||
ipmitool -I lanplus -H $IPMI_IP -U $IPMI_USER -P $IPMI_PASS raw 0x30 0x70 0x66 0x01 $FAN_ID $FAN_SPEED
|
||||
|
||||
# Log the action (optional)
|
||||
#echo "$(date) - Set FAN3 speed to 50%" >> /var/log/fan_control.log
|
||||
```
|
||||