Compare commits

..

6 Commits

Author SHA1 Message Date
Rusovich Violetta ef904ca952 fix-pull 2026-02-09 08:33:27 +03:00
Rusovich Violetta e8dc61f5a1 fix-index-compute-ssh 2025-12-26 16:12:26 +03:00
Rusovich Violetta 62f12c8ce1 delete-console 2025-12-26 16:09:31 +03:00
Rusovich Violetta a9cafb629c fix-edit-link-title 2025-12-26 16:08:55 +03:00
Rusovich Violetta abdc7bd70e fix-index 2025-12-25 16:16:46 +03:00
Rusovich Violetta 7fd1755a7d VEGA-6128 Генерация ссылок для index старниц 2025-12-25 14:13:59 +03:00
22 changed files with 738 additions and 982 deletions
Submodule beecloud-docs deleted from df88416247
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "docs",
"version": "0.6.5-main",
"version": "0.6.4-link",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "docs",
"version": "0.6.5-main",
"version": "0.6.4-link",
"license": "MIT",
"dependencies": {
"@beeline/design-tokens": "^1.31.6",
+236 -236
View File
@@ -2,7 +2,7 @@ import { defineConfig } from 'vitepress'
import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'
import { viteStaticCopy } from 'vite-plugin-static-copy'
import { overrideComponents } from './override-components'
import { resolve } from 'node:path'
import { resolve } from 'path'
import { fileURLToPath, URL } from 'node:url'
const gitlab = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
@@ -41,7 +41,240 @@ const gitlab = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
`
const new_version = process.env?.VITE_NEW_VERSION;
console.log({ base: typeof new_version !== 'undefined' ? '/' : '/docs/' })
const sidebarConfig = {
'/platform/': [
{
text: 'Платформа Beeline Cloud', link: '/platform/index.md',
collapsed: true,
items: [
{text: 'Обзор', link: '/platform/about.md'},
{text: 'Техническая поддержка', link: '/platform/support/support-overview.md'},
],
},
],
'/start/': [
{
text: 'Начало работы в Beeline Cloud', link: '/start/index.md',
},
{text: 'Начать работу', link: '/start/getting-started.md'},
{text: 'Бесплатный период', link: '/start/trial.md'},
{text: 'Платное использование', link: '/start/organization.md'},
],
// '/billing/': [
// ],
'/backups/': [
{
text: 'Резервное копирование', link: '/backups/index.md',
},
{
text: 'Обзор сервиса', link: '/backups/about.md',
collapsed: true,
items: [
{text: 'Квоты и лимиты', link: '/backups/backup-quatos.md'},
]
},
{text: 'Резервное копирование виртуальных машин Beeline Cloud', link: '/backups/backup-internal-infra.md'},
{text: 'Резервное копирование собственной инфраструктуры в Beeline Cloud', link: '/backups/backup-external-infra.md'},
{text: 'Каталог резервных копий', link: '/backups/view-backups.md'},
],
'/vdc/': [
{
text: 'Виртуальные дата-центры на VMware', link: '/vdc/index.md',
},
{
text: 'Обзор сервиса', link: '/vdc/vdc-overview.md',
collapsed: true,
items: [
{ text: 'О сервисе', link: '/vdc/vdc-about.md' },
{ text: 'Техническое описание', link: '/vdc/vdc-tech.md' },
{ text: 'Квоты и лимиты', link: '/vdc/vdc-quatos.md' },
]
},
{
text: 'Быстрый старт', link: '/vdc/vdc-getting-started.md'
},
{ text: 'Виртуальные дата-центры', link: '/vdc/vdc-how-to/vdc-index.md',
collapsed: true,
items: [
{ text: 'Создание дата-центра', link: '/vdc/vdc-how-to/vdc-create.md' },
{ text: 'Вход в дата-центр', link: '/vdc/vdc-how-to/vdc-enter.md' },
{ text: 'Управление дата-центром', link: '/vdc/vdc-how-to/vdc-manage.md'},
],
},
{ text: 'Виртуальные машины', link: '/vdc/vdc-how-to/vm/vm-index.md',
collapsed: true,
items: [
{text: 'Создание ВМ', link: '/vdc/vdc-how-to/vm/create-vm.md'},
{text: 'Создание vApp', link: '/vdc/vdc-how-to/vm/create-vapp.md'},
{text: 'Управление состоянием ВМ', link: '/vdc/vdc-how-to/vm/manage-vm.md'},
{text: 'Клонирование ВМ', link: '/vdc/vdc-how-to/vm/clone-vm.md'},
{text: 'Изменение конфигурации ВМ', link: '/vdc/vdc-how-to/vm/edit-vm.md'},
{text: 'Удаление ВМ', link: '/vdc/vdc-how-to/vm/delete-vm.md'},
{text: 'Группы размещения', link: '/vdc/vdc-how-to/vm/create-affinity-rules.md'},
{text: 'Снимки ВМ', link: '/vdc/vdc-how-to/vm/create-snapshot.md'},
{text: 'VMware Tools', link: '/vdc/vdc-how-to/vm/vmware-tools.md'},
],
},
{ text: 'Диски', link: '/vdc/vdc-how-to/disks/disks-index.md',
collapsed: true,
items: [
{text: 'Обзор', link: '/vdc/vdc-how-to/disks/about.md'},
{text: 'Создание диска', link: '/vdc/vdc-how-to/disks/create-disk.md'},
{text: 'Проверка состояния диска', link: '/vdc/vdc-how-to/disks/view-disk.md'},
{text: 'Управление выделенными дисками', link: '/vdc/vdc-how-to/disks/attach-disk.md'},
{text: 'Изменение политики хранения дисков ВМ', link: '/vdc/vdc-how-to/disks/change-storage-policy-of-vm.md'},
{text: 'Редактирование параметров диска', link: '/vdc/vdc-how-to/disks/edit-disk.md'},
{text: 'Удаление диска', link: '/vdc/vdc-how-to/disks/delete-disk.md'},
],
},
{ text: 'Сети', link: '/vdc/vdc-how-to/networks/networks-index.md',
collapsed: true,
items: [
{text: 'Обзор', link: '/vdc/vdc-how-to/networks/about.md'},
{text: 'Настройка доступа к ВМ из интернета', link: '/vdc/vdc-how-to/networks/allow-external-connections-to-vm.md'},
{text: 'Подключение ВМ в vApp к сети', link: '/vdc/vdc-how-to/networks/connect-vapp-to-network.md'},
{text: 'Подключение ВМ к интернету', link: '/vdc/vdc-how-to/networks/connect-vm-to-network.md'},
{text: 'Создание сети в организации и подключение к Edge Gateway', link: '/vdc/vdc-how-to/networks/create-network.md'},
{text: 'Подключение сети к Edge Gateway', link: '/vdc/vdc-how-to/networks/connect-to-edge-gateway.md'},
{text: 'Создание Pre-Shared Key', link: '/vdc/vdc-how-to/networks/create-psk.md'},
{ text: 'Настройка site-to-site подключения с помощью IPSec', link: '/vdc/vdc-how-to/networks/how-to-setup-ipsec-vpn.md',
collapsed: true,
items: [
{text: 'Настройка ASAv', link: '/vdc/vdc-how-to/networks/ipsec/asav.md'},
{text: 'Настройка CSR 1000v', link: '/vdc/vdc-how-to/networks/ipsec/csr1000v.md'},
{text: 'Настройка Fortigate', link: '/vdc/vdc-how-to/networks/ipsec/fortigate.md'},
{text: 'Проверить сетевую связанность', link: '/vdc/vdc-how-to/networks/ipsec/check-vpn-status.md'},
],
},
],
},
{ text: 'Пользователи и роли', link: '/vdc/vdc-how-to/users/users-index.md',
collapsed: true,
items: [
{text: 'Ролевая модель', link: '/vdc/vdc-how-to/users/roles.md'},
{text: 'Создание пользователя', link: '/vdc/vdc-how-to/users/add-user.md'},
{text: 'Изменение пароля пользователя', link: '/vdc/vdc-how-to/users/change-users-password.md'},
{text: 'Настройка квот', link: '/vdc/vdc-how-to/users/quotas.md'},
],
},
{ text: 'Двухфакторная аутентификация', link: '/vdc/vdc-how-to/vdc-2fa.md',
collapsed: true,
items: [
{text: 'Подключение 2FA', link: '/vdc/vdc-how-to/vdc-2fa-start.md'},
{text: 'Управление 2FA', link: '/vdc/vdc-how-to/vdc-2fa-manage.md'},
],
},
],
// { text: 'Тарификация', link: '/vdc/vdc-tarif.md' },
'/compute/': [
{
text: 'Виртуальные машины', link: '/compute/index.md',
},
{ text: 'Обзор сервиса', link: '/compute/compute-overview-index.md' ,
collapsed: true,
items: [
{ text: 'Техническое описание', link: '/compute/compute-overview.md' },
{ text: 'Квоты и лимиты', link: '/compute/compute-quatos.md' },
]
},
{text: 'Быстрый старт', link: '/compute/compute-getting-started.md', excludeFromIndex: true },
{ text: 'Виртуальные машины', link: '/compute/compute-how-to/compute-index.md',
collapsed: true,
items: [
{ text: 'Создание ВМ', link: '/compute/compute-how-to/compute-servers-create.md' },
{ text: 'Создание ВМ джамп-хоста', link: '/compute/compute-how-to/compute-servers-jump-create.md' },
{ text: 'Подключение к ВМ', link: '/compute/compute-how-to/compute-connect-index.md',
collapsed: true,
items: [
{ text: 'Подключение по SSH по внешнему IP-адресу с помощью ключевой пары', link: '/compute/compute-how-to/compute-connect-public.md'},
{ text: 'Подключение по SSH по внутреннему IP-адресу с помощью ключевой пары', link: '/compute/compute-how-to/compute-connect-inside.md' },
{ text: 'Подключение по SSH по логину и паролю', link: '/compute/compute-how-to/compute-connect-pwd.md' },
]
},
{ text: 'Управление ВМ', link: '/compute/compute-how-to/compute-servers-manage.md' },
],
},
{ text: 'Диски', link: '/compute/compute-how-to/compute-disks/compute-disk-index.md',
collapsed: true,
items: [
{ text: 'Обзор', link: '/compute/compute-how-to/compute-disks/compute-disk-about.md' },
{ text: 'Создание диска', link: '/compute/compute-how-to/compute-disks/compute-disk-create.md' },
{ text: 'Управление дисками', link: '/compute/compute-how-to/compute-disks/compute-disk-manage.md' },
{ text: 'Удаление диска', link: '/compute/compute-how-to/compute-disks/compute-disk-del.md' },
]
},
{ text: 'IP-адреса', link: '/compute/compute-how-to/compute-ip/compute-ip-index.md',
collapsed: true,
items: [
{ text: 'Обзор', link: '/compute/compute-how-to/compute-ip/compute-ip-about.md' },
{ text: 'Просмотр IP-адресов', link: '/compute/compute-how-to/compute-ip/compute-ip-view.md' },
{ text: 'Создание IP-адреса', link: '/compute/compute-how-to/compute-ip/compute-ip-create.md' },
{ text: 'Управление IP-адресами', link: '/compute/compute-how-to/compute-ip/compute-ip-manager.md' },
{ text: 'Удаление IP-адреса', link: '/compute/compute-how-to/compute-ip/compute-ip-del.md' },
]
},
{ text: 'Группы размещения', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-index.md',
collapsed: true,
items: [
{ text: 'Обзор', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-about.md'},
{ text: 'Создание группы размещения', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-create.md'},
{ text: 'Управление группами размещения', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-manager.md' },
{ text: 'Удаление группы размещения', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-del.md' },
]
},
{ text: 'Сети', link: '/compute/compute-how-to/compute-network/compute-network-index.md',
collapsed: true,
items: [
{ text: 'Настройка site-to-site VPN с помощью VyOS', link: '/compute/compute-how-to/compute-network/compute-vpn-vyos.md' },
{ text: 'Подключение ВМ закрытого контура к интернету', link: '/compute/compute-how-to/compute-network/compute-network-inside.md' },
],
excludeFromIndex: true,
},
],
'/admin/': [
{
text: 'Администрирование', link: '/admin/index.md',
},
{text: 'Управление ключевыми парами', link: '/admin/ssh.md'},
],
'/vdi/': [
{
text: 'Виртуальные рабочие столы', link: '/vdi/index.md',
},
{
text: 'Обзор сервиса', link: '/vdi/vdi-overview.md',
collapsed: true,
items: [
{ text: 'О сервисе', link: '/vdi/vdi-about.md' },
{ text: 'Техническое описание', link: '/vdi/vdi-tech.md' },
{ text: 'Квоты и лимиты', link: '/vdi/vdi-quatos.md' },
{ text: 'Тарификация', link: '/vdi/vdi-tarif.md' },
]
},
{
text: 'Заказ виртуальных рабочих столов', link: '/vdi/vdi-how-to/vdi-create.md'
},
{
text: 'Настройка сервиса', link: '/vdi/vdi-how-to/vdi-nastroika.md',
collapsed: true,
items: [
{ text: 'Настройка интеграции с Active Directory', link: '/vdi/vdi-how-to/vdi-connect-to-ad.md' },
{ text: 'Настройка сети', link: '/vdi/vdi-how-to/vdi-interconnect.md' },
]
},
// {
// text: 'Gold-образ', link: '/vdi/vdi-how-to/vdi-gold.md'
// },
{
text: 'Подключение к виртуальному рабочему месту', link: '/vdi/vdi-how-to/vdi-connect.md'
},
],
}
// https://vitepress.dev/reference/site-config
export default defineConfig({
@@ -140,240 +373,7 @@ export default defineConfig({
outline: {
label: 'Содержание'
},
sidebar: {
'/platform/': [
{
text: 'Платформа Beeline Cloud', link: '/platform/index.md',
collapsed: true,
items: [
{text: 'Обзор', link: '/platform/about.md'},
{text: 'Техническая поддержка', link: '/platform/support/support-overview.md'},
],
},
],
'/start/': [
{
text: 'Начало работы в Beeline Cloud', link: '/start/index.md',
},
{text: 'Начать работу', link: '/start/getting-started.md'},
{text: 'Бесплатный период', link: '/start/trial.md'},
{text: 'Платное использование', link: '/start/organization.md'},
],
// '/billing/': [
// ],
'/backups/': [
{
text: 'Резервное копирование', link: '/backups/index.md',
},
{
text: 'Обзор сервиса', link: '/backups/backups-overview.md',
collapsed: true,
items: [
{text: 'О сервисе', link: '/backups/about.md'},
{text: 'Квоты и лимиты', link: '/backups/backup-quatos.md'},
]
},
{text: 'Резервное копирование виртуальных машин Beeline Cloud', link: '/backups/backup-internal-infra.md'},
{text: 'Резервное копирование собственной инфраструктуры в Beeline Cloud', link: '/backups/backup-external-infra.md'},
{text: 'Каталог резервных копий', link: '/backups/view-backups.md'},
],
'/vdc/': [
{
text: 'Виртуальные дата-центры на VMware', link: '/vdc/index.md',
},
{
text: 'Обзор сервиса', link: '/vdc/vdc-overview.md',
collapsed: true,
items: [
{ text: 'О сервисе', link: '/vdc/vdc-about.md' },
{ text: 'Техническое описание', link: '/vdc/vdc-tech.md' },
{ text: 'Квоты и лимиты', link: '/vdc/vdc-quatos.md' },
]
},
{
text: 'Быстрый старт', link: '/vdc/vdc-getting-started.md'
},
{ text: 'Виртуальные дата-центры', link: '/vdc/vdc-how-to/vdc-index.md',
collapsed: true,
items: [
{ text: 'Создание дата-центра', link: '/vdc/vdc-how-to/vdc-create.md' },
{ text: 'Вход в дата-центр', link: '/vdc/vdc-how-to/vdc-enter.md' },
{ text: 'Управление дата-центром', link: '/vdc/vdc-how-to/vdc-manage.md'},
],
},
{ text: 'Виртуальные машины', link: '/vdc/vdc-how-to/vm/vm-index.md',
collapsed: true,
items: [
{text: 'Создание ВМ', link: '/vdc/vdc-how-to/vm/create-vm.md'},
{text: 'Создание vApp', link: '/vdc/vdc-how-to/vm/create-vapp.md'},
{text: 'Управление состоянием ВМ', link: '/vdc/vdc-how-to/vm/manage-vm.md'},
{text: 'Клонирование ВМ', link: '/vdc/vdc-how-to/vm/clone-vm.md'},
{text: 'Изменение конфигурации ВМ', link: '/vdc/vdc-how-to/vm/edit-vm.md'},
{text: 'Удаление ВМ', link: '/vdc/vdc-how-to/vm/delete-vm.md'},
{text: 'Группы размещения', link: '/vdc/vdc-how-to/vm/create-affinity-rules.md'},
{text: 'Снимки ВМ', link: '/vdc/vdc-how-to/vm/create-snapshot.md'},
{text: 'VMware Tools', link: '/vdc/vdc-how-to/vm/vmware-tools.md'},
],
},
{ text: 'Диски', link: '/vdc/vdc-how-to/disks/disks-index.md',
collapsed: true,
items: [
{text: 'Обзор', link: '/vdc/vdc-how-to/disks/about.md'},
{text: 'Создание диска', link: '/vdc/vdc-how-to/disks/create-disk.md'},
{text: 'Проверка состояния диска', link: '/vdc/vdc-how-to/disks/view-disk.md'},
{text: 'Управление выделенными дисками', link: '/vdc/vdc-how-to/disks/attach-disk.md'},
{text: 'Изменение политики хранения дисков ВМ', link: '/vdc/vdc-how-to/disks/change-storage-policy-of-vm.md'},
{text: 'Редактирование параметров диска', link: '/vdc/vdc-how-to/disks/edit-disk.md'},
{text: 'Удаление диска', link: '/vdc/vdc-how-to/disks/delete-disk.md'},
],
},
{ text: 'Сети', link: '/vdc/vdc-how-to/networks/networks-index.md',
collapsed: true,
items: [
{text: 'Обзор', link: '/vdc/vdc-how-to/networks/about.md'},
{text: 'Настройка доступа к ВМ из интернета', link: '/vdc/vdc-how-to/networks/allow-external-connections-to-vm.md'},
{text: 'Подключение ВМ в vApp к сети', link: '/vdc/vdc-how-to/networks/connect-vapp-to-network.md'},
{text: 'Подключение ВМ к интернету', link: '/vdc/vdc-how-to/networks/connect-vm-to-network.md'},
{text: 'Создание сети в организации и подключение к Edge Gateway', link: '/vdc/vdc-how-to/networks/create-network.md'},
{text: 'Подключение сети к Edge Gateway', link: '/vdc/vdc-how-to/networks/connect-to-edge-gateway.md'},
{text: 'Создание Pre-Shared Key', link: '/vdc/vdc-how-to/networks/create-psk.md'},
{ text: 'Настройка site-to-site подключения с помощью IPSec', link: '/vdc/vdc-how-to/networks/how-to-setup-ipsec-vpn.md',
collapsed: true,
items: [
{text: 'Настройка IPSec VPN', link: '/vdc/vdc-how-to/networks/ipsec/setup-ipsec-vpn.md'},
{text: 'Настройка ASAv', link: '/vdc/vdc-how-to/networks/ipsec/asav.md'},
{text: 'Настройка CSR 1000v', link: '/vdc/vdc-how-to/networks/ipsec/csr1000v.md'},
{text: 'Настройка Fortigate', link: '/vdc/vdc-how-to/networks/ipsec/fortigate.md'},
{text: 'Проверить сетевую связанность', link: '/vdc/vdc-how-to/networks/ipsec/check-vpn-status.md'},
],
},
],
},
{ text: 'Пользователи и роли', link: '/vdc/vdc-how-to/users/users-index.md',
collapsed: true,
items: [
{text: 'Ролевая модель', link: '/vdc/vdc-how-to/users/roles.md'},
{text: 'Создание пользователя', link: '/vdc/vdc-how-to/users/add-user.md'},
{text: 'Изменение пароля пользователя', link: '/vdc/vdc-how-to/users/change-users-password.md'},
{text: 'Настройка квот', link: '/vdc/vdc-how-to/users/quotas.md'},
],
},
{ text: 'Двухфакторная аутентификация', link: '/vdc/vdc-how-to/vdc-2fa.md',
collapsed: true,
items: [
{text: 'Подключение 2FA', link: '/vdc/vdc-how-to/vdc-2fa-start.md'},
{text: 'Управление 2FA', link: '/vdc/vdc-how-to/vdc-2fa-manage.md'},
],
},
],
// { text: 'Тарификация', link: '/vdc/vdc-tarif.md' },
'/compute/': [
{
text: 'Виртуальные машины', link: '/compute/index.md',
},
{ text: 'Обзор сервиса', link: '/compute/compute-overview-index.md' ,
collapsed: true,
items: [
{ text: 'Техническое описание', link: '/compute/compute-overview.md' },
{ text: 'Квоты и лимиты', link: '/compute/compute-quatos.md' },
]
},
{text: 'Быстрый старт', link: '/compute/compute-getting-started.md'},
{ text: 'Виртуальные машины', link: '/compute/compute-how-to/compute-index.md',
collapsed: true,
items: [
{ text: 'Создание ВМ', link: '/compute/compute-how-to/compute-servers-create.md' },
{ text: 'Создание ВМ джамп-хоста', link: '/compute/compute-how-to/compute-servers-jump-create.md' },
{ text: 'Подключение к ВМ', link: '/compute/compute-how-to/compute-connect-index.md',
collapsed: true,
items: [
{ text: 'Подключение по SSH по внешнему IP-адресу с помощью ключевой пары', link: '/compute/compute-how-to/compute-connect-public.md'},
{ text: 'Подключение по SSH по внутреннему IP-адресу с помощью ключевой пары', link: '/compute/compute-how-to/compute-connect-inside.md' },
{ text: 'Подключение по SSH по логину и паролю', link: '/compute/compute-how-to/compute-connect-pwd.md' },
]
},
{ text: 'Управление ВМ', link: '/compute/compute-how-to/compute-servers-manage.md' },
],
},
{ text: 'Диски', link: '/compute/compute-how-to/compute-disks/compute-disk-index.md',
collapsed: true,
items: [
{ text: 'Обзор', link: '/compute/compute-how-to/compute-disks/compute-disk-about.md' },
{ text: 'Создание диска', link: '/compute/compute-how-to/compute-disks/compute-disk-create.md' },
{ text: 'Управление дисками', link: '/compute/compute-how-to/compute-disks/compute-disk-manage.md' },
{ text: 'Удаление диска', link: '/compute/compute-how-to/compute-disks/compute-disk-del.md' },
]
},
{ text: 'IP-адреса', link: '/compute/compute-how-to/compute-ip/compute-ip-index.md',
collapsed: true,
items: [
{ text: 'Обзор', link: '/compute/compute-how-to/compute-ip/compute-ip-about.md' },
{ text: 'Просмотр IP-адресов', link: '/compute/compute-how-to/compute-ip/compute-ip-view.md' },
{ text: 'Создание IP-адреса', link: '/compute/compute-how-to/compute-ip/compute-ip-create.md' },
{ text: 'Управление IP-адресами', link: '/compute/compute-how-to/compute-ip/compute-ip-manager.md' },
{ text: 'Удаление IP-адреса', link: '/compute/compute-how-to/compute-ip/compute-ip-del.md' },
]
},
{ text: 'Группы размещения', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-index.md',
collapsed: true,
items: [
{ text: 'Обзор', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-about.md'},
{ text: 'Создание группы размещения', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-create.md'},
{ text: 'Управление группами размещения', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-manager.md' },
{ text: 'Удаление группы размещения', link: '/compute/compute-how-to/compute-placement-groups/compute-placement-groups-del.md' },
]
},
{ text: 'Сети', link: '/compute/compute-how-to/compute-network/compute-network-index.md',
collapsed: true,
items: [
{ text: 'Настройка site-to-site VPN с помощью VyOS', link: '/compute/compute-how-to/compute-network/compute-vpn-vyos.md' },
{ text: 'Подключение ВМ закрытого контура к интернету', link: '/compute/compute-how-to/compute-network/compute-network-inside.md' },
],
},
],
'/admin/': [
{
text: 'Администрирование', link: '/admin/index.md',
},
{text: 'Управление ключевыми парами', link: '/admin/ssh.md'},
],
'/vdi/': [
{
text: 'Виртуальные рабочие столы', link: '/vdi/index.md',
},
{
text: 'Обзор сервиса', link: '/vdi/vdi-overview.md',
collapsed: true,
items: [
{ text: 'О сервисе', link: '/vdi/vdi-about.md' },
{ text: 'Техническое описание', link: '/vdi/vdi-tech.md' },
{ text: 'Квоты и лимиты', link: '/vdi/vdi-quatos.md' },
{ text: 'Тарификация', link: '/vdi/vdi-tarif.md' },
]
},
{
text: 'Заказ виртуальных рабочих столов', link: '/vdi/vdi-how-to/vdi-create.md'
},
{
text: 'Настройка сервиса', link: '/vdi/vdi-how-to/vdi-nastroika.md',
collapsed: true,
items: [
{ text: 'Настройка интеграции с Active Directory', link: '/vdi/vdi-how-to/vdi-connect-to-ad.md' },
{ text: 'Настройка сети', link: '/vdi/vdi-how-to/vdi-interconnect.md' },
]
},
// {
// text: 'Gold-образ', link: '/vdi/vdi-how-to/vdi-gold.md'
// },
{
text: 'Подключение к виртуальному рабочему месту', link: '/vdi/vdi-how-to/vdi-connect.md'
},
],
},
sidebar: sidebarConfig,
},
}
)
@@ -0,0 +1,16 @@
import type { Plugin } from 'vite'
import type { SidebarItem } from './utils/types'
import { processAllFiles } from './hook/process-files'
export const autoSectionLinksPlugin = (
srcDir: string,
sidebarConfig: Record<string, SidebarItem[]>
): Plugin => ({
name: 'auto-section-links',
buildStart: () => {
processAllFiles(srcDir, sidebarConfig)
},
configureServer: () => {
processAllFiles(srcDir, sidebarConfig)
}
})
+4
View File
@@ -0,0 +1,4 @@
export const INDEX_FILE = 'index.md'
export const INDEX_FILE_PATTERN = /-index\.md$|index\.md$/
export const FRONTMATTER_REGEX = /^---\s*\n([\s\S]*?)\n---/
export const SECTION_LINK_KEYS = ['title', 'link', 'description'] as const
@@ -0,0 +1,36 @@
import { existsSync } from 'fs'
import { relative, resolve } from 'path'
import type { SidebarItem } from '../utils/types'
import { findMarkdownFiles } from '../utils/file-finder'
import { processIndexFile, processPageWithItems } from '../utils/file-processor'
import { INDEX_FILE, INDEX_FILE_PATTERN } from '../constants'
export const processAllFiles = (
srcDir: string,
sidebarConfig: Record<string, SidebarItem[]>
) => {
const srcPath = resolve(srcDir)
for (const [folderPath, items] of Object.entries(sidebarConfig)) {
const normalizedFolder = folderPath.replace(/^\/+|\/+$/g, '')
const folderFullPath = resolve(srcPath, normalizedFolder)
if (!existsSync(folderFullPath)) {
continue
}
const mdFiles = findMarkdownFiles(folderFullPath)
for (const filePath of mdFiles) {
const fileName = filePath.split(/[/\\]/).pop() || ''
const relativePath = relative(srcPath, filePath).replace(/\\/g, '/')
const normalizedPath = relativePath.startsWith('/') ? relativePath : `/${relativePath}`
if (fileName === INDEX_FILE) {
processIndexFile(filePath, items, srcPath)
} else if (INDEX_FILE_PATTERN.test(fileName) && fileName !== INDEX_FILE) {
processPageWithItems(filePath, items, srcPath)
}
}
}
}
@@ -0,0 +1,17 @@
import { readFileSync, existsSync } from 'fs'
import { resolve } from 'path'
import { parseFrontmatter } from './frontmatter'
export const getPageDescription = (filePath: string, srcDir: string) => {
try {
const fullPath = resolve(srcDir, filePath.replace(/^\//, ''))
if (!existsSync(fullPath)) return undefined
const fileContent = readFileSync(fullPath, 'utf-8')
const { frontmatter } = parseFrontmatter(fileContent)
return frontmatter.description as string | undefined
} catch {
return undefined
}
}
@@ -0,0 +1,24 @@
import { readdirSync, statSync } from 'fs'
import { join } from 'path'
export const findMarkdownFiles = (dir: string) => {
const files: string[] = []
try {
const entries = readdirSync(dir)
for (const entry of entries) {
const fullPath = join(dir, entry)
const stat = statSync(fullPath)
if (stat.isDirectory()) {
files.push(...findMarkdownFiles(fullPath))
} else if (entry.endsWith('.md')) {
files.push(fullPath)
}
}
} catch {
}
return files
}
@@ -0,0 +1,117 @@
import { readFileSync, writeFileSync, existsSync } from 'fs'
import { relative, resolve } from 'path'
import type { SidebarItem } from './types'
import { parseFrontmatter, stringifyFrontmatter } from './frontmatter'
import { mergeSectionLinks, extractTopLevelLinks, extractItemsForPage } from './links'
import { normalizeLink } from './path-utils'
import { SectionLinkListItem } from '../../theme/components/SectionLinkList/SectionLinkList.types'
const removeDuplicates = (links: SectionLinkListItem[]) => {
const result: SectionLinkListItem[] = []
const seenLinks = new Set<string>()
for (const link of links) {
if (link.link) {
const normalized = normalizeLink(link.link)
if (!seenLinks.has(normalized)) {
seenLinks.add(normalized)
result.push(link)
}
}
}
return result
}
const hasChanges = (
existingLinks: SectionLinkListItem[],
mergedLinks: SectionLinkListItem[]
) => {
if (existingLinks.length !== mergedLinks.length) return true
const existingSet = new Set(
existingLinks
.filter(link => link.link)
.map(link => `${normalizeLink(link.link!)}|${link.title}`)
)
const mergedSet = new Set(
mergedLinks
.filter(link => link.link)
.map(link => `${normalizeLink(link.link!)}|${link.title}`)
)
if (existingSet.size !== mergedSet.size) return true
for (const item of existingSet) {
if (!mergedSet.has(item)) return true
}
return false
}
export const processIndexFile = (
filePath: string,
sidebarItems: SidebarItem[],
srcDir: string
) => {
if (!existsSync(filePath)) return false
try {
const fileContent = readFileSync(filePath, 'utf-8')
const { frontmatter, content } = parseFrontmatter(fileContent)
const relativePath = relative(srcDir, filePath).replace(/\\/g, '/')
const normalizedPath = relativePath.startsWith('/') ? relativePath : `/${relativePath}`
const existingLinks = removeDuplicates(
Array.isArray(frontmatter.section_links) ? [...frontmatter.section_links] : []
)
const newLinks = extractTopLevelLinks(sidebarItems, normalizedPath, srcDir)
if (!newLinks.length) return false
const mergedLinks = removeDuplicates(mergeSectionLinks(existingLinks, newLinks))
if (!hasChanges(existingLinks, mergedLinks)) return false
frontmatter.section_links = mergedLinks
writeFileSync(filePath, stringifyFrontmatter(frontmatter, content), 'utf-8')
return true
} catch {
return false
}
}
export const processPageWithItems = (
filePath: string,
sidebarItems: SidebarItem[],
srcDir: string
) => {
if (!existsSync(filePath)) return false
try {
const fileContent = readFileSync(filePath, 'utf-8')
const { frontmatter, content } = parseFrontmatter(fileContent)
const relativePath = relative(srcDir, filePath).replace(/\\/g, '/')
const normalizedPath = relativePath.startsWith('/') ? relativePath : `/${relativePath}`
const existingLinks = removeDuplicates(
Array.isArray(frontmatter.section_links) ? [...frontmatter.section_links] : []
)
const newLinks = extractItemsForPage(sidebarItems, normalizedPath, srcDir)
const mergedLinks = newLinks.length > 0
? removeDuplicates(mergeSectionLinks(existingLinks, newLinks))
: []
if (!hasChanges(existingLinks, mergedLinks)) return false
frontmatter.section_links = mergedLinks
writeFileSync(filePath, stringifyFrontmatter(frontmatter, content), 'utf-8')
return true
} catch {
return false
}
}
+142
View File
@@ -0,0 +1,142 @@
import type { Frontmatter } from './types'
import { SECTION_LINK_KEYS, FRONTMATTER_REGEX } from '../constants'
import { SectionLinkListItem } from '../../theme/components/SectionLinkList/SectionLinkList.types'
export const parseFrontmatter = (content: string) => {
const frontmatterMatch = content.match(FRONTMATTER_REGEX)
if (!frontmatterMatch) {
const cleanContent = content.replace(/^---[\s\S]*?---\s*\n*/g, '').trim()
return { frontmatter: {}, content: cleanContent || content }
}
const [, frontmatterText] = frontmatterMatch
const frontmatterEnd = frontmatterMatch[0].length
let cleanContent = content.slice(frontmatterEnd)
cleanContent = cleanContent.replace(/^---[\s\S]*?---\s*\n*/g, '').trim()
if (!cleanContent) {
cleanContent = content.slice(frontmatterEnd).replace(/^---[\s\S]*?---\s*\n*/g, '').trim()
}
const frontmatter: Frontmatter = {}
const lines = frontmatterText.split('\n')
let currentKey: string | undefined
let currentValue: SectionLinkListItem[] = []
let currentItem: Record<string, string> | undefined
let inArray = false
for (const line of lines) {
const trimmed = line.trim()
if (trimmed && !trimmed.startsWith('#')) {
const lineIndent = line.match(/^(\s*)/)?.[1]?.length ?? 0
if (lineIndent === 0 && trimmed.includes(':')) {
if (inArray && currentKey) {
frontmatter[currentKey] = currentValue
currentValue = []
inArray = false
}
const colonMatch = trimmed.match(/^([^:]+):\s*(.*)$/)
if (colonMatch) {
const [, key, value] = colonMatch
currentKey = key.trim()
const trimmedValue = value.trim()
if (trimmedValue === '') {
inArray = true
currentValue = []
} else {
frontmatter[currentKey] = trimmedValue.replace(/^["']|["']$/g, '')
}
}
} else if (lineIndent === 2 && trimmed.startsWith('- ')) {
if (!inArray && currentKey) {
inArray = true
currentValue = []
}
if (currentItem && currentItem.title && currentItem.link !== undefined) {
const link: SectionLinkListItem = {
title: currentItem.title,
link: currentItem.link,
description: currentItem.description
}
if (!currentValue.some(item => item.link === link.link)) {
currentValue.push(link)
}
}
const itemText = trimmed.slice(2).trim()
if (itemText.includes(':')) {
currentItem = {}
const parts = itemText.split(',').map(p => p.trim())
for (const part of parts) {
const colonMatch = part.match(/^(\w+):\s*(.+)$/)
if (colonMatch) {
const [, key, value] = colonMatch
if (SECTION_LINK_KEYS.includes(key as typeof SECTION_LINK_KEYS[number])) {
currentItem[key] = value.replace(/^["']|["']$/g, '')
}
}
}
} else {
currentValue.push({ title: itemText, link: '' })
}
} else if (lineIndent >= 4 && currentItem && trimmed.includes(':')) {
const colonIndex = trimmed.indexOf(':')
if (colonIndex !== -1) {
const key = trimmed.substring(0, colonIndex).trim()
const value = trimmed.substring(colonIndex + 1).trim()
if (SECTION_LINK_KEYS.includes(key as typeof SECTION_LINK_KEYS[number])) {
currentItem[key] = value === '' ? '' : value.replace(/^["']|["']$/g, '')
}
}
}
}
}
if (currentItem && inArray && currentItem.title && currentItem.link !== undefined) {
const link: SectionLinkListItem = {
title: currentItem.title,
link: currentItem.link,
description: currentItem.description
}
if (!currentValue.some(item => item.link === link.link)) {
currentValue.push(link)
}
}
if (inArray && currentKey) {
frontmatter[currentKey] = currentValue
}
return { frontmatter, content: cleanContent || content }
}
export const stringifyFrontmatter = (frontmatter: Frontmatter, content: string) => {
const lines: string[] = []
for (const [key, value] of Object.entries(frontmatter)) {
if (Array.isArray(value)) {
lines.push(`${key}:`)
for (const item of value) {
if (typeof item === 'object' && item) {
const link = item as SectionLinkListItem
lines.push(` - title: ${link.title ?? ''}`)
if (link.link) lines.push(` link: ${link.link}`)
if ('description' in link && link.description !== undefined && link.description !== null && String(link.description).trim() !== '') {
lines.push(` description: ${String(link.description)}`)
}
} else {
lines.push(` - ${item}`)
}
}
} else if (value) {
const strValue = String(value)
const needsQuotes = strValue.includes(':') || (strValue.includes(' ') && !strValue.startsWith('"')) || strValue === ''
const escaped = strValue.replace(/"/g, '\\"')
lines.push(`${key}: ${needsQuotes ? `"${escaped}"` : strValue}`)
}
}
return `---\n${lines.join('\n')}\n---\n\n${content}`
}
+118
View File
@@ -0,0 +1,118 @@
import type { SidebarItem } from './types'
import { getPageDescription } from './descriptions'
import { normalizeLink } from './path-utils'
import { SectionLinkListItem } from '../../theme/components/SectionLinkList/SectionLinkList.types'
export const mergeSectionLinks = (
existingLinks: SectionLinkListItem[],
newLinks: SectionLinkListItem[]
) => {
const existingLinksMap = new Map<string, SectionLinkListItem>()
const result: SectionLinkListItem[] = []
const processedLinks = new Set<string>()
for (const existingLink of existingLinks) {
if (existingLink.link) {
const normalizedLink = normalizeLink(existingLink.link)
if (!existingLinksMap.has(normalizedLink)) {
existingLinksMap.set(normalizedLink, existingLink)
}
}
}
for (const newLink of newLinks) {
if (newLink.link) {
const normalizedLink = normalizeLink(newLink.link)
if (!processedLinks.has(normalizedLink)) {
processedLinks.add(normalizedLink)
if (existingLinksMap.has(normalizedLink)) {
const existingLink = existingLinksMap.get(normalizedLink)!
result.push({ ...existingLink, title: newLink.title })
} else {
result.push(newLink)
}
}
}
}
return result
}
export const extractTopLevelLinks = (
items: SidebarItem[],
currentIndexPath: string,
srcDir: string
) => {
const links: SectionLinkListItem[] = []
const normalizedCurrentPath = normalizeLink(currentIndexPath)
for (const item of items) {
if ('excludeFromIndex' in item && item.excludeFromIndex) {
continue
}
if (item.link) {
const normalizedItemPath = normalizeLink(item.link)
if (normalizedItemPath === normalizedCurrentPath) {
continue
}
links.push({
title: item.text || '',
link: item.link,
description: getPageDescription(item.link, srcDir)
})
}
}
return links
}
const findItemsRecursive = (
itemsList: SidebarItem[],
pagePath: string,
srcDir: string
): SectionLinkListItem[] => {
const normalizedPagePath = normalizeLink(pagePath)
const links: SectionLinkListItem[] = []
for (const item of itemsList) {
if (item.link) {
const normalizedItemPath = normalizeLink(item.link)
if (normalizedItemPath === normalizedPagePath && item.items && Array.isArray(item.items) && item.items.length > 0) {
for (const subItem of item.items) {
if ('excludeFromIndex' in subItem && subItem.excludeFromIndex) {
continue
}
if (subItem.link) {
links.push({
title: subItem.text || '',
link: subItem.link,
description: getPageDescription(subItem.link, srcDir)
})
}
}
return links
}
}
if (item.items && Array.isArray(item.items)) {
const found = findItemsRecursive(item.items, pagePath, srcDir)
if (found.length > 0) {
return found
}
}
}
return links
}
export const extractItemsForPage = (
items: SidebarItem[],
pagePath: string,
srcDir: string
) => findItemsRecursive(items, pagePath, srcDir)
@@ -0,0 +1,6 @@
export const normalizeLink = (link: string): string =>
!link ? '' : link
.replace(/^\/+/, '')
.replace(/\.md$/, '')
.replace(/\\/g, '/')
.trim()
+12
View File
@@ -0,0 +1,12 @@
import { SectionLinkListItem } from "../../theme/components/SectionLinkList/SectionLinkList.types"
export type SidebarItem = {
text: string
link?: string
items?: SidebarItem[]
}
export type Frontmatter = {
section_links?: SectionLinkListItem[]
[key: string]: string | number | boolean | string[] | SectionLinkListItem[] | undefined
}
@@ -2,6 +2,8 @@ export type SectionLinkListItem = {
title: string,
link: string,
description?: string
collapsed?: boolean
excludeFromIndex?: boolean
}
export type SectionLinkListProps = {
-87
View File
@@ -1,87 +0,0 @@
# Cloud PostgreSQL
## Назначение сервиса
**Cloud PostgreSQL** - это управляемый облачный сервис реляционной базы данных PostgreSQL. Он позволяет развернуть и использовать отказоустойчивый кластер базы данных без необходимости самостоятельно настраивать серверы, репликацию и механизмы отказоустойчивости.
PostgreSQL - это современная система управления базами данных, которая поддерживает стандарт SQL и используется для хранения и обработки данных приложений.
В **Cloud PostgreSQL** все основные операции по управлению кластером выполняются автоматически.
Сервис самостоятельно:
- управляет ролями серверов базы данных (основной сервер и реплики);
- отслеживает состояние узлов;
- автоматически переключает основной сервер при сбоях.
Для обеспечения стабильной работы сервиса используется несколько инфраструктурных компонентов:
- **Patroni** - управляет кластером PostgreSQL и автоматическим переключением при отказах;
- **etcd** - хранит состояние кластера и обеспечивает согласованность работы узлов;
- **HAProxy** - обеспечивает единую точку подключения и распределяет клиентские подключения между узлами.
Подключение к базе данных выполняется через прокси-узлы сервиса. Пользователю не требуется подключаться к отдельным серверам кластера — все операции производятся через единую точку доступа.
Для управления базами данных и пользователями доступен web-интерфейс **pgAdmin**, позволяющий выполнять администрирование непосредственно через браузер.
## Конфигурации кластера
Сервис Cloud PostgreSQL поддерживает версии СУБД с 13 по 17 включительно.
Кластер предоставляется в архитектуре Primary–Standby, которая обеспечивает:
- синхронную репликацию данных;
- повышенную отказоустойчивость.
В рамках данной конфигурации создаётся кластер из виртуальных серверов, включающий:
- **Primary** (основной сервер) — обязательный узел, на котором выполняются операции записи данных;
- **Replica** (реплики) — дополнительные узлы (от 0 до 4), создаваемые по желанию пользователя.
Реплики являются полноценными участниками кластера PostgreSQL и могут использоваться для выполнения запросов, не изменяющих данные (например, SELECT).
В многоузловой конфигурации серверы кластера размещаются на разных физических хостах гипервизора, что повышает устойчивость сервиса к отказам оборудования.
## Режимы репликации
По умолчанию фиксация изменений выполняется в **синхронном режиме**. Это означает, что операция записи считается завершённой только после того, как данные будут зафиксированы как на основном сервере, так и на одной из реплик.
Если в кластере настроено несколько реплик, синхронный режим применяется только к одной из них. Остальные реплики работают в асинхронном режиме — изменения передаются на них без ожидания подтверждения.
При необходимости режим репликации может быть изменён на полностью **асинхронный**. В этом случае изменения сначала фиксируются на основном сервере, а затем передаются на реплики с задержкой.
## Доступ к серверам и оптимизация соединений
Прямой доступ к серверам кластера (например, по протоколу SSH) не предоставляется. Пользователь взаимодействует с базой данных исключительно через точки подключения, предоставленные сервисом.
На каждом узле кластера установлен пулер соединений **PgBouncer**, который может использоваться для ускорения работы приложений за счёт оптимизации подключений к базе данных.
::: warning Примечание
Использование PgBouncer не является обязательным - подключение возможно как напрямую к PostgreSQL, так и через пулер, а также одновременно обоими способами.
:::
## Возможности сервиса
**Cloud PostgreSQL** предоставляет набор возможностей, позволяющих использовать PostgreSQL в облаке без необходимости самостоятельного администрирования инфраструктуры.
Сервис обеспечивает:
- автоматическое управление кластером PostgreSQL;
- высокую доступность за счёт репликации и автоматического переключения primary-узла;
- единую точку подключения к базе данных через прокси;
- автоматическое переключение при отказе узлов кластера без вмешательства пользователя;
- web-доступ к управлению базами данных и пользователями через pgAdmin;
- совместимость со стандартными клиентскими инструментами PostgreSQL;
- возможность установки расширений PostgreSQL в базу данных.
## Сценарии использования сервиса
**Cloud PostgreSQL** подходит для использования в системах, где требуется надёжное хранение данных и упрощённое управление инфраструктурой базы данных.
Сервис может применяться в следующих сценариях:
- размещение production-баз данных с высокими требованиями к доступности;
- использование PostgreSQL в микросервисной архитектуре с единой точкой подключения к базе данных;
- хранение критичных данных с минимальным временем простоя при отказах инфраструктуры;
- быстрое развёртывание PostgreSQL-кластера без необходимости ручной настройки репликации и failover;
- администрирование баз данных через веб-интерфейс без прямого доступа к серверам кластера.
-205
View File
@@ -1,205 +0,0 @@
# О разделе
Данный раздел содержит описание технических параметров кластера PostgreSQL и порядок их первичной конфигурации.
Настройка указанных параметров выполняется администратором облачного провайдера на этапе развёртывания сервиса. Пользователь не имеет прямого доступа к их самостоятельной установке.
Перед созданием кластера клиент предоставляет перечень требуемых параметров менеджеру. Администратор облачного провайдера выполняет конфигурацию в соответствии с согласованными требованиями.
## Выбор типа и размера дискового хранилища
Производительность базы данных напрямую зависит от скорости, с которой она может читать и записывать данные на диск. При заказе кластера необходимо выбрать тип дискового хранилища, который определит максимальную скорость работы (IOPS) и время отклика.
**IOPS (Input/Output Operations Per Second)** — количество операций чтения или записи, которые диск может выполнить за секунду. Чем выше этот показатель, тем быстрее база данных обрабатывает запросы.
## Доступные типы хранилищ:
| Название | Лимит IOPS | Время отклика |
| ---------------| ------------------ | ------------- |
| **Fast SAS** | до 2 IOPS на 1 ГБ | до 10 мс |
| **SSD** | до 5 IOPS на 1 ГБ | до 7 мс |
| **Fast SSD** | до 10 IOPS на 1 ГБ | до 5 мс |
| **Ultra NVMe** | до 25 IOPS на 1 ГБ | до 3 мс |
::: warning Примечание
После выбора типа диска необходимо указать объем дискового хранилища, который будет выделен под данные кластера PostgreSQL. Минимальный объем - 50 ГБ.
:::
## Конфигурация вычислительных ресурсов
В данном разделе определяются вычислительные мощности кластера: процессорные ресурсы, оперативная память и количество серверов (нод), из которых будет состоять кластер PostgreSQL.
### Количество нод в кластере
Количество нод определяет отказоустойчивость кластера и возможность распределять запросы на чтение между репликами. Чем больше нод, тем выше надёжность и производительность операций чтения.
Количество нод выбирается в диапазоне **от 1 до 5**.
### Процессор (CPU)
Процессор — это вычислительная мощность, выделяемая каждой ноде кластера. Количество vCPU определяет, насколько быстро база данных сможет:
- обрабатывать запросы;
- выполнять сложные операции (сортировки, объединения таблиц);
- обслуживать одновременные подключения.
Доступный диапазон: **от 2 до 24 vCPU** на ноду.
### Оперативная память (RAM)
Оперативная память — один из ключевых ресурсов для производительности базы данных. Данные, помещающиеся в RAM, обрабатываются максимально быстро, без обращения к диску.
Доступный диапазон: **от 4 до 768 ГБ RAM** на ноду.
### Доступ в интернет
При заказе сервиса можно выбрать пропускную способность канала связи, через который будет осуществляться доступ к кластеру PostgreSQL из сети интернет.
**Доступные варианты скорости:**
- 50 Мбит/с;
- 100 Мбит/с;
- 200 Мбит/с;
- 300 Мбит/с;
- 400 Мбит/с;
- 500 Мбит/с;
- 1000 Мбит/с (1 Гбит/с).
::: warning Примечание
Для выбранного канала предоставляется статический белый IP-адрес.
:::
## Параметры конфигурации IPSEC
Ниже приведены основные параметры, задаваемые при развёртывании кластера PostgreSQL. Часть параметров определяется клиентом на этапе заказа услуги, часть — фиксирована и не подлежит изменению.
### Данные о конфигурации IPSEC
Параметры подключения (имя туннеля, устройство, публичный IP-адрес) заполняются вручную на основании информации, предоставленной заказчиком.
### Версия IKE (Internet Key Exchange)
Версия IKE выбирается из выпадающего списка, который содержит два значения:
- **IKE v1** — более ранняя версия протокола;
- **IKE v2** — более современная версия, обеспечивающая лучшую устойчивость соединения и более гибкую обработку ошибок.
Рекомендуется использовать IKE v2, если оборудование заказчика это поддерживает.
### Метод аутентификации
Метод аутентификации выбирается из выпадающего списка, который содержит два варианта:
- **PSK** (Pre-Shared Key) — аутентификация с использованием заранее согласованного общего ключа;
- **Certificate** (сертификат) — аутентификация с использованием цифровых сертификатов.
## Этап 1 - установка защищенного соединения
На данном этапе задаются параметры шифрования и аутентификации для защищённого канала связи. Все параметры выбираются вручную из выпадающих списков.
### Алгоритм хэширования
Определяет алгоритм хэширования для защиты управляющего канала. Параметр заполняется вручную из выпадающего списка:
- **SHA1** — формирует хэш длиной 160 бит, имеет коллизии (уязвимости), в современных системах считается устаревшим, используется только для совместимости со старым оборудованием.
- **SHA2-256** — формирует хэш длиной 256 бит, существенно более устойчив к атакам, оптимальный баланс между безопасностью и производительностью.
- **SHA2-384** — длина хэша составляет 384 бита, имеет повышенную криптостойкость, требует больше вычислительных ресурсов, чем SHA-1 и SHA2-256. Используется в средах с повышенными требованиями к безопасности.
- **SHA2-512** — длина хэша составляет 512 бит, обеспечивает самый высокий уровень стойкости из перечисленных, создает наибольшую нагрузку на процессор. Обычно применяется в системах с повышенными требованиями к криптографии.
### Шифрование (Hash)
Определяет алгоритм симметричного шифрования. Параметр заполняется вручную из выпадающего списка:
AES 128 — использует 128-битный ключ, обеспечивает быстрое шифрование, имеет достаточный уровень безопасности для большинства задач.
AES 256 — использует 256-битный ключ, обеспечивает более высокую криптостойкость, оказывает немного большую нагрузку на CPU.
AES GCM 128 / AES GCM 192 / AES GCM 256 — данные алгоритмы совмещают шифрование и контроль целостности, обладают более современным режимом работы, считаются более эффективными по производительности, рекомендуются в современных конфигурациях. Разница между алгоритмами — в длине ключа.
### DH Group (группа Диффи — Хеллмана)
Механизм Diffie-Hellman используется для безопасной генерации общего секретного ключа между сторонами туннеля без передачи этого ключа по сети. Чем выше номер группы и длина ключа, тем выше криптографическая стойкость соединения.
Параметр заполняется вручную из выпадающего списка:
group 2;
group 5;
group 14;
group 15;
group 16;
group 19;
group 20;
group 21.
### IKE Mode (только для IKEv1)
Параметр **IKE Mode** определяет способ установления соединения на этапе 1 при использовании протокола IKEv1.
Доступны два режима: Main и Aggressive. Они отличаются количеством сообщений при установке соединения и уровнем защиты идентификационных данных.
- **Main Mode** — стандартный и более безопасный режим работы IKEv1;
- **Aggressive Mode** — упрощённый и ускоренный режим установления соединения с более низким уровнем защиты данных.
### Время жизни (Lifetime)
Параметр определяет, как долго действуют согласованные ключи в рамках первой фазы. После истечения времени выполняется повторная генерация ключей.
## Этап 2 - передача данных
Этап 2 IPsec-соединения отвечает за шифрование и защиту пользовательского трафика после того, как защищённый канал был установлен на этапе 1. Этот этап регулирует передачу данных между сторонами через безопасный туннель, который обеспечивает конфиденциальность и целостность данных.
### Алгоритм хэширование (Hash)
Аналогично этапу 1, параметр Hash используется для защиты целостности передаваемых данных. Он обеспечивает проверку того, что данные не были изменены при передаче. Доступны следующие алгоритмы:
- SHA1;
- SHA2-256;
- SHA2-384;
- SHA2-512.
## Шифрование
Этап 2 отвечает за шифрование пользовательского трафика. Это важнейший параметр, который защищает данные при их передаче по сети. Доступны следующие алгоритмы:
- AES 128;
- AES 256;
- AES GCM 128;
- AES GCM 192;
- AES GCM 256.
### PFS
**Enable perfect forward secrecy (PFS)** - параметр, активирующий генерацию нового ключа на этапе 2. При включенном PFS группа Diffie-Hellman (DH) будет такая же как и на 1-й фазе.
Данный параметр представлен в виде чекбокса. При его включении:
- на этапе 2 выполняется дополнительный обмен ключами DH;
- для каждой новой IPsec-сессии формируется новый независимый криптографический секрет;
- ключи шифрования пользовательского трафика не зависят от ключей этапа 1.
### DH Group (группа Диффи — Хеллмана)
Группа DH определяет параметры обмена ключами между сторонами. Чем выше номер группы, тем выше криптографическая стойкость и безопасность обмена.
Данный параметр так же содержит в себе выпадающий список, состоящий из следующих значений:
- group 2;
- group 5;
- group 14;
- group 15;
- group 16;
- group 19;
- group 20;
- group 21.
### Время жизни (Lifetime)
Определяет, как долго действуют согласованные ключи в рамках второй фазы.
- рекомендуемое значение: 3600 секунд (1 час);
- после истечения времени выполняется повторная генерация ключей.
### Префиксы локальной сети заказчика
Этот параметр определяет, какие сети на стороне заказчика будут маршрутизироваться через **IPsec-туннель**. Префиксы задаются в формате `192.168.1.0/24`, который позволяет указать диапазон IP-адресов.
-86
View File
@@ -1,86 +0,0 @@
# Общая схема подключения
Доступ к кластеру PostgreSQL осуществляется через прокси. Клиентские подключения принимаются прокси, который маршрутизирует трафик к соответствующим узлам кластера (master или replica) в зависимости от выбранного порта. Прямое подключение к узлам базы данных не используется.
Подключение к кластеру **Cloud PostgreSQL** осуществляется через прокси-сервер. Прокси является единой точкой входа для всех клиентских подключений и принимает входящие соединения от приложений, административных инструментов и пользователей.
В зависимости от выбранного порта прокси автоматически направляет трафик:
- на активный primary-узел - для операций чтения и записи
- на реплики - для операций только чтения
Прямое подключение к отдельным узлам базы данных не используется и не предоставляется. Взаимодействие с кластером всегда выполняется через прокси-сервер.
## Подключение к базе данных
Для подключения к базе данных необходимо использовать IP-адрес прокси-сервера, который предоставляется после заказа услуги.
Этот IP-адрес является единой точкой входа для работы с кластером PostgreSQL. Все подключения к базе данных - как из приложений, так и из клиентских инструментов - выполняются через него.
Использование других IP-адресов или попытка прямого подключения к отдельным узлам кластера не предусмотрены.
## Доступные порты
Для разных типов нагрузки используются разные порты:
|Порт |Назначение |
|------|-----------------------------------------|
|5432 |Primary (чтение и запись) |
|15432 |Replica (только чтение) |
|6432 |Primary через PgBouncer (чтение и запись)|
|16432 |Replica через PgBouncer (только чтение) |
### Особенности работы портов
- Порты для чтения и записи (5432, 6432) всегда направляют трафик на активный primary-узел. При смене primary переключение происходит автоматически;
- Порты только для чтения (15432, 16432) направляют трафик на активные реплики. Если реплик несколько, нагрузка распределяется между ними по принципу round-robin;
- Если в кластере отсутствуют реплики, порты для чтения не используются - подключение по ним не устанавливается.
### Рекомендации по выбору порта
- Для OLTP-нагрузки и большого количества соединений рекомендуется использовать **порты PgBouncer (6432 или 16432)**;
- Для операций записи используйте **master-порты (5432 или 6432)**;
- Для read-only запросов можно использовать **replica-порты (15432 или 16432)**.
## Доступ к pgAdmin
Для администрирования базы данных используется web-интерфейс pgAdmin.
Доступ осуществляется по DNS-имени, которое нужно прописать локально в инфраструктуре откуда будет происходить доступ к web-интерфейсу сервиса:
`10.X.X.4 <domain>.cloud-pg.dfcloud.ru`
После добавления записи pgAdmin будет доступен по адресу:
`https://<domain>.cloud-pg.dfcloud.ru`
Авторизация выполняется с использованием учётных данных, предоставленных вместе с доступом к сервису.
::: warning Важно
- подключение к базе данных возможно только через указанный прокси-IP;
- в интерфейсе pgAdmin уже добавлен сервер базы данных, созданный для данной инсталляции. Для подключения требуется ввести пароль от учётной записи базы данных;
- pgAdmin предназначен для администрирования и не рекомендуется для выполнения тяжёлых или длительных запросов в production-среде.
:::
## Примеры подключения к PostgreSQL
Подключение к primary:
`psql -h 10.X.X.4 -p 5432 -U <username> -d <database>`
Подключение через PgBouncer:
`psql -h 10.X.X.4 -p 6432 -U <username> -d <database>`
### Подключение через DBeaver / DataGrip
При создании подключения укажите:
- Host: 10.X.X.4;
- Port: 5432 или 6432;
- Database: `<database>`;
- User / Password: согласно выданным доступам;
- Тип подключения: PostgreSQL.
### Пример строки подключения
Primary:
`postgresql://<username>:<password>@10.X.X.4:5432/<database>`
Через PgBouncer:
`postgresql://<username>:<password>@10.X.X.4:6432/<database>`
-98
View File
@@ -1,98 +0,0 @@
# Метрики
## Инструкция по подключению к Grafana.
Для того, чтобы получить доступ к метрикам кластера, предварительно необходимо запросить доступы. Когда доступы будут получены, появится возможность перейти в систему мониторинга.
Ссылка для входа - https://metrics.dfcloud.ru.
При переходе по ссылке откроется главная страница Grafana. Для того чтобы найти нужные метрики, необходимо проделать следующий путь:
1. Нажать на кнопку "Dashboards", которая располагается в левом боковом меню.
2. В открывшемся списке всех имеющихся дашбордов необходимо выбрать папку "Cloud PostgreSQL".
3. Внутри будет элемент **Cloud PostgreSQL** - это именно тот дашборд, который нам нужен.
Перейдя на дашборд Cloud PostgreSQL, открываются все метрики кластера.
В верхней части дашборда расположены все селекторы, с помощью которых можно управлять отображаемыми данными:
- **InstallationID** - выбор одного из кластеров. Если у клиента несколько кластеров PostgreSQL, он может выбирать тот кластер, по которому хочет посмотреть информацию;
- **Cluster node name** - выбор конкретной ноды кластера. Значения графиков меняются в зависимости от того, какой хост выбран. Этот селектор влияет на все графики, кроме блока Patroni;
- **Database** - выбор базы данных, по которой можно смотреть показатели метрик;
- **Lock table** - данный селектор применим не для всех графиков. С его помощью можно выбирать, какой тип блокировки использовать для отображения информации;
## Блок метрик PostgreSQL
Данный блок отображает ключевые параметры конфигурации и текущие показатели работы экземпляра PostgreSQL.
| Наименование метрики | Описание метрики |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Version** | Показывает текущую версию PostgreSQL, установленную на кластере. |
| **Current fetch data** | Объем данных, извлеченных из базы за текущий период (операции чтения). |
| **Current insert data** | Объем данных, вставленных в базу (операции записи новых данных). |
| **Current update data** | Объем данных, обновленных в базе. |
| **Seq Page Cost** | Стоимость последовательного чтения страницы данных. Влияет на выбор плана запроса: чем выше значение, тем реже оптимизатор будет выбирать последовательное сканирование таблиц. |
| **Random Page Cost** | Стоимость чтения случайной страницы данных. Низкое значение говорит о том, что в системе используются быстрые диски, и оптимизатор будет чаще выбирать доступ по индексам. |
| **Max Connections** | Максимальное количество одновременных подключений к базе данных, разрешенное на сервере. |
| **Shared Buffers** | Объем оперативной памяти, выделенный под кэш данных PostgreSQL. Здесь хранятся часто используемые данные для ускорения доступа к ним. |
| **Effective Cache** | Предполагаемый размер системного кэша файлов. Используется оптимизатором для оценки вероятности нахождения данных в кэше операционной системы. |
| **Maintenance Work Mem** | Объем памяти для выполнения операций обслуживания. |
| **Work Mem** | Объем памяти, выделяемый для внутренних сортировок и хеш-таблиц при выполнении запросов (на каждую операцию). |
| **Max WAL Size** | Максимальный размер журнала предзаписи, после достижения которого запускается процесс контрольной точки (checkpoint). |
| **Max Worker Processes** | Максимальное количество фоновых процессов, которые могут быть запущены в системе. |
| **Max Parallel Workers** | Максимальное количество параллельных процессов, которые могут быть задействованы при выполнении одного запроса. |
## Блок метрик Database Stats
Данный блок метрик отражает текущую нагрузку и состояние баз данных в кластере PostgreSQL. Эти метрики позволяют оценить, насколько эффективно работает база данных, отследить скачки нагрузки и своевременно среагировать на потенциальные проблемы до того, как они повлияют на работу приложений.
| Наименование метрики | Описание метрики |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Average CPU Usage** | Показывает время, затраченное на выполнение пользовательских и системных задач, а также, насколько интенсивно используются вычислительные ресурсы сервера базы данных. |
| **Average Memory Usage** | Средний объем оперативной памяти, используемой процессами PostgreSQL за 5-минутные интервалы. Показывает, сколько памяти потребляет база данных в процессе работы. |
| **Open File Descriptors** | Количество открытых файловых дескрипторов процессами PostgreSQL. Метрика показывает среднее (Mean), последнее (Last), максимальное (Max) и минимальное (Min) значение за интервал. |
| **Active sessions** | Показывает, сколько в данный момент выполняется запросов к PostgreSQL. Метрика показывает среднее (Mean), последнее (Last), максимальное (Max) значение. |
| **Transcations** | Количество транзакций в базах данных кластера. Метрика разделена на два типа операций: commits (успешно завершенные транзакции) и rollbacks (откаченные транзакции). |
| **Update data** | Объем данных, обновленных в базах данных кластера. Показывает, сколько данных было изменено в результате выполнения операций UPDATE. |
| **Fetch data (SELECT)** | Объем данных, извлеченных из базы с помощью запросов SELECT. Показывает, сколько данных было считано из базы в результате операций чтения. |
| **Insert data** | Объем данных, вставленных в базы данных кластера. Показывает, сколько данных было добавлено в результате выполнения операций INSERT. |
| **Lock tables** | Количество блокировок таблиц в базах данных кластера. Показывает, сколько раз таблицы были заблокированы для выполнения операций.<br>AccessShareLock - это блокировка, которая возникает, когда кто-то читает данные из таблицы (делает SELECT). Данная блокировка не мешает операциям чтения, но не дает удалить в этот момент таблицу или изменить ее структуру. |
| **Return data** | Объем данных, возвращаемых клиенту в результате выполнения запросов. Показывает, сколько данных было отправлено обратно клиенту после обработки запросов в базе. |
| **Idle sessions** | Количество бездействующих сессий подключения к базе данных. Показывает, сколько открытых подключений в данный момент не выполняют никаких запросов и просто ждут. |
| **Delete data** | Объем данных, удаленных из базы данных в результате выполнения операций DELETE. Показывает, сколько данных было удалено из таблиц. |
| **Cache Hit Rate** | Показывает процент запросов к данным, которые были удовлетворены из кэша (оперативной памяти), без обращения к диску. Показывает, насколько эффективно используется кэш PostgreSQL. |
| **Buffers (bgwriter)** | Метрика, показывающая активность фонового процесса записи, который занимается синхронизацией данных из оперативной памяти на диск. |
| **Conflicts/Deadlocks** | Метрика, отслеживающая две проблемы при работе с базой данных: конфликты восстановления и взаимоблокировки. |
| **Temp File (Bytes)** | Объем данных, записанных во временные файлы при выполнении запросов в базах данных. PostgreSQL создает временные файлы на диске, когда для выполнения запроса не хватает оперативной памяти. |
| **Checkpoint Stats** | Метрика, показывающая время, затрачиваемое на выполнение checkpoints в PostgreSQL, где: <br>- write_time - время, затраченное на запись данных на диск во время checkpoint (сколько миллисекунд ушло на запись файлов).<br>- sync_time - время, затраченное на синхронизацию файлов с диском (чтобы данные гарантированно сохранились). |
## Блок метрик Patroni
Данный блок метрик отображает состояние и конфигурацию кластера PostgreSQL под управлением Patroni. Эти метрики позволяют контролировать отказоустойчивость кластера, отслеживать переключения мастера и убеждаться, что репликация работает штатно.
| Наименование метрики | Описание метрики |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Patroni Leader** | Метрика, которая показывает, какая нода в кластере PostgreSQL в данный момент является master-сервером, принимающим запросы на запись. |
| **Patroni Replica** | Метрика, которая показывает, какие узлы кластера PostgreSQL в данный момент выполняют роль реплики. |
| **Sync Standby** | Метрика, которая показывает, какая из реплик в кластере PostgreSQL назначена синхронной. |
| **PostgreSQL WAL Replay** | Метрика, которая показывает, включена ли на узлах кластера синхронизация данных через WAL. |
| **PostgreSQL Pending Restart** | Метрика, которая показывает, требуется ли перезагрузка PostgreSQL на узлах кластера после изменения конфигурационных параметров. |
| **Patroni Primary Node** | Метрика, которая показывает, какой узел в кластере PostgreSQL в данный момент является основным и принимает запросы на запись. |
| **Patroni Secondary Nodes** | Метрика, которая показывает, какие узлы кластера PostgreSQL в определенные моменты времени выполняли роль реплик. |
| **Replicas Received WAL Location** | Метрика, показывающая объем журналов предзаписи (WAL), полученных каждой репликой кластера. |
| **Primary WAL Location** | Метрика, показывающая объем журналов предзаписи (WAL), на основном сервере кластера PostgreSQL. |
| **Replicas Replayed WAL Location** | Метрика, показывающая объем журналов предзаписи (WAL), которые были не просто получены, а уже применены на репликах кластера. |
| **WAL Replay Paused** | Метрика, которая отслеживает, не приостановлен ли процесс применения WAL-журналов на узлах кластера. Если передача или применение WAL-файлов останавливается, на графике происходит скачок. |
## Блок метрик Hosts
Блок Hosts управляется селектором **Cluster node name**. Данный блок метрик отображает состояние и ресурсы серверов, на которых развернут кластер PostgreSQL. Эти метрики позволяют оценить, хватает ли серверу ресурсов для текущей нагрузки, и своевременно обнаружить проблемы с производительностью или нехваткой места на дисках.
| Наименование метрики | Описание метрики |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **CPU Busy** | Метрика, показывающая общую загруженность всех процессорных ядер на сервере, где работает PostgreSQL. |
| **RAM Used** | Метрика, показывающая процент оперативной памяти, который занят на сервере всеми процессами. |
| **CPU Cores** | Метрика, показывающая общее количество процессорных ядер, доступных на сервере, где работает PostgreSQL. |
| **RAM Total** | Метрика, показывающая общий объем оперативной памяти, установленный на сервере. |
| **DB Disk Total** | Метрика, показывающая общий объем дискового пространства, выделенного для хранения данных базы данных PostgreSQL на сервере. |
| **CPU Basic** | Метрика, которая показывает детальную разбивку загрузки процессора по типам выполняемых задач. Она позволяет увидеть, на что именно тратится процессорное время на сервере. |
| **Memory Basic** | Метрика, которая показывает детальную разбивку использования оперативной памяти на сервере, а также информацию о SWAP. |
| **Disk IOps** | Метрика, показывающая количество операций чтения и записи, выполняемых на диске сервера в секунду. |
| **Disk Space Used Basic** | Метрика, показывающая процент занятого дискового пространства на всех подключенных файловых системах сервера. |
| **Disk R/W Data** | Показывает объем данных в байтах, читаемых с диска и записываемых на диск в секунду. |
| **Filesystem space available** | Метрика, показывающая объем свободного дискового пространства на файловой системе сервера. |
-58
View File
@@ -1,58 +0,0 @@
# PgAdmin
После предоставления доступа к сервису Cloud PostgreSQL пользователь получает возможность управлять базами данных через веб-интерфейс pgAdmin. Ниже приведена инструкция по входу в систему и выполнению основных операций.
## Вход в pgAdmin
1. Откройте веб-браузер и перейдите по адресу, предоставленному для доступа к pgAdmin;
2. На странице авторизации введите **логин и пароль от pgAdmin**;
> Учетные данные направляются пользователю на электронную почту при предоставлении доступа.
3. После входа в систему в левой панели навигации откройте раздел **Servers**;
4. Выберите предварительно настроенный сервер с названием **PostgreSQL**;
5. В открывшемся окне введите пароль;
> Важно: на данном этапе необходимо указать **пароль учетной записи базы данных**, а не пароль от pgAdmin.
6. Нажмите **ОК**;
7. После успешной аутентификации станет доступен веб-интерфейс СУБД PostgreSQL.
## Просмотр реплик и параметров конфигурации
pgAdmin позволяет осуществлять мониторинг реплик, входящих в состав кластера.
Чтобы просмотреть список реплик:
- Откройте раздел **Replica nodes** в панели навигации.
Чтобы проверить состояние репликации:
1. Выберите нужную реплику в разделе **Replica nodes**;
2. Перейдите в подраздел **Replication**;
3. Откройте пункт **Replication stats**;
4. Разверните раздел **Подробности** - в нем отображаются все параметры и текущее состояние репликации;
> Вкладка **Replication** позволяет определить, выполняется ли передача данных на дополнительные узлы кластера.
Так же, есть возможность посмотреть **параметры конфигурации PostgreSQL**, применённых к конкретной реплике. Для этого необходимо перейти в раздел **Конфигурация**, который расположен в блоке **Replica nodes**.
Во вкладке отображается таблица со следующими колонками:
- **Имя** - наименование конфигурационного параметра;
- **Категория** - логическая группа параметра;
- **Значение** - текущее установленное значение;
- **Единицы** - единицы измерения (если применимо);
- **Описание** - краткое пояснение назначения параметра.
> Вкладка **Конфигурация** предназначена для просмотра текущих настроек реплики.
## Просмотр и управление базами данных
Для просмотра существующих баз данных:
- Откройте раздел **Базы данных** в панели навигации. В этом разделе отображается перечень всех созданных баз.
Для создания новой базы данных:
1. Щелкните правой кнопкой мыши по разделу **Базы данных**;
2. В контекстном меню выберите **Создать**, затем - **База данных**;
3. Заполните обязательные поля в открывшейся форме;
4. Нажмите **Сохранить**.
## Роли входа / группы
В разделе **Роли входа/группы** отображается список пользователей (ролей), имеющих доступ к базам данных кластера.
Для создания новой роли:
1. Щелкните правой кнопкой мыши по разделу **Роли входа/группы**;
2. Выберите **Создать**, затем - **Роль входа/группы**;
3. Заполните необходимые параметры в форме создания роли;
4. Нажмите **Сохранить**.
-203
View File
@@ -1,203 +0,0 @@
# Создание сервиса Cloud PostgreSQL
Данный раздел описывает права, которые предоставляются пользователю PostgreSQL при создании сервиса **Cloud PostgreSQ**L**, а также перечень административных операций, доступных ему для самостоятельного выполнения.
При развертывании сервиса автоматически создаётся пользователь базы данных с преднастроенными атрибутами и привилегиями. Эти права позволяют заказчику самостоятельно управлять своими базами данных, ролями и пользователями в рамках созданного экземпляра PostgreSQL.
## Общая информация о пользователе
При инициализации сервиса автоматически создаётся пользователь:
```nginx
client
```
Данный пользователь является основной учётной записью для административной работы в рамках предоставленного экземпляра PostgreSQL. Он предназначен для самостоятельного управления базами данных, ролями и правами доступа в пределах выданных привилегий.
## Выданные права и ограничения
Пользователю `client` назначается набор атрибутов и привилегий, позволяющих выполнять административные операции в рамках своего экземпляра базы данных.
### Атрибуты роли
Пользователь создаётся со следующими атрибутами:
- `CREATEDB` — разрешено создание и удаление баз данных;
- `CREATEROLE` — разрешено создание ролей и пользователей, а также управление их.
Атрибут `SUPERUSER` пользователю не предоставляется. Соответственно, доступ к системным операциям уровня кластера и настройкам сервера отсутствует.
### Права на системную базу postgres:
К стандартной базе данных `postgres` пользователю предоставлено только право подключения:
- `CONNECT`
Иные привилегии (создание объектов, изменение схем и т.д.) на данную базу не выдаются.
### Мониторинг и системные представления:
Для выполнения базовых задач мониторинга пользователю дополнительно предоставлены:
- членство в роли `pg_monitor`;
- право `SELECT` на системное представление:
```sql
pg_catalog.pg_stat_replication
```
Доступ к системной информации предоставляется исключительно в режиме чтения. Изменение системных представлений и параметров сервера недоступно.
## Обязательная смена пароля
После первого подключения к базе данных пользователь `client` обязан выполнить смену пароля.
Смена пароля может быть выполнена:
- в открытом виде (с передачей нового значения пароля);
- с указанием заранее сгенерированного хэша.
На сервере используется алгоритм шифрования паролей:
```
scram-sha-256
```
При использовании SCRAM применяется следующий формат хэша:
```
$<iterations>:<salt>$<storedkey>:<serverkey>
```
### Пример смены пароля в открытом виде
```sql
ALTER USER client WITH PASSWORD 'new_strong_password';
```
### Пример смены пароля с указанием хэша
```sql
ALTER USER client WITH ENCRYPTED PASSWORD '$4096:...';
```
Рекомендуется использовать сложный уникальный пароль, соответствующий требованиям информационной безопасности, и хранить его в защищённом хранилище.
## Создание новой базы данных
Пользователь `client` имеет право создавать новые базы данных в рамках своего экземпляра PostgreSQL.
### Пример создания базы данных
Для создания базы данных используется стандартная команда:
```sql
CREATE DATABASE app_db;
```
Если необходимо назначить владельца базы данных, можно указать соответствующего пользователя. По умолчанию владельцем создаваемой базы данных является пользователь, который её создает.
### Пример создания базы данных с указанием владельца
```sql
CREATE DATABASE app_db OWNER client;
```
В этом примере база данных `app_db` будет принадлежать пользователю `client`. Пользователь, указанный как владелец, будет иметь полный контроль над базой данных, включая права на её удаление и изменение.
## Создание пользователей и ролей
Пользователь `client` имеет право создавать новые роли и пользователей для приложений, а также управлять их правами доступа.
### Создание роли без логина
Если требуется создать роль, которая не будет иметь возможности входа в базу данных (например, для организации прав доступа), можно использовать команду:
```sql
CREATE ROLE app_role;
```
### Создание пользователя с паролем
Для создания пользователя с паролем используется команда:
```sql
CREATE USER app_user WITH PASSWORD 'app_password';
```
После этого новый пользователь `app_user` будет иметь возможность входа в базу данных, используя указанный пароль.
### Назначение роли пользователю
Для назначения роли пользователю используется команда `GRANT`. Это позволяет управлять правами пользователя в рамках определённой роли:
```sql
GRANT app_role TO app_user;
```
После выполнения этой команды пользователь `app_user` станет членом роли `app_role`, и будет наследовать все права, связанные с этой ролью.
### Передача владельца базы данных
Если необходимо передать право владения базой данных другому пользователю, это можно сделать с помощью следующей команды:
```sql
ALTER DATABASE app_db OWNER TO app_user;
```
Теперь база данных `app_db` будет принадлежать пользователю `app_user`, и он будет иметь полный контроль над ней.
### Управление правами доступа
После создания пользователей и ролей необходимо назначить им соответствующие права доступа.
### Выдача прав на подключение к базе данных
Для того чтобы пользователь мог подключаться к базе данных, нужно предоставить ему соответствующие права:
```sql
GRANT CONNECT ON DATABASE app_db TO app_user;
```
Эта команда разрешает пользователю `app_user` подключаться к базе данных `app_db`.
### Права на схему public
Для предоставления пользователю прав на использование схемы `public` можно выполнить следующую команду:
```sql
GRANT USAGE, CREATE ON SCHEMA public TO app_user;
```
Эти права позволяют пользователю `app_user` использовать объекты в схеме `public`, а также создавать новые объекты внутри неё.
### Права на существующие таблицы
Чтобы предоставить пользователю доступ к существующим таблицам в схеме `public`, можно использовать команду:
```sql
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_user;
```
Эта команда позволяет пользователю `app_user` выполнять операции чтения, вставки, обновления и удаления данных в существующих таблицах схемы `public`.
### Права на будущие таблицы
Если необходимо автоматически предоставить пользователю права на новые таблицы, создаваемые в схеме `public`, используйте команду:
```sql
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;
```
Эта команда обеспечит, что все будущие таблицы, создаваемые в схеме `public`, будут автоматически иметь права для пользователя `app_user` на чтение, вставку, обновление и удаление данных.
## Мониторинг репликации
Пользователь `client` имеет доступ к системным представлениям для мониторинга состояния репликации в кластере PostgreSQL.
### Просмотр состояния репликации
Для того чтобы просмотреть текущий статус репликации, пользователь может выполнить запрос к системному представлению:
``` SQL
SELECT * FROM pg_stat_replication;
```
Этот запрос возвращает информацию о всех репликах, подключённых к основному (primary) серверу.
### Ограничения доступа
Пользователь `client` имеет доступ к данным в представлении `pg_stat_replication` только в режиме **read-only**. Это означает, что он может просматривать состояние репликации, но не может изменять или вмешиваться в процесс репликации.
@@ -7,8 +7,8 @@ section_links:
link: /compute/compute-how-to/compute-connect-inside.md
description: Подключиться к виртуальной машине по SSH с помощью ключевой пары по внутреннему IP-адресу через джамп-хост
- title: Подключение по SSH по логину и паролю
link: /compute/compute-how-to/compute-connect-inside.md
link: /compute/compute-how-to/compute-connect-pwd.md
description: Подключиться к виртуальной машине по SSH с помощью логина и пароля
---
---
# Подключение к ВМ
# Подключение к ВМ
+3 -3
View File
@@ -14,9 +14,9 @@ section_links:
description: Резервирование, назначение IP-адреса виртуальной машине, удаление IP-адресов
- title: Группы размещения
link: /compute/compute-how-to/compute-affinity.md
description: Создание правил размещения виртуальных машин на физических хостах, управление группами размещения
---
description: Создание правил размещения виртуальных машин на физических хостах, управление группами размещения
---
# Виртуальные машины
Сервис **Виртуальные машины** предоставляет пользователям виртуальные машины.
Сервис **Виртуальные машины** предоставляет пользователям виртуальные машины.