Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c853d18b49 | ||
|
|
d5f7005ddd | ||
|
|
70d6fcd32a | ||
|
|
17caaa59af | ||
|
|
2dac6ee38b | ||
|
|
8be67a2d5b | ||
|
|
9c2132882c | ||
|
|
9f25bb059b | ||
|
|
ee3094c5e5 | ||
|
|
ba9f263b75 | ||
|
|
30eaa1a8e6 | ||
|
|
6a8daedbe2 | ||
|
|
2b96ac0b44 | ||
|
|
986cd11705 | ||
|
|
b804051eaf | ||
|
|
3cc326500e | ||
|
|
f848c450a4 | ||
|
|
4121c66281 | ||
|
|
b3716fbe23 | ||
|
|
97f49d7d94 | ||
|
|
131de4b790 | ||
|
|
ce359c5a69 | ||
|
|
521e867b10 | ||
|
|
333c54ebbf | ||
|
|
58d3da95c8 | ||
|
|
4e90e752eb | ||
|
|
09342d7189 | ||
|
|
eb3e8b8c19 | ||
|
|
e2ca3ad99e | ||
|
|
dd4b0aed2b | ||
|
|
42851a061c | ||
|
|
8e0f242d30 | ||
|
|
0daa8ea39b | ||
|
|
b263d311ef | ||
|
|
8720185780 | ||
|
|
20584414d8 | ||
|
|
306a3db7f3 | ||
|
|
5b0aebada4 | ||
|
|
d6f0b480c8 | ||
|
|
f1f8531fd4 | ||
|
|
8d79d59964 | ||
|
|
551a209a50 | ||
|
|
06cafd7702 | ||
|
|
3018352443 | ||
|
|
f8edfb4a71 | ||
|
|
8239ea2356 | ||
|
|
e898335b8d | ||
|
|
e7869611fa | ||
|
|
e1c2500b60 | ||
|
|
42cf3a11df | ||
|
|
4d9293f0e9 | ||
|
|
7a13f85ae2 | ||
|
|
fc219b8602 | ||
|
|
989d73f874 | ||
|
|
f0630722ce | ||
|
|
93b0947720 | ||
|
|
9c628646fa | ||
|
|
cf476a3b95 | ||
|
|
23f9273ba3 | ||
|
|
74b88bf8ba | ||
|
|
1254d5a0de | ||
|
|
f87bece253 | ||
|
|
ba85d0ef16 | ||
|
|
17a909ea3a | ||
|
|
a4dfc220ab | ||
|
|
26426dd95e | ||
|
|
9f38b7e5c1 | ||
|
|
20057defbe | ||
|
|
b4e9140755 | ||
|
|
413959e75a | ||
|
|
8973982570 | ||
|
|
990c3ba7eb | ||
|
|
1771d2ef36 | ||
|
|
d88ab76636 | ||
|
|
c010a0aa54 | ||
|
|
0d42712d29 | ||
|
|
66b438106a | ||
|
|
3aef6682fb | ||
|
|
8535bccf4c | ||
|
|
0487b3b239 | ||
|
|
a54ef97f5d | ||
|
|
10434a9b2b | ||
|
|
c6be194508 | ||
|
|
df668286fb | ||
|
|
667c5999c9 | ||
|
|
8ad63465cd | ||
|
|
976290e6a9 | ||
|
|
79f1d1969b | ||
|
|
918e1f83b0 | ||
|
|
abbba6ade4 | ||
|
|
21d1171ba4 | ||
|
|
8f83086889 | ||
|
|
ceb18f25db | ||
|
|
ed51a89f70 | ||
|
|
f59456f22d | ||
|
|
ca63cd507d | ||
|
|
ea0d72289c | ||
|
|
e400a851f4 | ||
|
|
0fec7a9fea | ||
|
|
b9de2a92a9 | ||
|
|
5360a70853 | ||
|
|
4c2328eb13 | ||
|
|
313daef12d | ||
|
|
ad9c12e1b9 | ||
|
|
4473eb5512 | ||
|
|
6501abc060 | ||
|
|
1228403e74 | ||
|
|
4eabebd245 | ||
|
|
cf60b6818c | ||
|
|
1a4a7cdc37 | ||
|
|
1b48085e21 | ||
|
|
a71847244e | ||
|
|
848c2d2722 | ||
|
|
86832dc43f | ||
|
|
1f6da79463 | ||
|
|
9bf57c3760 | ||
|
|
a0305b5b4a | ||
|
|
1546f8e447 | ||
|
|
8ce962b312 |
@@ -16,6 +16,7 @@ env:
|
|||||||
BUILDENV_IMAGE: git.yourcmc.ru/vitalif/vitastor/buildenv
|
BUILDENV_IMAGE: git.yourcmc.ru/vitalif/vitastor/buildenv
|
||||||
TEST_IMAGE: git.yourcmc.ru/vitalif/vitastor/test
|
TEST_IMAGE: git.yourcmc.ru/vitalif/vitastor/test
|
||||||
OSD_ARGS: '--etcd_quick_timeout 2000'
|
OSD_ARGS: '--etcd_quick_timeout 2000'
|
||||||
|
USE_RAMDISK: 1
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ci-${{ github.ref }}
|
group: ci-${{ github.ref }}
|
||||||
@@ -197,6 +198,24 @@ jobs:
|
|||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
|
|
||||||
|
test_etcd_fail_antietcd:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 10
|
||||||
|
run: ANTIETCD=1 /root/vitastor/tests/test_etcd_fail.sh
|
||||||
|
- name: Print logs
|
||||||
|
if: always() && steps.test.outcome == 'failure'
|
||||||
|
run: |
|
||||||
|
for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do
|
||||||
|
echo "-------- $i --------"
|
||||||
|
cat $i
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
test_interrupted_rebalance:
|
test_interrupted_rebalance:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
@@ -539,6 +558,24 @@ jobs:
|
|||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
|
|
||||||
|
test_dd:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 3
|
||||||
|
run: /root/vitastor/tests/test_dd.sh
|
||||||
|
- name: Print logs
|
||||||
|
if: always() && steps.test.outcome == 'failure'
|
||||||
|
run: |
|
||||||
|
for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do
|
||||||
|
echo "-------- $i --------"
|
||||||
|
cat $i
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
test_root_node:
|
test_root_node:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
@@ -665,6 +702,24 @@ jobs:
|
|||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
|
|
||||||
|
test_heal_antietcd:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 10
|
||||||
|
run: ANTIETCD=1 /root/vitastor/tests/test_heal.sh
|
||||||
|
- name: Print logs
|
||||||
|
if: always() && steps.test.outcome == 'failure'
|
||||||
|
run: |
|
||||||
|
for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do
|
||||||
|
echo "-------- $i --------"
|
||||||
|
cat $i
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
test_heal_csum_32k_dmj:
|
test_heal_csum_32k_dmj:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ for my $line (<>)
|
|||||||
{
|
{
|
||||||
$test_name .= '_imm';
|
$test_name .= '_imm';
|
||||||
}
|
}
|
||||||
|
elsif ($1 eq 'ANTIETCD')
|
||||||
|
{
|
||||||
|
$test_name .= '_antietcd';
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$test_name .= '_'.lc($1).'_'.$2;
|
$test_name .= '_'.lc($1).'_'.$2;
|
||||||
|
|||||||
+1
-1
@@ -2,6 +2,6 @@ cmake_minimum_required(VERSION 2.8.12)
|
|||||||
|
|
||||||
project(vitastor)
|
project(vitastor)
|
||||||
|
|
||||||
set(VERSION "1.6.1")
|
set(VITASTOR_VERSION "1.8.0")
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|||||||
+2
-1
@@ -19,7 +19,7 @@ Vitastor нацелен в первую очередь на SSD и SSD+HDD кл
|
|||||||
TCP и RDMA и на хорошем железе может достигать задержки 4 КБ чтения и записи на уровне ~0.1 мс,
|
TCP и RDMA и на хорошем железе может достигать задержки 4 КБ чтения и записи на уровне ~0.1 мс,
|
||||||
что примерно в 10 раз быстрее, чем Ceph и другие популярные программные СХД.
|
что примерно в 10 раз быстрее, чем Ceph и другие популярные программные СХД.
|
||||||
|
|
||||||
Vitastor поддерживает QEMU-драйвер, протоколы NBD и NFS, драйверы OpenStack, Proxmox, Kubernetes.
|
Vitastor поддерживает QEMU-драйвер, протоколы NBD и NFS, драйверы OpenStack, OpenNebula, Proxmox, Kubernetes.
|
||||||
Другие драйверы могут также быть легко реализованы.
|
Другие драйверы могут также быть легко реализованы.
|
||||||
|
|
||||||
Подробности смотрите в документации по ссылкам ниже.
|
Подробности смотрите в документации по ссылкам ниже.
|
||||||
@@ -42,6 +42,7 @@ Vitastor поддерживает QEMU-драйвер, протоколы NBD и
|
|||||||
- Установка
|
- Установка
|
||||||
- [Пакеты](docs/installation/packages.ru.md)
|
- [Пакеты](docs/installation/packages.ru.md)
|
||||||
- [Proxmox](docs/installation/proxmox.ru.md)
|
- [Proxmox](docs/installation/proxmox.ru.md)
|
||||||
|
- [OpenNebula](docs/installation/opennebula.ru.md)
|
||||||
- [OpenStack](docs/installation/openstack.ru.md)
|
- [OpenStack](docs/installation/openstack.ru.md)
|
||||||
- [Kubernetes CSI](docs/installation/kubernetes.ru.md)
|
- [Kubernetes CSI](docs/installation/kubernetes.ru.md)
|
||||||
- [Сборка из исходных кодов](docs/installation/source.ru.md)
|
- [Сборка из исходных кодов](docs/installation/source.ru.md)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ supports TCP and RDMA and may achieve 4 KB read and write latency as low as ~0.1
|
|||||||
with proper hardware which is ~10 times faster than other popular SDS's like Ceph
|
with proper hardware which is ~10 times faster than other popular SDS's like Ceph
|
||||||
or internal systems of public clouds.
|
or internal systems of public clouds.
|
||||||
|
|
||||||
Vitastor supports QEMU, NBD, NFS protocols, OpenStack, Proxmox, Kubernetes drivers.
|
Vitastor supports QEMU, NBD, NFS protocols, OpenStack, OpenNebula, Proxmox, Kubernetes drivers.
|
||||||
More drivers may be created easily.
|
More drivers may be created easily.
|
||||||
|
|
||||||
Read more details below in the documentation.
|
Read more details below in the documentation.
|
||||||
@@ -42,6 +42,7 @@ Read more details below in the documentation.
|
|||||||
- Installation
|
- Installation
|
||||||
- [Packages](docs/installation/packages.en.md)
|
- [Packages](docs/installation/packages.en.md)
|
||||||
- [Proxmox](docs/installation/proxmox.en.md)
|
- [Proxmox](docs/installation/proxmox.en.md)
|
||||||
|
- [OpenNebula](docs/installation/opennebula.en.md)
|
||||||
- [OpenStack](docs/installation/openstack.en.md)
|
- [OpenStack](docs/installation/openstack.en.md)
|
||||||
- [Kubernetes CSI](docs/installation/kubernetes.en.md)
|
- [Kubernetes CSI](docs/installation/kubernetes.en.md)
|
||||||
- [Building from Source](docs/installation/source.en.md)
|
- [Building from Source](docs/installation/source.en.md)
|
||||||
|
|||||||
+1
-1
Submodule cpp-btree updated: 8de8b467ac...45e6d1f131
+3
-3
@@ -1,9 +1,9 @@
|
|||||||
VERSION ?= v1.6.1
|
VITASTOR_VERSION ?= v1.8.0
|
||||||
|
|
||||||
all: build push
|
all: build push
|
||||||
|
|
||||||
build:
|
build:
|
||||||
@docker build --rm -t vitalif/vitastor-csi:$(VERSION) .
|
@docker build --rm -t vitalif/vitastor-csi:$(VITASTOR_VERSION) .
|
||||||
|
|
||||||
push:
|
push:
|
||||||
@docker push vitalif/vitastor-csi:$(VERSION)
|
@docker push vitalif/vitastor-csi:$(VITASTOR_VERSION)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ spec:
|
|||||||
capabilities:
|
capabilities:
|
||||||
add: ["SYS_ADMIN"]
|
add: ["SYS_ADMIN"]
|
||||||
allowPrivilegeEscalation: true
|
allowPrivilegeEscalation: true
|
||||||
image: vitalif/vitastor-csi:v1.6.1
|
image: vitalif/vitastor-csi:v1.8.0
|
||||||
args:
|
args:
|
||||||
- "--node=$(NODE_ID)"
|
- "--node=$(NODE_ID)"
|
||||||
- "--endpoint=$(CSI_ENDPOINT)"
|
- "--endpoint=$(CSI_ENDPOINT)"
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ spec:
|
|||||||
privileged: true
|
privileged: true
|
||||||
capabilities:
|
capabilities:
|
||||||
add: ["SYS_ADMIN"]
|
add: ["SYS_ADMIN"]
|
||||||
image: vitalif/vitastor-csi:v1.6.1
|
image: vitalif/vitastor-csi:v1.8.0
|
||||||
args:
|
args:
|
||||||
- "--node=$(NODE_ID)"
|
- "--node=$(NODE_ID)"
|
||||||
- "--endpoint=$(CSI_ENDPOINT)"
|
- "--endpoint=$(CSI_ENDPOINT)"
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ package vitastor
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
vitastorCSIDriverName = "csi.vitastor.io"
|
vitastorCSIDriverName = "csi.vitastor.io"
|
||||||
vitastorCSIDriverVersion = "1.6.1"
|
vitastorCSIDriverVersion = "1.8.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config struct fills the parameters of request or user input
|
// Config struct fills the parameters of request or user input
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
vitastor (1.6.1-1) unstable; urgency=medium
|
vitastor (1.8.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Bugfixes
|
* Bugfixes
|
||||||
|
|
||||||
|
|||||||
Vendored
+6
@@ -53,3 +53,9 @@ Architecture: amd64
|
|||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, vitastor-client (= ${binary:Version})
|
Depends: ${shlibs:Depends}, ${misc:Depends}, vitastor-client (= ${binary:Version})
|
||||||
Description: Vitastor Proxmox Virtual Environment storage plugin
|
Description: Vitastor Proxmox Virtual Environment storage plugin
|
||||||
Vitastor storage plugin for Proxmox Virtual Environment.
|
Vitastor storage plugin for Proxmox Virtual Environment.
|
||||||
|
|
||||||
|
Package: vitastor-opennebula
|
||||||
|
Architecture: amd64
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends}, vitastor-client, patch, python3, jq
|
||||||
|
Description: Vitastor OpenNebula storage plugin
|
||||||
|
Vitastor storage plugin for OpenNebula.
|
||||||
|
|||||||
Vendored
+3
-2
@@ -1,2 +1,3 @@
|
|||||||
mon usr/lib/vitastor
|
mon usr/lib/vitastor/
|
||||||
mon/vitastor-mon.service /lib/systemd/system
|
mon/scripts/make-etcd usr/lib/vitastor/mon
|
||||||
|
mon/scripts/vitastor-mon.service /lib/systemd/system
|
||||||
|
|||||||
Vendored
+2
@@ -6,4 +6,6 @@ if [ "$1" = "configure" ]; then
|
|||||||
addgroup --system --quiet vitastor
|
addgroup --system --quiet vitastor
|
||||||
adduser --system --quiet --ingroup vitastor --no-create-home --home /nonexistent vitastor
|
adduser --system --quiet --ingroup vitastor --no-create-home --home /nonexistent vitastor
|
||||||
mkdir -p /etc/vitastor
|
mkdir -p /etc/vitastor
|
||||||
|
mkdir -p /var/lib/vitastor
|
||||||
|
chown vitastor:vitastor /var/lib/vitastor
|
||||||
fi
|
fi
|
||||||
|
|||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
opennebula/remotes var/lib/one/
|
||||||
|
opennebula/sudoers.d etc/
|
||||||
|
opennebula/install.sh var/lib/one/remotes/datastore/vitastor/
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$1" = "configure" ]; then
|
||||||
|
/var/lib/one/remotes/datastore/vitastor/install.sh
|
||||||
|
fi
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
interest /var/lib/one/remotes/datastore/downloader.sh
|
||||||
|
interest /etc/one/oned.conf
|
||||||
|
interest /etc/one/vmm_exec/vmm_execrc
|
||||||
|
interest /etc/apparmor.d/local/abstractions/libvirt-qemu
|
||||||
Vendored
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
usr/bin/vitastor-osd
|
usr/bin/vitastor-osd
|
||||||
usr/bin/vitastor-disk
|
usr/bin/vitastor-disk
|
||||||
usr/bin/vitastor-dump-journal
|
usr/bin/vitastor-dump-journal
|
||||||
mon/vitastor-osd@.service /lib/systemd/system
|
mon/scripts/vitastor-osd@.service /lib/systemd/system
|
||||||
mon/vitastor.target /lib/systemd/system
|
mon/scripts/vitastor.target /lib/systemd/system
|
||||||
mon/90-vitastor.rules /lib/udev/rules.d
|
mon/scripts/90-vitastor.rules /lib/udev/rules.d
|
||||||
|
|||||||
Vendored
+19
-14
@@ -9,12 +9,12 @@ ARG REL=
|
|||||||
|
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|
||||||
RUN if [ "$REL" = "buster" -o "$REL" = "bullseye" ]; then \
|
RUN set -e -x; \
|
||||||
echo "deb http://deb.debian.org/debian $REL-backports main" >> /etc/apt/sources.list; \
|
if [ "$REL" = "buster" ]; then \
|
||||||
echo >> /etc/apt/preferences; \
|
apt-get update; \
|
||||||
echo 'Package: *' >> /etc/apt/preferences; \
|
apt-get -y install wget; \
|
||||||
echo "Pin: release a=$REL-backports" >> /etc/apt/preferences; \
|
wget https://vitastor.io/debian/pubkey.gpg -O /etc/apt/trusted.gpg.d/vitastor.gpg; \
|
||||||
echo 'Pin-Priority: 500' >> /etc/apt/preferences; \
|
echo "deb https://vitastor.io/debian $REL main" >> /etc/apt/sources.list; \
|
||||||
fi; \
|
fi; \
|
||||||
grep '^deb ' /etc/apt/sources.list | perl -pe 's/^deb/deb-src/' >> /etc/apt/sources.list; \
|
grep '^deb ' /etc/apt/sources.list | perl -pe 's/^deb/deb-src/' >> /etc/apt/sources.list; \
|
||||||
perl -i -pe 's/Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/debian.sources || true; \
|
perl -i -pe 's/Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/debian.sources || true; \
|
||||||
@@ -22,10 +22,9 @@ RUN if [ "$REL" = "buster" -o "$REL" = "bullseye" ]; then \
|
|||||||
echo 'APT::Install-Suggests false;' >> /etc/apt/apt.conf
|
echo 'APT::Install-Suggests false;' >> /etc/apt/apt.conf
|
||||||
|
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN apt-get -y install fio liburing-dev libgoogle-perftools-dev devscripts
|
RUN apt-get -y install fio liburing-dev libgoogle-perftools-dev devscripts libjerasure-dev cmake libibverbs-dev libisal-dev libnl-3-dev libnl-genl-3-dev curl
|
||||||
RUN apt-get -y build-dep fio
|
RUN apt-get -y build-dep fio
|
||||||
RUN apt-get --download-only source fio
|
RUN apt-get --download-only source fio
|
||||||
RUN apt-get update && apt-get -y install libjerasure-dev cmake libibverbs-dev libisal-dev libnl-3-dev libnl-genl-3-dev
|
|
||||||
|
|
||||||
ADD . /root/vitastor
|
ADD . /root/vitastor
|
||||||
RUN set -e -x; \
|
RUN set -e -x; \
|
||||||
@@ -37,8 +36,10 @@ RUN set -e -x; \
|
|||||||
mkdir -p /root/packages/vitastor-$REL; \
|
mkdir -p /root/packages/vitastor-$REL; \
|
||||||
rm -rf /root/packages/vitastor-$REL/*; \
|
rm -rf /root/packages/vitastor-$REL/*; \
|
||||||
cd /root/packages/vitastor-$REL; \
|
cd /root/packages/vitastor-$REL; \
|
||||||
cp -r /root/vitastor vitastor-1.6.1; \
|
FULLVER=$(head -n1 /root/vitastor/debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \
|
||||||
cd vitastor-1.6.1; \
|
VER=${FULLVER%%-*}; \
|
||||||
|
cp -r /root/vitastor vitastor-$VER; \
|
||||||
|
cd vitastor-$VER; \
|
||||||
ln -s /root/fio-build/fio-*/ ./fio; \
|
ln -s /root/fio-build/fio-*/ ./fio; \
|
||||||
FIO=$(head -n1 fio/debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \
|
FIO=$(head -n1 fio/debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \
|
||||||
ls /usr/include/linux/raw.h || cp ./debian/raw.h /usr/include/linux/raw.h; \
|
ls /usr/include/linux/raw.h || cp ./debian/raw.h /usr/include/linux/raw.h; \
|
||||||
@@ -50,10 +51,14 @@ RUN set -e -x; \
|
|||||||
echo fio-headers.patch >> debian/patches/series; \
|
echo fio-headers.patch >> debian/patches/series; \
|
||||||
rm -rf a b; \
|
rm -rf a b; \
|
||||||
echo "dep:fio=$FIO" > debian/fio_version; \
|
echo "dep:fio=$FIO" > debian/fio_version; \
|
||||||
|
cd /root/packages/vitastor-$REL/vitastor-$VER; \
|
||||||
|
mkdir mon/node_modules; \
|
||||||
|
cd mon/node_modules; \
|
||||||
|
curl -s https://git.yourcmc.ru/vitalif/antietcd/archive/master.tar.gz | tar -zx; \
|
||||||
|
curl -s https://git.yourcmc.ru/vitalif/tinyraft/archive/master.tar.gz | tar -zx; \
|
||||||
cd /root/packages/vitastor-$REL; \
|
cd /root/packages/vitastor-$REL; \
|
||||||
tar --sort=name --mtime='2020-01-01' --owner=0 --group=0 --exclude=debian -cJf vitastor_1.6.1.orig.tar.xz vitastor-1.6.1; \
|
tar --sort=name --mtime='2020-01-01' --owner=0 --group=0 --exclude=debian -cJf vitastor_$VER.orig.tar.xz vitastor-$VER; \
|
||||||
cd vitastor-1.6.1; \
|
cd vitastor-$VER; \
|
||||||
V=$(head -n1 debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \
|
DEBFULLNAME="Vitaliy Filippov <vitalif@yourcmc.ru>" dch -D $REL -v "$FULLVER""$REL" "Rebuild for $REL"; \
|
||||||
DEBFULLNAME="Vitaliy Filippov <vitalif@yourcmc.ru>" dch -D $REL -v "$V""$REL" "Rebuild for $REL"; \
|
|
||||||
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage --jobs=auto -sa; \
|
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage --jobs=auto -sa; \
|
||||||
rm -rf /root/packages/vitastor-$REL/vitastor-*/
|
rm -rf /root/packages/vitastor-$REL/vitastor-*/
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
These parameters apply only to Vitastor clients (QEMU, fio, NBD and so on) and
|
These parameters apply only to Vitastor clients (QEMU, fio, NBD and so on) and
|
||||||
affect their interaction with the cluster.
|
affect their interaction with the cluster.
|
||||||
|
|
||||||
|
- [client_iothread_count](#client_iothread_count)
|
||||||
- [client_retry_interval](#client_retry_interval)
|
- [client_retry_interval](#client_retry_interval)
|
||||||
- [client_eio_retry_interval](#client_eio_retry_interval)
|
- [client_eio_retry_interval](#client_eio_retry_interval)
|
||||||
- [client_retry_enospc](#client_retry_enospc)
|
- [client_retry_enospc](#client_retry_enospc)
|
||||||
@@ -23,6 +24,23 @@ affect their interaction with the cluster.
|
|||||||
- [nbd_max_part](#nbd_max_part)
|
- [nbd_max_part](#nbd_max_part)
|
||||||
- [osd_nearfull_ratio](#osd_nearfull_ratio)
|
- [osd_nearfull_ratio](#osd_nearfull_ratio)
|
||||||
|
|
||||||
|
## client_iothread_count
|
||||||
|
|
||||||
|
- Type: integer
|
||||||
|
- Default: 0
|
||||||
|
|
||||||
|
Number of separate threads for handling TCP network I/O at client library
|
||||||
|
side. Enabling 4 threads usually allows to increase peak performance of each
|
||||||
|
client from approx. 2-3 to 7-8 GByte/s linear read/write and from approx.
|
||||||
|
100-150 to 400 thousand iops, but at the same time it increases latency.
|
||||||
|
Latency increase depends on CPU: with CPU power saving disabled latency
|
||||||
|
only increases by ~10 us (equivalent to Q=1 iops decrease from 10500 to 9500),
|
||||||
|
with CPU power saving enabled it may be as high as 500 us (equivalent to Q=1
|
||||||
|
iops decrease from 2000 to 1000). RDMA isn't affected by this option.
|
||||||
|
|
||||||
|
It's recommended to enable client I/O threads if you don't use RDMA and want
|
||||||
|
to increase peak client performance.
|
||||||
|
|
||||||
## client_retry_interval
|
## client_retry_interval
|
||||||
|
|
||||||
- Type: milliseconds
|
- Type: milliseconds
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
Данные параметры применяются только к клиентам Vitastor (QEMU, fio, NBD и т.п.) и
|
Данные параметры применяются только к клиентам Vitastor (QEMU, fio, NBD и т.п.) и
|
||||||
затрагивают логику их работы с кластером.
|
затрагивают логику их работы с кластером.
|
||||||
|
|
||||||
|
- [client_iothread_count](#client_iothread_count)
|
||||||
- [client_retry_interval](#client_retry_interval)
|
- [client_retry_interval](#client_retry_interval)
|
||||||
- [client_eio_retry_interval](#client_eio_retry_interval)
|
- [client_eio_retry_interval](#client_eio_retry_interval)
|
||||||
- [client_retry_enospc](#client_retry_enospc)
|
- [client_retry_enospc](#client_retry_enospc)
|
||||||
@@ -23,6 +24,24 @@
|
|||||||
- [nbd_max_part](#nbd_max_part)
|
- [nbd_max_part](#nbd_max_part)
|
||||||
- [osd_nearfull_ratio](#osd_nearfull_ratio)
|
- [osd_nearfull_ratio](#osd_nearfull_ratio)
|
||||||
|
|
||||||
|
## client_iothread_count
|
||||||
|
|
||||||
|
- Тип: целое число
|
||||||
|
- Значение по умолчанию: 0
|
||||||
|
|
||||||
|
Число отдельных потоков для обработки ввода-вывода через TCP сеть на стороне
|
||||||
|
клиентской библиотеки. Включение 4 потоков обычно позволяет поднять пиковую
|
||||||
|
производительность каждого клиента примерно с 2-3 до 7-8 Гбайт/с линейного
|
||||||
|
чтения/записи и примерно с 100-150 до 400 тысяч операций ввода-вывода в
|
||||||
|
секунду, но ухудшает задержку. Увеличение задержки зависит от процессора:
|
||||||
|
при отключённом энергосбережении CPU это всего ~10 микросекунд (равносильно
|
||||||
|
падению iops с Q=1 с 10500 до 9500), а при включённом это может быть
|
||||||
|
и 500 микросекунд (равносильно падению iops с Q=1 с 2000 до 1000). На работу
|
||||||
|
RDMA данная опция не влияет.
|
||||||
|
|
||||||
|
Рекомендуется включать клиентские потоки ввода-вывода, если вы не используете
|
||||||
|
RDMA и хотите повысить пиковую производительность клиентов.
|
||||||
|
|
||||||
## client_retry_interval
|
## client_retry_interval
|
||||||
|
|
||||||
- Тип: миллисекунды
|
- Тип: миллисекунды
|
||||||
|
|||||||
@@ -56,14 +56,24 @@ Can't be smaller than the OSD data device sector.
|
|||||||
## immediate_commit
|
## immediate_commit
|
||||||
|
|
||||||
- Type: string
|
- Type: string
|
||||||
- Default: false
|
- Default: all
|
||||||
|
|
||||||
Another parameter which is really important for performance.
|
One of "none", "all" or "small". Global value, may be overriden [at pool level](pool.en.md#immediate_commit).
|
||||||
|
|
||||||
|
This parameter is also really important for performance.
|
||||||
|
|
||||||
|
TLDR: default "all" is optimal for server-grade SSDs with supercapacitor-based
|
||||||
|
power loss protection (nonvolatile write-through cache) and also for most HDDs.
|
||||||
|
"none" or "small" should be only selected if you use desktop SSDs without
|
||||||
|
capacitors or drives with slow write-back cache that can't be disabled. Check
|
||||||
|
immediate_commit of your OSDs in [ls-osd](../usage/cli.en.md#ls-osd).
|
||||||
|
|
||||||
|
Detailed explanation:
|
||||||
|
|
||||||
Desktop SSDs are very fast (100000+ iops) for simple random writes
|
Desktop SSDs are very fast (100000+ iops) for simple random writes
|
||||||
without cache flush. However, they are really slow (only around 1000 iops)
|
without cache flush. However, they are really slow (only around 1000 iops)
|
||||||
if you try to fsync() each write, that is, when you want to guarantee that
|
if you try to fsync() each write, that is, if you want to guarantee that
|
||||||
each change gets immediately persisted to the physical media.
|
each change gets actually persisted to the physical media.
|
||||||
|
|
||||||
Server-grade SSDs with "Advanced/Enhanced Power Loss Protection" or with
|
Server-grade SSDs with "Advanced/Enhanced Power Loss Protection" or with
|
||||||
"Supercapacitor-based Power Loss Protection", on the other hand, are equally
|
"Supercapacitor-based Power Loss Protection", on the other hand, are equally
|
||||||
@@ -75,8 +85,8 @@ really slow when used with desktop SSDs. Vitastor, however, can also
|
|||||||
efficiently utilize desktop SSDs by postponing fsync until the client calls
|
efficiently utilize desktop SSDs by postponing fsync until the client calls
|
||||||
it explicitly.
|
it explicitly.
|
||||||
|
|
||||||
This is what this parameter regulates. When it's set to "all" the whole
|
This is what this parameter regulates. When it's set to "all" Vitastor
|
||||||
Vitastor cluster commits each change to disks immediately and clients just
|
cluster commits each change to disks immediately and clients just
|
||||||
ignore fsyncs because they know for sure that they're unneeded. This reduces
|
ignore fsyncs because they know for sure that they're unneeded. This reduces
|
||||||
the amount of network roundtrips performed by clients and improves
|
the amount of network roundtrips performed by clients and improves
|
||||||
performance. So it's always better to use server grade SSDs with
|
performance. So it's always better to use server grade SSDs with
|
||||||
@@ -99,9 +109,5 @@ Setting this parameter to "all" or "small" in OSD parameters requires enabling
|
|||||||
[disable_journal_fsync](layout-osd.en.yml#disable_journal_fsync) and
|
[disable_journal_fsync](layout-osd.en.yml#disable_journal_fsync) and
|
||||||
[disable_meta_fsync](layout-osd.en.yml#disable_meta_fsync), setting it to
|
[disable_meta_fsync](layout-osd.en.yml#disable_meta_fsync), setting it to
|
||||||
"all" also requires enabling [disable_data_fsync](layout-osd.en.yml#disable_data_fsync).
|
"all" also requires enabling [disable_data_fsync](layout-osd.en.yml#disable_data_fsync).
|
||||||
|
vitastor-disk tried to do that by default, first checking/disabling drive cache.
|
||||||
TLDR: For optimal performance, set immediate_commit to "all" if you only use
|
If it can't disable drive cache, OSD get initialized with "none".
|
||||||
SSDs with supercapacitor-based power loss protection (nonvolatile
|
|
||||||
write-through cache) for both data and journals in the whole Vitastor
|
|
||||||
cluster. Set it to "small" if you only use such SSDs for journals. Leave
|
|
||||||
empty if your drives have write-back cache.
|
|
||||||
|
|||||||
@@ -57,9 +57,18 @@ amplification) и эффективность распределения нагр
|
|||||||
## immediate_commit
|
## immediate_commit
|
||||||
|
|
||||||
- Тип: строка
|
- Тип: строка
|
||||||
- Значение по умолчанию: false
|
- Значение по умолчанию: all
|
||||||
|
|
||||||
Ещё один важный для производительности параметр.
|
Одно из значений "none", "small" или "all". Глобальное значение, может быть
|
||||||
|
переопределено [на уровне пула](pool.ru.md#immediate_commit).
|
||||||
|
|
||||||
|
Данный параметр тоже важен для производительности.
|
||||||
|
|
||||||
|
Вкратце: значение по умолчанию "all" оптимально для всех серверных SSD с
|
||||||
|
суперконденсаторами и также для большинства HDD. "none" и "small" имеет смысл
|
||||||
|
устанавливать только при использовании SSD настольного класса без
|
||||||
|
суперконденсаторов или дисков с медленным неотключаемым кэшем записи.
|
||||||
|
Проверьте настройку immediate_commit своих OSD в выводе команды [ls-osd](../usage/cli.ru.md#ls-osd).
|
||||||
|
|
||||||
Модели SSD для настольных компьютеров очень быстрые (100000+ операций в
|
Модели SSD для настольных компьютеров очень быстрые (100000+ операций в
|
||||||
секунду) при простой случайной записи без сбросов кэша. Однако они очень
|
секунду) при простой случайной записи без сбросов кэша. Однако они очень
|
||||||
@@ -80,7 +89,7 @@ Power Loss Protection" - одинаково быстрые и со сбросо
|
|||||||
эффективно утилизировать настольные SSD.
|
эффективно утилизировать настольные SSD.
|
||||||
|
|
||||||
Данный параметр влияет как раз на это. Когда он установлен в значение "all",
|
Данный параметр влияет как раз на это. Когда он установлен в значение "all",
|
||||||
весь кластер Vitastor мгновенно фиксирует каждое изменение на физические
|
кластер Vitastor мгновенно фиксирует каждое изменение на физические
|
||||||
носители и клиенты могут просто игнорировать запросы fsync, т.к. они точно
|
носители и клиенты могут просто игнорировать запросы fsync, т.к. они точно
|
||||||
знают, что fsync-и не нужны. Это уменьшает число необходимых обращений к OSD
|
знают, что fsync-и не нужны. Это уменьшает число необходимых обращений к OSD
|
||||||
по сети и улучшает производительность. Поэтому даже с Vitastor лучше всегда
|
по сети и улучшает производительность. Поэтому даже с Vitastor лучше всегда
|
||||||
@@ -106,10 +115,3 @@ HDD-дисках с внутренним SSD или "медиа" кэшем - н
|
|||||||
включения [disable_journal_fsync](layout-osd.ru.yml#disable_journal_fsync) и
|
включения [disable_journal_fsync](layout-osd.ru.yml#disable_journal_fsync) и
|
||||||
[disable_meta_fsync](layout-osd.ru.yml#disable_meta_fsync), значение "all"
|
[disable_meta_fsync](layout-osd.ru.yml#disable_meta_fsync), значение "all"
|
||||||
также требует включения [disable_data_fsync](layout-osd.ru.yml#disable_data_fsync).
|
также требует включения [disable_data_fsync](layout-osd.ru.yml#disable_data_fsync).
|
||||||
|
|
||||||
Итого, вкратце: для оптимальной производительности установите
|
|
||||||
immediate_commit в значение "all", если вы используете в кластере только SSD
|
|
||||||
с суперконденсаторами и для данных, и для журналов. Если вы используете
|
|
||||||
такие SSD для всех журналов, но не для данных - можете установить параметр
|
|
||||||
в "small". Если и какие-то из дисков журналов имеют волатильный кэш записи -
|
|
||||||
оставьте параметр пустым.
|
|
||||||
|
|||||||
@@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
These parameters only apply to Monitors.
|
These parameters only apply to Monitors.
|
||||||
|
|
||||||
|
- [use_antietcd](#use_antietcd)
|
||||||
|
- [enable_prometheus](#enable_prometheus)
|
||||||
|
- [mon_http_port](#mon_http_port)
|
||||||
|
- [mon_http_ip](#mon_http_ip)
|
||||||
|
- [mon_https_cert](#mon_https_cert)
|
||||||
|
- [mon_https_key](#mon_https_key)
|
||||||
|
- [mon_https_client_auth](#mon_https_client_auth)
|
||||||
|
- [mon_https_ca](#mon_https_ca)
|
||||||
- [etcd_mon_ttl](#etcd_mon_ttl)
|
- [etcd_mon_ttl](#etcd_mon_ttl)
|
||||||
- [etcd_mon_timeout](#etcd_mon_timeout)
|
- [etcd_mon_timeout](#etcd_mon_timeout)
|
||||||
- [etcd_mon_retries](#etcd_mon_retries)
|
- [etcd_mon_retries](#etcd_mon_retries)
|
||||||
@@ -17,6 +25,87 @@ These parameters only apply to Monitors.
|
|||||||
- [placement_levels](#placement_levels)
|
- [placement_levels](#placement_levels)
|
||||||
- [use_old_pg_combinator](#use_old_pg_combinator)
|
- [use_old_pg_combinator](#use_old_pg_combinator)
|
||||||
|
|
||||||
|
## use_antietcd
|
||||||
|
|
||||||
|
- Type: boolean
|
||||||
|
- Default: false
|
||||||
|
|
||||||
|
Enable experimental built-in etcd replacement (clustered key-value database):
|
||||||
|
[antietcd](https://git.yourcmc.ru/vitalif/antietcd/).
|
||||||
|
|
||||||
|
When set to true, monitor runs internal antietcd automatically if it finds
|
||||||
|
a network interface with an IP address matching one of addresses in the
|
||||||
|
`etcd_address` configuration option (in `/etc/vitastor/vitastor.conf` or in
|
||||||
|
the monitor command line). If there are multiple matching addresses, it also
|
||||||
|
checks `antietcd_port` and antietcd is started for address with matching port.
|
||||||
|
By default, antietcd accepts connection on the selected IP address, but it
|
||||||
|
can also be overridden manually in the `antietcd_ip` option.
|
||||||
|
|
||||||
|
When antietcd is started, monitor stores cluster metadata itself and exposes
|
||||||
|
a etcd-compatible REST API. On disk, these metadata are stored in
|
||||||
|
`/var/lib/vitastor/mon_2379.json.gz` (can be overridden in antietcd_data_file
|
||||||
|
or antietcd_data_dir options). All other antietcd parameters
|
||||||
|
(see [here](https://git.yourcmc.ru/vitalif/antietcd/)) except node_id,
|
||||||
|
cluster, cluster_key, persist_filter, stale_read can also be set in
|
||||||
|
Vitastor configuration with `antietcd_` prefix.
|
||||||
|
|
||||||
|
You can dump/load data to or from antietcd using Antietcd `anticli` tool:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm exec anticli -e http://etcd:2379/v3 get --prefix '' --no-temp > dump.json
|
||||||
|
npm exec anticli -e http://antietcd:2379/v3 load < dump.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## enable_prometheus
|
||||||
|
|
||||||
|
- Type: boolean
|
||||||
|
- Default: true
|
||||||
|
|
||||||
|
Enable built-in Prometheus metrics exporter at mon_http_port (8060 by default).
|
||||||
|
|
||||||
|
Note that only the active (master) monitor exposes metrics, others return
|
||||||
|
HTTP 503. So you should add all monitor URLs to your Prometheus job configuration.
|
||||||
|
|
||||||
|
Grafana dashboard suitable for this exporter is here: [Vitastor-Grafana-6+.json](../../mon/scripts/Vitastor-Grafana-6+.json).
|
||||||
|
|
||||||
|
## mon_http_port
|
||||||
|
|
||||||
|
- Type: integer
|
||||||
|
- Default: 8060
|
||||||
|
|
||||||
|
HTTP port for monitors to listen on (including metrics exporter)
|
||||||
|
|
||||||
|
## mon_http_ip
|
||||||
|
|
||||||
|
- Type: string
|
||||||
|
|
||||||
|
IP address for monitors to listen on (all addresses by default)
|
||||||
|
|
||||||
|
## mon_https_cert
|
||||||
|
|
||||||
|
- Type: string
|
||||||
|
|
||||||
|
Path to PEM SSL certificate file for monitor to listen using HTTPS
|
||||||
|
|
||||||
|
## mon_https_key
|
||||||
|
|
||||||
|
- Type: string
|
||||||
|
|
||||||
|
Path to PEM SSL private key file for monitor to listen using HTTPS
|
||||||
|
|
||||||
|
## mon_https_client_auth
|
||||||
|
|
||||||
|
- Type: boolean
|
||||||
|
- Default: false
|
||||||
|
|
||||||
|
Enable HTTPS client certificate-based authorization for monitor connections
|
||||||
|
|
||||||
|
## mon_https_ca
|
||||||
|
|
||||||
|
- Type: string
|
||||||
|
|
||||||
|
Path to CA certificate for client HTTPS authorization
|
||||||
|
|
||||||
## etcd_mon_ttl
|
## etcd_mon_ttl
|
||||||
|
|
||||||
- Type: seconds
|
- Type: seconds
|
||||||
|
|||||||
@@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
Данные параметры используются только мониторами Vitastor.
|
Данные параметры используются только мониторами Vitastor.
|
||||||
|
|
||||||
|
- [use_antietcd](#use_antietcd)
|
||||||
|
- [enable_prometheus](#enable_prometheus)
|
||||||
|
- [mon_http_port](#mon_http_port)
|
||||||
|
- [mon_http_ip](#mon_http_ip)
|
||||||
|
- [mon_https_cert](#mon_https_cert)
|
||||||
|
- [mon_https_key](#mon_https_key)
|
||||||
|
- [mon_https_client_auth](#mon_https_client_auth)
|
||||||
|
- [mon_https_ca](#mon_https_ca)
|
||||||
- [etcd_mon_ttl](#etcd_mon_ttl)
|
- [etcd_mon_ttl](#etcd_mon_ttl)
|
||||||
- [etcd_mon_timeout](#etcd_mon_timeout)
|
- [etcd_mon_timeout](#etcd_mon_timeout)
|
||||||
- [etcd_mon_retries](#etcd_mon_retries)
|
- [etcd_mon_retries](#etcd_mon_retries)
|
||||||
@@ -17,6 +25,89 @@
|
|||||||
- [placement_levels](#placement_levels)
|
- [placement_levels](#placement_levels)
|
||||||
- [use_old_pg_combinator](#use_old_pg_combinator)
|
- [use_old_pg_combinator](#use_old_pg_combinator)
|
||||||
|
|
||||||
|
## use_antietcd
|
||||||
|
|
||||||
|
- Тип: булево (да/нет)
|
||||||
|
- Значение по умолчанию: false
|
||||||
|
|
||||||
|
Включить экспериментальный встроенный заменитель etcd (кластерную БД ключ-значение):
|
||||||
|
[antietcd](https://git.yourcmc.ru/vitalif/antietcd/).
|
||||||
|
|
||||||
|
Если параметр установлен в true, монитор запускает antietcd автоматически,
|
||||||
|
если обнаруживает сетевой интерфейс с одним из адресов, указанных в опции
|
||||||
|
конфигурации `etcd_address` (в `/etc/vitastor/vitastor.conf` или в опциях
|
||||||
|
командной строки монитора). Если таких адресов несколько, также проверяется
|
||||||
|
опция `antietcd_port` и antietcd запускается для адреса с соответствующим
|
||||||
|
портом. По умолчанию antietcd принимает подключения по выбранному совпадающему
|
||||||
|
IP, но его также можно определить вручную опцией `antietcd_ip`.
|
||||||
|
|
||||||
|
При запуске antietcd монитор сам хранит центральные метаданные кластера и
|
||||||
|
выставляет etcd-совместимое REST API. На диске эти метаданные хранятся в файле
|
||||||
|
`/var/lib/vitastor/mon_2379.json.gz` (можно переопределить параметрами
|
||||||
|
antietcd_data_file или antietcd_data_dir). Все остальные параметры antietcd
|
||||||
|
(смотрите [по ссылке](https://git.yourcmc.ru/vitalif/antietcd/)), за исключением
|
||||||
|
node_id, cluster, cluster_key, persist_filter, stale_read также можно задавать
|
||||||
|
в конфигурации Vitastor с префиксом `antietcd_`.
|
||||||
|
|
||||||
|
Вы можете выгружать/загружать данные в или из antietcd с помощью его инструмента
|
||||||
|
`anticli`:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm exec anticli -e http://etcd:2379/v3 get --prefix '' --no-temp > dump.json
|
||||||
|
npm exec anticli -e http://antietcd:2379/v3 load < dump.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## enable_prometheus
|
||||||
|
|
||||||
|
- Тип: булево (да/нет)
|
||||||
|
- Значение по умолчанию: true
|
||||||
|
|
||||||
|
Включить встроенный Prometheus-экспортер метрик на порту mon_http_port (по умолчанию 8060).
|
||||||
|
|
||||||
|
Обратите внимание, что метрики выставляет только активный (главный) монитор, остальные
|
||||||
|
возвращают статус HTTP 503, поэтому вам следует добавлять адреса всех мониторов
|
||||||
|
в задание по сбору метрик Prometheus.
|
||||||
|
|
||||||
|
Дашборд для Grafana, подходящий для этого экспортера: [Vitastor-Grafana-6+.json](../../mon/scripts/Vitastor-Grafana-6+.json).
|
||||||
|
|
||||||
|
## mon_http_port
|
||||||
|
|
||||||
|
- Тип: целое число
|
||||||
|
- Значение по умолчанию: 8060
|
||||||
|
|
||||||
|
Порт, на котором мониторы принимают HTTP-соединения (в том числе для отдачи метрик)
|
||||||
|
|
||||||
|
## mon_http_ip
|
||||||
|
|
||||||
|
- Тип: строка
|
||||||
|
|
||||||
|
IP-адрес, на котором мониторы принимают HTTP-соединения (по умолчанию все адреса)
|
||||||
|
|
||||||
|
## mon_https_cert
|
||||||
|
|
||||||
|
- Тип: строка
|
||||||
|
|
||||||
|
Путь к PEM-файлу SSL-сертификата для монитора, чтобы принимать соединения через HTTPS
|
||||||
|
|
||||||
|
## mon_https_key
|
||||||
|
|
||||||
|
- Тип: строка
|
||||||
|
|
||||||
|
Путь к PEM-файлу секретного SSL-ключа для монитора, чтобы принимать соединения через HTTPS
|
||||||
|
|
||||||
|
## mon_https_client_auth
|
||||||
|
|
||||||
|
- Тип: булево (да/нет)
|
||||||
|
- Значение по умолчанию: false
|
||||||
|
|
||||||
|
Включить в HTTPS-сервере монитора авторизацию по клиентским сертификатам
|
||||||
|
|
||||||
|
## mon_https_ca
|
||||||
|
|
||||||
|
- Тип: строка
|
||||||
|
|
||||||
|
Путь к удостоверяющему сертификату для авторизации клиентских HTTPS соединений
|
||||||
|
|
||||||
## etcd_mon_ttl
|
## etcd_mon_ttl
|
||||||
|
|
||||||
- Тип: секунды
|
- Тип: секунды
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ etcd_report_interval to guarantee that keepalive actually works.
|
|||||||
## etcd_ws_keepalive_interval
|
## etcd_ws_keepalive_interval
|
||||||
|
|
||||||
- Type: seconds
|
- Type: seconds
|
||||||
- Default: 30
|
- Default: 5
|
||||||
- Can be changed online: yes
|
- Can be changed online: yes
|
||||||
|
|
||||||
etcd websocket ping interval required to keep the connection alive and
|
etcd websocket ping interval required to keep the connection alive and
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ etcd_report_interval, чтобы keepalive гарантированно рабо
|
|||||||
## etcd_ws_keepalive_interval
|
## etcd_ws_keepalive_interval
|
||||||
|
|
||||||
- Тип: секунды
|
- Тип: секунды
|
||||||
- Значение по умолчанию: 30
|
- Значение по умолчанию: 5
|
||||||
- Можно менять на лету: да
|
- Можно менять на лету: да
|
||||||
|
|
||||||
Интервал проверки живости вебсокет-подключений к etcd.
|
Интервал проверки живости вебсокет-подключений к etcd.
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ These parameters only apply to OSDs, are not fixed at the moment of OSD drive
|
|||||||
initialization and can be changed - either with an OSD restart or, for some of
|
initialization and can be changed - either with an OSD restart or, for some of
|
||||||
them, even without restarting by updating configuration in etcd.
|
them, even without restarting by updating configuration in etcd.
|
||||||
|
|
||||||
|
- [osd_iothread_count](#osd_iothread_count)
|
||||||
- [etcd_report_interval](#etcd_report_interval)
|
- [etcd_report_interval](#etcd_report_interval)
|
||||||
- [etcd_stats_interval](#etcd_stats_interval)
|
- [etcd_stats_interval](#etcd_stats_interval)
|
||||||
- [run_primary](#run_primary)
|
- [run_primary](#run_primary)
|
||||||
@@ -61,6 +62,18 @@ them, even without restarting by updating configuration in etcd.
|
|||||||
- [recovery_tune_sleep_min_us](#recovery_tune_sleep_min_us)
|
- [recovery_tune_sleep_min_us](#recovery_tune_sleep_min_us)
|
||||||
- [recovery_tune_sleep_cutoff_us](#recovery_tune_sleep_cutoff_us)
|
- [recovery_tune_sleep_cutoff_us](#recovery_tune_sleep_cutoff_us)
|
||||||
|
|
||||||
|
## osd_iothread_count
|
||||||
|
|
||||||
|
- Type: integer
|
||||||
|
- Default: 0
|
||||||
|
|
||||||
|
TCP network I/O thread count for OSD. When non-zero, a single OSD process
|
||||||
|
may handle more TCP I/O, but at a cost of increased latency because thread
|
||||||
|
switching overhead occurs. RDMA isn't affected by this option.
|
||||||
|
|
||||||
|
Because of latency, instead of enabling OSD I/O threads it's recommended to
|
||||||
|
just create multiple OSDs per disk, or use RDMA.
|
||||||
|
|
||||||
## etcd_report_interval
|
## etcd_report_interval
|
||||||
|
|
||||||
- Type: seconds
|
- Type: seconds
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
момент с помощью перезапуска OSD, а некоторые и без перезапуска, с помощью
|
момент с помощью перезапуска OSD, а некоторые и без перезапуска, с помощью
|
||||||
изменения конфигурации в etcd.
|
изменения конфигурации в etcd.
|
||||||
|
|
||||||
|
- [osd_iothread_count](#osd_iothread_count)
|
||||||
- [etcd_report_interval](#etcd_report_interval)
|
- [etcd_report_interval](#etcd_report_interval)
|
||||||
- [etcd_stats_interval](#etcd_stats_interval)
|
- [etcd_stats_interval](#etcd_stats_interval)
|
||||||
- [run_primary](#run_primary)
|
- [run_primary](#run_primary)
|
||||||
@@ -62,6 +63,19 @@
|
|||||||
- [recovery_tune_sleep_min_us](#recovery_tune_sleep_min_us)
|
- [recovery_tune_sleep_min_us](#recovery_tune_sleep_min_us)
|
||||||
- [recovery_tune_sleep_cutoff_us](#recovery_tune_sleep_cutoff_us)
|
- [recovery_tune_sleep_cutoff_us](#recovery_tune_sleep_cutoff_us)
|
||||||
|
|
||||||
|
## osd_iothread_count
|
||||||
|
|
||||||
|
- Тип: целое число
|
||||||
|
- Значение по умолчанию: 0
|
||||||
|
|
||||||
|
Число отдельных потоков для обработки ввода-вывода через TCP-сеть на
|
||||||
|
стороне OSD. Включение опции позволяет каждому отдельному OSD передавать
|
||||||
|
по сети больше данных, но ухудшает задержку из-за накладных расходов
|
||||||
|
переключения потоков. На работу RDMA опция не влияет.
|
||||||
|
|
||||||
|
Из-за задержек вместо включения потоков ввода-вывода OSD рекомендуется
|
||||||
|
просто создавать по несколько OSD на каждом диске, или использовать RDMA.
|
||||||
|
|
||||||
## etcd_report_interval
|
## etcd_report_interval
|
||||||
|
|
||||||
- Тип: секунды
|
- Тип: секунды
|
||||||
|
|||||||
@@ -1,3 +1,32 @@
|
|||||||
|
- name: client_iothread_count
|
||||||
|
type: int
|
||||||
|
default: 0
|
||||||
|
online: false
|
||||||
|
info: |
|
||||||
|
Number of separate threads for handling TCP network I/O at client library
|
||||||
|
side. Enabling 4 threads usually allows to increase peak performance of each
|
||||||
|
client from approx. 2-3 to 7-8 GByte/s linear read/write and from approx.
|
||||||
|
100-150 to 400 thousand iops, but at the same time it increases latency.
|
||||||
|
Latency increase depends on CPU: with CPU power saving disabled latency
|
||||||
|
only increases by ~10 us (equivalent to Q=1 iops decrease from 10500 to 9500),
|
||||||
|
with CPU power saving enabled it may be as high as 500 us (equivalent to Q=1
|
||||||
|
iops decrease from 2000 to 1000). RDMA isn't affected by this option.
|
||||||
|
|
||||||
|
It's recommended to enable client I/O threads if you don't use RDMA and want
|
||||||
|
to increase peak client performance.
|
||||||
|
info_ru: |
|
||||||
|
Число отдельных потоков для обработки ввода-вывода через TCP сеть на стороне
|
||||||
|
клиентской библиотеки. Включение 4 потоков обычно позволяет поднять пиковую
|
||||||
|
производительность каждого клиента примерно с 2-3 до 7-8 Гбайт/с линейного
|
||||||
|
чтения/записи и примерно с 100-150 до 400 тысяч операций ввода-вывода в
|
||||||
|
секунду, но ухудшает задержку. Увеличение задержки зависит от процессора:
|
||||||
|
при отключённом энергосбережении CPU это всего ~10 микросекунд (равносильно
|
||||||
|
падению iops с Q=1 с 10500 до 9500), а при включённом это может быть
|
||||||
|
и 500 микросекунд (равносильно падению iops с Q=1 с 2000 до 1000). На работу
|
||||||
|
RDMA данная опция не влияет.
|
||||||
|
|
||||||
|
Рекомендуется включать клиентские потоки ввода-вывода, если вы не используете
|
||||||
|
RDMA и хотите повысить пиковую производительность клиентов.
|
||||||
- name: client_retry_interval
|
- name: client_retry_interval
|
||||||
type: ms
|
type: ms
|
||||||
min: 10
|
min: 10
|
||||||
|
|||||||
@@ -47,14 +47,24 @@
|
|||||||
Не может быть меньше размера сектора дисков данных OSD.
|
Не может быть меньше размера сектора дисков данных OSD.
|
||||||
- name: immediate_commit
|
- name: immediate_commit
|
||||||
type: string
|
type: string
|
||||||
default: false
|
default: all
|
||||||
info: |
|
info: |
|
||||||
Another parameter which is really important for performance.
|
One of "none", "all" or "small". Global value, may be overriden [at pool level](pool.en.md#immediate_commit).
|
||||||
|
|
||||||
|
This parameter is also really important for performance.
|
||||||
|
|
||||||
|
TLDR: default "all" is optimal for server-grade SSDs with supercapacitor-based
|
||||||
|
power loss protection (nonvolatile write-through cache) and also for most HDDs.
|
||||||
|
"none" or "small" should be only selected if you use desktop SSDs without
|
||||||
|
capacitors or drives with slow write-back cache that can't be disabled. Check
|
||||||
|
immediate_commit of your OSDs in [ls-osd](../usage/cli.en.md#ls-osd).
|
||||||
|
|
||||||
|
Detailed explanation:
|
||||||
|
|
||||||
Desktop SSDs are very fast (100000+ iops) for simple random writes
|
Desktop SSDs are very fast (100000+ iops) for simple random writes
|
||||||
without cache flush. However, they are really slow (only around 1000 iops)
|
without cache flush. However, they are really slow (only around 1000 iops)
|
||||||
if you try to fsync() each write, that is, when you want to guarantee that
|
if you try to fsync() each write, that is, if you want to guarantee that
|
||||||
each change gets immediately persisted to the physical media.
|
each change gets actually persisted to the physical media.
|
||||||
|
|
||||||
Server-grade SSDs with "Advanced/Enhanced Power Loss Protection" or with
|
Server-grade SSDs with "Advanced/Enhanced Power Loss Protection" or with
|
||||||
"Supercapacitor-based Power Loss Protection", on the other hand, are equally
|
"Supercapacitor-based Power Loss Protection", on the other hand, are equally
|
||||||
@@ -66,8 +76,8 @@
|
|||||||
efficiently utilize desktop SSDs by postponing fsync until the client calls
|
efficiently utilize desktop SSDs by postponing fsync until the client calls
|
||||||
it explicitly.
|
it explicitly.
|
||||||
|
|
||||||
This is what this parameter regulates. When it's set to "all" the whole
|
This is what this parameter regulates. When it's set to "all" Vitastor
|
||||||
Vitastor cluster commits each change to disks immediately and clients just
|
cluster commits each change to disks immediately and clients just
|
||||||
ignore fsyncs because they know for sure that they're unneeded. This reduces
|
ignore fsyncs because they know for sure that they're unneeded. This reduces
|
||||||
the amount of network roundtrips performed by clients and improves
|
the amount of network roundtrips performed by clients and improves
|
||||||
performance. So it's always better to use server grade SSDs with
|
performance. So it's always better to use server grade SSDs with
|
||||||
@@ -90,14 +100,19 @@
|
|||||||
[disable_journal_fsync](layout-osd.en.yml#disable_journal_fsync) and
|
[disable_journal_fsync](layout-osd.en.yml#disable_journal_fsync) and
|
||||||
[disable_meta_fsync](layout-osd.en.yml#disable_meta_fsync), setting it to
|
[disable_meta_fsync](layout-osd.en.yml#disable_meta_fsync), setting it to
|
||||||
"all" also requires enabling [disable_data_fsync](layout-osd.en.yml#disable_data_fsync).
|
"all" also requires enabling [disable_data_fsync](layout-osd.en.yml#disable_data_fsync).
|
||||||
|
vitastor-disk tried to do that by default, first checking/disabling drive cache.
|
||||||
TLDR: For optimal performance, set immediate_commit to "all" if you only use
|
If it can't disable drive cache, OSD get initialized with "none".
|
||||||
SSDs with supercapacitor-based power loss protection (nonvolatile
|
|
||||||
write-through cache) for both data and journals in the whole Vitastor
|
|
||||||
cluster. Set it to "small" if you only use such SSDs for journals. Leave
|
|
||||||
empty if your drives have write-back cache.
|
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Ещё один важный для производительности параметр.
|
Одно из значений "none", "small" или "all". Глобальное значение, может быть
|
||||||
|
переопределено [на уровне пула](pool.ru.md#immediate_commit).
|
||||||
|
|
||||||
|
Данный параметр тоже важен для производительности.
|
||||||
|
|
||||||
|
Вкратце: значение по умолчанию "all" оптимально для всех серверных SSD с
|
||||||
|
суперконденсаторами и также для большинства HDD. "none" и "small" имеет смысл
|
||||||
|
устанавливать только при использовании SSD настольного класса без
|
||||||
|
суперконденсаторов или дисков с медленным неотключаемым кэшем записи.
|
||||||
|
Проверьте настройку immediate_commit своих OSD в выводе команды [ls-osd](../usage/cli.ru.md#ls-osd).
|
||||||
|
|
||||||
Модели SSD для настольных компьютеров очень быстрые (100000+ операций в
|
Модели SSD для настольных компьютеров очень быстрые (100000+ операций в
|
||||||
секунду) при простой случайной записи без сбросов кэша. Однако они очень
|
секунду) при простой случайной записи без сбросов кэша. Однако они очень
|
||||||
@@ -118,7 +133,7 @@
|
|||||||
эффективно утилизировать настольные SSD.
|
эффективно утилизировать настольные SSD.
|
||||||
|
|
||||||
Данный параметр влияет как раз на это. Когда он установлен в значение "all",
|
Данный параметр влияет как раз на это. Когда он установлен в значение "all",
|
||||||
весь кластер Vitastor мгновенно фиксирует каждое изменение на физические
|
кластер Vitastor мгновенно фиксирует каждое изменение на физические
|
||||||
носители и клиенты могут просто игнорировать запросы fsync, т.к. они точно
|
носители и клиенты могут просто игнорировать запросы fsync, т.к. они точно
|
||||||
знают, что fsync-и не нужны. Это уменьшает число необходимых обращений к OSD
|
знают, что fsync-и не нужны. Это уменьшает число необходимых обращений к OSD
|
||||||
по сети и улучшает производительность. Поэтому даже с Vitastor лучше всегда
|
по сети и улучшает производительность. Поэтому даже с Vitastor лучше всегда
|
||||||
@@ -144,10 +159,3 @@
|
|||||||
включения [disable_journal_fsync](layout-osd.ru.yml#disable_journal_fsync) и
|
включения [disable_journal_fsync](layout-osd.ru.yml#disable_journal_fsync) и
|
||||||
[disable_meta_fsync](layout-osd.ru.yml#disable_meta_fsync), значение "all"
|
[disable_meta_fsync](layout-osd.ru.yml#disable_meta_fsync), значение "all"
|
||||||
также требует включения [disable_data_fsync](layout-osd.ru.yml#disable_data_fsync).
|
также требует включения [disable_data_fsync](layout-osd.ru.yml#disable_data_fsync).
|
||||||
|
|
||||||
Итого, вкратце: для оптимальной производительности установите
|
|
||||||
immediate_commit в значение "all", если вы используете в кластере только SSD
|
|
||||||
с суперконденсаторами и для данных, и для журналов. Если вы используете
|
|
||||||
такие SSD для всех журналов, но не для данных - можете установить параметр
|
|
||||||
в "small". Если и какие-то из дисков журналов имеют волатильный кэш записи -
|
|
||||||
оставьте параметр пустым.
|
|
||||||
|
|||||||
@@ -1,3 +1,103 @@
|
|||||||
|
- name: use_antietcd
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
info: |
|
||||||
|
Enable experimental built-in etcd replacement (clustered key-value database):
|
||||||
|
[antietcd](https://git.yourcmc.ru/vitalif/antietcd/).
|
||||||
|
|
||||||
|
When set to true, monitor runs internal antietcd automatically if it finds
|
||||||
|
a network interface with an IP address matching one of addresses in the
|
||||||
|
`etcd_address` configuration option (in `/etc/vitastor/vitastor.conf` or in
|
||||||
|
the monitor command line). If there are multiple matching addresses, it also
|
||||||
|
checks `antietcd_port` and antietcd is started for address with matching port.
|
||||||
|
By default, antietcd accepts connection on the selected IP address, but it
|
||||||
|
can also be overridden manually in the `antietcd_ip` option.
|
||||||
|
|
||||||
|
When antietcd is started, monitor stores cluster metadata itself and exposes
|
||||||
|
a etcd-compatible REST API. On disk, these metadata are stored in
|
||||||
|
`/var/lib/vitastor/mon_2379.json.gz` (can be overridden in antietcd_data_file
|
||||||
|
or antietcd_data_dir options). All other antietcd parameters
|
||||||
|
(see [here](https://git.yourcmc.ru/vitalif/antietcd/)) except node_id,
|
||||||
|
cluster, cluster_key, persist_filter, stale_read can also be set in
|
||||||
|
Vitastor configuration with `antietcd_` prefix.
|
||||||
|
|
||||||
|
You can dump/load data to or from antietcd using Antietcd `anticli` tool:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm exec anticli -e http://etcd:2379/v3 get --prefix '' --no-temp > dump.json
|
||||||
|
npm exec anticli -e http://antietcd:2379/v3 load < dump.json
|
||||||
|
```
|
||||||
|
info_ru: |
|
||||||
|
Включить экспериментальный встроенный заменитель etcd (кластерную БД ключ-значение):
|
||||||
|
[antietcd](https://git.yourcmc.ru/vitalif/antietcd/).
|
||||||
|
|
||||||
|
Если параметр установлен в true, монитор запускает antietcd автоматически,
|
||||||
|
если обнаруживает сетевой интерфейс с одним из адресов, указанных в опции
|
||||||
|
конфигурации `etcd_address` (в `/etc/vitastor/vitastor.conf` или в опциях
|
||||||
|
командной строки монитора). Если таких адресов несколько, также проверяется
|
||||||
|
опция `antietcd_port` и antietcd запускается для адреса с соответствующим
|
||||||
|
портом. По умолчанию antietcd принимает подключения по выбранному совпадающему
|
||||||
|
IP, но его также можно определить вручную опцией `antietcd_ip`.
|
||||||
|
|
||||||
|
При запуске antietcd монитор сам хранит центральные метаданные кластера и
|
||||||
|
выставляет etcd-совместимое REST API. На диске эти метаданные хранятся в файле
|
||||||
|
`/var/lib/vitastor/mon_2379.json.gz` (можно переопределить параметрами
|
||||||
|
antietcd_data_file или antietcd_data_dir). Все остальные параметры antietcd
|
||||||
|
(смотрите [по ссылке](https://git.yourcmc.ru/vitalif/antietcd/)), за исключением
|
||||||
|
node_id, cluster, cluster_key, persist_filter, stale_read также можно задавать
|
||||||
|
в конфигурации Vitastor с префиксом `antietcd_`.
|
||||||
|
|
||||||
|
Вы можете выгружать/загружать данные в или из antietcd с помощью его инструмента
|
||||||
|
`anticli`:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm exec anticli -e http://etcd:2379/v3 get --prefix '' --no-temp > dump.json
|
||||||
|
npm exec anticli -e http://antietcd:2379/v3 load < dump.json
|
||||||
|
```
|
||||||
|
- name: enable_prometheus
|
||||||
|
type: bool
|
||||||
|
default: true
|
||||||
|
info: |
|
||||||
|
Enable built-in Prometheus metrics exporter at mon_http_port (8060 by default).
|
||||||
|
|
||||||
|
Note that only the active (master) monitor exposes metrics, others return
|
||||||
|
HTTP 503. So you should add all monitor URLs to your Prometheus job configuration.
|
||||||
|
|
||||||
|
Grafana dashboard suitable for this exporter is here: [Vitastor-Grafana-6+.json](../../mon/scripts/Vitastor-Grafana-6+.json).
|
||||||
|
info_ru: |
|
||||||
|
Включить встроенный Prometheus-экспортер метрик на порту mon_http_port (по умолчанию 8060).
|
||||||
|
|
||||||
|
Обратите внимание, что метрики выставляет только активный (главный) монитор, остальные
|
||||||
|
возвращают статус HTTP 503, поэтому вам следует добавлять адреса всех мониторов
|
||||||
|
в задание по сбору метрик Prometheus.
|
||||||
|
|
||||||
|
Дашборд для Grafana, подходящий для этого экспортера: [Vitastor-Grafana-6+.json](../../mon/scripts/Vitastor-Grafana-6+.json).
|
||||||
|
- name: mon_http_port
|
||||||
|
type: int
|
||||||
|
default: 8060
|
||||||
|
info: HTTP port for monitors to listen on (including metrics exporter)
|
||||||
|
info_ru: Порт, на котором мониторы принимают HTTP-соединения (в том числе для отдачи метрик)
|
||||||
|
- name: mon_http_ip
|
||||||
|
type: string
|
||||||
|
info: IP address for monitors to listen on (all addresses by default)
|
||||||
|
info_ru: IP-адрес, на котором мониторы принимают HTTP-соединения (по умолчанию все адреса)
|
||||||
|
- name: mon_https_cert
|
||||||
|
type: string
|
||||||
|
info: Path to PEM SSL certificate file for monitor to listen using HTTPS
|
||||||
|
info_ru: Путь к PEM-файлу SSL-сертификата для монитора, чтобы принимать соединения через HTTPS
|
||||||
|
- name: mon_https_key
|
||||||
|
type: string
|
||||||
|
info: Path to PEM SSL private key file for monitor to listen using HTTPS
|
||||||
|
info_ru: Путь к PEM-файлу секретного SSL-ключа для монитора, чтобы принимать соединения через HTTPS
|
||||||
|
- name: mon_https_client_auth
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
info: Enable HTTPS client certificate-based authorization for monitor connections
|
||||||
|
info_ru: Включить в HTTPS-сервере монитора авторизацию по клиентским сертификатам
|
||||||
|
- name: mon_https_ca
|
||||||
|
type: string
|
||||||
|
info: Path to CA certificate for client HTTPS authorization
|
||||||
|
info_ru: Путь к удостоверяющему сертификату для авторизации клиентских HTTPS соединений
|
||||||
- name: etcd_mon_ttl
|
- name: etcd_mon_ttl
|
||||||
type: sec
|
type: sec
|
||||||
min: 5
|
min: 5
|
||||||
|
|||||||
@@ -282,7 +282,7 @@
|
|||||||
etcd_report_interval, чтобы keepalive гарантированно работал.
|
etcd_report_interval, чтобы keepalive гарантированно работал.
|
||||||
- name: etcd_ws_keepalive_interval
|
- name: etcd_ws_keepalive_interval
|
||||||
type: sec
|
type: sec
|
||||||
default: 30
|
default: 5
|
||||||
online: true
|
online: true
|
||||||
info: |
|
info: |
|
||||||
etcd websocket ping interval required to keep the connection alive and
|
etcd websocket ping interval required to keep the connection alive and
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
- name: osd_iothread_count
|
||||||
|
type: int
|
||||||
|
default: 0
|
||||||
|
info: |
|
||||||
|
TCP network I/O thread count for OSD. When non-zero, a single OSD process
|
||||||
|
may handle more TCP I/O, but at a cost of increased latency because thread
|
||||||
|
switching overhead occurs. RDMA isn't affected by this option.
|
||||||
|
|
||||||
|
Because of latency, instead of enabling OSD I/O threads it's recommended to
|
||||||
|
just create multiple OSDs per disk, or use RDMA.
|
||||||
|
info_ru: |
|
||||||
|
Число отдельных потоков для обработки ввода-вывода через TCP-сеть на
|
||||||
|
стороне OSD. Включение опции позволяет каждому отдельному OSD передавать
|
||||||
|
по сети больше данных, но ухудшает задержку из-за накладных расходов
|
||||||
|
переключения потоков. На работу RDMA опция не влияет.
|
||||||
|
|
||||||
|
Из-за задержек вместо включения потоков ввода-вывода OSD рекомендуется
|
||||||
|
просто создавать по несколько OSD на каждом диске, или использовать RDMA.
|
||||||
- name: etcd_report_interval
|
- name: etcd_report_interval
|
||||||
type: sec
|
type: sec
|
||||||
default: 5
|
default: 5
|
||||||
|
|||||||
Executable
+55
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/nodejs
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const yaml = require('yaml');
|
||||||
|
|
||||||
|
const L = {
|
||||||
|
en: {},
|
||||||
|
ru: {
|
||||||
|
Type: 'Тип',
|
||||||
|
Default: 'Значение по умолчанию',
|
||||||
|
Minimum: 'Минимальное значение',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const types = {
|
||||||
|
en: {
|
||||||
|
string: 'string',
|
||||||
|
bool: 'boolean',
|
||||||
|
int: 'integer',
|
||||||
|
sec: 'seconds',
|
||||||
|
ms: 'milliseconds',
|
||||||
|
us: 'microseconds',
|
||||||
|
},
|
||||||
|
ru: {
|
||||||
|
string: 'строка',
|
||||||
|
bool: 'булево (да/нет)',
|
||||||
|
int: 'целое число',
|
||||||
|
sec: 'секунды',
|
||||||
|
ms: 'миллисекунды',
|
||||||
|
us: 'микросекунды',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const params_files = fs.readdirSync(__dirname+'/params')
|
||||||
|
.filter(f => f.substr(-4) == '.yml')
|
||||||
|
.map(f => f.substr(0, f.length-4));
|
||||||
|
|
||||||
|
for (const file of params_files)
|
||||||
|
{
|
||||||
|
const cfg = yaml.parse(fs.readFileSync(__dirname+'/params/'+file+'.yml', { encoding: 'utf-8' }));
|
||||||
|
for (const lang in types)
|
||||||
|
{
|
||||||
|
let out = '\n\n{{< toc >}}';
|
||||||
|
for (const c of cfg)
|
||||||
|
{
|
||||||
|
out += `\n\n## ${c.name}\n\n`;
|
||||||
|
out += `- ${L[lang]['Type'] || 'Type'}: ${c["type_"+lang] || types[lang][c.type] || c.type}\n`;
|
||||||
|
if (c.default !== undefined)
|
||||||
|
out += `- ${L[lang]['Default'] || 'Default'}: ${c.default}\n`;
|
||||||
|
if (c.min !== undefined)
|
||||||
|
out += `- ${L[lang]['Minimum'] || 'Minimum'}: ${c.min}\n`;
|
||||||
|
out += `\n`+(c["info_"+lang] || c["info"]).replace(/\s+$/, '');
|
||||||
|
}
|
||||||
|
const head = fs.readFileSync(__dirname+'/params/head/'+file+'.'+lang+'.md', { encoding: 'utf-8' });
|
||||||
|
fs.writeFileSync(__dirname+'/hugo/content/config/'+file+'.'+lang+'.md', head.replace(/\s+$/, '')+out+"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
[Documentation](../../README.md#documentation) → Installation → OpenNebula
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
[Читать на русском](opennebula.ru.md)
|
||||||
|
|
||||||
|
## Automatic Installation
|
||||||
|
|
||||||
|
OpenNebula plugin is packaged as `vitastor-opennebula` Debian and RPM package since Vitastor 1.9.0. So:
|
||||||
|
|
||||||
|
- Run `apt-get install vitastor-opennebula` or `yum install vitastor-opennebula` after installing OpenNebula on all nodes
|
||||||
|
- Check that it prints "OK, Vitastor OpenNebula patches successfully applied" or "OK, Vitastor OpenNebula patches are already applied"
|
||||||
|
- If it does not, refer to [Manual Installation](#manual-installation) and apply configuration file changes manually
|
||||||
|
- Make sure that Vitastor patched versions of QEMU and libvirt are installed
|
||||||
|
(`dpkg -l qemu-system-x86`, `dpkg -l | grep libvirt`, `rpm -qa | grep qemu`, `rpm -qa | grep qemu`, `rpm -qa | grep libvirt-libs` should show "vitastor" in version names)
|
||||||
|
- [Block VM access to Vitastor cluster](#block-vm-access-to-vitastor-cluster)
|
||||||
|
|
||||||
|
## Manual Installation
|
||||||
|
|
||||||
|
Install OpenNebula. Then, on each node:
|
||||||
|
|
||||||
|
- Copy [opennebula/remotes](../../opennebula/remotes) into `/var/lib/one` recursively: `cp -r opennebula/remotes /var/lib/one/`
|
||||||
|
- Copy [opennebula/sudoers.d](../../opennebula/sudoers.d) to `/etc`: `cp -r opennebula/sudoers.d /etc/`
|
||||||
|
- Apply [downloader-vitastor.sh.diff](../../opennebula/remotes/datastore/vitastor/downloader-vitastor.sh.diff) to `/var/lib/one/remotes/datastore/downloader.sh`:
|
||||||
|
`patch /var/lib/one/remotes/datastore/downloader.sh < opennebula/remotes/datastore/vitastor/downloader-vitastor.sh.diff` - or read the patch and apply the same change manually
|
||||||
|
- Add `kvm-vitastor` to `LIVE_DISK_SNAPSHOTS` in `/etc/one/vmm_exec/vmm_execrc`
|
||||||
|
- If on Debian or Ubuntu (and AppArmor is used), add Vitastor config file path(s) to `/etc/apparmor.d/local/abstractions/libvirt-qemu`: for example,
|
||||||
|
`echo ' "/etc/vitastor/vitastor.conf" r,' >> /etc/apparmor.d/local/abstractions/libvirt-qemu`
|
||||||
|
- Apply changes to `/etc/one/oned.conf`
|
||||||
|
|
||||||
|
### oned.conf changes
|
||||||
|
|
||||||
|
1. Add deploy script override in kvm VM_MAD: add `-l deploy.vitastor` to ARGUMENTS.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
VM_MAD = [
|
||||||
|
NAME = "kvm",
|
||||||
|
SUNSTONE_NAME = "KVM",
|
||||||
|
EXECUTABLE = "one_vmm_exec",
|
||||||
|
- ARGUMENTS = "-t 15 -r 0 kvm -p",
|
||||||
|
+ ARGUMENTS = "-t 15 -r 0 kvm -p -l deploy=deploy.vitastor",
|
||||||
|
DEFAULT = "vmm_exec/vmm_exec_kvm.conf",
|
||||||
|
TYPE = "kvm",
|
||||||
|
KEEP_SNAPSHOTS = "yes",
|
||||||
|
LIVE_RESIZE = "yes",
|
||||||
|
SUPPORT_SHAREABLE = "yes",
|
||||||
|
IMPORTED_VMS_ACTIONS = "terminate, terminate-hard, hold, release, suspend,
|
||||||
|
resume, delete, reboot, reboot-hard, resched, unresched, disk-attach,
|
||||||
|
disk-detach, nic-attach, nic-detach, snapshot-create, snapshot-delete,
|
||||||
|
resize, updateconf, update"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional: if you also want to save VM RAM checkpoints to Vitastor, use
|
||||||
|
`-l deploy=deploy.vitastor,save=save.vitastor,restore=restore.vitastor`
|
||||||
|
instead of just `-l deploy=deploy.vitastor`.
|
||||||
|
|
||||||
|
2. Add `vitastor` to TM_MAD.ARGUMENTS and DATASTORE_MAD.ARGUMENTS:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
TM_MAD = [
|
||||||
|
EXECUTABLE = "one_tm",
|
||||||
|
- ARGUMENTS = "-t 15 -d dummy,lvm,shared,fs_lvm,fs_lvm_ssh,qcow2,ssh,ceph,dev,vcenter,iscsi_libvirt"
|
||||||
|
+ ARGUMENTS = "-t 15 -d dummy,lvm,shared,fs_lvm,fs_lvm_ssh,qcow2,ssh,ceph,vitastor,dev,vcenter,iscsi_libvirt"
|
||||||
|
]
|
||||||
|
|
||||||
|
DATASTORE_MAD = [
|
||||||
|
EXECUTABLE = "one_datastore",
|
||||||
|
- ARGUMENTS = "-t 15 -d dummy,fs,lvm,ceph,dev,iscsi_libvirt,vcenter,restic,rsync -s shared,ssh,ceph,fs_lvm,fs_lvm_ssh,qcow2,vcenter"
|
||||||
|
+ ARGUMENTS = "-t 15 -d dummy,fs,lvm,ceph,vitastor,dev,iscsi_libvirt,vcenter,restic,rsync -s shared,ssh,ceph,vitastor,fs_lvm,fs_lvm_ssh,qcow2,vcenter"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Add INHERIT_DATASTORE_ATTR for two Vitastor attributes:
|
||||||
|
|
||||||
|
```
|
||||||
|
INHERIT_DATASTORE_ATTR = "VITASTOR_CONF"
|
||||||
|
INHERIT_DATASTORE_ATTR = "IMAGE_PREFIX"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Add TM_MAD_CONF and DS_MAD_CONF for Vitastor:
|
||||||
|
|
||||||
|
```
|
||||||
|
TM_MAD_CONF = [
|
||||||
|
NAME = "vitastor", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES",
|
||||||
|
DS_MIGRATE = "NO", DRIVER = "raw", ALLOW_ORPHANS="format",
|
||||||
|
TM_MAD_SYSTEM = "ssh,shared", LN_TARGET_SSH = "SYSTEM", CLONE_TARGET_SSH = "SYSTEM",
|
||||||
|
DISK_TYPE_SSH = "FILE", LN_TARGET_SHARED = "NONE",
|
||||||
|
CLONE_TARGET_SHARED = "SELF", DISK_TYPE_SHARED = "FILE"
|
||||||
|
]
|
||||||
|
|
||||||
|
DS_MAD_CONF = [
|
||||||
|
NAME = "vitastor",
|
||||||
|
REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST",
|
||||||
|
PERSISTENT_ONLY = "NO",
|
||||||
|
MARKETPLACE_ACTIONS = "export"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create Datastores
|
||||||
|
|
||||||
|
Example Image and System Datastore definitions:
|
||||||
|
[opennebula/vitastor-imageds.conf](../../opennebula/vitastor-imageds.conf) and
|
||||||
|
[opennebula/vitastor-systemds.conf](../../opennebula/vitastor-systemds.conf).
|
||||||
|
|
||||||
|
Change parameters to your will:
|
||||||
|
|
||||||
|
- POOL_NAME is Vitastor pool name to store images.
|
||||||
|
- IMAGE_PREFIX is a string prepended to all Vitastor image names.
|
||||||
|
- BRIDGE_LIST is a list of hosts with access to Vitastor cluster, mostly used for image (not system) datastore operations.
|
||||||
|
- VITASTOR_CONF is the path to cluster configuration. Note that it should be also added to `/etc/apparmor.d/local/abstractions/libvirt-qemu` if you use AppArmor.
|
||||||
|
- STAGING_DIR is a temporary directory used when importing external images. Should have free space sufficient for downloading external images.
|
||||||
|
|
||||||
|
Then create datastores using `onedatastore create vitastor-imageds.conf` and `onedatastore create vitastor-systemds.conf` (or use UI).
|
||||||
|
|
||||||
|
## Block VM access to Vitastor cluster
|
||||||
|
|
||||||
|
Vitastor doesn't support any authentication yet, so you MUST block VM guest access to the Vitastor cluster at the network level.
|
||||||
|
|
||||||
|
If you use VLAN networking for VMs - make sure you use different VLANs for VMs and hypervisor/storage network and
|
||||||
|
block access between them using your firewall/switch configuration.
|
||||||
|
|
||||||
|
If you use something more stupid like bridged networking, you probably have to use manual firewall/iptables setup
|
||||||
|
to only allow access to Vitastor from hypervisor IPs.
|
||||||
|
|
||||||
|
Also you need to switch network to "Bridged & Security Groups" and enable IP spoofing filters in OpenNebula.
|
||||||
|
Problem is that OpenNebula's IP spoofing filter doesn't affect local interfaces of the hypervisor i.e. when
|
||||||
|
it's enabled a VM can't talk to other VMs or to the outer world using a spoofed IP, but it CAN talk to the
|
||||||
|
hypervisor if it takes an IP from its subnet. To fix that you also need some more iptables.
|
||||||
|
|
||||||
|
So the complete "stupid" bridged network filter setup could look like the following
|
||||||
|
(here `10.0.3.0/24` is the VM subnet and `10.0.2.0/24` is the hypervisor subnet):
|
||||||
|
|
||||||
|
```
|
||||||
|
# Allow incoming traffic from physical device
|
||||||
|
iptables -A INPUT -m physdev --physdev-in eth0 -j ACCEPT
|
||||||
|
# Do not allow incoming traffic from VMs, but not from VM subnet
|
||||||
|
iptables -A INPUT ! -s 10.0.3.0/24 -i onebr0 -j DROP
|
||||||
|
# Drop traffic from VMs to hypervisor/storage subnet
|
||||||
|
iptables -I FORWARD 1 -s 10.0.3.0/24 -d 10.0.2.0/24 -j DROP
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
The OpenNebula plugin includes quite a bit of bash scripts, so here's their description to get an idea about what they actually do.
|
||||||
|
|
||||||
|
| Script | Action | How to Test |
|
||||||
|
| ----------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||||
|
| vmm/kvm/deploy.vitastor | Start a VM | Create and start a VM with Vitastor disk(s): persistent / non-persistent / volatile. |
|
||||||
|
| vmm/kvm/save.vitastor | Save VM memory checkpoint | Stop a VM using "Stop" command. |
|
||||||
|
| vmm/kvm/restore.vitastor| Restore VM memory checkpoint | Start a VM back after stopping it. |
|
||||||
|
| datastore/clone | Copy an image as persistent | Create a VM template and instantiate it as persistent. |
|
||||||
|
| datastore/cp | Import an external image | Import a VM template with images from Marketplace. |
|
||||||
|
| datastore/export | Export an image as URL | Probably: export a VM template with images to Marketplace. |
|
||||||
|
| datastore/mkfs | Create an image with FS | Storage → Images → Create → Type: Datablock, Location: Empty disk image, Filesystem: Not empty. |
|
||||||
|
| datastore/monitor | Monitor used space in image datastore | Check reported used/free space in image datastore list. |
|
||||||
|
| datastore/rm | Remove a persistent image | Storage → Images → Select an image → Delete. |
|
||||||
|
| datastore/snap_delete | Delete a snapshot of a persistent image | Storage → Images → Select an image → Select a snapshot → Delete; <br> To create an image with snapshot: attach a persistent image to a VM; create a snapshot; detach the image. |
|
||||||
|
| datastore/snap_flatten | Revert an image to snapshot and delete other snapshots | Storage → Images → Select an image → Select a snapshot → Flatten. |
|
||||||
|
| datastore/snap_revert | Revert an image to snapshot | Storage → Images → Select an image → Select a snapshot → Revert. |
|
||||||
|
| datastore/stat | Get virtual size of an image in MB | No idea. Seems to be unused both in Vitastor and Ceph datastores. |
|
||||||
|
| tm/clone | Clone a non-persistent image to a VM disk | Attach a non-persistent image to a VM. |
|
||||||
|
| tm/context | Generate a contextualisation VM disk | Create a VM with enabled contextualisation (default). Common host FS-based version is used in Vitastor and Ceph datastores. |
|
||||||
|
| tm/cpds | Copy a VM disk / its snapshot to an image | Select a VM → Select a disk → Optionally select a snapshot → Save as. |
|
||||||
|
| tm/delete | Delete a cloned or volatile VM disk | Detach a volatile disk or a non-persistent image from a VM. |
|
||||||
|
| tm/failmigrate | Handle live migration failure | No action. Script is empty in Vitastor and Ceph. In other datastores, should roll back actions done by tm/premigrate. |
|
||||||
|
| tm/ln | Attach a persistent image to a VM | No action. Script is empty in Vitastor and Ceph. |
|
||||||
|
| tm/mkimage | Create a volatile disk, maybe with FS | Attach a volatile disk to a VM, with or without file system. |
|
||||||
|
| tm/mkswap | Create a volatile swap disk | Attach a volatile disk to a VM, formatted as swap. |
|
||||||
|
| tm/monitor | Monitor used space in system datastore | Check reported used/free space in system datastore list. |
|
||||||
|
| tm/mv | Move a migrated VM disk between hosts | Migrate a VM between hosts. In Vitastor and Ceph datastores, doesn't do any storage action. |
|
||||||
|
| tm/mvds | Detach a persistent image from a VM | No action. The opposite of tm/ln. Script is empty in Vitastor and Ceph. In other datastores, script may copy the image from VM host back to the datastore. |
|
||||||
|
| tm/postbackup | Executed after backup | Seems that the script just removes temporary files after backup. Perform a VM backup and check that temporary files are cleaned up. |
|
||||||
|
| tm/postbackup_live | Executed after backup of a running VM | Same as tm/postbackup, but for a running VM. |
|
||||||
|
| tm/postmigrate | Executed after VM live migration | No action. Only executed for system datastore, so the script tries to call other TMs for other disks. Except that, the script does nothing in Vitastor and Ceph datastores. |
|
||||||
|
| tm/prebackup | Actual backup script: backup VM disks | Set up "rsync" backup datastore → Backup a VM to it. |
|
||||||
|
| tm/prebackup_live | Backup VM disks of a running VM | Same as tm/prebackup, but also does fsfreeze/thaw. So perform a live backup, restore it and check that disks are consistent. |
|
||||||
|
| tm/premigrate | Executed before live migration | No action. Only executed for system datastore, so the script tries to call other TMs for other disks. Except that, the script does nothing in Vitastor and Ceph datastores. |
|
||||||
|
| tm/resize | Resize a VM disk | Select a VM → Select a non-persistent disk → Resize. |
|
||||||
|
| tm/restore | Restore VM disks from backup | Set up "rsync" backup datastore → Backup a VM to it → Restore it back. |
|
||||||
|
| tm/snap_create | Create a VM disk snapshot | Select a VM → Select a disk → Create snapshot. |
|
||||||
|
| tm/snap_create_live | Create a VM disk snapshot for a live VM | Select a running VM → Select a disk → Create snapshot. |
|
||||||
|
| tm/snap_delete | Delete a VM disk snapshot | Select a VM → Select a disk → Select a snapshot → Delete. |
|
||||||
|
| tm/snap_revert | Revert a VM disk to a snapshot | Select a VM → Select a disk → Select a snapshot → Revert. |
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
[Документация](../../README-ru.md#документация) → Установка → OpenNebula
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
[Read in English](opennebula.en.md)
|
||||||
|
|
||||||
|
## Автоматическая установка
|
||||||
|
|
||||||
|
Плагин OpenNebula Vitastor распространяется как Debian и RPM пакет `vitastor-opennebula`, начиная с версии Vitastor 1.9.0. Так что:
|
||||||
|
|
||||||
|
- Запустите `apt-get install vitastor-opennebula` или `yum install vitastor-opennebula` после установки OpenNebula на всех серверах
|
||||||
|
- Проверьте, что он выводит "OK, Vitastor OpenNebula patches successfully applied" или "OK, Vitastor OpenNebula patches are already applied" в процессе установки
|
||||||
|
- Если сообщение не выведено, пройдите по шагам инструкцию [Ручная установка](#ручная-установка) и примените правки файлов конфигурации вручную
|
||||||
|
- Удостоверьтесь, что установлены версии QEMU и libvirt с изменениями Vitastor
|
||||||
|
(`dpkg -l qemu-system-x86`, `dpkg -l | grep libvirt`, `rpm -qa | grep qemu`, `rpm -qa | grep qemu`, `rpm -qa | grep libvirt-libs` должны показывать "vitastor" в номере версии)
|
||||||
|
- [Заблокируйте доступ виртуальных машин в Vitastor](#блокировка-доступа-вм-в-vitastor)
|
||||||
|
|
||||||
|
## Ручная установка
|
||||||
|
|
||||||
|
Сначала установите саму OpenNebula. После этого, на каждом сервере:
|
||||||
|
|
||||||
|
- Скопируйте директорию [opennebula/remotes](../../opennebula/remotes) в `/var/lib/one`: `cp -r opennebula/remotes /var/lib/one/`
|
||||||
|
- Скопируйте директорию [opennebula/sudoers.d](../../opennebula/sudoers.d) в `/etc`: `cp -r opennebula/sudoers.d /etc/`
|
||||||
|
- Примените патч [downloader-vitastor.sh.diff](../../opennebula/remotes/datastore/vitastor/downloader-vitastor.sh.diff) к `/var/lib/one/remotes/datastore/downloader.sh`:
|
||||||
|
`patch /var/lib/one/remotes/datastore/downloader.sh < opennebula/remotes/datastore/vitastor/downloader-vitastor.sh.diff` - либо прочитайте патч и примените изменение вручную
|
||||||
|
- Добавьте `kvm-vitastor` в список `LIVE_DISK_SNAPSHOTS` в файле `/etc/one/vmm_exec/vmm_execrc`
|
||||||
|
- Если вы используете Debian или Ubuntu (и AppArmor), добавьте пути к файлу(ам) конфигурации Vitastor в файл `/etc/apparmor.d/local/abstractions/libvirt-qemu`: например,
|
||||||
|
`echo ' "/etc/vitastor/vitastor.conf" r,' >> /etc/apparmor.d/local/abstractions/libvirt-qemu`
|
||||||
|
- Примените изменения `/etc/one/oned.conf`
|
||||||
|
|
||||||
|
### Изменения oned.conf
|
||||||
|
|
||||||
|
1. Добавьте переопределение скрипта deploy в VM_MAD kvm, добавив `-l deploy.vitastor` в `ARGUMENTS`:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
VM_MAD = [
|
||||||
|
NAME = "kvm",
|
||||||
|
SUNSTONE_NAME = "KVM",
|
||||||
|
EXECUTABLE = "one_vmm_exec",
|
||||||
|
- ARGUMENTS = "-t 15 -r 0 kvm -p",
|
||||||
|
+ ARGUMENTS = "-t 15 -r 0 kvm -p -l deploy=deploy.vitastor",
|
||||||
|
DEFAULT = "vmm_exec/vmm_exec_kvm.conf",
|
||||||
|
TYPE = "kvm",
|
||||||
|
KEEP_SNAPSHOTS = "yes",
|
||||||
|
LIVE_RESIZE = "yes",
|
||||||
|
SUPPORT_SHAREABLE = "yes",
|
||||||
|
IMPORTED_VMS_ACTIONS = "terminate, terminate-hard, hold, release, suspend,
|
||||||
|
resume, delete, reboot, reboot-hard, resched, unresched, disk-attach,
|
||||||
|
disk-detach, nic-attach, nic-detach, snapshot-create, snapshot-delete,
|
||||||
|
resize, updateconf, update"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Опционально: если вы хотите также сохранять снимки памяти ВМ в Vitastor, добавьте
|
||||||
|
`-l deploy=deploy.vitastor,save=save.vitastor,restore=restore.vitastor`
|
||||||
|
вместо просто `-l deploy=deploy.vitastor`.
|
||||||
|
|
||||||
|
2. Добавьте `vitastor` в значения TM_MAD.ARGUMENTS и DATASTORE_MAD.ARGUMENTS:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
TM_MAD = [
|
||||||
|
EXECUTABLE = "one_tm",
|
||||||
|
- ARGUMENTS = "-t 15 -d dummy,lvm,shared,fs_lvm,fs_lvm_ssh,qcow2,ssh,ceph,dev,vcenter,iscsi_libvirt"
|
||||||
|
+ ARGUMENTS = "-t 15 -d dummy,lvm,shared,fs_lvm,fs_lvm_ssh,qcow2,ssh,ceph,vitastor,dev,vcenter,iscsi_libvirt"
|
||||||
|
]
|
||||||
|
|
||||||
|
DATASTORE_MAD = [
|
||||||
|
EXECUTABLE = "one_datastore",
|
||||||
|
- ARGUMENTS = "-t 15 -d dummy,fs,lvm,ceph,dev,iscsi_libvirt,vcenter,restic,rsync -s shared,ssh,ceph,fs_lvm,fs_lvm_ssh,qcow2,vcenter"
|
||||||
|
+ ARGUMENTS = "-t 15 -d dummy,fs,lvm,ceph,vitastor,dev,iscsi_libvirt,vcenter,restic,rsync -s shared,ssh,ceph,vitastor,fs_lvm,fs_lvm_ssh,qcow2,vcenter"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Добавьте строчки с INHERIT_DATASTORE_ATTR для двух атрибутов Vitastor-хранилищ:
|
||||||
|
|
||||||
|
```
|
||||||
|
INHERIT_DATASTORE_ATTR = "VITASTOR_CONF"
|
||||||
|
INHERIT_DATASTORE_ATTR = "IMAGE_PREFIX"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Добавьте TM_MAD_CONF и DS_MAD_CONF для Vitastor:
|
||||||
|
|
||||||
|
```
|
||||||
|
TM_MAD_CONF = [
|
||||||
|
NAME = "vitastor", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES",
|
||||||
|
DS_MIGRATE = "NO", DRIVER = "raw", ALLOW_ORPHANS="format",
|
||||||
|
TM_MAD_SYSTEM = "ssh,shared", LN_TARGET_SSH = "SYSTEM", CLONE_TARGET_SSH = "SYSTEM",
|
||||||
|
DISK_TYPE_SSH = "FILE", LN_TARGET_SHARED = "NONE",
|
||||||
|
CLONE_TARGET_SHARED = "SELF", DISK_TYPE_SHARED = "FILE"
|
||||||
|
]
|
||||||
|
|
||||||
|
DS_MAD_CONF = [
|
||||||
|
NAME = "vitastor",
|
||||||
|
REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST",
|
||||||
|
PERSISTENT_ONLY = "NO",
|
||||||
|
MARKETPLACE_ACTIONS = "export"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Создайте хранилища
|
||||||
|
|
||||||
|
Примеры настроек хранилищ образов (image) и дисков ВМ (system):
|
||||||
|
[opennebula/vitastor-imageds.conf](../../opennebula/vitastor-imageds.conf) и
|
||||||
|
[opennebula/vitastor-systemds.conf](../../opennebula/vitastor-systemds.conf).
|
||||||
|
|
||||||
|
Скопируйте настройки и поменяйте следующие параметры так, как вам необходимо:
|
||||||
|
|
||||||
|
- POOL_NAME - имя пула Vitastor для сохранения образов дисков.
|
||||||
|
- IMAGE_PREFIX - строка, добавляемая в начало имён образов дисков.
|
||||||
|
- BRIDGE_LIST - список серверов с доступом к кластеру Vitastor, используемых для операций с хранилищем образов (image, не system).
|
||||||
|
- VITASTOR_CONF - путь к конфигурации Vitastor. Имейте в виду, что этот путь также надо добавить в `/etc/apparmor.d/local/abstractions/libvirt-qemu`, если вы используете AppArmor.
|
||||||
|
- STAGING_DIR - путь к временному каталогу, используемому при импорте внешних образов. Должен иметь достаточно свободного места, чтобы вмещать скачанные образы.
|
||||||
|
|
||||||
|
После этого создайте хранилища с помощью команд `onedatastore create vitastor-imageds.conf` и `onedatastore create vitastor-systemds.conf` (либо через UI).
|
||||||
|
|
||||||
|
## Блокировка доступа ВМ в Vitastor
|
||||||
|
|
||||||
|
Vitastor пока не поддерживает никакую аутентификацию, так что вы ДОЛЖНЫ заблокировать доступ гостевых ВМ
|
||||||
|
в кластер Vitastor на сетевом уровне.
|
||||||
|
|
||||||
|
Если вы используете VLAN-сети для ВМ - удостоверьтесь, что ВМ и гипервизор/сеть хранения помещены в разные
|
||||||
|
изолированные друг от друга VLAN-ы.
|
||||||
|
|
||||||
|
Если вы используете что-то более примитивное, например, мосты (bridge), вам, скорее всего, придётся вручную
|
||||||
|
настроить iptables / межсетевой экран, чтобы разрешить доступ к Vitastor только с IP гипервизоров.
|
||||||
|
|
||||||
|
Также в этом случае нужно будет переключить обычные мосты на "Bridged & Security Groups" и включить фильтр
|
||||||
|
спуфинга IP в OpenNebula. Правда, реализация этого фильтра пока не полная, и она не блокирует доступ к
|
||||||
|
локальным интерфейсам гипервизора. То есть, включённый фильтр спуфинга IP запрещает ВМ отправлять трафик
|
||||||
|
с чужими IP к другим ВМ или во внешний мир, но не запрещает отправлять его напрямую гипервизору. Чтобы
|
||||||
|
исправить это, тоже нужны дополнительные правила iptables.
|
||||||
|
|
||||||
|
Таким образом, более-менее полная блокировка при использовании простой сети на сетевых мостах может
|
||||||
|
выглядеть так (здесь `10.0.3.0/24` - подсеть ВМ, `10.0.2.0/24` - подсеть гипервизора):
|
||||||
|
|
||||||
|
```
|
||||||
|
# Разрешаем входящий трафик с физического устройства
|
||||||
|
iptables -A INPUT -m physdev --physdev-in eth0 -j ACCEPT
|
||||||
|
# Запрещаем трафик со всех ВМ, но с IP не из подсети ВМ
|
||||||
|
iptables -A INPUT ! -s 10.0.3.0/24 -i onebr0 -j DROP
|
||||||
|
# Запрещаем трафик от ВМ к сети гипервизора
|
||||||
|
iptables -I FORWARD 1 -s 10.0.3.0/24 -d 10.0.2.0/24 -j DROP
|
||||||
|
```
|
||||||
|
|
||||||
|
## Тестирование
|
||||||
|
|
||||||
|
Плагин OpenNebula по большей части состоит из bash-скриптов, и чтобы было понятнее, что они
|
||||||
|
вообще делают - ниже приведены описания процедур, которыми можно протестировать каждый из них.
|
||||||
|
|
||||||
|
| Скрипт | Описание | Как протестировать |
|
||||||
|
| ----------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||||
|
| vmm/kvm/deploy.vitastor | Запустить виртуальную машину | Создайте и запустите виртуальную машину с дисками Vitastor: постоянным / непостоянным / волатильным (временным). |
|
||||||
|
| vmm/kvm/save.vitastor | Сохранить снимок памяти ВМ | Остановите виртуальную машину командой "Остановить". |
|
||||||
|
| vmm/kvm/restore.vitastor| Восстановить снимок памяти ВМ | Запустите ВМ после остановки обратно. |
|
||||||
|
| datastore/clone | Скопировать образ как "постоянный" | Создайте шаблон ВМ и создайте из него постоянную ВМ. |
|
||||||
|
| datastore/cp | Импортировать внешний образ | Импортируйте шаблон ВМ с образами дисков из Магазина OpenNebula. |
|
||||||
|
| datastore/export | Экспортировать образ как URL | Вероятно: экспортируйте шаблон ВМ с образами в Магазин. |
|
||||||
|
| datastore/mkfs | Создать образ с файловой системой | Хранилище → Образы → Создать → Тип: базовый блок данных, Расположение: пустой образ диска, Файловая система: любая непустая. |
|
||||||
|
| datastore/monitor | Вывод статистики места в хранилище образов | Проверьте статистику свободного/занятого места в списке хранилищ образов. |
|
||||||
|
| datastore/rm | Удалить "постоянный" образ | Хранилище → Образы → Выберите образ → Удалить. |
|
||||||
|
| datastore/snap_delete | Удалить снимок "постоянного" образа | Хранилище → Образы → Выберите образ → Выберите снимок → Удалить; <br> Чтобы создать образ со снимком: подключите постоянный образ к ВМ, создайте снимок, отключите образ. |
|
||||||
|
| datastore/snap_flatten | Откатить образ к снимку, удалив другие снимки | Хранилище → Образы → Выберите образ → Выберите снимок → "Выровнять" (flatten). |
|
||||||
|
| datastore/snap_revert | Откатить образ к снимку | Хранилище → Образы → Выберите образ → Выберите снимок → Откатить. |
|
||||||
|
| datastore/stat | Показать виртуальный размер образа в МБ | Неизвестно. По-видимому, в плагинах Vitastor и Ceph не используется. |
|
||||||
|
| tm/clone | Клонировать "непостоянный" образ в диск ВМ | Подключите "непостоянный" образ к ВМ. |
|
||||||
|
| tm/context | Создать диск контекстуализации ВМ | Создайте ВМ с контекстуализацией, как обычно. Но тестировать особенно нечего: в плагинах Vitastor и Ceph образ контекста хранится в локальной ФС гипервизора. |
|
||||||
|
| tm/cpds | Копировать диск ВМ/его снимок в новый образ | Выберите ВМ → Выберите диск → Опционально выберите снимок → "Сохранить как". |
|
||||||
|
| tm/delete | Удалить диск-клон или волатильный диск ВМ | Отключите волатильный или не-постоянный диск от ВМ. |
|
||||||
|
| tm/failmigrate | Обработать неудачную миграцию | Тестировать нечего. Скрипт пуст в плагинах Vitastor и Ceph. В других плагинах скрипт должен откатывать действия tm/premigrate. |
|
||||||
|
| tm/ln | Подключить "постоянный" образ к ВМ | Тестировать нечего. Скрипт пуст в плагинах Vitastor и Ceph. |
|
||||||
|
| tm/mkimage | Создать волатильный диск, без или с ФС | Подключите волатильный диск к ВМ, с или без файловой системы. |
|
||||||
|
| tm/mkswap | Создать волатильный диск подкачки | Подключите волатильный диск к ВМ, форматированный как диск подкачки (swap). |
|
||||||
|
| tm/monitor | Вывод статистики места в хранилище дисков ВМ | Проверьте статистику свободного/занятого места в списке хранилищ дисков ВМ. |
|
||||||
|
| tm/mv | Мигрировать диск ВМ между хостами | Мигрируйте ВМ между серверами. Правда, с точки зрения хранилища в плагинах Vitastor и Ceph этот скрипт ничего не делает. |
|
||||||
|
| tm/mvds | Отключить "постоянный" образ от ВМ | Тестировать нечего. Скрипт пуст в плагинах Vitastor и Ceph. В целом же скрипт обратный к tm/ln и в других хранилищах он может, например, копировать образ ВМ с диска гипервизора обратно в хранилище. |
|
||||||
|
| tm/postbackup | Выполняется после бэкапа | По-видимому, скрипт просто удаляет временные файлы после резервного копирования. Так что можно провести его и проверить, что на серверах не осталось временных файлов. |
|
||||||
|
| tm/postbackup_live | Выполняется после бэкапа запущенной ВМ | То же, что tm/postbackup, но для запущенной ВМ. |
|
||||||
|
| tm/postmigrate | Выполняется после миграции ВМ | Тестировать нечего. Однако, OpenNebula запускает скрипт только для системного хранилища, поэтому он вызывает аналогичные скрипты для хранилищ других дисков той же ВМ. Помимо этого в плагинах Vitastor и Ceph скрипт ничего не делает. |
|
||||||
|
| tm/prebackup | Выполнить резервное копирование дисков ВМ | Создайте хранилище резервных копий типа "rsync" → Забэкапьте в него ВМ. |
|
||||||
|
| tm/prebackup_live | То же самое для запущенной ВМ | То же, что tm/prebackup, но запускает fsfreeze/thaw (остановку доступа к дискам). Так что смысл теста - проведите резервное копирование и проверьте, что данные скопировались консистентно. |
|
||||||
|
| tm/premigrate | Выполняется перед миграцией ВМ | Тестировать нечего. Аналогично tm/postmigrate запускается только для системного хранилища. |
|
||||||
|
| tm/resize | Изменить размер диска ВМ | Выберите ВМ → Выберите непостоянный диск → Измените его размер. |
|
||||||
|
| tm/restore | Восстановить диски ВМ из бэкапа | Создайте хранилище резервных копий → Забэкапьте в него ВМ → Восстановите её обратно. |
|
||||||
|
| tm/snap_create | Создать снимок диска ВМ | Выберите ВМ → Выберите диск → Создайте снимок. |
|
||||||
|
| tm/snap_create_live | Создать снимок диска запущенной ВМ | Выберите запущенную ВМ → Выберите диск → Создайте снимок. |
|
||||||
|
| tm/snap_delete | Удалить снимок диска ВМ | Выберите ВМ → Выберите диск → Выберите снимок → Удалить. |
|
||||||
|
| tm/snap_revert | Откатить диск ВМ к снимку | Выберите ВМ → Выберите диск → Выберите снимок → Откатить. |
|
||||||
@@ -16,8 +16,6 @@
|
|||||||
- Debian 10 (Buster): `deb https://vitastor.io/debian buster main`
|
- Debian 10 (Buster): `deb https://vitastor.io/debian buster main`
|
||||||
- Add `-oldstable` to bookworm/bullseye/buster in this line to install the last
|
- Add `-oldstable` to bookworm/bullseye/buster in this line to install the last
|
||||||
stable version from 0.9.x branch instead of 1.x
|
stable version from 0.9.x branch instead of 1.x
|
||||||
- For Debian 10 (Buster) also enable backports repository:
|
|
||||||
`deb http://deb.debian.org/debian buster-backports main`
|
|
||||||
- Install packages: `apt update; apt install vitastor lp-solve etcd linux-image-amd64 qemu-system-x86`
|
- Install packages: `apt update; apt install vitastor lp-solve etcd linux-image-amd64 qemu-system-x86`
|
||||||
|
|
||||||
## CentOS
|
## CentOS
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
- Debian 10 (Buster): `deb https://vitastor.io/debian buster main`
|
- Debian 10 (Buster): `deb https://vitastor.io/debian buster main`
|
||||||
- Добавьте `-oldstable` к слову bookworm/bullseye/buster в этой строке, чтобы
|
- Добавьте `-oldstable` к слову bookworm/bullseye/buster в этой строке, чтобы
|
||||||
установить последнюю стабильную версию из ветки 0.9.x вместо 1.x
|
установить последнюю стабильную версию из ветки 0.9.x вместо 1.x
|
||||||
- Для Debian 10 (Buster) также включите репозиторий backports:
|
|
||||||
`deb http://deb.debian.org/debian buster-backports main`
|
|
||||||
- Установите пакеты: `apt update; apt install vitastor lp-solve etcd linux-image-amd64 qemu-system-x86`
|
- Установите пакеты: `apt update; apt install vitastor lp-solve etcd linux-image-amd64 qemu-system-x86`
|
||||||
|
|
||||||
## CentOS
|
## CentOS
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ To enable Vitastor support in Proxmox Virtual Environment (6.4-8.1 are supported
|
|||||||
- Restart pvedaemon: `systemctl restart pvedaemon`
|
- Restart pvedaemon: `systemctl restart pvedaemon`
|
||||||
|
|
||||||
`/etc/pve/storage.cfg` example (the only required option is vitastor_pool, all others
|
`/etc/pve/storage.cfg` example (the only required option is vitastor_pool, all others
|
||||||
are listed below with their default values):
|
are listed below with their default values; `vitastor_ssd` is Proxmox storage pool id):
|
||||||
|
|
||||||
```
|
```
|
||||||
vitastor: vitastor
|
vitastor: vitastor_ssd
|
||||||
# pool to put new images into
|
# pool to put new images into
|
||||||
vitastor_pool testpool
|
vitastor_pool testpool
|
||||||
# path to the configuration file
|
# path to the configuration file
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
- Перезапустите демон Proxmox: `systemctl restart pvedaemon`
|
- Перезапустите демон Proxmox: `systemctl restart pvedaemon`
|
||||||
|
|
||||||
Пример `/etc/pve/storage.cfg` (единственная обязательная опция - vitastor_pool, все остальные
|
Пример `/etc/pve/storage.cfg` (единственная обязательная опция - vitastor_pool, все остальные
|
||||||
перечислены внизу для понимания значений по умолчанию):
|
перечислены внизу для понимания значений по умолчанию; `vitastor_ssd` - имя хранилища в Proxmox):
|
||||||
|
|
||||||
```
|
```
|
||||||
vitastor: vitastor
|
vitastor: vitastor_ssd
|
||||||
# Пул, в который будут помещаться образы дисков
|
# Пул, в который будут помещаться образы дисков
|
||||||
vitastor_pool testpool
|
vitastor_pool testpool
|
||||||
# Путь к файлу конфигурации
|
# Путь к файлу конфигурации
|
||||||
|
|||||||
@@ -34,9 +34,15 @@
|
|||||||
- [Client write-back cache](../config/client.en.md#client_enable_writeback)
|
- [Client write-back cache](../config/client.en.md#client_enable_writeback)
|
||||||
- [Intelligent recovery auto-tuning](../config/osd.en.md#recovery_tune_interval)
|
- [Intelligent recovery auto-tuning](../config/osd.en.md#recovery_tune_interval)
|
||||||
- [Clustered file system](../usage/nfs.en.md#vitastorfs)
|
- [Clustered file system](../usage/nfs.en.md#vitastorfs)
|
||||||
|
- [Experimental internal etcd replacement - antietcd](../config/monitor.en.md#use_antietcd)
|
||||||
|
- [Built-in Prometheus metric exporter](../config/monitor.en.md#enable_prometheus)
|
||||||
|
|
||||||
## Plugins and tools
|
## Plugins and tools
|
||||||
|
|
||||||
|
- [Proxmox storage plugin and packages](../installation/proxmox.en.md)
|
||||||
|
- [OpenNebula storage plugin](../installation/opennebula.en.md)
|
||||||
|
- [CSI plugin for Kubernetes](../installation/kubernetes.en.md)
|
||||||
|
- [OpenStack support: Cinder driver, Nova and libvirt patches](../installation/openstack.en.md)
|
||||||
- [Debian and CentOS packages](../installation/packages.en.md)
|
- [Debian and CentOS packages](../installation/packages.en.md)
|
||||||
- [Image management CLI (vitastor-cli)](../usage/cli.en.md)
|
- [Image management CLI (vitastor-cli)](../usage/cli.en.md)
|
||||||
- [Disk management CLI (vitastor-disk)](../usage/disk.en.md)
|
- [Disk management CLI (vitastor-disk)](../usage/disk.en.md)
|
||||||
@@ -44,9 +50,6 @@
|
|||||||
- [Native QEMU driver](../usage/qemu.en.md)
|
- [Native QEMU driver](../usage/qemu.en.md)
|
||||||
- [Loadable fio engine for benchmarks](../usage/fio.en.md)
|
- [Loadable fio engine for benchmarks](../usage/fio.en.md)
|
||||||
- [NBD proxy for kernel mounts](../usage/nbd.en.md)
|
- [NBD proxy for kernel mounts](../usage/nbd.en.md)
|
||||||
- [CSI plugin for Kubernetes](../installation/kubernetes.en.md)
|
|
||||||
- [OpenStack support: Cinder driver, Nova and libvirt patches](../installation/openstack.en.md)
|
|
||||||
- [Proxmox storage plugin and packages](../installation/proxmox.en.md)
|
|
||||||
- [Simplified NFS proxy for file-based image access emulation (suitable for VMWare)](../usage/nfs.en.md#pseudo-fs)
|
- [Simplified NFS proxy for file-based image access emulation (suitable for VMWare)](../usage/nfs.en.md#pseudo-fs)
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
@@ -56,7 +59,6 @@ The following features are planned for the future:
|
|||||||
- Control plane optimisation
|
- Control plane optimisation
|
||||||
- Other administrative tools
|
- Other administrative tools
|
||||||
- Web GUI
|
- Web GUI
|
||||||
- OpenNebula plugin
|
|
||||||
- iSCSI and NVMeoF gateways
|
- iSCSI and NVMeoF gateways
|
||||||
- Multi-threaded client
|
- Multi-threaded client
|
||||||
- Faster failover
|
- Faster failover
|
||||||
|
|||||||
@@ -36,9 +36,15 @@
|
|||||||
- [Буферизация записи на стороне клиента](../config/client.ru.md#client_enable_writeback)
|
- [Буферизация записи на стороне клиента](../config/client.ru.md#client_enable_writeback)
|
||||||
- [Интеллектуальная автоподстройка скорости восстановления](../config/osd.ru.md#recovery_tune_interval)
|
- [Интеллектуальная автоподстройка скорости восстановления](../config/osd.ru.md#recovery_tune_interval)
|
||||||
- [Кластерная файловая система](../usage/nfs.ru.md#vitastorfs)
|
- [Кластерная файловая система](../usage/nfs.ru.md#vitastorfs)
|
||||||
|
- [Экспериментальная встроенная замена etcd - antietcd](../config/monitor.ru.md#use_antietcd)
|
||||||
|
- [Встроенный Prometheus-экспортер метрик](../config/monitor.ru.md#enable_prometheus)
|
||||||
|
|
||||||
## Драйверы и инструменты
|
## Драйверы и инструменты
|
||||||
|
|
||||||
|
- [Плагин для Proxmox](../installation/proxmox.ru.md)
|
||||||
|
- [Плагин для OpenNebula](../installation/opennebula.ru.md)
|
||||||
|
- [CSI-плагин для Kubernetes](../installation/kubernetes.ru.md)
|
||||||
|
- [Базовая поддержка OpenStack: драйвер Cinder, патчи для Nova и libvirt](../installation/openstack.ru.md)
|
||||||
- [Пакеты для Debian и CentOS](../installation/packages.ru.md)
|
- [Пакеты для Debian и CentOS](../installation/packages.ru.md)
|
||||||
- [Консольный интерфейс управления образами (vitastor-cli)](../usage/cli.ru.md)
|
- [Консольный интерфейс управления образами (vitastor-cli)](../usage/cli.ru.md)
|
||||||
- [Инструмент управления дисками (vitastor-disk)](../usage/disk.ru.md)
|
- [Инструмент управления дисками (vitastor-disk)](../usage/disk.ru.md)
|
||||||
@@ -46,9 +52,6 @@
|
|||||||
- [Драйвер диска для QEMU](../usage/qemu.ru.md)
|
- [Драйвер диска для QEMU](../usage/qemu.ru.md)
|
||||||
- [Драйвер диска для утилиты тестирования производительности fio](../usage/fio.ru.md)
|
- [Драйвер диска для утилиты тестирования производительности fio](../usage/fio.ru.md)
|
||||||
- [NBD-прокси для монтирования образов ядром](../usage/nbd.ru.md) ("блочное устройство в режиме пользователя")
|
- [NBD-прокси для монтирования образов ядром](../usage/nbd.ru.md) ("блочное устройство в режиме пользователя")
|
||||||
- [CSI-плагин для Kubernetes](../installation/kubernetes.ru.md)
|
|
||||||
- [Базовая поддержка OpenStack: драйвер Cinder, патчи для Nova и libvirt](../installation/openstack.ru.md)
|
|
||||||
- [Плагин для Proxmox](../installation/proxmox.ru.md)
|
|
||||||
- [Упрощённая NFS-прокси для эмуляции файлового доступа к образам (подходит для VMWare)](../usage/nfs.ru.md#псевдо-фс)
|
- [Упрощённая NFS-прокси для эмуляции файлового доступа к образам (подходит для VMWare)](../usage/nfs.ru.md#псевдо-фс)
|
||||||
|
|
||||||
## Планы развития
|
## Планы развития
|
||||||
@@ -56,7 +59,6 @@
|
|||||||
- Оптимизация слоя управления
|
- Оптимизация слоя управления
|
||||||
- Другие инструменты администрирования
|
- Другие инструменты администрирования
|
||||||
- Web-интерфейс
|
- Web-интерфейс
|
||||||
- Плагин для OpenNebula
|
|
||||||
- iSCSI и NVMeoF прокси
|
- iSCSI и NVMeoF прокси
|
||||||
- Многопоточный клиент
|
- Многопоточный клиент
|
||||||
- Более быстрое переключение при отказах
|
- Более быстрое переключение при отказах
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
with lazy fsync, but prepare for inferior single-thread latency. Read more about capacitors
|
with lazy fsync, but prepare for inferior single-thread latency. Read more about capacitors
|
||||||
[here](../config/layout-cluster.en.md#immediate_commit).
|
[here](../config/layout-cluster.en.md#immediate_commit).
|
||||||
- If you want to use HDDs, get modern HDDs with Media Cache or SSD Cache: HGST Ultrastar,
|
- If you want to use HDDs, get modern HDDs with Media Cache or SSD Cache: HGST Ultrastar,
|
||||||
Toshiba MG08, Seagate EXOS or something similar. If your drives don't have such cache then
|
Toshiba MG, Seagate EXOS or something similar. If your drives don't have such cache then
|
||||||
you also need small SSDs for journal and metadata (even 2 GB per 1 TB of HDD space is enough).
|
you also need small SSDs for journal and metadata (even 2 GB per 1 TB of HDD space is enough).
|
||||||
- Get a fast network (at least 10 Gbit/s). Something like Mellanox ConnectX-4 with RoCEv2 is ideal.
|
- Get a fast network (at least 10 Gbit/s). Something like Mellanox ConnectX-4 with RoCEv2 is ideal.
|
||||||
- Disable CPU powersaving: `cpupower idle-set -D 0 && cpupower frequency-set -g performance`.
|
- Disable CPU powersaving: `cpupower idle-set -D 0 && cpupower frequency-set -g performance`.
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
- SATA SSD: Micron 5100/5200/5300/5400, Samsung PM863/PM883/PM893, Intel D3-S4510/4520/4610/4620, Kingston DC500M
|
- SATA SSD: Micron 5100/5200/5300/5400, Samsung PM863/PM883/PM893, Intel D3-S4510/4520/4610/4620, Kingston DC500M
|
||||||
- NVMe: Micron 9100/9200/9300/9400, Micron 7300/7450, Samsung PM983/PM9A3, Samsung PM1723/1735/1743,
|
- NVMe: Micron 9100/9200/9300/9400, Micron 7300/7450, Samsung PM983/PM9A3, Samsung PM1723/1735/1743,
|
||||||
Intel DC-P3700/P4500/P4600, Intel D7-P5500/P5600, Intel Optane, Kingston DC1000B/DC1500M
|
Intel DC-P3700/P4500/P4600, Intel D7-P5500/P5600, Intel Optane, Kingston DC1000B/DC1500M
|
||||||
- HDD: HGST Ultrastar, Toshiba MG06/MG07/MG08, Seagate EXOS
|
- HDD: HGST Ultrastar, Toshiba MG, Seagate EXOS
|
||||||
|
|
||||||
## Configure monitors
|
## Configure monitors
|
||||||
|
|
||||||
@@ -68,10 +68,6 @@ On the monitor hosts:
|
|||||||
but some free unpartitioned space must be available because the script creates new partitions for journals.
|
but some free unpartitioned space must be available because the script creates new partitions for journals.
|
||||||
- You can change OSD configuration in units or in `vitastor.conf`.
|
- You can change OSD configuration in units or in `vitastor.conf`.
|
||||||
Check [Configuration Reference](../config.en.md) for parameter descriptions.
|
Check [Configuration Reference](../config.en.md) for parameter descriptions.
|
||||||
- If all your drives have capacitors, and even if not, but if you ran `vitastor-disk`
|
|
||||||
without `--disable_data_fsync off` at the first step, then put the following
|
|
||||||
setting into etcd: \
|
|
||||||
`etcdctl --endpoints=... put /vitastor/config/global '{"immediate_commit":"all"}'`
|
|
||||||
- Start all OSDs: `systemctl start vitastor.target`
|
- Start all OSDs: `systemctl start vitastor.target`
|
||||||
|
|
||||||
## Create a pool
|
## Create a pool
|
||||||
@@ -88,6 +84,10 @@ For EC pools the configuration should look like the following:
|
|||||||
vitastor-cli create-pool testpool --ec 2+2 --pg_count 256
|
vitastor-cli create-pool testpool --ec 2+2 --pg_count 256
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Add `--immediate_commit none` if you added `--disable_data_fsync off` at the OSD
|
||||||
|
initialization step, or if `vitastor-disk` complained about impossibility to
|
||||||
|
disable drive cache.
|
||||||
|
|
||||||
After you do this, one of the monitors will configure PGs and OSDs will start them.
|
After you do this, one of the monitors will configure PGs and OSDs will start them.
|
||||||
|
|
||||||
If you use HDDs you should also add `"block_size": 1048576` to pool configuration.
|
If you use HDDs you should also add `"block_size": 1048576` to pool configuration.
|
||||||
|
|||||||
@@ -69,11 +69,6 @@
|
|||||||
для журналов, на SSD должно быть доступно свободное нераспределённое место.
|
для журналов, на SSD должно быть доступно свободное нераспределённое место.
|
||||||
- Вы можете менять параметры OSD в юнитах systemd или в `vitastor.conf`. Описания параметров
|
- Вы можете менять параметры OSD в юнитах systemd или в `vitastor.conf`. Описания параметров
|
||||||
смотрите в [справке по конфигурации](../config.ru.md).
|
смотрите в [справке по конфигурации](../config.ru.md).
|
||||||
- Если все ваши диски - серверные с конденсаторами, и даже если нет, но при этом
|
|
||||||
вы не добавляли опцию `--disable_data_fsync off` на первом шаге, а `vitastor-disk`
|
|
||||||
не ругался на невозможность отключения кэша дисков, пропишите следующую настройку
|
|
||||||
в глобальную конфигурацию в etcd: \
|
|
||||||
`etcdctl --endpoints=... put /vitastor/config/global '{"immediate_commit":"all"}'`.
|
|
||||||
- Запустите все OSD: `systemctl start vitastor.target`
|
- Запустите все OSD: `systemctl start vitastor.target`
|
||||||
|
|
||||||
## Создайте пул
|
## Создайте пул
|
||||||
@@ -90,6 +85,10 @@ vitastor-cli create-pool testpool --pg_size 2 --pg_count 256
|
|||||||
vitastor-cli create-pool testpool --ec 2+2 --pg_count 256
|
vitastor-cli create-pool testpool --ec 2+2 --pg_count 256
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Добавьте также опцию `--immediate_commit none`, если вы добавляли `--disable_data_fsync off`
|
||||||
|
на этапе инициализации OSD, либо если `vitastor-disk` ругался на невозможность отключения
|
||||||
|
кэша дисков.
|
||||||
|
|
||||||
После этого один из мониторов должен сконфигурировать PG, а OSD должны запустить их.
|
После этого один из мониторов должен сконфигурировать PG, а OSD должны запустить их.
|
||||||
|
|
||||||
Если вы используете HDD-диски, то добавьте в конфигурацию пулов опцию `"block_size": 1048576`.
|
Если вы используете HDD-диски, то добавьте в конфигурацию пулов опцию `"block_size": 1048576`.
|
||||||
@@ -123,4 +122,4 @@ vitastor-cli create -s 10G testimg
|
|||||||
Если вы хотите использовать не только блочные образы виртуальных машин или контейнеров,
|
Если вы хотите использовать не только блочные образы виртуальных машин или контейнеров,
|
||||||
а также кластерную файловую систему, то:
|
а также кластерную файловую систему, то:
|
||||||
|
|
||||||
- [Следуйте инструкциям](../usage/nfs.en.md#vitastorfs)
|
- [Следуйте инструкциям](../usage/nfs.ru.md#vitastorfs)
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: Common Parameters
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
These are the most common parameters which apply to all components of Vitastor.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: Общие параметры
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
Это наиболее общие параметры, используемые всеми компонентами Vitastor.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Cluster-Wide Disk Layout Parameters
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
These parameters apply to clients and OSDs, are fixed at the moment of OSD drive
|
||||||
|
initialization and can't be changed after it without losing data.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Дисковые параметры уровня кластера
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются клиентами и OSD, задаются в момент инициализации
|
||||||
|
диска OSD и не могут быть изменены после этого без потери данных.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: OSD Disk Layout Parameters
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
These parameters apply to OSDs, are fixed at the moment of OSD drive
|
||||||
|
initialization and can't be changed after it without losing data.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: Дисковые параметры OSD
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются только OSD и, также как и общекластерные
|
||||||
|
дисковые параметры, задаются в момент инициализации дисков OSD и не могут быть
|
||||||
|
изменены после этого без потери данных.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: Monitor Parameters
|
||||||
|
weight: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
These parameters only apply to Monitors.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: Параметры мониторов
|
||||||
|
weight: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются только мониторами Vitastor.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Network Protocol Parameters
|
||||||
|
weight: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
These parameters apply to clients and OSDs and affect network connection logic
|
||||||
|
between clients, OSDs and etcd.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Параметры сетевого протокола
|
||||||
|
weight: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются клиентами и OSD и влияют на логику сетевого
|
||||||
|
взаимодействия между клиентами, OSD, а также etcd.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Runtime OSD Parameters
|
||||||
|
weight: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
These parameters only apply to OSDs, are not fixed at the moment of OSD drive
|
||||||
|
initialization and can be changed with an OSD restart.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: Изменяемые параметры OSD
|
||||||
|
weight: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются только OSD, но, в отличие от дисковых параметров,
|
||||||
|
не фиксируются в момент инициализации дисков OSD и могут быть изменены в любой
|
||||||
|
момент с перезапуском OSD.
|
||||||
+52
-21
@@ -42,7 +42,7 @@ PG state always includes exactly 1 of the following base states:
|
|||||||
- **offline** — PG isn't activated by any OSD at all. Either primary OSD isn't set for
|
- **offline** — PG isn't activated by any OSD at all. Either primary OSD isn't set for
|
||||||
this PG at all (if the pool is just created), or an unavailable OSD is set as primary,
|
this PG at all (if the pool is just created), or an unavailable OSD is set as primary,
|
||||||
or the primary OSD refuses to start this PG (for example, because of wrong block_size),
|
or the primary OSD refuses to start this PG (for example, because of wrong block_size),
|
||||||
or the PG is stopped by the monitor using `pause: true` flag in `/vitastor/config/pgs` in etcd.
|
or the PG is stopped by the monitor using `pause: true` flag in `/vitastor/pg/config` in etcd.
|
||||||
- **starting** — primary OSD has acquired PG lock in etcd, PG is starting.
|
- **starting** — primary OSD has acquired PG lock in etcd, PG is starting.
|
||||||
- **peering** — primary OSD requests PG object listings from secondary OSDs and calculates
|
- **peering** — primary OSD requests PG object listings from secondary OSDs and calculates
|
||||||
the PG state.
|
the PG state.
|
||||||
@@ -107,16 +107,17 @@ If a PG is active it can also have any number of the following additional states
|
|||||||
|
|
||||||
## Removing a healthy disk
|
## Removing a healthy disk
|
||||||
|
|
||||||
Befor removing a healthy disk from the cluster set its OSD weight(s) to 0 to
|
Before removing a healthy disk from the cluster set its OSD weight(s) to 0 to
|
||||||
move data away. To do that, add `"reweight":0` to etcd key `/vitastor/config/osd/<OSD_NUMBER>`.
|
move data away. To do that, run `vitastor-cli modify-osd --reweight 0 <НОМЕР_OSD>`.
|
||||||
For example:
|
|
||||||
|
Then wait until rebalance finishes and remove OSD by running `vitastor-disk purge /dev/vitastor/osdN-data`.
|
||||||
|
|
||||||
|
Zero weight can also be put manually into etcd key `/vitastor/config/osd/<НОМЕР_OSD>`, for example:
|
||||||
|
|
||||||
```
|
```
|
||||||
etcdctl --endpoints=http://1.1.1.1:2379/v3 put /vitastor/config/osd/1 '{"reweight":0}'
|
etcdctl --endpoints=http://1.1.1.1:2379/v3 put /vitastor/config/osd/1 '{"reweight":0}'
|
||||||
```
|
```
|
||||||
|
|
||||||
Then wait until rebalance finishes and remove OSD by running `vitastor-disk purge /dev/vitastor/osdN-data`.
|
|
||||||
|
|
||||||
## Removing a failed disk
|
## Removing a failed disk
|
||||||
|
|
||||||
If a disk is already dead, its OSD(s) are likely already stopped.
|
If a disk is already dead, its OSD(s) are likely already stopped.
|
||||||
@@ -149,7 +150,7 @@ POOL_ID=1
|
|||||||
ALL_OSDS=$(etcdctl --endpoints=your_etcd_address:2379 get --keys-only --prefix /vitastor/osd/stats/ | \
|
ALL_OSDS=$(etcdctl --endpoints=your_etcd_address:2379 get --keys-only --prefix /vitastor/osd/stats/ | \
|
||||||
perl -e '$/ = undef; $a = <>; $a =~ s/\s*$//; $a =~ s!/vitastor/osd/stats/!!g; $a =~ s/\s+/,/g; print $a')
|
perl -e '$/ = undef; $a = <>; $a =~ s/\s*$//; $a =~ s!/vitastor/osd/stats/!!g; $a =~ s/\s+/,/g; print $a')
|
||||||
for i in $(seq 1 $PG_COUNT); do
|
for i in $(seq 1 $PG_COUNT); do
|
||||||
etcdctl --endpoints=your_etcd_address:2379 put /vitastor/pg/history/$POOL_ID/$i '{"all_peers":['$ALL_OSDS']}'; done
|
etcdctl --endpoints=your_etcd_address:2379 put /vitastor/pg/history/$POOL_ID/$i '{"all_peers":['$ALL_OSDS']}'
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -168,21 +169,51 @@ Upgrading is performed without stopping clients (VMs/containers), you just need
|
|||||||
upgrade and restart servers one by one. However, ideally you should restart VMs too
|
upgrade and restart servers one by one. However, ideally you should restart VMs too
|
||||||
to make them use the new version of the client library.
|
to make them use the new version of the client library.
|
||||||
|
|
||||||
Exceptions (specific upgrade instructions):
|
### 1.1.x to 1.2.0
|
||||||
- Upgrading <= 1.1.x to 1.2.0 or later, if you use EC n+k with k>=2, is recommended
|
|
||||||
to be performed with full downtime: first you should stop all clients, then all OSDs,
|
|
||||||
then upgrade and start everything back — because versions before 1.2.0 have several
|
|
||||||
bugs leading to invalid data being read in EC n+k, k>=2 configurations in degraded pools.
|
|
||||||
- Versions <= 0.8.7 are incompatible with versions >= 0.9.0, so you should first
|
|
||||||
upgrade from <= 0.8.7 to 0.8.8 or 0.8.9, and only then to >= 0.9.x. If you upgrade
|
|
||||||
without this intermediate step, client I/O will hang until the end of upgrade process.
|
|
||||||
- Upgrading from <= 0.5.x to >= 0.6.x is not supported.
|
|
||||||
|
|
||||||
Rollback:
|
Upgrading version <= 1.1.x to version >= 1.2.0, if you use EC n+k with k>=2, is recommended
|
||||||
- Version 1.0.0 has a new disk format, so OSDs initiaziled on 1.0.0 can't be rolled
|
to be performed with full downtime: first you should stop all clients, then all OSDs,
|
||||||
back to 0.9.x or previous versions.
|
then upgrade and start everything back — because versions before 1.2.0 have several
|
||||||
- Versions before 0.8.0 don't have vitastor-disk, so OSDs, initialized by it, won't
|
bugs leading to invalid data being read in EC n+k, k>=2 configurations in degraded pools.
|
||||||
start with 0.7.x or 0.6.x. :-)
|
|
||||||
|
### 0.8.7 to 0.9.0
|
||||||
|
|
||||||
|
Versions <= 0.8.7 are incompatible with versions >= 0.9.0, so you should first
|
||||||
|
upgrade from <= 0.8.7 to 0.8.8 or 0.8.9, and only then to >= 0.9.x. If you upgrade
|
||||||
|
without this intermediate step, client I/O will hang until the end of upgrade process.
|
||||||
|
|
||||||
|
### 0.5.x to 0.6.x
|
||||||
|
|
||||||
|
Upgrading from <= 0.5.x to >= 0.6.x is not supported.
|
||||||
|
|
||||||
|
## Downgrade
|
||||||
|
|
||||||
|
Downgrade are also allowed freely, except the following specific instructions:
|
||||||
|
|
||||||
|
### 1.8.0 to 1.7.1
|
||||||
|
|
||||||
|
Before downgrading from version >= 1.8.0 to version <= 1.7.1
|
||||||
|
you have to copy /vitastor/pg/config etcd key to /vitastor/config/pgs:
|
||||||
|
|
||||||
|
```
|
||||||
|
etcdctl --endpoints=http://... get --print-value-only /vitastor/pg/config | \
|
||||||
|
etcdctl --endpoints=http://... put /vitastor/config/pgs
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can just install older packages and restart all services.
|
||||||
|
|
||||||
|
If you performed downgrade without first copying that key, run "add all OSDs into the
|
||||||
|
history records of all PGs" from [Restoring from lost pool configuration](#restoring-from-lost-pool-configuration).
|
||||||
|
|
||||||
|
### 1.0.0 to 0.9.x
|
||||||
|
|
||||||
|
Version 1.0.0 has a new disk format, so OSDs initialized on 1.0.0 or later can't
|
||||||
|
be rolled back to 0.9.x or previous versions.
|
||||||
|
|
||||||
|
### 0.8.0 to 0.7.x
|
||||||
|
|
||||||
|
Versions before 0.8.0 don't have vitastor-disk, so OSDs, initialized by it, won't
|
||||||
|
start with older versions (0.4.x - 0.7.x). :-)
|
||||||
|
|
||||||
## OSD memory usage
|
## OSD memory usage
|
||||||
|
|
||||||
|
|||||||
+51
-19
@@ -42,7 +42,7 @@
|
|||||||
- **offline** — PG вообще не активирована ни одним OSD. Либо первичный OSD не назначен вообще
|
- **offline** — PG вообще не активирована ни одним OSD. Либо первичный OSD не назначен вообще
|
||||||
(если пул только создан), либо в качестве первичного назначен недоступный OSD, либо
|
(если пул только создан), либо в качестве первичного назначен недоступный OSD, либо
|
||||||
назначенный OSD отказывается запускать эту PG (например, из-за несовпадения block_size),
|
назначенный OSD отказывается запускать эту PG (например, из-за несовпадения block_size),
|
||||||
либо PG остановлена монитором через флаг `pause: true` в `/vitastor/config/pgs` в etcd.
|
либо PG остановлена монитором через флаг `pause: true` в `/vitastor/pg/config` в etcd.
|
||||||
- **starting** — первичный OSD захватил блокировку PG в etcd, PG запускается.
|
- **starting** — первичный OSD захватил блокировку PG в etcd, PG запускается.
|
||||||
- **peering** — первичный OSD опрашивает вторичные OSD на предмет списков объектов данной PG и рассчитывает её состояние.
|
- **peering** — первичный OSD опрашивает вторичные OSD на предмет списков объектов данной PG и рассчитывает её состояние.
|
||||||
- **repeering** — PG ожидает завершения текущих операций ввода-вывода, после чего перейдёт в состояние **peering**.
|
- **repeering** — PG ожидает завершения текущих операций ввода-вывода, после чего перейдёт в состояние **peering**.
|
||||||
@@ -105,14 +105,16 @@ PG должны очень быстро переходить из них в др
|
|||||||
## Удаление исправного диска
|
## Удаление исправного диска
|
||||||
|
|
||||||
Перед удалением исправного диска из кластера установите его OSD вес в 0, чтобы убрать с него данные.
|
Перед удалением исправного диска из кластера установите его OSD вес в 0, чтобы убрать с него данные.
|
||||||
Для этого добавьте в ключ `/vitastor/config/osd/<НОМЕР_OSD>` в etcd значение `"reweight":0`, например:
|
Для этого выполните команду `vitastor-cli modify-osd --reweight 0 <НОМЕР_OSD>`.
|
||||||
|
|
||||||
|
Дождитесь завершения перебалансировки данных, после чего удалите OSD командой `vitastor-disk purge /dev/vitastor/osdN-data`.
|
||||||
|
|
||||||
|
Также вес 0 можно прописать вручную прямо в etcd в ключ `/vitastor/config/osd/<НОМЕР_OSD>`, например:
|
||||||
|
|
||||||
```
|
```
|
||||||
etcdctl --endpoints=http://1.1.1.1:2379/v3 put /vitastor/config/osd/1 '{"reweight":0}'
|
etcdctl --endpoints=http://1.1.1.1:2379/v3 put /vitastor/config/osd/1 '{"reweight":0}'
|
||||||
```
|
```
|
||||||
|
|
||||||
Дождитесь завершения ребаланса, после чего удалите OSD командой `vitastor-disk purge /dev/vitastor/osdN-data`.
|
|
||||||
|
|
||||||
## Удаление неисправного диска
|
## Удаление неисправного диска
|
||||||
|
|
||||||
Если диск уже умер, его OSD, скорее всего, уже будет/будут остановлен(ы).
|
Если диск уже умер, его OSD, скорее всего, уже будет/будут остановлен(ы).
|
||||||
@@ -145,7 +147,7 @@ POOL_ID=1
|
|||||||
ALL_OSDS=$(etcdctl --endpoints=your_etcd_address:2379 get --keys-only --prefix /vitastor/osd/stats/ | \
|
ALL_OSDS=$(etcdctl --endpoints=your_etcd_address:2379 get --keys-only --prefix /vitastor/osd/stats/ | \
|
||||||
perl -e '$/ = undef; $a = <>; $a =~ s/\s*$//; $a =~ s!/vitastor/osd/stats/!!g; $a =~ s/\s+/,/g; print $a')
|
perl -e '$/ = undef; $a = <>; $a =~ s/\s*$//; $a =~ s!/vitastor/osd/stats/!!g; $a =~ s/\s+/,/g; print $a')
|
||||||
for i in $(seq 1 $PG_COUNT); do
|
for i in $(seq 1 $PG_COUNT); do
|
||||||
etcdctl --endpoints=your_etcd_address:2379 put /vitastor/pg/history/$POOL_ID/$i '{"all_peers":['$ALL_OSDS']}'; done
|
etcdctl --endpoints=your_etcd_address:2379 put /vitastor/pg/history/$POOL_ID/$i '{"all_peers":['$ALL_OSDS']}'
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -164,21 +166,51 @@ done
|
|||||||
достаточно обновлять серверы по одному. Однако, конечно, чтобы запущенные виртуальные машины
|
достаточно обновлять серверы по одному. Однако, конечно, чтобы запущенные виртуальные машины
|
||||||
начали использовать новую версию клиентской библиотеки, их тоже нужно перезапустить.
|
начали использовать новую версию клиентской библиотеки, их тоже нужно перезапустить.
|
||||||
|
|
||||||
Исключения (особые указания при обновлении):
|
### 1.1.x -> 1.2.0
|
||||||
- Обновляться с версий <= 1.1.x до версий >= 1.2.0, если вы используете EC n+k и k>=2,
|
|
||||||
рекомендуется с временной остановкой кластера — сначала нужно остановить всех клиентов,
|
|
||||||
потом все OSD, потом обновить и запустить всё обратно — из-за нескольких багов, которые
|
|
||||||
могли приводить к некорректному чтению данных в деградированных EC-пулах.
|
|
||||||
- Версии <= 0.8.7 несовместимы с версиями >= 0.9.0, поэтому при обновлении с <= 0.8.7
|
|
||||||
нужно сначала обновиться до 0.8.8 или 0.8.9, а уже потом до любых версий >= 0.9.x.
|
|
||||||
Иначе клиентский ввод-вывод зависнет до завершения обновления.
|
|
||||||
- Обновление с версий 0.5.x и более ранних до 0.6.x и более поздних не поддерживается.
|
|
||||||
|
|
||||||
Откат:
|
Обновляться с версий <= 1.1.x до версий >= 1.2.0, если вы используете EC n+k и k>=2,
|
||||||
- В версии 1.0.0 поменялся дисковый формат, поэтому OSD, созданные на версии >= 1.0.0,
|
рекомендуется с временной остановкой кластера — сначала нужно остановить всех клиентов,
|
||||||
нельзя откатить до версии 0.9.x и более ранних.
|
потом все OSD, потом обновить и запустить всё обратно — из-за нескольких багов, которые
|
||||||
- В версиях ранее 0.8.0 нет vitastor-disk, значит, созданные им OSD нельзя откатить
|
могли приводить к некорректному чтению данных в деградированных EC-пулах.
|
||||||
до 0.7.x или 0.6.x. :-)
|
|
||||||
|
### 0.8.7 -> 0.9.0
|
||||||
|
|
||||||
|
Версии <= 0.8.7 несовместимы с версиями >= 0.9.0, поэтому при обновлении с <= 0.8.7
|
||||||
|
нужно сначала обновиться до 0.8.8 или 0.8.9, а уже потом до любых версий >= 0.9.x.
|
||||||
|
Иначе клиентский ввод-вывод зависнет до завершения обновления.
|
||||||
|
|
||||||
|
### 0.5.x -> 0.6.x
|
||||||
|
|
||||||
|
Обновление с версий 0.5.x и более ранних до 0.6.x и более поздних не поддерживается.
|
||||||
|
|
||||||
|
## Откат версии
|
||||||
|
|
||||||
|
Откат (понижение версии) тоже свободно разрешён, кроме указанных ниже случаев:
|
||||||
|
|
||||||
|
### 1.8.0 -> 1.7.1
|
||||||
|
|
||||||
|
Перед понижением версии с >= 1.8.0 до <= 1.7.1 вы должны скопировать ключ
|
||||||
|
etcd `/vitastor/pg/config` в `/vitastor/config/pgs`:
|
||||||
|
|
||||||
|
```
|
||||||
|
etcdctl --endpoints=http://... get --print-value-only /vitastor/pg/config | \
|
||||||
|
etcdctl --endpoints=http://... put /vitastor/config/pgs
|
||||||
|
```
|
||||||
|
|
||||||
|
После этого можно просто установить более старые пакеты и перезапустить все сервисы.
|
||||||
|
|
||||||
|
Если вы откатили версию, не скопировав предварительно этот ключ - выполните "добавление всех
|
||||||
|
OSD в исторические записи всех PG" из раздела [Восстановление потерянной конфигурации пулов](#восстановление-потерянной-конфигурации-пулов).
|
||||||
|
|
||||||
|
### 1.0.0 -> 0.9.x
|
||||||
|
|
||||||
|
В версии 1.0.0 поменялся дисковый формат, поэтому OSD, созданные на версии >= 1.0.0,
|
||||||
|
нельзя откатить до версии 0.9.x и более ранних.
|
||||||
|
|
||||||
|
### 0.8.0 -> 0.7.x
|
||||||
|
|
||||||
|
В версиях ранее 0.8.0 нет vitastor-disk, значит, созданные им OSD не запустятся на
|
||||||
|
более ранних версиях (0.4.x - 0.7.x). :-)
|
||||||
|
|
||||||
## Потребление памяти OSD
|
## Потребление памяти OSD
|
||||||
|
|
||||||
|
|||||||
+130
-7
@@ -16,6 +16,7 @@ It supports the following commands:
|
|||||||
- [create](#create)
|
- [create](#create)
|
||||||
- [snap-create](#create)
|
- [snap-create](#create)
|
||||||
- [modify](#modify)
|
- [modify](#modify)
|
||||||
|
- [dd](#dd)
|
||||||
- [rm](#rm)
|
- [rm](#rm)
|
||||||
- [flatten](#flatten)
|
- [flatten](#flatten)
|
||||||
- [rm-data](#rm-data)
|
- [rm-data](#rm-data)
|
||||||
@@ -24,6 +25,10 @@ It supports the following commands:
|
|||||||
- [fix](#fix)
|
- [fix](#fix)
|
||||||
- [alloc-osd](#alloc-osd)
|
- [alloc-osd](#alloc-osd)
|
||||||
- [rm-osd](#rm-osd)
|
- [rm-osd](#rm-osd)
|
||||||
|
- [osd-tree](#osd-tree)
|
||||||
|
- [ls-osd](#ls-osd)
|
||||||
|
- [modify-osd](#modify-osd)
|
||||||
|
- [pg-list](#pg-list)
|
||||||
- [create-pool](#create-pool)
|
- [create-pool](#create-pool)
|
||||||
- [modify-pool](#modify-pool)
|
- [modify-pool](#modify-pool)
|
||||||
- [ls-pools](#ls-pools)
|
- [ls-pools](#ls-pools)
|
||||||
@@ -144,19 +149,60 @@ You should resize file system in the image, if present, before shrinking it.
|
|||||||
* `-f|--force` - Proceed with shrinking or setting readwrite flag even if the image has children.
|
* `-f|--force` - Proceed with shrinking or setting readwrite flag even if the image has children.
|
||||||
* `--down-ok` - Proceed with shrinking even if some data will be left on unavailable OSDs.
|
* `--down-ok` - Proceed with shrinking even if some data will be left on unavailable OSDs.
|
||||||
|
|
||||||
|
## dd
|
||||||
|
|
||||||
|
```
|
||||||
|
vitastor-cli dd [iimg=<image> | if=<file>] [oimg=<image> | of=<file>] [bs=1M] \
|
||||||
|
[count=N] [seek/oseek=N] [skip/iseek=M] [iodepth=N] [status=progress] \
|
||||||
|
[conv=nocreat,noerror,nofsync,trunc,nosparse] [iflag=direct] [oflag=direct,append]
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy data between Vitastor images, files and pipes.
|
||||||
|
|
||||||
|
Options can be specified in classic dd style (`key=value`) or like usual (`--key value`).
|
||||||
|
|
||||||
|
| <!-- --> | <!-- --> |
|
||||||
|
|-----------------|-------------------------------------------------------------------------|
|
||||||
|
| `iimg=<image>` | Copy from Vitastor image `<image>` |
|
||||||
|
| `if=<file>` | Copy from file `<file>` |
|
||||||
|
| `oimg=<image>` | Copy to Vitastor image `<image>` |
|
||||||
|
| `of=<file>` | Copy to file `<file>` |
|
||||||
|
| `bs=1M` | Set copy block size |
|
||||||
|
| `count=N` | Copy only N input blocks. If N ends in B it counts bytes, not blocks |
|
||||||
|
| `seek/oseek=N` | Skip N output blocks. If N ends in B it counts bytes, not blocks |
|
||||||
|
| `skip/iseek=N` | Skip N input blocks. If N ends in B it counts bytes, not blocks |
|
||||||
|
| `iodepth=N` | Send N reads or writes in parallel (default 4) |
|
||||||
|
| `status=LEVEL` | The LEVEL of information to print to stderr: none/noxfer/progress |
|
||||||
|
| `size=N` | Specify size for the created output file/image (defaults to input size) |
|
||||||
|
| `iflag=direct` | For input files only: use direct I/O |
|
||||||
|
| `oflag=direct` | For output files only: use direct I/O |
|
||||||
|
| `oflag=append` | For files only: append to output file |
|
||||||
|
| `conv=nocreat` | Do not create output file/image |
|
||||||
|
| `conv=trunc` | Truncate output file/image |
|
||||||
|
| `conv=noerror` | Continue copying after errors |
|
||||||
|
| `conv=nofsync` | Do not call fsync before finishing (default behaviour is fsync) |
|
||||||
|
| `conv=nosparse` | Write all output blocks including all-zero blocks |
|
||||||
|
|
||||||
## rm
|
## rm
|
||||||
|
|
||||||
`vitastor-cli rm <from> [<to>] [--writers-stopped] [--down-ok]`
|
`vitastor-cli rm <from> [<to>] [--writers-stopped] [--down-ok]`
|
||||||
|
|
||||||
Remove `<from>` or all layers between `<from>` and `<to>` (`<to>` must be a child of `<from>`),
|
`vitastor-cli rm (--exact|--matching) <glob> ...`
|
||||||
rebasing all their children accordingly. --writers-stopped allows merging to be a bit
|
|
||||||
more effective in case of a single 'slim' read-write child and 'fat' removed parent:
|
|
||||||
the child is merged into parent and parent is renamed to child in that case.
|
|
||||||
In other cases parent layers are always merged into children.
|
|
||||||
|
|
||||||
Other options:
|
Remove layer(s) and rebase all their children accordingly.
|
||||||
|
|
||||||
* `--down-ok` - Continue deletion/merging even if some data will be left on unavailable OSDs.
|
In the first form, remove `<from>` or layers between `<from>` and its child `<to>`.
|
||||||
|
|
||||||
|
In the second form, remove all images with exact or pattern-matched names.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
* `--writers-stopped` allows optimised removal in case of a single 'slim' read-write
|
||||||
|
child and 'fat' removed parent: the child is merged into parent and parent is renamed
|
||||||
|
to child in that case. In other cases parent layers are always merged into children.
|
||||||
|
* `--exact` - remove multiple images with names matching given glob patterns.
|
||||||
|
* `--matching` - remove multiple images with given names
|
||||||
|
* `--down-ok` - continue deletion/merging even if some data will be left on unavailable OSDs.
|
||||||
|
|
||||||
## flatten
|
## flatten
|
||||||
|
|
||||||
@@ -174,6 +220,7 @@ Remove inode data without changing metadata.
|
|||||||
--wait-list Retrieve full objects listings before starting to remove objects.
|
--wait-list Retrieve full objects listings before starting to remove objects.
|
||||||
Requires more memory, but allows to show correct removal progress.
|
Requires more memory, but allows to show correct removal progress.
|
||||||
--min-offset Purge only data starting with specified offset.
|
--min-offset Purge only data starting with specified offset.
|
||||||
|
--max-offset Purge only data before specified offset.
|
||||||
```
|
```
|
||||||
|
|
||||||
## merge-data
|
## merge-data
|
||||||
@@ -246,6 +293,82 @@ Refuses to remove OSDs with data without `--force` and `--allow-data-loss`.
|
|||||||
With `--dry-run` only checks if deletion is possible without data loss and
|
With `--dry-run` only checks if deletion is possible without data loss and
|
||||||
redundancy degradation.
|
redundancy degradation.
|
||||||
|
|
||||||
|
## osd-tree
|
||||||
|
|
||||||
|
`vitastor-cli osd-tree [-l|--long]`
|
||||||
|
|
||||||
|
Show current OSD tree, optionally with I/O statistics if -l is specified.
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
|
||||||
|
```
|
||||||
|
TYPE NAME UP SIZE USED% TAGS WEIGHT BLOCK BITMAP IMM NOOUT
|
||||||
|
host kaveri
|
||||||
|
disk nvme0n1p1
|
||||||
|
osd 3 down 100G 0 % abc,kaveri 1 128k 4k none -
|
||||||
|
osd 4 down 100G 0 % 1 128k 4k none -
|
||||||
|
disk nvme1n1p1
|
||||||
|
osd 5 down 100G 0 % abc,kaveri 1 128k 4k none -
|
||||||
|
osd 6 down 100G 0 % 1 128k 4k none -
|
||||||
|
host stump
|
||||||
|
osd 1 up 100G 37.29 % osdone 1 128k 4k all -
|
||||||
|
osd 2 up 100G 26.8 % abc 1 128k 4k all -
|
||||||
|
osd 7 up 100G 21.84 % 1 128k 4k all -
|
||||||
|
osd 8 up 100G 21.63 % 1 128k 4k all -
|
||||||
|
osd 9 up 100G 20.69 % 1 128k 4k all -
|
||||||
|
osd 10 up 100G 21.61 % 1 128k 4k all -
|
||||||
|
osd 11 up 100G 21.53 % 1 128k 4k all -
|
||||||
|
osd 12 up 100G 22.4 % 1 128k 4k all -
|
||||||
|
```
|
||||||
|
|
||||||
|
## ls-osd
|
||||||
|
|
||||||
|
`vitastor-cli osds|ls-osd|osd-ls [-l|--long]`
|
||||||
|
|
||||||
|
Show current OSDs as list, optionally with I/O statistics if -l is specified.
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
|
||||||
|
```
|
||||||
|
OSD PARENT UP SIZE USED% TAGS WEIGHT BLOCK BITMAP IMM NOOUT
|
||||||
|
3 kaveri/nvme0n1p1 down 100G 0 % globl,kaveri 1 128k 4k none -
|
||||||
|
4 kaveri/nvme0n1p1 down 100G 0 % 1 128k 4k none -
|
||||||
|
5 kaveri/nvme1n1p1 down 100G 0 % globl,kaveri 1 128k 4k none -
|
||||||
|
6 kaveri/nvme1n1p1 down 100G 0 % 1 128k 4k none -
|
||||||
|
1 stump up 100G 37.29 % osdone 1 128k 4k all -
|
||||||
|
2 stump up 100G 26.8 % globl 1 128k 4k all -
|
||||||
|
7 stump up 100G 21.84 % 1 128k 4k all -
|
||||||
|
8 stump up 100G 21.63 % 1 128k 4k all -
|
||||||
|
9 stump up 100G 20.69 % 1 128k 4k all -
|
||||||
|
10 stump up 100G 21.61 % 1 128k 4k all -
|
||||||
|
11 stump up 100G 21.53 % 1 128k 4k all -
|
||||||
|
12 stump up 100G 22.4 % 1 128k 4k all -
|
||||||
|
```
|
||||||
|
|
||||||
|
## modify-osd
|
||||||
|
|
||||||
|
`vitastor-cli modify-osd [--tags tag1,tag2,...] [--reweight <number>] [--noout true/false] <osd_number>`
|
||||||
|
|
||||||
|
Set OSD reweight, tags or noout flag. See detail description in [OSD config documentation](../config/pool.en.md#osd-settings).
|
||||||
|
|
||||||
|
## pg-list
|
||||||
|
|
||||||
|
`vitastor-cli pg-list|pg-ls|list-pg|ls-pg|ls-pgs [OPTIONS] [state1+state2] [^state3] [...]`
|
||||||
|
|
||||||
|
List PGs with any of listed state filters (^ or ! in the beginning is negation). Options:
|
||||||
|
|
||||||
|
```
|
||||||
|
--pool <pool name or number> Only list PGs of the given pool.
|
||||||
|
--min <min pg number> Only list PGs with number >= min.
|
||||||
|
--max <max pg number> Only list PGs with number <= max.
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
`vitastor-cli pg-list active+degraded`
|
||||||
|
|
||||||
|
`vitastor-cli pg-list ^active`
|
||||||
|
|
||||||
## create-pool
|
## create-pool
|
||||||
|
|
||||||
`vitastor-cli create-pool|pool-create <name> (-s <pg_size>|--ec <N>+<K>) -n <pg_count> [OPTIONS]`
|
`vitastor-cli create-pool|pool-create <name> (-s <pg_size>|--ec <N>+<K>) -n <pg_count> [OPTIONS]`
|
||||||
|
|||||||
+130
-9
@@ -17,12 +17,17 @@ vitastor-cli - интерфейс командной строки для адм
|
|||||||
- [create](#create)
|
- [create](#create)
|
||||||
- [snap-create](#create)
|
- [snap-create](#create)
|
||||||
- [modify](#modify)
|
- [modify](#modify)
|
||||||
|
- [dd](#dd)
|
||||||
- [rm](#rm)
|
- [rm](#rm)
|
||||||
- [flatten](#flatten)
|
- [flatten](#flatten)
|
||||||
- [rm-data](#rm-data)
|
- [rm-data](#rm-data)
|
||||||
- [merge-data](#merge-data)
|
- [merge-data](#merge-data)
|
||||||
- [alloc-osd](#alloc-osd)
|
- [alloc-osd](#alloc-osd)
|
||||||
- [rm-osd](#rm-osd)
|
- [rm-osd](#rm-osd)
|
||||||
|
- [osd-tree](#osd-tree)
|
||||||
|
- [ls-osd](#ls-osd)
|
||||||
|
- [modify-osd](#modify-osd)
|
||||||
|
- [pg-list](#pg-list)
|
||||||
- [create-pool](#create-pool)
|
- [create-pool](#create-pool)
|
||||||
- [modify-pool](#modify-pool)
|
- [modify-pool](#modify-pool)
|
||||||
- [ls-pools](#ls-pools)
|
- [ls-pools](#ls-pools)
|
||||||
@@ -147,23 +152,61 @@ vitastor-cli snap-create [-p|--pool <id|name>] <image>@<snapshot>
|
|||||||
* `-f|--force` - Разрешить уменьшение или перевод в чтение-запись образа, у которого есть клоны.
|
* `-f|--force` - Разрешить уменьшение или перевод в чтение-запись образа, у которого есть клоны.
|
||||||
* `--down-ok` - Разрешить уменьшение, даже если часть данных останется неудалённой на недоступных OSD.
|
* `--down-ok` - Разрешить уменьшение, даже если часть данных останется неудалённой на недоступных OSD.
|
||||||
|
|
||||||
|
## dd
|
||||||
|
|
||||||
|
```
|
||||||
|
vitastor-cli dd [iimg=<image> | if=<file>] [oimg=<image> | of=<file>] [bs=1M] \
|
||||||
|
[count=N] [seek/oseek=N] [skip/iseek=M] [iodepth=N] [status=progress] \
|
||||||
|
[conv=nocreat,noerror,nofsync,trunc,nosparse] [iflag=direct] [oflag=direct,append]
|
||||||
|
```
|
||||||
|
|
||||||
|
Копировать данные между образами Vitastor, файлами и каналами.
|
||||||
|
|
||||||
|
Опции можно передавать в классическом стиле dd (`key=value`) или как обычно (`--key value`).
|
||||||
|
|
||||||
|
| <!-- --> | <!-- --> |
|
||||||
|
|-----------------|-------------------------------------------------------------------------|
|
||||||
|
| `iimg=<image>` | Копировать из образа Vitastor `<image>` |
|
||||||
|
| `if=<file>` | Копировать из файла `<file>` |
|
||||||
|
| `oimg=<image>` | Копировать в образ Vitastor `<image>` |
|
||||||
|
| `of=<file>` | Копировать в файл `<file>` |
|
||||||
|
| `bs=1M` | Задать размер блока копирования |
|
||||||
|
| `count=N` | Копировать не более N блоков. Если N заканчивается на B - то N байт. |
|
||||||
|
| `seek/oseek=N` | Пропустить N выходных блоков. Если N заканчивается на B - то N байт. |
|
||||||
|
| `skip/iseek=N` | Пропустить N входных блоков. Если N заканчивается на B - то N байт. |
|
||||||
|
| `iodepth=N` | Отправлять N чтений/записей параллельно (по умолчанию 4). |
|
||||||
|
| `status=LEVEL` | Уровень вывода в консоль: none/noxfer/progress |
|
||||||
|
| `size=N` | Задать размер выходного файла/образа (по умолчанию равен размеру входа).|
|
||||||
|
| `iflag=direct` | Только для входного файла: использовать прямой ввод-вывод |
|
||||||
|
| `oflag=direct` | Только для выходного файла: использовать прямой ввод-вывод |
|
||||||
|
| `oflag=append` | Только для файлов: дописывать в конец выходного файла |
|
||||||
|
| `conv=nocreat` | Не создавать выходной файл/образ |
|
||||||
|
| `conv=trunc` | Обрезать выходной файл/образ до размера входа |
|
||||||
|
| `conv=noerror` | Продолжать копирование после ошибок |
|
||||||
|
| `conv=nofsync` | Не вызывать fsync перед завершением |
|
||||||
|
| `conv=nosparse` | Записывать все выходные блоки, включая пустые |
|
||||||
|
|
||||||
## rm
|
## rm
|
||||||
|
|
||||||
`vitastor-cli rm <from> [<to>] [--writers-stopped] [--down-ok]`
|
`vitastor-cli rm <from> [<to>] [--writers-stopped] [--down-ok]`
|
||||||
|
|
||||||
Удалить образ `<from>` или все слои от `<from>` до `<to>` (`<to>` должен быть дочерним
|
`vitastor-cli rm (--exact|--matching) <glob> ...`
|
||||||
образом `<from>`), одновременно меняя родительские образы их клонов (если таковые есть).
|
|
||||||
|
|
||||||
`--writers-stopped` позволяет чуть более эффективно удалять образы в частом случае, когда
|
Удалить образ(ы), корректно перебазируя их дочерние образы.
|
||||||
у удаляемой цепочки есть только один дочерний образ, содержащий небольшой объём данных.
|
|
||||||
В этом случае дочерний образ вливается в родительский и удаляется, а родительский
|
|
||||||
переименовывается в дочерний.
|
|
||||||
|
|
||||||
В других случаях родительские слои вливаются в дочерние.
|
В первой форме удаляет один образ `<from>` или все слои между `<from>` и его дочерним `<to>`.
|
||||||
|
|
||||||
Другие опции:
|
Во второй форме, удаляет все образы с точными именами или именами, подходящими под шаблон(ы).
|
||||||
|
|
||||||
* `--down-ok` - Продолжать удаление/слияние, даже если часть данных останется неудалённой на недоступных OSD.
|
Опции:
|
||||||
|
|
||||||
|
* `--writers-stopped` позволяет чуть более эффективно удалять образы в частом случае, когда
|
||||||
|
у удаляемой цепочки есть только один дочерний образ, содержащий небольшой объём данных.
|
||||||
|
В этом случае дочерний образ вливается в родительский и удаляется, а родительский
|
||||||
|
переименовывается в дочерний.
|
||||||
|
* `--exact` - удалить все образы с именами, подходящими под переданные glob-шаблоны.
|
||||||
|
* `--matching` - удалить все образы с точно заданными именами.
|
||||||
|
* `--down-ok` - продолжать удаление/слияние, даже если часть данных останется неудалённой на недоступных OSD.
|
||||||
|
|
||||||
## flatten
|
## flatten
|
||||||
|
|
||||||
@@ -182,6 +225,7 @@ vitastor-cli snap-create [-p|--pool <id|name>] <image>@<snapshot>
|
|||||||
--wait-list Сначала запросить полный листинг объектов, а потом начать удалять.
|
--wait-list Сначала запросить полный листинг объектов, а потом начать удалять.
|
||||||
Требует больше памяти, но позволяет правильно печатать прогресс удаления.
|
Требует больше памяти, но позволяет правильно печатать прогресс удаления.
|
||||||
--min-offset Удалять только данные, начиная с заданного смещения.
|
--min-offset Удалять только данные, начиная с заданного смещения.
|
||||||
|
--max-offset Удалять только данные до (исключительно) заданного смещения.
|
||||||
```
|
```
|
||||||
|
|
||||||
## merge-data
|
## merge-data
|
||||||
@@ -263,6 +307,83 @@ vitastor-cli snap-create [-p|--pool <id|name>] <image>@<snapshot>
|
|||||||
С опцией `--dry-run` только проверяет, возможно ли удаление без потери данных и деградации
|
С опцией `--dry-run` только проверяет, возможно ли удаление без потери данных и деградации
|
||||||
избыточности.
|
избыточности.
|
||||||
|
|
||||||
|
## osd-tree
|
||||||
|
|
||||||
|
`vitastor-cli osd-tree [-l|--long]`
|
||||||
|
|
||||||
|
Показать дерево OSD, со статистикой ввода-вывода, если установлено -l.
|
||||||
|
|
||||||
|
Пример вывода:
|
||||||
|
|
||||||
|
```
|
||||||
|
TYPE NAME UP SIZE USED% TAGS WEIGHT BLOCK BITMAP IMM NOOUT
|
||||||
|
host kaveri
|
||||||
|
disk nvme0n1p1
|
||||||
|
osd 3 down 100G 0 % globl,kaveri 1 128k 4k none -
|
||||||
|
osd 4 down 100G 0 % 1 128k 4k none -
|
||||||
|
disk nvme1n1p1
|
||||||
|
osd 5 down 100G 0 % globl,kaveri 1 128k 4k none -
|
||||||
|
osd 6 down 100G 0 % 1 128k 4k none -
|
||||||
|
host stump
|
||||||
|
osd 1 up 100G 37.29 % osdone 1 128k 4k all -
|
||||||
|
osd 2 up 100G 26.8 % globl 1 128k 4k all -
|
||||||
|
osd 7 up 100G 21.84 % 1 128k 4k all -
|
||||||
|
osd 8 up 100G 21.63 % 1 128k 4k all -
|
||||||
|
osd 9 up 100G 20.69 % 1 128k 4k all -
|
||||||
|
osd 10 up 100G 21.61 % 1 128k 4k all -
|
||||||
|
osd 11 up 100G 21.53 % 1 128k 4k all -
|
||||||
|
osd 12 up 100G 22.4 % 1 128k 4k all -
|
||||||
|
```
|
||||||
|
|
||||||
|
## ls-osd
|
||||||
|
|
||||||
|
`vitastor-cli osds|ls-osd|osd-ls [-l|--long]`
|
||||||
|
|
||||||
|
Показать список OSD, со статистикой ввода-вывода, если установлено -l.
|
||||||
|
|
||||||
|
Пример вывода:
|
||||||
|
|
||||||
|
```
|
||||||
|
OSD PARENT UP SIZE USED% TAGS WEIGHT BLOCK BITMAP IMM NOOUT
|
||||||
|
3 kaveri/nvme0n1p1 down 100G 0 % globl,kaveri 1 128k 4k none -
|
||||||
|
4 kaveri/nvme0n1p1 down 100G 0 % 1 128k 4k none -
|
||||||
|
5 kaveri/nvme1n1p1 down 100G 0 % globl,kaveri 1 128k 4k none -
|
||||||
|
6 kaveri/nvme1n1p1 down 100G 0 % 1 128k 4k none -
|
||||||
|
1 stump up 100G 37.29 % osdone 1 128k 4k all -
|
||||||
|
2 stump up 100G 26.8 % globl 1 128k 4k all -
|
||||||
|
7 stump up 100G 21.84 % 1 128k 4k all -
|
||||||
|
8 stump up 100G 21.63 % 1 128k 4k all -
|
||||||
|
9 stump up 100G 20.69 % 1 128k 4k all -
|
||||||
|
10 stump up 100G 21.61 % 1 128k 4k all -
|
||||||
|
11 stump up 100G 21.53 % 1 128k 4k all -
|
||||||
|
12 stump up 100G 22.4 % 1 128k 4k all -
|
||||||
|
```
|
||||||
|
|
||||||
|
## modify-osd
|
||||||
|
|
||||||
|
`vitastor-cli modify-osd [--tags tag1,tag2,...] [--reweight <number>] [--noout true/false] <osd_number>`
|
||||||
|
|
||||||
|
Установить вес OSD, теги или флаг noout. Смотрите подробное описание в [документации настроек OSD](../config/pool.ru.md#настройки-osd).
|
||||||
|
|
||||||
|
## pg-list
|
||||||
|
|
||||||
|
`vitastor-cli pg-list|pg-ls|list-pg|ls-pg|ls-pgs [OPTIONS] [state1+state2] [^state3] [...]`
|
||||||
|
|
||||||
|
Вывести список PG с состояними, удовлетворяющими любому из переданных фильтров (^ или !
|
||||||
|
в начале фильтра означает отрицание). Опции:
|
||||||
|
|
||||||
|
```
|
||||||
|
--pool <pool name or number> Only list PGs of the given pool.
|
||||||
|
--min <min pg number> Only list PGs with number >= min.
|
||||||
|
--max <max pg number> Only list PGs with number <= max.
|
||||||
|
```
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
`vitastor-cli pg-list active+degraded`
|
||||||
|
|
||||||
|
`vitastor-cli pg-list ^active`
|
||||||
|
|
||||||
## create-pool
|
## create-pool
|
||||||
|
|
||||||
`vitastor-cli create-pool|pool-create <name> (-s <pg_size>|--ec <N>+<K>) -n <pg_count> [OPTIONS]`
|
`vitastor-cli create-pool|pool-create <name> (-s <pg_size>|--ec <N>+<K>) -n <pg_count> [OPTIONS]`
|
||||||
|
|||||||
+33
-4
@@ -11,6 +11,8 @@ Vitastor has two file system implementations. Both can be used via `vitastor-nfs
|
|||||||
Commands:
|
Commands:
|
||||||
- [mount](#mount)
|
- [mount](#mount)
|
||||||
- [start](#start)
|
- [start](#start)
|
||||||
|
- [upgrade](#upgrade)
|
||||||
|
- [defrag](#defrag)
|
||||||
|
|
||||||
## Pseudo-FS
|
## Pseudo-FS
|
||||||
|
|
||||||
@@ -86,10 +88,6 @@ POSIX features currently not implemented in VitastorFS:
|
|||||||
- Modification time (`mtime`) is updated lazily every second (like `-o lazytime`)
|
- Modification time (`mtime`) is updated lazily every second (like `-o lazytime`)
|
||||||
|
|
||||||
Other notable missing features which should be addressed in the future:
|
Other notable missing features which should be addressed in the future:
|
||||||
- Defragmentation of "shared" inodes. Files smaller than pool object size (block_size
|
|
||||||
multiplied by data part count if pool is EC) are internally stored in large block
|
|
||||||
volumes sequentially, one after another, and leave garbage after deleting or resizing.
|
|
||||||
Defragmentator will be implemented to collect this garbage.
|
|
||||||
- Inode ID reuse. Currently inode IDs always grow, the limit is 2^48 inodes, so
|
- Inode ID reuse. Currently inode IDs always grow, the limit is 2^48 inodes, so
|
||||||
in theory you may hit it if you create and delete a very large number of files
|
in theory you may hit it if you create and delete a very large number of files
|
||||||
- Compaction of the key-value B-Tree. Current implementation never merges or deletes
|
- Compaction of the key-value B-Tree. Current implementation never merges or deletes
|
||||||
@@ -139,6 +137,37 @@ Start network NFS server. Options:
|
|||||||
| `--port <PORT>` | use port \<PORT> for NFS services (default is 2049) |
|
| `--port <PORT>` | use port \<PORT> for NFS services (default is 2049) |
|
||||||
| `--portmap 0` | do not listen on port 111 (portmap/rpcbind, requires root) |
|
| `--portmap 0` | do not listen on port 111 (portmap/rpcbind, requires root) |
|
||||||
|
|
||||||
|
### upgrade
|
||||||
|
|
||||||
|
`vitastor-nfs --fs <NAME> upgrade`
|
||||||
|
|
||||||
|
Upgrade FS metadata. Can be run online, but server(s) should be restarted after upgrade.
|
||||||
|
|
||||||
|
### defrag
|
||||||
|
|
||||||
|
`vitastor-nfs --fs <NAME> defrag [OPTIONS] [--dry-run]`
|
||||||
|
|
||||||
|
Defragment volumes used for small file storage having more than \<defrag_percent> %
|
||||||
|
of data removed. Can be run online.
|
||||||
|
|
||||||
|
In VitastorFS, small files are stored in large "volumes" / "shared inodes" one
|
||||||
|
after another. When you delete or extend such files, they are moved and garbage is left
|
||||||
|
behind. Defragmentation removes garbage and moves data still in use to new volumes.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
| <!-- --> | <!-- --> |
|
||||||
|
|--------------------------|------------------------------------------------------------------------ |
|
||||||
|
| --volume_untouched 86400 | Defragment volumes last appended to at least this number of seconds ago |
|
||||||
|
| --defrag_percent 50 | Defragment volumes with at least this % of removed data |
|
||||||
|
| --defrag_block_count 16 | Read this number of pool blocks at once during defrag |
|
||||||
|
| --defrag_iodepth 16 | Move up to this number of files in parallel during defrag |
|
||||||
|
| --trace | Print verbose defragmentation status |
|
||||||
|
| --dry-run | Skip modifications, only print status |
|
||||||
|
| --recalc-stats | Recalculate all volume statistics |
|
||||||
|
| --include-empty | Include old and empty volumes; make sure to restart NFS servers before using it |
|
||||||
|
| --no-rm | Move, but do not delete data |
|
||||||
|
|
||||||
## Common options
|
## Common options
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
| <!-- --> | <!-- --> |
|
||||||
|
|||||||
+36
-5
@@ -11,6 +11,8 @@
|
|||||||
Команды:
|
Команды:
|
||||||
- [mount](#mount)
|
- [mount](#mount)
|
||||||
- [start](#start)
|
- [start](#start)
|
||||||
|
- [upgrade](#upgrade)
|
||||||
|
- [defrag](#defrag)
|
||||||
|
|
||||||
## Псевдо-ФС
|
## Псевдо-ФС
|
||||||
|
|
||||||
@@ -88,11 +90,6 @@ JSON-формате :-). Для инспекции содержимого БД
|
|||||||
- Времена модификации (`mtime`) отслеживаются асинхронно (как будто ФС смонтирована с `-o lazytime`)
|
- Времена модификации (`mtime`) отслеживаются асинхронно (как будто ФС смонтирована с `-o lazytime`)
|
||||||
|
|
||||||
Другие недостающие функции, которые нужно добавить в будущем:
|
Другие недостающие функции, которые нужно добавить в будущем:
|
||||||
- Дефрагментация "общих инодов". На уровне реализации ФС файлы, меньшие, чем размер
|
|
||||||
объекта пула (block_size умножить на число частей данных, если пул EC),
|
|
||||||
упаковываются друг за другом в большие "общие" иноды/тома. Если такие файлы удалять
|
|
||||||
или увеличивать, они перемещаются и оставляют за собой "мусор", вот тут-то и нужен
|
|
||||||
дефрагментатор.
|
|
||||||
- Переиспользование номеров инодов. В текущей реализации номера инодов всё время
|
- Переиспользование номеров инодов. В текущей реализации номера инодов всё время
|
||||||
увеличиваются, так что в теории вы можете упереться в лимит, если насоздаёте
|
увеличиваются, так что в теории вы можете упереться в лимит, если насоздаёте
|
||||||
и наудаляете больше, чем 2^48 файлов.
|
и наудаляете больше, чем 2^48 файлов.
|
||||||
@@ -145,6 +142,40 @@ JSON-формате :-). Для инспекции содержимого БД
|
|||||||
| `--port <PORT>` | использовать порт \<PORT> для NFS-сервисов (по умолчанию 2049) |
|
| `--port <PORT>` | использовать порт \<PORT> для NFS-сервисов (по умолчанию 2049) |
|
||||||
| `--portmap 0` | отключить сервис portmap/rpcbind на порту 111 (по умолчанию включён и требует root привилегий) |
|
| `--portmap 0` | отключить сервис portmap/rpcbind на порту 111 (по умолчанию включён и требует root привилегий) |
|
||||||
|
|
||||||
|
### upgrade
|
||||||
|
|
||||||
|
`vitastor-nfs --fs <NAME> upgrade`
|
||||||
|
|
||||||
|
Обновить метаданные ФС. Можно запускать онлайн (при запущенных серверах NFS), но после выполнения их всё
|
||||||
|
же желательно перезапустить.
|
||||||
|
|
||||||
|
### defrag
|
||||||
|
|
||||||
|
`vitastor-nfs --fs <NAME> defrag [OPTIONS] [--dry-run]`
|
||||||
|
|
||||||
|
Дефрагментировать тома, используемые для хранения мелких файлов, в которых более, чем
|
||||||
|
<defrag_percent> процентов данных удалено. Можно запускать онлайн.
|
||||||
|
|
||||||
|
На уровне реализации ФС файлы, меньшие, чем размер объекта пула (block_size умножить на число
|
||||||
|
частей данных, если пул EC), упаковываются друг за другом в большие "тома" / "общие иноды".
|
||||||
|
Когда такие файлы удаляются или увеличиваются, они перемещаются и оставляют за собой "мусор".
|
||||||
|
|
||||||
|
При дефрагментации мусор удаляется, а всё ещё используемые данные перемещаются в новые тома.
|
||||||
|
|
||||||
|
Опции:
|
||||||
|
|
||||||
|
| <!-- --> | <!-- --> |
|
||||||
|
|--------------------------|------------------------------------------------------------------------ |
|
||||||
|
| --volume_untouched 86400 | Дефрагментировать только тома, в которые уже не писали это число секунд |
|
||||||
|
| --defrag_percent 50 | Дефрагментировать только тома, в которых этот % данных удалён |
|
||||||
|
| --defrag_block_count 16 | Читать это количество блоков пула за один раз |
|
||||||
|
| --defrag_iodepth 16 | Перемещать одновременно до этого числа файлов |
|
||||||
|
| --trace | Печатать детальную статистику дефрагментации |
|
||||||
|
| --dry-run | Не производить никаких изменений, только описать выполняемые действия |
|
||||||
|
| --recalc-stats | Пересчитать и сохранить статистику всех томов |
|
||||||
|
| --include-empty | Дефрагментировать старые и пустые тома; обязательно перезапустите NFS-сервера после использования этой опции |
|
||||||
|
| --no-rm | Перемещать, но не удалять данные |
|
||||||
|
|
||||||
## Общие опции
|
## Общие опции
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
| <!-- --> | <!-- --> |
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: "{{ replace .Name "-" " " | title }}"
|
||||||
|
date: {{ .Date }}
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
baseURL: http://localhost
|
||||||
|
title: Vitastor
|
||||||
|
theme: hugo-geekdoc
|
||||||
|
#languageCode: en-us
|
||||||
|
|
||||||
|
pluralizeListTitles: false
|
||||||
|
|
||||||
|
# Geekdoc required configuration
|
||||||
|
pygmentsUseClasses: true
|
||||||
|
pygmentsCodeFences: true
|
||||||
|
disablePathToLower: true
|
||||||
|
|
||||||
|
# Required if you want to render robots.txt template
|
||||||
|
enableRobotsTXT: true
|
||||||
|
|
||||||
|
defaultContentLanguage: en
|
||||||
|
languages:
|
||||||
|
en:
|
||||||
|
weight: 1
|
||||||
|
languageName: English
|
||||||
|
ru:
|
||||||
|
weight: 1
|
||||||
|
languageName: Русский
|
||||||
|
|
||||||
|
markup:
|
||||||
|
goldmark:
|
||||||
|
renderer:
|
||||||
|
# Needed for mermaid shortcode
|
||||||
|
unsafe: true
|
||||||
|
tableOfContents:
|
||||||
|
startLevel: 1
|
||||||
|
endLevel: 9
|
||||||
|
|
||||||
|
taxonomies:
|
||||||
|
tag: tags
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
## The Idea
|
||||||
|
|
||||||
|
Vitastor is a small, simple and fast clustered block storage (storage for VM drives),
|
||||||
|
architecturally similar to Ceph which means strong consistency, primary-replication,
|
||||||
|
symmetric clustering and automatic data distribution over any number of drives
|
||||||
|
of any size with configurable redundancy (replication or erasure codes/XOR).
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Parameter Reference
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Перечень настроек
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Pool configuration
|
||||||
|
weight: 100
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Packages
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Quick Start
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Building from Source
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: Introduction
|
||||||
|
weight: -1
|
||||||
|
---
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Architecture
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Author and License
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Features
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Example Comparison with Ceph
|
||||||
|
weight: 4
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Vitastor's Theoretical Maximum Performance
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Tuning
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Understanding Storage Performance
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Vitastor CLI
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
{{< toc >}}
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: NBD
|
||||||
|
weight: 6
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: QEMU and qemu-img
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
nav_navigation: Навигация
|
||||||
|
nav_tags: Теги
|
||||||
|
nav_more: Подробнее
|
||||||
|
nav_top: К началу
|
||||||
|
|
||||||
|
form_placeholder_search: Поиск
|
||||||
|
|
||||||
|
error_page_title: Открыта несуществующая страница
|
||||||
|
error_message_title: Потерялись?
|
||||||
|
error_message_code: Ошибка 404
|
||||||
|
error_message_text: >
|
||||||
|
Похоже, страница, которую вы открыли, не существует. Попробуйте найти
|
||||||
|
нужную информацию с <a class="gdoc-error__link" href="{{ . }}">главной страницы</a>.
|
||||||
|
|
||||||
|
button_toggle_dark: Переключить тёмный/светлый/авто режим
|
||||||
|
button_nav_open: Показать навигацию
|
||||||
|
button_nav_close: Скрыть навигацию
|
||||||
|
button_menu_open: Открыть меню
|
||||||
|
button_menu_close: Закрыть меню
|
||||||
|
button_homepage: На главную
|
||||||
|
|
||||||
|
title_anchor_prefix: "Ссылка на:"
|
||||||
|
|
||||||
|
posts_read_more: Читать подробнее
|
||||||
|
posts_read_time:
|
||||||
|
one: "Одна минута на чтение"
|
||||||
|
other: "{{ . }} минут(ы) на чтение"
|
||||||
|
posts_update_prefix: Обновлено
|
||||||
|
|
||||||
|
footer_build_with: >
|
||||||
|
Сделано на <a href="https://gohugo.io/" class="gdoc-footer__link">Hugo</a> с
|
||||||
|
<svg class="icon gdoc_heart"><use xlink:href="#gdoc_heart"></use></svg>
|
||||||
|
footer_legal_notice: Правовая информация
|
||||||
|
footer_privacy_policy: Приватность
|
||||||
|
|
||||||
|
language_switch_no_tranlation_prefix: "Страница не переведена:"
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<footer class="gdoc-footer">
|
||||||
|
<div class="container flex">
|
||||||
|
<div class="flex flex-wrap" style="flex: 1">
|
||||||
|
<span class="gdoc-footer__item gdoc-footer__item--row">
|
||||||
|
© Vitaliy Filippov, 2021+
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
{{ with .Site.Params.GeekdocLegalNotice }}
|
||||||
|
<span class="gdoc-footer__item gdoc-footer__item--row">
|
||||||
|
<a href="{{ . | relURL }}" class="gdoc-footer__link">{{ i18n "footer_legal_notice" }}</a>
|
||||||
|
</span>
|
||||||
|
{{ end }}
|
||||||
|
{{ with .Site.Params.GeekdocPrivacyPolicy }}
|
||||||
|
<span class="gdoc-footer__item gdoc-footer__item--row">
|
||||||
|
<a href="{{ . | relURL }}" class="gdoc-footer__link">{{ i18n "footer_privacy_policy" }}</a>
|
||||||
|
</span>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ if (default true .Site.Params.GeekdocBackToTop) }}
|
||||||
|
<div class="flex flex-25 justify-end">
|
||||||
|
<span class="gdoc-footer__item gdoc-footer__item--row" style="margin-right: 50px">
|
||||||
|
{{ i18n "footer_build_with" | safeHTML }}
|
||||||
|
</span>
|
||||||
|
<span class="gdoc-footer__item">
|
||||||
|
<a class="gdoc-footer__link fake-link" href="#" aria-label="{{ i18n "nav_top" }}">
|
||||||
|
<svg class="icon gdoc_keyboard_arrow_up"><use xlink:href="#gdoc_keyboard_arrow_up"></use></svg>
|
||||||
|
<span class="hidden-mobile">{{ i18n "nav_top" }}</span>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
sodipodi:docname="logo_only2.svg"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
|
||||||
|
id="svg1340"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 100 86.80192"
|
||||||
|
height="86.801918mm"
|
||||||
|
width="100mm"
|
||||||
|
inkscape:export-filename="/var/home/vitali/SVN/vitastor/presentation/logos/logo_only.png"
|
||||||
|
inkscape:export-xdpi="92.889999"
|
||||||
|
inkscape:export-ydpi="92.889999">
|
||||||
|
<defs
|
||||||
|
id="defs1334">
|
||||||
|
<linearGradient
|
||||||
|
osb:paint="gradient"
|
||||||
|
id="linearGradient866">
|
||||||
|
<stop
|
||||||
|
id="stop862"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#c0c0c0;stop-opacity:1" />
|
||||||
|
<stop
|
||||||
|
id="stop864"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#000000;stop-opacity:0" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient846"
|
||||||
|
osb:paint="gradient">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffd42a;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop842" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffa200;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop844" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
r="50"
|
||||||
|
fy="159.11139"
|
||||||
|
fx="202.36813"
|
||||||
|
cy="159.11139"
|
||||||
|
cx="202.36813"
|
||||||
|
gradientTransform="matrix(1.2462942,-1.2279529,0.77712408,0.78873143,-190.96813,230.1331)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1530"
|
||||||
|
xlink:href="#linearGradient1352"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1352">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#00c9e6;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop1348" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#5240d3;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop1350" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
y2="62.555599"
|
||||||
|
x2="51.484566"
|
||||||
|
y1="62.555599"
|
||||||
|
x1="38.105473"
|
||||||
|
gradientTransform="rotate(-16.930773,271.11609,-412.42594)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient1508"
|
||||||
|
xlink:href="#linearGradient1323"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1323">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0.47178105"
|
||||||
|
offset="0"
|
||||||
|
id="stop1319" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#eeaaff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop1321" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
r="21.541935"
|
||||||
|
fy="24.614815"
|
||||||
|
fx="45.312912"
|
||||||
|
cy="24.614815"
|
||||||
|
cx="45.312912"
|
||||||
|
gradientTransform="matrix(1.0933447,0.13113705,-0.12664108,1.0558599,-1.082187,93.974708)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1504"
|
||||||
|
xlink:href="#linearGradient846"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<filter
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
inkscape:label="Drop Shadow"
|
||||||
|
id="filter1497"
|
||||||
|
width="2"
|
||||||
|
height="2"
|
||||||
|
x="-0.5"
|
||||||
|
y="-0.5">
|
||||||
|
<feFlood
|
||||||
|
flood-opacity="0.498039"
|
||||||
|
flood-color="rgb(0,0,0)"
|
||||||
|
result="flood"
|
||||||
|
id="feFlood1487" />
|
||||||
|
<feComposite
|
||||||
|
in="flood"
|
||||||
|
in2="SourceGraphic"
|
||||||
|
operator="in"
|
||||||
|
result="composite1"
|
||||||
|
id="feComposite1489" />
|
||||||
|
<feGaussianBlur
|
||||||
|
in="composite1"
|
||||||
|
stdDeviation="6"
|
||||||
|
result="blur"
|
||||||
|
id="feGaussianBlur1491" />
|
||||||
|
<feOffset
|
||||||
|
dx="0"
|
||||||
|
dy="6"
|
||||||
|
result="offset"
|
||||||
|
id="feOffset1493" />
|
||||||
|
<feComposite
|
||||||
|
in="offset"
|
||||||
|
in2="offset"
|
||||||
|
operator="atop"
|
||||||
|
result="composite2"
|
||||||
|
id="feComposite1495" />
|
||||||
|
</filter>
|
||||||
|
<radialGradient
|
||||||
|
r="21.541935"
|
||||||
|
fy="24.614815"
|
||||||
|
fx="45.312912"
|
||||||
|
cy="24.614815"
|
||||||
|
cx="45.312912"
|
||||||
|
gradientTransform="matrix(1.0933447,0.13113705,-0.12664108,1.0558599,-1.082187,93.974708)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1506"
|
||||||
|
xlink:href="#linearGradient846"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="992"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-top="-30"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:cy="47.914558"
|
||||||
|
inkscape:cx="-103.69646"
|
||||||
|
inkscape:zoom="0.7"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="1"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#000000"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata1337">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(-133.26969,-52.101187)"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Слой 1">
|
||||||
|
<path
|
||||||
|
style="fill:url(#radialGradient1530);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 133.26969,59.089473 50,75.000087 50,-75.000087 z"
|
||||||
|
id="path1528"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
d="m 194.29572,89.403603 -8.41706,2.562119 -2.50682,7.49308 7.17785,23.579008 9.60097,-14.40173 z"
|
||||||
|
style="fill:url(#linearGradient1508);fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.501961"
|
||||||
|
id="path1459" />
|
||||||
|
<g
|
||||||
|
transform="translate(135.70225,-49.385894)"
|
||||||
|
id="g1465">
|
||||||
|
<path
|
||||||
|
id="path1461"
|
||||||
|
style="fill:url(#radialGradient1504);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter1497)"
|
||||||
|
d="m 28.817436,101.36529 c 3.112699,10.74423 6.225077,21.48892 9.333984,32.23438 2.519532,0 5.039063,0 7.558594,0 -0.985406,8.09729 -2.085815,16.18202 -2.951172,24.29297 -0.06053,0.88723 1.098131,1.61652 1.76,0.9155 1.007514,-1.05482 1.676008,-2.3829 2.528566,-3.56053 7.51538,-11.37722 14.987447,-22.78299 22.482919,-34.17333 -3.239584,0 -6.479167,0 -9.71875,0 2.887267,-6.79562 5.775365,-13.59088 8.662109,-20.38672 -13.284505,0 -26.56901,0 -39.853516,0 0.06576,0.22591 0.131511,0.45182 0.197266,0.67773 z" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccccc"
|
||||||
|
id="path1463"
|
||||||
|
d="m 30.735882,102.2764 h 35.342242 l -8.662729,20.3854 h 9.173783 l -22.106472,33.62346 3.027029,-24.27377 H 39.34604 Z"
|
||||||
|
style="fill:url(#radialGradient1506);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,138 @@
|
|||||||
|
/* Global customization */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--code-max-height: 60rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Light mode theming */
|
||||||
|
:root,
|
||||||
|
:root[color-mode="light"] {
|
||||||
|
--header-background: #404050;
|
||||||
|
--header-font-color: #ffffff;
|
||||||
|
|
||||||
|
--body-background: #ffffff;
|
||||||
|
--body-font-color: #343a40;
|
||||||
|
|
||||||
|
--button-background: #62cb97;
|
||||||
|
--button-border-color: #4ec58a;
|
||||||
|
|
||||||
|
--link-color: #c54e8a;
|
||||||
|
--link-color-visited: #c54e8a;
|
||||||
|
|
||||||
|
--code-background: #f5f6f8;
|
||||||
|
--code-accent-color: #e3e7eb;
|
||||||
|
--code-accent-color-lite: #eff1f3;
|
||||||
|
|
||||||
|
--accent-color: #e9ecef;
|
||||||
|
--accent-color-lite: #f8f9fa;
|
||||||
|
|
||||||
|
--control-icons: #b2bac1;
|
||||||
|
|
||||||
|
--footer-background: #606070;
|
||||||
|
--footer-font-color: #ffffff;
|
||||||
|
--footer-link-color: #ffcc5c;
|
||||||
|
--footer-link-color-visited: #ffcc5c;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
--header-background: #404050;
|
||||||
|
--header-font-color: #ffffff;
|
||||||
|
|
||||||
|
--body-background: #ffffff;
|
||||||
|
--body-font-color: #343a40;
|
||||||
|
|
||||||
|
--button-background: #62cb97;
|
||||||
|
--button-border-color: #4ec58a;
|
||||||
|
|
||||||
|
--link-color: #c54e8a;
|
||||||
|
--link-color-visited: #c54e8a;
|
||||||
|
|
||||||
|
--code-background: #f5f6f8;
|
||||||
|
--code-accent-color: #e3e7eb;
|
||||||
|
--code-accent-color-lite: #eff1f3;
|
||||||
|
|
||||||
|
--accent-color: #e9ecef;
|
||||||
|
--accent-color-lite: #f8f9fa;
|
||||||
|
|
||||||
|
--control-icons: #b2bac1;
|
||||||
|
|
||||||
|
--footer-background: #606070;
|
||||||
|
--footer-font-color: #ffffff;
|
||||||
|
--footer-link-color: #ffcc5c;
|
||||||
|
--footer-link-color-visited: #ffcc5c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode theming */
|
||||||
|
:root[color-mode="dark"] {
|
||||||
|
--header-background: #202830;
|
||||||
|
--header-font-color: #ffffff;
|
||||||
|
|
||||||
|
--body-background: #343a44;
|
||||||
|
--body-font-color: #ced3d8;
|
||||||
|
|
||||||
|
--button-background: #62cb97;
|
||||||
|
--button-border-color: #4ec58a;
|
||||||
|
|
||||||
|
--link-color: #7ac29e;
|
||||||
|
--link-color-visited: #7ac29e;
|
||||||
|
|
||||||
|
--code-background: #2f353a;
|
||||||
|
--code-accent-color: #262b2f;
|
||||||
|
--code-accent-color-lite: #2b3035;
|
||||||
|
|
||||||
|
--accent-color: #2b3035;
|
||||||
|
--accent-color-lite: #2f353a;
|
||||||
|
|
||||||
|
--control-icons: #b2bac1;
|
||||||
|
|
||||||
|
--footer-background: #2f333e;
|
||||||
|
--footer-font-color: #cccccc;
|
||||||
|
--footer-link-color: #7ac29e;
|
||||||
|
--footer-link-color-visited: #7ac29e;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--header-background: #404070;
|
||||||
|
--header-font-color: #ffffff;
|
||||||
|
|
||||||
|
--body-background: #343a40;
|
||||||
|
--body-font-color: #ced3d8;
|
||||||
|
|
||||||
|
--button-background: #62cb97;
|
||||||
|
--button-border-color: #4ec58a;
|
||||||
|
|
||||||
|
--link-color: #7ac29e;
|
||||||
|
--link-color-visited: #7ac29e;
|
||||||
|
|
||||||
|
--code-background: #2f353a;
|
||||||
|
--code-accent-color: #262b2f;
|
||||||
|
--code-accent-color-lite: #2b3035;
|
||||||
|
|
||||||
|
--accent-color: #2b3035;
|
||||||
|
--accent-color-lite: #2f353a;
|
||||||
|
|
||||||
|
--control-icons: #b2bac1;
|
||||||
|
|
||||||
|
--footer-background: #2f333e;
|
||||||
|
--footer-font-color: #cccccc;
|
||||||
|
--footer-link-color: #7ac29e;
|
||||||
|
--footer-link-color-visited: #7ac29e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.gdoc-brand__img {
|
||||||
|
width: 48px;
|
||||||
|
height: auto;
|
||||||
|
margin-top: -4px;
|
||||||
|
margin-bottom: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gdoc-menu-header > span {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.gdoc-language {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 709 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,196 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
sodipodi:docname="favicon.svg"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
|
||||||
|
id="svg1340"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
height="100mm"
|
||||||
|
width="100mm"
|
||||||
|
inkscape:export-filename="/var/home/vitali/SVN/vitastor/docs/static/favicon/favicon-64x64.png"
|
||||||
|
inkscape:export-xdpi="16.26"
|
||||||
|
inkscape:export-ydpi="16.26">
|
||||||
|
<defs
|
||||||
|
id="defs1334">
|
||||||
|
<linearGradient
|
||||||
|
osb:paint="gradient"
|
||||||
|
id="linearGradient866">
|
||||||
|
<stop
|
||||||
|
id="stop862"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#c0c0c0;stop-opacity:1" />
|
||||||
|
<stop
|
||||||
|
id="stop864"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#000000;stop-opacity:0" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient846"
|
||||||
|
osb:paint="gradient">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffd42a;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop842" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffa200;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop844" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
r="50"
|
||||||
|
fy="159.11139"
|
||||||
|
fx="202.36813"
|
||||||
|
cy="159.11139"
|
||||||
|
cx="202.36813"
|
||||||
|
gradientTransform="matrix(1.2462942,-1.2279529,0.77712408,0.78873143,-190.96813,230.1331)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1530"
|
||||||
|
xlink:href="#linearGradient1352"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1352">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#00c9e6;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop1348" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#5240d3;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop1350" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
y2="62.555599"
|
||||||
|
x2="51.484566"
|
||||||
|
y1="62.555599"
|
||||||
|
x1="38.105473"
|
||||||
|
gradientTransform="rotate(-16.930773,271.11609,-412.42594)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient1508"
|
||||||
|
xlink:href="#linearGradient1323"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1323">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0.47178105"
|
||||||
|
offset="0"
|
||||||
|
id="stop1319" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#eeaaff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop1321" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
inkscape:label="Drop Shadow"
|
||||||
|
id="filter1497"
|
||||||
|
width="2"
|
||||||
|
height="2"
|
||||||
|
x="-0.5"
|
||||||
|
y="-0.5">
|
||||||
|
<feFlood
|
||||||
|
flood-opacity="0.498039"
|
||||||
|
flood-color="rgb(0,0,0)"
|
||||||
|
result="flood"
|
||||||
|
id="feFlood1487" />
|
||||||
|
<feComposite
|
||||||
|
in="flood"
|
||||||
|
in2="SourceGraphic"
|
||||||
|
operator="in"
|
||||||
|
result="composite1"
|
||||||
|
id="feComposite1489" />
|
||||||
|
<feGaussianBlur
|
||||||
|
in="composite1"
|
||||||
|
stdDeviation="6"
|
||||||
|
result="blur"
|
||||||
|
id="feGaussianBlur1491" />
|
||||||
|
<feOffset
|
||||||
|
dx="0"
|
||||||
|
dy="6"
|
||||||
|
result="offset"
|
||||||
|
id="feOffset1493" />
|
||||||
|
<feComposite
|
||||||
|
in="offset"
|
||||||
|
in2="offset"
|
||||||
|
operator="atop"
|
||||||
|
result="composite2"
|
||||||
|
id="feComposite1495" />
|
||||||
|
</filter>
|
||||||
|
<radialGradient
|
||||||
|
r="21.541935"
|
||||||
|
fy="24.614815"
|
||||||
|
fx="45.312912"
|
||||||
|
cy="24.614815"
|
||||||
|
cx="45.312912"
|
||||||
|
gradientTransform="matrix(1.6678615,0.20004527,-0.19318681,1.6106796,108.48083,22.966962)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1506"
|
||||||
|
xlink:href="#linearGradient846"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="992"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-top="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:cy="83.752268"
|
||||||
|
inkscape:cx="-103.69645"
|
||||||
|
inkscape:zoom="0.7"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#000000"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata1337">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(-133.26969,-35.630924)"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Слой 1">
|
||||||
|
<path
|
||||||
|
style="fill:url(#radialGradient1530);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 133.26969,59.089473 50,75.000087 50,-75.000087 z"
|
||||||
|
id="path1528"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
d="m 194.29572,89.403603 -8.41706,2.562119 -2.50682,7.49308 7.17785,23.579008 9.60097,-14.40173 z"
|
||||||
|
style="fill:url(#linearGradient1508);fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.501961"
|
||||||
|
id="path1459" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccccc"
|
||||||
|
id="path1463"
|
||||||
|
d="m 157.01826,35.630924 h 53.91343 l -13.21471,31.09726 h 13.99432 l -33.7227,51.291496 4.61762,-37.02885 h -12.45344 z"
|
||||||
|
style="fill:url(#radialGradient1506);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.2 KiB |
+1
-1
Submodule json11 updated: fd37016cf8...52a3af664f
@@ -11,6 +11,7 @@ module.exports = {
|
|||||||
"ecmaVersion": 2020
|
"ecmaVersion": 2020
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
|
"import"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"indent": [
|
"indent": [
|
||||||
@@ -44,6 +45,10 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
"node/shebang": [
|
"node/shebang": [
|
||||||
"off"
|
"off"
|
||||||
|
],
|
||||||
|
"import/no-unresolved": [
|
||||||
|
2,
|
||||||
|
{ "commonjs": true }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,188 @@
|
|||||||
|
// Copyright (c) Vitaliy Filippov, 2019+
|
||||||
|
// License: VNPL-1.1 (see README.md for details)
|
||||||
|
|
||||||
|
const AntiEtcd = require('antietcd');
|
||||||
|
|
||||||
|
const vitastor_persist_filter = require('./vitastor_persist_filter.js');
|
||||||
|
const { b64, local_ips } = require('./utils.js');
|
||||||
|
|
||||||
|
class AntiEtcdAdapter
|
||||||
|
{
|
||||||
|
static async start_antietcd(config)
|
||||||
|
{
|
||||||
|
let antietcd;
|
||||||
|
if (config.use_antietcd)
|
||||||
|
{
|
||||||
|
let cluster = config.etcd_address;
|
||||||
|
if (!(cluster instanceof Array))
|
||||||
|
cluster = cluster ? (''+(cluster||'')).split(/,+/) : [];
|
||||||
|
cluster = Object.keys(cluster.reduce((a, url) =>
|
||||||
|
{
|
||||||
|
a[url.toLowerCase().replace(/^(https?:\/\/)/, '').replace(/\/.*$/, '')] = true;
|
||||||
|
return a;
|
||||||
|
}, {}));
|
||||||
|
const cfg_port = config.antietcd_port;
|
||||||
|
const is_local = local_ips(true).reduce((a, c) => { a[c] = true; return a; }, {});
|
||||||
|
const selected = cluster.map(s => s.split(':', 2)).filter(ip => is_local[ip[0]] && (!cfg_port || ip[1] == cfg_port));
|
||||||
|
if (selected.length > 1)
|
||||||
|
{
|
||||||
|
console.error('More than 1 etcd_address matches local IPs, please specify port');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
else if (selected.length == 1)
|
||||||
|
{
|
||||||
|
const antietcd_config = {
|
||||||
|
ip: selected[0][0],
|
||||||
|
port: selected[0][1],
|
||||||
|
data: config.antietcd_data_file || ((config.antietcd_data_dir || '/var/lib/vitastor') + '/mon_'+selected[0][1]+'.json.gz'),
|
||||||
|
persist_filter: vitastor_persist_filter({ vitastor_prefix: config.etcd_prefix || '/vitastor' }),
|
||||||
|
node_id: selected[0][0]+':'+selected[0][1], // node_id = ip:port
|
||||||
|
cluster: (cluster.length == 1 ? null : cluster.reduce((a, c) => { a[c] = "http://"+c; return a; }, {})),
|
||||||
|
cluster_key: (config.etcd_prefix || '/vitastor'),
|
||||||
|
stale_read: 1,
|
||||||
|
log_level: 1,
|
||||||
|
};
|
||||||
|
for (const key in config)
|
||||||
|
{
|
||||||
|
if (key.substr(0, 9) === 'antietcd_')
|
||||||
|
{
|
||||||
|
const noprefix = key.substr(9);
|
||||||
|
if (!(noprefix in antietcd_config) || noprefix == 'ip' || noprefix == 'cluster_key')
|
||||||
|
{
|
||||||
|
antietcd_config[noprefix] = config[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('Starting Antietcd node '+antietcd_config.node_id);
|
||||||
|
antietcd = new AntiEtcd(antietcd_config);
|
||||||
|
await antietcd.start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log('Antietcd is enabled, but etcd_address does not contain local IPs, proceeding without it');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return antietcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(mon, antietcd)
|
||||||
|
{
|
||||||
|
this.mon = mon;
|
||||||
|
this.antietcd = antietcd;
|
||||||
|
this.on_leader = [];
|
||||||
|
this.on_change = (st) =>
|
||||||
|
{
|
||||||
|
if (st.state === 'leader')
|
||||||
|
{
|
||||||
|
for (const cb of this.on_leader)
|
||||||
|
{
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
this.on_leader = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.antietcd.on('raftchange', this.on_change);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_config(/*config*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_watcher()
|
||||||
|
{
|
||||||
|
this.antietcd.off('raftchange', this.on_change);
|
||||||
|
const watch_id = this.watch_id;
|
||||||
|
if (watch_id)
|
||||||
|
{
|
||||||
|
this.watch_id = null;
|
||||||
|
this.antietcd.cancel_watch(watch_id).catch(console.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async start_watcher()
|
||||||
|
{
|
||||||
|
if (this.watch_id)
|
||||||
|
{
|
||||||
|
await this.antietcd.cancel_watch(this.watch_id);
|
||||||
|
this.watch_id = null;
|
||||||
|
}
|
||||||
|
const watch_id = await this.antietcd.create_watch({
|
||||||
|
key: b64(this.mon.config.etcd_prefix+'/'),
|
||||||
|
range_end: b64(this.mon.config.etcd_prefix+'0'),
|
||||||
|
start_revision: ''+this.mon.etcd_watch_revision,
|
||||||
|
watch_id: 1,
|
||||||
|
progress_notify: true,
|
||||||
|
}, (message) =>
|
||||||
|
{
|
||||||
|
setImmediate(() => this.mon.on_message(message.result));
|
||||||
|
});
|
||||||
|
console.log('Successfully subscribed to antietcd revision '+this.antietcd.etctree.mod_revision);
|
||||||
|
this.watch_id = watch_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
async become_master()
|
||||||
|
{
|
||||||
|
if (!this.antietcd.cluster)
|
||||||
|
{
|
||||||
|
console.log('Running in non-clustered mode');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log('Waiting to become master');
|
||||||
|
if (this.antietcd.cluster.raft.state !== 'leader')
|
||||||
|
{
|
||||||
|
await new Promise(ok => this.on_leader.push(ok));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const state = { ...this.mon.get_mon_state(), id: ''+this.mon.etcd_lease_id };
|
||||||
|
await this.etcd_call('/kv/txn', {
|
||||||
|
success: [ { requestPut: { key: b64(this.mon.config.etcd_prefix+'/mon/master'), value: b64(JSON.stringify(state)), lease: ''+this.mon.etcd_lease_id } } ],
|
||||||
|
}, this.mon.config.etcd_start_timeout, 0);
|
||||||
|
if (this.antietcd.cluster)
|
||||||
|
{
|
||||||
|
console.log('Became master');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async etcd_call(path, body, timeout, retries)
|
||||||
|
{
|
||||||
|
let retry = 0;
|
||||||
|
if (retries >= 0 && retries < 1)
|
||||||
|
{
|
||||||
|
retries = 1;
|
||||||
|
}
|
||||||
|
let prev = 0;
|
||||||
|
while (retries < 0 || retry < retries)
|
||||||
|
{
|
||||||
|
retry++;
|
||||||
|
if (this.mon.stopped)
|
||||||
|
{
|
||||||
|
throw new Error('Monitor instance is stopped');
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Date.now()-prev < timeout)
|
||||||
|
{
|
||||||
|
await new Promise(ok => setTimeout(ok, timeout-(Date.now()-prev)));
|
||||||
|
}
|
||||||
|
prev = Date.now();
|
||||||
|
const res = await this.antietcd.api(path.replace(/^\/+/, '').replace(/\/+$/, '').replace(/\/+/g, '_'), body);
|
||||||
|
if (res.error)
|
||||||
|
{
|
||||||
|
console.error('Failed to query antietcd '+path+' (retry '+retry+'/'+retries+'): '+res.error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
console.error('Failed to query antietcd '+path+' (retry '+retry+'/'+retries+'): '+e.stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error('Failed to query antietcd ('+retries+' retries)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = AntiEtcdAdapter;
|
||||||
@@ -0,0 +1,352 @@
|
|||||||
|
// Copyright (c) Vitaliy Filippov, 2019+
|
||||||
|
// License: VNPL-1.1 (see README.md for details)
|
||||||
|
|
||||||
|
const http = require('http');
|
||||||
|
const WebSocket = require('ws');
|
||||||
|
const { b64, local_ips } = require('./utils.js');
|
||||||
|
|
||||||
|
const MON_STOPPED = 'Monitor instance is stopped';
|
||||||
|
|
||||||
|
class EtcdAdapter
|
||||||
|
{
|
||||||
|
constructor(mon)
|
||||||
|
{
|
||||||
|
this.mon = mon;
|
||||||
|
this.ws = null;
|
||||||
|
this.ws_alive = false;
|
||||||
|
this.ws_keepalive_timer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_config(config)
|
||||||
|
{
|
||||||
|
this.parse_etcd_addresses(config.etcd_address||config.etcd_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_etcd_addresses(addrs)
|
||||||
|
{
|
||||||
|
const is_local_ip = local_ips(true).reduce((a, c) => { a[c] = true; return a; }, {});
|
||||||
|
this.etcd_local = [];
|
||||||
|
this.etcd_urls = [];
|
||||||
|
this.selected_etcd_url = null;
|
||||||
|
this.etcd_urls_to_try = [];
|
||||||
|
if (!(addrs instanceof Array))
|
||||||
|
addrs = addrs ? (''+(addrs||'')).split(/,/) : [];
|
||||||
|
if (!addrs.length)
|
||||||
|
{
|
||||||
|
console.error('Vitastor etcd address(es) not specified. Please set on the command line or in the config file');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
for (let url of addrs)
|
||||||
|
{
|
||||||
|
let scheme = 'http';
|
||||||
|
url = url.trim().replace(/^(https?):\/\//, (m, m1) => { scheme = m1; return ''; });
|
||||||
|
const slash = url.indexOf('/');
|
||||||
|
const colon = url.indexOf(':');
|
||||||
|
const is_local = is_local_ip[colon >= 0 ? url.substr(0, colon) : (slash >= 0 ? url.substr(0, slash) : url)];
|
||||||
|
url = scheme+'://'+(slash >= 0 ? url : url+'/v3');
|
||||||
|
if (is_local)
|
||||||
|
this.etcd_local.push(url);
|
||||||
|
else
|
||||||
|
this.etcd_urls.push(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pick_next_etcd()
|
||||||
|
{
|
||||||
|
if (this.selected_etcd_url)
|
||||||
|
return this.selected_etcd_url;
|
||||||
|
if (!this.etcd_urls_to_try || !this.etcd_urls_to_try.length)
|
||||||
|
{
|
||||||
|
this.etcd_urls_to_try = [ ...this.etcd_local ];
|
||||||
|
const others = [ ...this.etcd_urls ];
|
||||||
|
while (others.length)
|
||||||
|
{
|
||||||
|
const url = others.splice(0|(others.length*Math.random()), 1);
|
||||||
|
this.etcd_urls_to_try.push(url[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.selected_etcd_url = this.etcd_urls_to_try.shift();
|
||||||
|
return this.selected_etcd_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_watcher(cur_addr)
|
||||||
|
{
|
||||||
|
cur_addr = cur_addr || this.selected_etcd_url;
|
||||||
|
if (this.ws)
|
||||||
|
{
|
||||||
|
console.log('Disconnected from etcd at '+this.ws_used_url);
|
||||||
|
this.ws.close();
|
||||||
|
this.ws = null;
|
||||||
|
}
|
||||||
|
if (this.ws_keepalive_timer)
|
||||||
|
{
|
||||||
|
clearInterval(this.ws_keepalive_timer);
|
||||||
|
this.ws_keepalive_timer = null;
|
||||||
|
}
|
||||||
|
if (this.selected_etcd_url == cur_addr)
|
||||||
|
{
|
||||||
|
this.selected_etcd_url = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
restart_watcher(cur_addr)
|
||||||
|
{
|
||||||
|
this.stop_watcher(cur_addr);
|
||||||
|
this.start_watcher(this.mon.config.etcd_mon_retries).catch(this.mon.die);
|
||||||
|
}
|
||||||
|
|
||||||
|
async start_watcher(retries)
|
||||||
|
{
|
||||||
|
let retry = 0;
|
||||||
|
if (!retries || retries < 1)
|
||||||
|
{
|
||||||
|
retries = 1;
|
||||||
|
}
|
||||||
|
const tried = {};
|
||||||
|
while (retries < 0 || retry < retries)
|
||||||
|
{
|
||||||
|
const cur_addr = this.pick_next_etcd();
|
||||||
|
const base = 'ws'+cur_addr.substr(4);
|
||||||
|
let now = Date.now();
|
||||||
|
if (tried[base] && now-tried[base] < this.mon.config.etcd_start_timeout)
|
||||||
|
{
|
||||||
|
await new Promise(ok => setTimeout(ok, this.mon.config.etcd_start_timeout-(now-tried[base])));
|
||||||
|
now = Date.now();
|
||||||
|
}
|
||||||
|
tried[base] = now;
|
||||||
|
if (this.mon.stopped)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ok = await new Promise(ok =>
|
||||||
|
{
|
||||||
|
const timer_id = setTimeout(() =>
|
||||||
|
{
|
||||||
|
if (this.ws)
|
||||||
|
{
|
||||||
|
console.log('Disconnected from etcd at '+this.ws_used_url);
|
||||||
|
this.ws.close();
|
||||||
|
this.ws = null;
|
||||||
|
}
|
||||||
|
ok(false);
|
||||||
|
}, this.mon.config.etcd_mon_timeout);
|
||||||
|
this.ws = new WebSocket(base+'/watch');
|
||||||
|
this.ws_used_url = cur_addr;
|
||||||
|
const fail = () =>
|
||||||
|
{
|
||||||
|
ok(false);
|
||||||
|
};
|
||||||
|
this.ws.on('error', fail);
|
||||||
|
this.ws.on('open', () =>
|
||||||
|
{
|
||||||
|
this.ws.removeListener('error', fail);
|
||||||
|
if (timer_id)
|
||||||
|
clearTimeout(timer_id);
|
||||||
|
ok(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if (ok)
|
||||||
|
break;
|
||||||
|
if (this.selected_etcd_url == cur_addr)
|
||||||
|
this.selected_etcd_url = null;
|
||||||
|
this.ws = null;
|
||||||
|
retry++;
|
||||||
|
}
|
||||||
|
if (!this.ws)
|
||||||
|
{
|
||||||
|
this.mon.die('Failed to open etcd watch websocket');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.mon.stopped)
|
||||||
|
{
|
||||||
|
this.stop_watcher();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const cur_addr = this.selected_etcd_url;
|
||||||
|
this.ws_alive = true;
|
||||||
|
this.ws_keepalive_timer = setInterval(() =>
|
||||||
|
{
|
||||||
|
if (this.ws_alive && this.ws)
|
||||||
|
{
|
||||||
|
this.ws_alive = false;
|
||||||
|
this.ws.send(JSON.stringify({ progress_request: {} }));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log('etcd websocket timed out, restarting it');
|
||||||
|
this.restart_watcher(cur_addr);
|
||||||
|
}
|
||||||
|
}, (Number(this.mon.config.etcd_ws_keepalive_interval) || 5)*1000);
|
||||||
|
this.ws.on('error', () => this.restart_watcher(cur_addr));
|
||||||
|
this.ws.send(JSON.stringify({
|
||||||
|
create_request: {
|
||||||
|
key: b64(this.mon.config.etcd_prefix+'/'),
|
||||||
|
range_end: b64(this.mon.config.etcd_prefix+'0'),
|
||||||
|
start_revision: ''+this.mon.etcd_watch_revision,
|
||||||
|
watch_id: 1,
|
||||||
|
progress_notify: true,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
this.ws.on('message', (msg) =>
|
||||||
|
{
|
||||||
|
if (this.mon.stopped)
|
||||||
|
{
|
||||||
|
this.stop_watcher();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.ws_alive = true;
|
||||||
|
let data;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
data = JSON.parse(msg);
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
if (!data || !data.result)
|
||||||
|
{
|
||||||
|
console.error('Unknown message received from watch websocket: '+msg);
|
||||||
|
}
|
||||||
|
else if (data.result.canceled)
|
||||||
|
{
|
||||||
|
// etcd watch canceled
|
||||||
|
if (data.result.compact_revision)
|
||||||
|
{
|
||||||
|
// we may miss events if we proceed
|
||||||
|
this.mon.die('Revisions before '+data.result.compact_revision+' were compacted by etcd, exiting');
|
||||||
|
}
|
||||||
|
this.mon.die('Watch canceled by etcd, reason: '+data.result.cancel_reason+', exiting');
|
||||||
|
}
|
||||||
|
else if (data.result.created)
|
||||||
|
{
|
||||||
|
// etcd watch created
|
||||||
|
console.log('Successfully subscribed to etcd at '+this.selected_etcd_url+', revision '+data.result.header.revision);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.mon.on_message(data.result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async become_master()
|
||||||
|
{
|
||||||
|
const state = { ...this.mon.get_mon_state(), id: ''+this.mon.etcd_lease_id };
|
||||||
|
// eslint-disable-next-line no-constant-condition
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
const res = await this.etcd_call('/kv/txn', {
|
||||||
|
compare: [ { target: 'CREATE', create_revision: 0, key: b64(this.mon.config.etcd_prefix+'/mon/master') } ],
|
||||||
|
success: [ { requestPut: { key: b64(this.mon.config.etcd_prefix+'/mon/master'), value: b64(JSON.stringify(state)), lease: ''+this.mon.etcd_lease_id } } ],
|
||||||
|
}, this.mon.config.etcd_start_timeout, 0);
|
||||||
|
if (res.succeeded)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console.log('Waiting to become master');
|
||||||
|
await new Promise(ok => setTimeout(ok, this.mon.config.etcd_start_timeout));
|
||||||
|
}
|
||||||
|
console.log('Became master');
|
||||||
|
}
|
||||||
|
|
||||||
|
async etcd_call(path, body, timeout, retries)
|
||||||
|
{
|
||||||
|
let retry = 0;
|
||||||
|
if (retries >= 0 && retries < 1)
|
||||||
|
{
|
||||||
|
retries = 1;
|
||||||
|
}
|
||||||
|
const tried = {};
|
||||||
|
while (retries < 0 || retry < retries)
|
||||||
|
{
|
||||||
|
retry++;
|
||||||
|
const base = this.pick_next_etcd();
|
||||||
|
let now = Date.now();
|
||||||
|
if (tried[base] && now-tried[base] < timeout)
|
||||||
|
{
|
||||||
|
await new Promise(ok => setTimeout(ok, timeout-(now-tried[base])));
|
||||||
|
now = Date.now();
|
||||||
|
}
|
||||||
|
tried[base] = now;
|
||||||
|
if (this.mon.stopped)
|
||||||
|
{
|
||||||
|
throw new Error(MON_STOPPED);
|
||||||
|
}
|
||||||
|
const res = await POST(base+path, body, timeout);
|
||||||
|
if (this.mon.stopped)
|
||||||
|
{
|
||||||
|
throw new Error(MON_STOPPED);
|
||||||
|
}
|
||||||
|
if (res.error)
|
||||||
|
{
|
||||||
|
if (this.selected_etcd_url == base)
|
||||||
|
this.selected_etcd_url = null;
|
||||||
|
console.error('Failed to query etcd '+path+' (retry '+retry+'/'+retries+'): '+res.error);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (res.json)
|
||||||
|
{
|
||||||
|
if (res.json.error)
|
||||||
|
{
|
||||||
|
console.error(path+': etcd returned error: '+res.json.error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res.json;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error('Failed to query etcd ('+retries+' retries)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function POST(url, body, timeout)
|
||||||
|
{
|
||||||
|
return new Promise(ok =>
|
||||||
|
{
|
||||||
|
const body_text = Buffer.from(JSON.stringify(body));
|
||||||
|
let timer_id = timeout > 0 ? setTimeout(() =>
|
||||||
|
{
|
||||||
|
if (req)
|
||||||
|
req.abort();
|
||||||
|
req = null;
|
||||||
|
ok({ error: 'timeout' });
|
||||||
|
}, timeout) : null;
|
||||||
|
let req = http.request(url, { method: 'POST', headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Content-Length': body_text.length,
|
||||||
|
} }, (res) =>
|
||||||
|
{
|
||||||
|
if (!req)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearTimeout(timer_id);
|
||||||
|
let res_body = '';
|
||||||
|
res.setEncoding('utf8');
|
||||||
|
res.on('error', (error) => ok({ error }));
|
||||||
|
res.on('data', chunk => { res_body += chunk; });
|
||||||
|
res.on('end', () =>
|
||||||
|
{
|
||||||
|
if (res.statusCode != 200)
|
||||||
|
{
|
||||||
|
ok({ error: res_body, code: res.statusCode });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res_body = JSON.parse(res_body);
|
||||||
|
ok({ response: res, json: res_body });
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
ok({ error: e, response: res, body: res_body });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
req.on('error', (error) => ok({ error }));
|
||||||
|
req.on('close', () => ok({ error: new Error('Connection closed prematurely') }));
|
||||||
|
req.write(body_text);
|
||||||
|
req.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = EtcdAdapter;
|
||||||
@@ -0,0 +1,396 @@
|
|||||||
|
// Copyright (c) Vitaliy Filippov, 2019+
|
||||||
|
// License: VNPL-1.1 (see README.md for details)
|
||||||
|
|
||||||
|
// FIXME document all etcd keys and config variables in the form of JSON schema or similar
|
||||||
|
const etcd_nonempty_keys = {
|
||||||
|
'config/global': 1,
|
||||||
|
'config/node_placement': 1,
|
||||||
|
'config/pools': 1,
|
||||||
|
'pg/config': 1,
|
||||||
|
'history/last_clean_pgs': 1,
|
||||||
|
'stats': 1,
|
||||||
|
};
|
||||||
|
const etcd_allow = new RegExp('^'+[
|
||||||
|
'config/global',
|
||||||
|
'config/node_placement',
|
||||||
|
'config/pools',
|
||||||
|
'config/osd/[1-9]\\d*',
|
||||||
|
'config/pgs', // old name
|
||||||
|
'pg/config',
|
||||||
|
'config/inode/[1-9]\\d*/[1-9]\\d*',
|
||||||
|
'osd/state/[1-9]\\d*',
|
||||||
|
'osd/stats/[1-9]\\d*',
|
||||||
|
'osd/inodestats/[1-9]\\d*',
|
||||||
|
'osd/space/[1-9]\\d*',
|
||||||
|
'mon/master',
|
||||||
|
'mon/member/[a-f0-9]+',
|
||||||
|
'pg/state/[1-9]\\d*/[1-9]\\d*',
|
||||||
|
'pg/stats/[1-9]\\d*/[1-9]\\d*', // old name
|
||||||
|
'pgstats/[1-9]\\d*/[1-9]\\d*',
|
||||||
|
'pg/history/[1-9]\\d*/[1-9]\\d*',
|
||||||
|
'history/last_clean_pgs',
|
||||||
|
'inode/stats/[1-9]\\d*/\\d+',
|
||||||
|
'pool/stats/[1-9]\\d*',
|
||||||
|
'stats',
|
||||||
|
'index/image/.*',
|
||||||
|
'index/maxid/[1-9]\\d*',
|
||||||
|
].join('$|^')+'$');
|
||||||
|
|
||||||
|
const etcd_tree = {
|
||||||
|
config: {
|
||||||
|
/* global: {
|
||||||
|
// WARNING: NOT ALL OF THESE ARE ACTUALLY CONFIGURABLE HERE
|
||||||
|
// THIS IS JUST A POOR MAN'S CONFIG DOCUMENTATION
|
||||||
|
// etcd connection
|
||||||
|
config_path: "/etc/vitastor/vitastor.conf",
|
||||||
|
etcd_prefix: "/vitastor",
|
||||||
|
// etcd connection - configurable online
|
||||||
|
etcd_address: "10.0.115.10:2379/v3",
|
||||||
|
// mon
|
||||||
|
etcd_mon_ttl: 5, // min: 1
|
||||||
|
etcd_mon_timeout: 1000, // ms. min: 0
|
||||||
|
etcd_mon_retries: 5, // min: 0
|
||||||
|
mon_change_timeout: 1000, // ms. min: 100
|
||||||
|
mon_retry_change_timeout: 50, // ms. min: 10
|
||||||
|
mon_stats_timeout: 1000, // ms. min: 100
|
||||||
|
osd_out_time: 600, // seconds. min: 0
|
||||||
|
placement_levels: { datacenter: 1, rack: 2, host: 3, osd: 4, ... },
|
||||||
|
use_old_pg_combinator: false,
|
||||||
|
// client and osd
|
||||||
|
tcp_header_buffer_size: 65536,
|
||||||
|
use_sync_send_recv: false,
|
||||||
|
use_rdma: true,
|
||||||
|
rdma_device: null, // for example, "rocep5s0f0"
|
||||||
|
rdma_port_num: 1,
|
||||||
|
rdma_gid_index: 0,
|
||||||
|
rdma_mtu: 4096,
|
||||||
|
rdma_max_sge: 128,
|
||||||
|
rdma_max_send: 8,
|
||||||
|
rdma_max_recv: 16,
|
||||||
|
rdma_max_msg: 132096,
|
||||||
|
block_size: 131072,
|
||||||
|
disk_alignment: 4096,
|
||||||
|
bitmap_granularity: 4096,
|
||||||
|
immediate_commit: 'all', // 'none', 'all' or 'small'
|
||||||
|
// client - configurable online
|
||||||
|
client_max_dirty_bytes: 33554432,
|
||||||
|
client_max_dirty_ops: 1024,
|
||||||
|
client_enable_writeback: false,
|
||||||
|
client_max_buffered_bytes: 33554432,
|
||||||
|
client_max_buffered_ops: 1024,
|
||||||
|
client_max_writeback_iodepth: 256,
|
||||||
|
client_retry_interval: 50, // ms. min: 10
|
||||||
|
client_eio_retry_interval: 1000, // ms
|
||||||
|
client_retry_enospc: true,
|
||||||
|
osd_nearfull_ratio: 0.95,
|
||||||
|
// client and osd - configurable online
|
||||||
|
log_level: 0,
|
||||||
|
peer_connect_interval: 5, // seconds. min: 1
|
||||||
|
peer_connect_timeout: 5, // seconds. min: 1
|
||||||
|
osd_idle_timeout: 5, // seconds. min: 1
|
||||||
|
osd_ping_timeout: 5, // seconds. min: 1
|
||||||
|
max_etcd_attempts: 5,
|
||||||
|
etcd_quick_timeout: 1000, // ms
|
||||||
|
etcd_slow_timeout: 5000, // ms
|
||||||
|
etcd_keepalive_timeout: 30, // seconds, default is max(30, etcd_report_interval*2)
|
||||||
|
etcd_ws_keepalive_interval: 5, // seconds
|
||||||
|
// osd
|
||||||
|
etcd_report_interval: 5, // seconds
|
||||||
|
etcd_stats_interval: 30, // seconds
|
||||||
|
run_primary: true,
|
||||||
|
osd_network: null, // "192.168.7.0/24" or an array of masks
|
||||||
|
bind_address: "0.0.0.0",
|
||||||
|
bind_port: 0,
|
||||||
|
readonly: false,
|
||||||
|
osd_memlock: false,
|
||||||
|
// osd - configurable online
|
||||||
|
autosync_interval: 5,
|
||||||
|
autosync_writes: 128,
|
||||||
|
client_queue_depth: 128, // unused
|
||||||
|
recovery_queue_depth: 1,
|
||||||
|
recovery_sleep_us: 0,
|
||||||
|
recovery_tune_util_low: 0.1,
|
||||||
|
recovery_tune_client_util_low: 0,
|
||||||
|
recovery_tune_util_high: 1.0,
|
||||||
|
recovery_tune_client_util_high: 0.5,
|
||||||
|
recovery_tune_interval: 1,
|
||||||
|
recovery_tune_agg_interval: 10, // 10 times recovery_tune_interval
|
||||||
|
recovery_tune_sleep_min_us: 10, // 10 microseconds
|
||||||
|
recovery_pg_switch: 128,
|
||||||
|
recovery_sync_batch: 16,
|
||||||
|
no_recovery: false,
|
||||||
|
no_rebalance: false,
|
||||||
|
print_stats_interval: 3,
|
||||||
|
slow_log_interval: 10,
|
||||||
|
inode_vanish_time: 60,
|
||||||
|
auto_scrub: false,
|
||||||
|
no_scrub: false,
|
||||||
|
scrub_interval: '30d', // 1s/1m/1h/1d
|
||||||
|
scrub_queue_depth: 1,
|
||||||
|
scrub_sleep: 0, // milliseconds
|
||||||
|
scrub_list_limit: 1000, // objects to list on one scrub iteration
|
||||||
|
scrub_find_best: true,
|
||||||
|
scrub_ec_max_bruteforce: 100, // maximum EC error locator brute-force iterators
|
||||||
|
// blockstore - fixed in superblock
|
||||||
|
block_size,
|
||||||
|
disk_alignment,
|
||||||
|
journal_block_size,
|
||||||
|
meta_block_size,
|
||||||
|
bitmap_granularity,
|
||||||
|
journal_device,
|
||||||
|
journal_offset,
|
||||||
|
journal_size,
|
||||||
|
disable_journal_fsync,
|
||||||
|
data_device,
|
||||||
|
data_offset,
|
||||||
|
data_size,
|
||||||
|
disable_data_fsync,
|
||||||
|
meta_device,
|
||||||
|
meta_offset,
|
||||||
|
disable_meta_fsync,
|
||||||
|
disable_device_lock,
|
||||||
|
// blockstore - configurable offline
|
||||||
|
inmemory_metadata,
|
||||||
|
inmemory_journal,
|
||||||
|
journal_sector_buffer_count,
|
||||||
|
journal_no_same_sector_overwrites,
|
||||||
|
// blockstore - configurable online
|
||||||
|
max_write_iodepth,
|
||||||
|
min_flusher_count: 1,
|
||||||
|
max_flusher_count: 256,
|
||||||
|
throttle_small_writes: false,
|
||||||
|
throttle_target_iops: 100,
|
||||||
|
throttle_target_mbs: 100,
|
||||||
|
throttle_target_parallelism: 1,
|
||||||
|
throttle_threshold_us: 50,
|
||||||
|
}, */
|
||||||
|
global: {},
|
||||||
|
/* node_placement: {
|
||||||
|
host1: { level: 'host', parent: 'rack1' },
|
||||||
|
...
|
||||||
|
}, */
|
||||||
|
node_placement: {},
|
||||||
|
/* pools: {
|
||||||
|
<id>: {
|
||||||
|
name: 'testpool',
|
||||||
|
// 'ec' uses Reed-Solomon-Vandermonde codes, 'jerasure' is an alias for 'ec'
|
||||||
|
scheme: 'replicated' | 'xor' | 'ec' | 'jerasure',
|
||||||
|
pg_size: 3,
|
||||||
|
pg_minsize: 2,
|
||||||
|
// number of parity chunks, required for EC
|
||||||
|
parity_chunks?: 1,
|
||||||
|
pg_count: 100,
|
||||||
|
// default is failure_domain=host
|
||||||
|
failure_domain?: 'host',
|
||||||
|
// additional failure domain rules; failure_domain=x is equivalent to x=123..N
|
||||||
|
level_placement?: 'dc=112233 host=123456',
|
||||||
|
raw_placement?: 'any, dc=1 host!=1, dc=1 host!=(1,2)',
|
||||||
|
old_combinator: false,
|
||||||
|
max_osd_combinations: 10000,
|
||||||
|
// block_size, bitmap_granularity, immediate_commit must match all OSDs used in that pool
|
||||||
|
block_size: 131072,
|
||||||
|
bitmap_granularity: 4096,
|
||||||
|
// 'all'/'small'/'none', same as in OSD options
|
||||||
|
immediate_commit: 'all',
|
||||||
|
pg_stripe_size: 0,
|
||||||
|
root_node?: 'rack1',
|
||||||
|
// restrict pool to OSDs having all of these tags
|
||||||
|
osd_tags?: 'nvme' | [ 'nvme', ... ],
|
||||||
|
// prefer to put primary on OSD with these tags
|
||||||
|
primary_affinity_tags?: 'nvme' | [ 'nvme', ... ],
|
||||||
|
// scrub interval
|
||||||
|
scrub_interval?: '30d',
|
||||||
|
},
|
||||||
|
...
|
||||||
|
}, */
|
||||||
|
pools: {},
|
||||||
|
osd: {
|
||||||
|
/* <id>: { reweight?: 1, tags?: [ 'nvme', ... ], noout?: true }, ... */
|
||||||
|
},
|
||||||
|
/* inode: {
|
||||||
|
<pool_id>: {
|
||||||
|
<inode_t>: {
|
||||||
|
name: string,
|
||||||
|
size?: uint64_t, // bytes
|
||||||
|
parent_pool?: <pool_id>,
|
||||||
|
parent_id?: <inode_t>,
|
||||||
|
readonly?: boolean,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, */
|
||||||
|
inode: {},
|
||||||
|
},
|
||||||
|
osd: {
|
||||||
|
state: {
|
||||||
|
/* <osd_num_t>: {
|
||||||
|
state: "up",
|
||||||
|
addresses: string[],
|
||||||
|
host: string,
|
||||||
|
port: uint16_t,
|
||||||
|
primary_enabled: boolean,
|
||||||
|
blockstore_enabled: boolean,
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
stats: {
|
||||||
|
/* <osd_num_t>: {
|
||||||
|
time: number, // unix time
|
||||||
|
data_block_size: uint64_t, // bytes
|
||||||
|
bitmap_granularity: uint64_t, // bytes
|
||||||
|
immediate_commit: "all"|"small"|"none",
|
||||||
|
blockstore_ready: boolean,
|
||||||
|
size: uint64_t, // bytes
|
||||||
|
free: uint64_t, // bytes
|
||||||
|
host: string,
|
||||||
|
op_stats: {
|
||||||
|
<string>: { count: uint64_t, usec: uint64_t, bytes: uint64_t },
|
||||||
|
},
|
||||||
|
subop_stats: {
|
||||||
|
<string>: { count: uint64_t, usec: uint64_t },
|
||||||
|
},
|
||||||
|
recovery_stats: {
|
||||||
|
degraded: { count: uint64_t, bytes: uint64_t },
|
||||||
|
misplaced: { count: uint64_t, bytes: uint64_t },
|
||||||
|
},
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
inodestats: {
|
||||||
|
/* <pool_id>: {
|
||||||
|
<inode_t>: {
|
||||||
|
read: { count: uint64_t, usec: uint64_t, bytes: uint64_t },
|
||||||
|
write: { count: uint64_t, usec: uint64_t, bytes: uint64_t },
|
||||||
|
delete: { count: uint64_t, usec: uint64_t, bytes: uint64_t },
|
||||||
|
},
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
space: {
|
||||||
|
/* <osd_num_t>: {
|
||||||
|
<pool_id>: {
|
||||||
|
<inode_t>: uint64_t, // bytes
|
||||||
|
},
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mon: {
|
||||||
|
master: {
|
||||||
|
/* ip: [ string ], id: uint64_t */
|
||||||
|
},
|
||||||
|
member: {
|
||||||
|
/* <uint64_t>: { ip: [ string ] }, */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pg: {
|
||||||
|
/* config: {
|
||||||
|
hash: string,
|
||||||
|
items: {
|
||||||
|
<pool_id>: {
|
||||||
|
<pg_id>: {
|
||||||
|
osd_set: [ 1, 2, 3 ],
|
||||||
|
primary: 1,
|
||||||
|
pause: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, */
|
||||||
|
config: {},
|
||||||
|
state: {
|
||||||
|
/* <pool_id>: {
|
||||||
|
<pg_id>: {
|
||||||
|
primary: osd_num_t,
|
||||||
|
state: ("starting"|"peering"|"incomplete"|"active"|"repeering"|"stopping"|"offline"|
|
||||||
|
"degraded"|"has_incomplete"|"has_degraded"|"has_misplaced"|"has_unclean"|
|
||||||
|
"has_invalid"|"has_inconsistent"|"has_corrupted"|"left_on_dead"|"scrubbing")[],
|
||||||
|
}
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
history: {
|
||||||
|
/* <pool_id>: {
|
||||||
|
<pg_id>: {
|
||||||
|
osd_sets: osd_num_t[][],
|
||||||
|
all_peers: osd_num_t[],
|
||||||
|
epoch: uint64_t,
|
||||||
|
next_scrub: uint64_t,
|
||||||
|
},
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pgstats: {
|
||||||
|
/* <pool_id>: {
|
||||||
|
<pg_id>: {
|
||||||
|
object_count: uint64_t,
|
||||||
|
clean_count: uint64_t,
|
||||||
|
misplaced_count: uint64_t,
|
||||||
|
degraded_count: uint64_t,
|
||||||
|
incomplete_count: uint64_t,
|
||||||
|
write_osd_set: osd_num_t[],
|
||||||
|
},
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
inode: {
|
||||||
|
stats: {
|
||||||
|
/* <pool_id>: {
|
||||||
|
<inode_t>: {
|
||||||
|
raw_used: uint64_t, // raw used bytes on OSDs
|
||||||
|
read: { count: uint64_t, usec: uint64_t, bytes: uint64_t, bps: uint64_t, iops: uint64_t, lat: uint64_t },
|
||||||
|
write: { count: uint64_t, usec: uint64_t, bytes: uint64_t, bps: uint64_t, iops: uint64_t, lat: uint64_t },
|
||||||
|
delete: { count: uint64_t, usec: uint64_t, bytes: uint64_t, bps: uint64_t, iops: uint64_t, lat: uint64_t },
|
||||||
|
},
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pool: {
|
||||||
|
stats: {
|
||||||
|
/* <pool_id>: {
|
||||||
|
used_raw_tb: float, // used raw space in the pool
|
||||||
|
total_raw_tb: float, // maximum amount of space in the pool
|
||||||
|
raw_to_usable: float, // raw to usable ratio
|
||||||
|
space_efficiency: float, // 0..1
|
||||||
|
} */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stats: {
|
||||||
|
/* op_stats: {
|
||||||
|
<string>: { count: uint64_t, usec: uint64_t, bytes: uint64_t, bps: uint64_t, iops: uint64_t, lat: uint64_t },
|
||||||
|
},
|
||||||
|
subop_stats: {
|
||||||
|
<string>: { count: uint64_t, usec: uint64_t, iops: uint64_t, lat: uint64_t },
|
||||||
|
},
|
||||||
|
recovery_stats: {
|
||||||
|
degraded: { count: uint64_t, bytes: uint64_t, bps: uint64_t, iops: uint64_t },
|
||||||
|
misplaced: { count: uint64_t, bytes: uint64_t, bps: uint64_t, iops: uint64_t },
|
||||||
|
},
|
||||||
|
object_counts: {
|
||||||
|
object: uint64_t,
|
||||||
|
clean: uint64_t,
|
||||||
|
misplaced: uint64_t,
|
||||||
|
degraded: uint64_t,
|
||||||
|
incomplete: uint64_t,
|
||||||
|
},
|
||||||
|
object_bytes: {
|
||||||
|
total: uint64_t,
|
||||||
|
clean: uint64_t,
|
||||||
|
misplaced: uint64_t,
|
||||||
|
degraded: uint64_t,
|
||||||
|
incomplete: uint64_t,
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
history: {
|
||||||
|
last_clean_pgs: {},
|
||||||
|
},
|
||||||
|
index: {
|
||||||
|
image: {
|
||||||
|
/* <name>: {
|
||||||
|
id: uint64_t,
|
||||||
|
pool_id: uint64_t,
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
maxid: {
|
||||||
|
/* <pool_id>: uint64_t, */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
etcd_nonempty_keys,
|
||||||
|
etcd_allow,
|
||||||
|
etcd_tree,
|
||||||
|
};
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) Vitaliy Filippov, 2019+
|
||||||
|
// License: VNPL-1.1 (see README.md for details)
|
||||||
|
|
||||||
|
const fsp = require('fs').promises;
|
||||||
|
const http = require('http');
|
||||||
|
const https = require('https');
|
||||||
|
|
||||||
|
async function create_http_server(cfg, handler)
|
||||||
|
{
|
||||||
|
let server;
|
||||||
|
if (cfg.mon_https_cert)
|
||||||
|
{
|
||||||
|
const tls = {
|
||||||
|
key: await fsp.readFile(cfg.mon_https_key),
|
||||||
|
cert: await fsp.readFile(cfg.mon_https_cert),
|
||||||
|
};
|
||||||
|
if (cfg.mon_https_ca)
|
||||||
|
{
|
||||||
|
tls.mon_https_ca = await fsp.readFile(cfg.mon_https_ca);
|
||||||
|
}
|
||||||
|
if (cfg.mon_https_client_auth)
|
||||||
|
{
|
||||||
|
tls.requestCert = true;
|
||||||
|
}
|
||||||
|
server = https.createServer(tls, handler);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server = http.createServer(handler);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
let err;
|
||||||
|
server.once('error', e => err = e);
|
||||||
|
server.listen(cfg.mon_http_port || 8060, cfg.mon_http_ip || undefined);
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
console.error(
|
||||||
|
'HTTP server disabled because listen at address: '+
|
||||||
|
(cfg.mon_http_ip || '')+':'+(cfg.mon_http_port || 9090)+' failed with error: '+e
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { create_http_server };
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user