Для работы оркестратора необходимы следующие компоненты:
Компоненты необходимо установить и запустить на нескольких узлах отказоустойчивого кластера в виде Docker-контейнеров. В качестве узлов кластера вы можете использовать как существующие виртуальные машины (далее ВМ) или физические серверы под управлением ОС Linux с установленным Docker Engine, так и выделить отдельные ВМ/физические серверы.
Аппаратные и программные требования
Для работы компонентов оркестратора на узлах должно быть установлено следующее ПО и его зависимости:
Для расчета необходимых свободных ресурсов на конкретном узле в зависимости от схемы развертывания и количества управляемых устройств вы можете использовать таблицу ниже.
Таблица расчета необходимых вычислительных ресурсов на узлах
Компонент решения |
Виртуальный процессор (vCPU) |
ОЗУ, ГБ |
Диск, ГБ |
IOPS |
|---|---|---|---|---|
50 управляемых устройств |
||||
Redis |
2 |
1 |
100 |
1000 |
Redis Sentinel |
2 |
1 |
||
MongoDB |
2 |
2 |
||
KNBE |
4 |
4 |
||
100 управляемых устройств |
||||
Redis |
2 |
1 |
100 |
1000 |
Redis Sentinel |
2 |
1 |
||
MongoDB |
4 |
4 |
||
KNBE |
4 |
4 |
||
250 управляемых устройств |
||||
Redis |
2 |
2 |
100 |
1000 |
Redis Sentinel |
2 |
2 |
||
MongoDB |
4 |
4 |
||
KNBE |
6 |
4 |
||
500 управляемых устройств |
||||
Redis |
2 |
2 |
100 |
1000 |
Redis Sentinel |
2 |
2 |
||
MongoDB |
6 |
4 |
||
KNBE |
6 |
6 |
||
1000 управляемых устройств |
||||
Redis |
4 |
2 |
100 |
1000 |
Redis Sentinel |
2 |
2 |
||
MongoDB |
6 |
6 |
||
KNBE |
6 |
8 |
||
2000 управляемых устройств |
||||
Redis |
4 |
4 |
200 |
2000 |
Redis Sentinel |
2 |
4 |
||
MongoDB |
6 |
8 |
||
KNBE |
6 |
10 |
||
Пример расчета:
На первом и втором узле будут развернуты все компоненты, на третьем – только MongoDB и Redis Sentinel. Следовательно, если требуется подключить до 50 устройств, то на первом и втором узле должно быть доступно по 10 vCPU, 8 ГБ ОЗУ, 100 ГБ дискового пространства и по 1000 IOPS (на каждом), на третьем узле – 4 vCPU, 3 ГБ ОЗУ, 100 ГБ дискового пространства и 1000 IOPS.
В этой статье описан сценарий развертыванию оркестратора в виде минимального отказоустойчивого кластера на трех узлах: Node_1, Node_2 и Node_3. Узлы создаются в виде виртуальных машин. Схема развертывания показана ниже.

Схема развертывания оркестратора на трех узлах
Отказоустойчивость оркестратора достигается за счет настройки виртуального IP-адреса (Virtual IP, VIP), что подразумевает подключение узлов Node_1 и Node_2 в один L2-сегмент сети. Если необходимо разместить узлы Node_1 и Node_2 в разных подсетях, то необходимо обеспечить отказоустойчивость средствами клиентского приложения или используя другие технологии (DNS Health Checking, BGP Anycast).
https://registry.astralinux.ru/ui/native/mg-generic/alse/cloudinit (например, дистрибутив alse-1.8.2-base-cloudinit-mg15.5.0-amd64.qcow2).При использовании Astra Linux требуемые пакеты необходимо будет устанавливать из репозитория https://download.astralinux.ru/astra/frozen/1.8_x86-64/1.8.2/main-repository 1.8_x86-64.
https://cloud-images.ubuntu.com/jammy/current (например, дистрибутив jammy-server-cloudimg-amd64.img).mongo:5.0.7, собранный с помощью исполняемых файлов из комплекта поставки Kaspersky NGFW;astra/ubi18-redis7015:1.8.2 из Astra Container Registry для Astra Linux 1.8 или redis:6.2.20 из Docker Hub для Ubuntu 22.04;knbe-1.0.0.release.*.cis.amd64_en-US_ru-RU.tgz из комплекта поставки Kaspersky NGFW.На каждом узле задайте перечисленные ниже переменные среды. При необходимости измените значения переменных.
Переменные среды задаются на время сеанса пользователя. Если сессия прервалась, переменные необходимо задать заново.
export HACLUSTER_PASS="SmplPss"
export ORC_KEY_PASS="SmplPss"
export NODE_1="192.168.1.101"
export NODE_1_HOSTNAME="knbe-orc-1"
export NODE_2="192.168.1.102"
export NODE_2_HOSTNAME="knbe-orc-2"
export NODE_3="192.168.1.103"
export NODES_VIP="192.168.1.100"
export NODES_NET_MASK="24"
export NODES_VIP_ETH="eth0"
export MONGO_ADMIN_PASS="SmplPss"
export MONGO_KNAAS_PASS="SmplPss"
Переменная ORC_ENC_PASS должна быть не менее 32 символов.
export ORC_ENC_PASS="SmplPssSmplPssSmplPssSmplSmplPss"
export ORC_CONTAINER_NAME="knaas-orc:2.25.03.release.39.cis.amd64_en-US_ru-RU"
Установка выполняется от имени пользователя sdwan.
На каждом узле установите docker:
sudo apt install docker.io -y
sudo usermod -aG docker $USER
На узлах Node_1 и Node_2 установите pacemaker, corosync и pcs:
sudo apt install pacemaker corosync pcs -y
На узле Node_1 установите OpenJDK, чтобы получить доступ к входящему в его состав keytool:
sudo apt install openjdk-17-jre-headless -y
Настройка выполняется на узлах Node_1 и Node_2. Узел Node_3 является арбитром и не участвует в обработке запросов.
hosts файл на узлах Node_1 и Node_2:sudo sed -i "/^127\.0\.1\.1\s.*$HOSTNAME/d" /etc/hosts
echo "$NODE_1 $NODE_1_HOSTNAME" | sudo tee -a /etc/hosts
echo "$NODE_2 $NODE_2_HOSTNAME" | sudo tee -a /etc/hosts
echo "hacluster:$HACLUSTER_PASS" | sudo chpasswd
sudo systemctl enable --now pcsd corosync pacemaker
sudo pcs cluster destroy --force
sudo pcs host auth $NODE_1_HOSTNAME $NODE_2_HOSTNAME -u hacluster -p $HACLUSTER_PASS
sudo pcs cluster setup orc-ha $NODE_1_HOSTNAME $NODE_2_HOSTNAME --force
sudo pcs cluster start --all
sudo pcs cluster enable --all
sudo pcs property set stonith-enabled=false
sudo pcs property set no-quorum-policy=stop
sudo pcs property set symmetric-cluster=true
sudo pcs status
Список узлов должен состоять из двух и они должны быть онлайн:
Node List:
* Online: [ knbe-orc-1 knbe-orc-2 ]
sudo pcs resource create VirtualIP ocf:heartbeat:IPaddr2 ip=$NODES_VIP cidr_netmask=$NODES_NET_MASK nic=$NODES_VIP_ETH op monitor interval=2s meta target-role="Started"
sudo pcs constraint location VirtualIP prefers $NODE_1_HOSTNAME=200
sudo pcs constraint location VirtualIP prefers $NODE_2_HOSTNAME=0
Все действия c сертификатами необходимо выполнить на узле Node_1.
mkdir -p -m 0755 $HOME/ssl/ca
mkdir -p -m 0755 $HOME/ssl/mongo
mkdir -p -m 0755 $HOME/ssl/redis
mkdir -p -m 0755 $HOME/ssl/redis-sentinel
mkdir -p -m 0755 $HOME/ssl/orc
Для этого создайте закрытый ключ:
openssl genpkey -algorithm RSA -out $HOME/ssl/ca/certificate.key -pkeyopt rsa_keygen_bits:4096
Затем создайте корневой сертификат:
openssl req -x509 -new -key $HOME/ssl/ca/certificate.key \
-subj "/C=RU/ST=Moscow/O=Kaspersky/CN=*" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign" \
-days 3650 -out $HOME/ssl/ca/certificate.pem
Создайте закрытый ключ:
openssl genpkey -algorithm RSA -out $HOME/ssl/mongo/cert.key -pkeyopt rsa_keygen_bits:4096
Создайте сертификат:
openssl req -x509 -new -key $HOME/ssl/mongo/cert.key \
-subj "/C=RU/ST=Moscow/L=Moscow/O=LK/OU=LK/CN=mongo" \
-addext "subjectAltName=DNS:mongo,IP:127.0.0.1,IP:$NODE_1,IP:$NODE_2,IP:$NODE_3,IP:$NODES_VIP" \
-CA $HOME/ssl/ca/certificate.pem \
-CAkey $HOME/ssl/ca/certificate.key \
-out $HOME/ssl/mongo/cert.pem \
-days 365
Объедините созданный ключ и сертификат в один файл:
cat $HOME/ssl/mongo/cert.key $HOME/ssl/mongo/cert.pem > $HOME/ssl/mongo/combined.pem
Создайте закрытый ключ:
openssl genpkey -algorithm RSA -out $HOME/ssl/redis/cert.key -pkeyopt rsa_keygen_bits:4096
Создайте сертификат:
openssl req -x509 -new -key $HOME/ssl/redis/cert.key \
-subj "/C=RU/ST=Moscow/L=Moscow/O=LK/OU=LK/CN=redis" \
-addext "subjectAltName=DNS:redis,IP:127.0.0.1,IP:$NODE_1,IP:$NODE_2,IP:$NODE_3,IP:$NODES_VIP" \
-CA $HOME/ssl/ca/certificate.pem \
-CAkey $HOME/ssl/ca/certificate.key \
-out $HOME/ssl/redis/cert.pem \
-days 365
Сконвертируйте ключ:
openssl pkcs8 -topk8 -in $HOME/ssl/redis/cert.key -out $HOME/ssl/redis/key.pem -nocrypt
Создайте закрытый ключ:
openssl genpkey -algorithm RSA -out $HOME/ssl/redis-sentinel/cert.key -pkeyopt rsa_keygen_bits:4096
Создайте сертификат:
openssl req -x509 -new -key $HOME/ssl/redis-sentinel/cert.key \
-subj "/C=RU/ST=Moscow/L=Moscow/O=LK/OU=LK/CN=redis-sentinel" \
-addext "subjectAltName=DNS:redis-sentinel,IP:127.0.0.1,IP:$NODE_1,IP:$NODE_2,IP:$NODE_3,IP:$NODES_VIP" \
-CA $HOME/ssl/ca/certificate.pem \
-CAkey $HOME/ssl/ca/certificate.key \
-out $HOME/ssl/redis-sentinel/cert.pem \
-days 365
Сконвертируйте ключ:
openssl pkcs8 -topk8 -in $HOME/ssl/redis-sentinel/cert.key -out $HOME/ssl/redis-sentinel/key.pem -nocrypt
Создайте закрытый ключ:
openssl genpkey -algorithm RSA -out $HOME/ssl/orc/cert.key -pkeyopt rsa_keygen_bits:4096
Сконвертируйте ключ:
openssl pkcs8 -topk8 -in $HOME/ssl/orc/cert.key -out $HOME/ssl/orc/key.pem -nocrypt
Создайте сертификат:
openssl req -x509 -new -key $HOME/ssl/orc/cert.key \
-subj "/C=RU/ST=Moscow/L=Moscow/O=LK/OU=LK/CN=orc" \
-addext "subjectAltName=DNS:orc,IP:127.0.0.1,IP:$NODE_1,IP:$NODE_2,IP:$NODE_3,IP:$NODES_VIP" \
-CA $HOME/ssl/ca/certificate.pem \
-CAkey $HOME/ssl/ca/certificate.key \
-out $HOME/ssl/orc/cert.pem \
-days 365
Создайте хранилище ключей (PKCS12 KeyStore):
openssl pkcs12 -export \
-in $HOME/ssl/orc/cert.pem \
-inkey $HOME/ssl/orc/cert.key \
-certfile $HOME/ssl/ca/certificate.pem \
-out $HOME/ssl/orc/keyStore.p12 \
-name "orc" \
-passout env:ORC_KEY_PASS && \
chmod 644 $HOME/ssl/orc/keyStore.p12
Добавьте в хранилище CA-сертификат:
keytool -importcert -alias ca \
-file $HOME/ssl/ca/certificate.pem \
-keystore $HOME/ssl/orc/keyStore.p12 \
-storetype PKCS12 \
-storepass $ORC_KEY_PASS \
-trustcacerts -noprompt
Создайте хранилище доверенных сертификатов (PKCS12 TrustStore):
openssl pkcs12 -export \
-name "orc" \
-inkey $HOME/ssl/orc/cert.key \
-in $HOME/ssl/orc/cert.pem \
-certfile $HOME/ssl/ca/certificate.pem \
-out $HOME/ssl/orc/trustStore.p12 \
-passout env:ORC_KEY_PASS && \
chmod 644 $HOME/ssl/orc/trustStore.p12
Добавьте в хранилище CA-сертификат:
keytool -importcert -alias ca \
-file $HOME/ssl/ca/certificate.pem \
-keystore $HOME/ssl/orc/trustStore.p12 \
-storetype PKCS12 \
-storepass $ORC_KEY_PASS \
-trustcacerts -noprompt
Распространите сертификаты на узлы:
Выполните на узле Node_1:
scp -r ssl $NODE_2:/tmp
scp -r ssl $NODE_3:/tmp
Выполните на узлах Node_2 и Node_3:
cp -r /tmp/ssl $HOME
docker network create \
--driver=bridge \
--subnet=10.11.11.0/24 \
--gateway=10.11.11.1 \
--opt com.docker.network.bridge.name=knaas_aio_int \
knaas_aio_int
Для использования MongoDB необходимо включить у CPU расширение системы команд AVX. Для этого при развертывании ВМ задайте режим CPU host-passthrough, если для развертывания вы используете KVM.
Создайте Docker volume на всех узлах:
docker volume create --name orc_dbs_data
Создайте и запустите контейнер на узле Node_1:
docker run -d --name=mongo-1 \
--hostname=mongo-1 \
--volume orc_dbs_data:/data/db \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/cert.pem:ro \
--volume $HOME/ssl/mongo/combined.pem:/ssl/certs/mongo/combined.pem:ro \
--volume /data/configdb \
--env=TZ=Europe/Moscow \
--network=knaas_aio_int \
-p 27017:27017 \
--restart=unless-stopped \
--runtime=runc \
mongo:5.0.7 \
mongod --bind_ip_all --replSet knaas --tlsMode requireTLS --tlsCertificateKeyFile /ssl/certs/mongo/combined.pem --tlsCAFile /ssl/certs/ca/cert.pem --tlsDisabledProtocols TLS1_0,TLS1_1
Создайте и запустите контейнер на узле Node_2:
docker run -d --name=mongo-2 \
--hostname=mongo-2 \
--volume orc_dbs_data:/data/db \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/cert.pem:ro \
--volume $HOME/ssl/mongo/combined.pem:/ssl/certs/mongo/combined.pem:ro \
--volume /data/configdb \
--env=TZ=Europe/Moscow \
--network=knaas_aio_int \
-p 27017:27017 \
--restart=unless-stopped \
--runtime=runc \
mongo:5.0.7 \
mongod --bind_ip_all --replSet knaas --tlsMode requireTLS --tlsCertificateKeyFile /ssl/certs/mongo/combined.pem --tlsCAFile /ssl/certs/ca/cert.pem --tlsDisabledProtocols TLS1_0,TLS1_1
Создайте и запустите контейнер на узле Node_3:
docker run -d --name=mongo-3 \
--hostname=mongo-3 \
--volume orc_dbs_data:/data/db \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/cert.pem:ro \
--volume $HOME/ssl/mongo/combined.pem:/ssl/certs/mongo/combined.pem:ro \
--volume /data/configdb \
--env=TZ=Europe/Moscow \
--network=knaas_aio_int \
-p 27017:27017 \
--restart=unless-stopped \
--runtime=runc \
mongo:5.0.7 \
mongod --bind_ip_all --replSet knaas --tlsMode requireTLS --tlsCertificateKeyFile /ssl/certs/mongo/combined.pem --tlsCAFile /ssl/certs/ca/cert.pem --tlsDisabledProtocols TLS1_0,TLS1_1
Инициируйте replica set на узле Node_1:
docker exec -i mongo-1 mongosh --tls \
--tlsCertificateKeyFile /ssl/certs/mongo/combined.pem \
--tlsCAFile /ssl/certs/ca/cert.pem <<EOF
rs.initiate({
_id: 'knaas',
version: 1,
members: [
{_id: 0, host: '$NODE_1:27017', priority: 2},
{_id: 1, host: '$NODE_2:27017', priority: 1},
{_id: 2, host: '$NODE_3:27017', arbiterOnly: true}
]
})
EOF
На узле Node_1 добавьте в БД пользователя admin:
docker exec -i mongo-1 mongosh --tls \
--tlsCertificateKeyFile /ssl/certs/mongo/combined.pem \
--tlsCAFile /ssl/certs/ca/cert.pem <<EOF
db.getSiblingDB("admin").createUser({
user:"admin",
pwd:"$MONGO_ADMIN_PASS",
roles:[{
role:"userAdminAnyDatabase",
db:"admin"
}]
})
EOF
На узле Node_1 добавьте в БД пользователя knaas:
docker exec -i mongo-1 mongosh --tls \
--tlsCertificateKeyFile /ssl/certs/mongo/combined.pem \
--tlsCAFile /ssl/certs/ca/cert.pem <<EOF
db.getSiblingDB("admin").auth("admin","$MONGO_ADMIN_PASS");
db.getSiblingDB("knaas").createUser({
user:"knaas",
pwd:"$MONGO_KNAAS_PASS",
roles:["readWrite"]
})
EOF
Для Ubuntu 22.04 используйте образ redis:6.2.20 вместо registry.astralinux.ru/library/astra/ubi18-redis7015:1.8.2.
docker volume create --name redis_data
docker run -d \
--name redis-master \
-p 6379:6379 \
-v redis_data:/data \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/ca.pem:ro \
--volume $HOME/ssl/redis/cert.pem:/ssl/certs/redis/cert.pem:ro \
--volume $HOME/ssl/redis/cert.key:/ssl/keys/redis/key.pem:ro \
registry.astralinux.ru/library/astra/ubi18-redis7015:1.8.2 \
redis-server \
--port 0 \
--bind 0.0.0.0 \
--protected-mode no \
--tls-port 6379 \
--tls-replication yes \
--tls-cert-file /ssl/certs/redis/cert.pem \
--tls-key-file /ssl/keys/redis/key.pem \
--tls-ca-cert-file /ssl/certs/ca/ca.pem
docker run -d \
--name redis-replica \
-p 6379:6379 \
-v redis_data:/data \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/ca.pem:ro \
--volume $HOME/ssl/redis/cert.pem:/ssl/certs/redis/cert.pem:ro \
--volume $HOME/ssl/redis/cert.key:/ssl/keys/redis/key.pem:ro \
registry.astralinux.ru/library/astra/ubi18-redis7015:1.8.2 \
redis-server \
--port 0 \
--bind 0.0.0.0 \
--protected-mode no \
--tls-port 6379 \
--tls-replication yes \
--tls-cert-file /ssl/certs/redis/cert.pem \
--tls-key-file /ssl/keys/redis/key.pem \
--tls-ca-cert-file /ssl/certs/ca/ca.pem \
--replicaof $NODE_1 6379
Для Ubuntu 22.04 используйте образ redis:6.2.20 вместо registry.astralinux.ru/library/astra/ubi18-redis7015:1.8.2.
docker volume create --name redis_sentinel_data
docker run -d \
--name redis-sentinel-1 \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/ca.pem:ro \
--volume $HOME/ssl/redis-sentinel/cert.pem:/ssl/certs/redis/cert.pem:ro \
--volume $HOME/ssl/redis-sentinel/cert.key:/ssl/keys/redis/key.pem:ro \
-p 26379:26379 \
registry.astralinux.ru/library/astra/ubi18-redis7015:1.8.2 \
sh -c "cat > /sentinel.conf <<EOF
port 0
bind 0.0.0.0
protected-mode no
tls-port 26379
tls-cert-file /ssl/certs/redis/cert.pem
tls-key-file /ssl/keys/redis/key.pem
tls-ca-cert-file /ssl/certs/ca/ca.pem
tls-auth-clients optional
tls-replication yes
tls-cluster yes
sentinel monitor mymaster $NODE_1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel announce-ip $NODE_1
sentinel announce-port 26379
EOF
redis-server /sentinel.conf --sentinel"
docker run -d \
--name redis-sentinel-2 \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/ca.pem:ro \
--volume $HOME/ssl/redis-sentinel/cert.pem:/ssl/certs/redis/cert.pem:ro \
--volume $HOME/ssl/redis-sentinel/cert.key:/ssl/keys/redis/key.pem:ro \
-p 26379:26379 \
registry.astralinux.ru/library/astra/ubi18-redis7015:1.8.2 \
sh -c "cat > /sentinel.conf <<EOF
port 0
bind 0.0.0.0
protected-mode no
tls-port 26379
tls-cert-file /ssl/certs/redis/cert.pem
tls-key-file /ssl/keys/redis/key.pem
tls-ca-cert-file /ssl/certs/ca/ca.pem
tls-auth-clients optional
tls-replication yes
tls-cluster yes
sentinel monitor mymaster $NODE_1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel announce-ip $NODE_2
sentinel announce-port 26379
EOF
redis-server /sentinel.conf --sentinel"
docker run -d \
--name redis-sentinel-3 \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/ca.pem:ro \
--volume $HOME/ssl/redis-sentinel/cert.pem:/ssl/certs/redis/cert.pem:ro \
--volume $HOME/ssl/redis-sentinel/cert.key:/ssl/keys/redis/key.pem:ro \
-p 26379:26379 \
registry.astralinux.ru/library/astra/ubi18-redis7015:1.8.2 \
sh -c "cat > /sentinel.conf <<EOF
port 0
bind 0.0.0.0
protected-mode no
tls-port 26379
tls-cert-file /ssl/certs/redis/cert.pem
tls-key-file /ssl/keys/redis/key.pem
tls-ca-cert-file /ssl/certs/ca/ca.pem
tls-auth-clients optional
tls-replication yes
tls-cluster yes
sentinel monitor mymaster $NODE_1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel announce-ip $NODE_3
sentinel announce-port 26379
EOF
redis-server /sentinel.conf --sentinel"
docker load -i "${ORC_CONTAINER_NAME//:/_}.tar"
docker volume create --name orc_data
docker run -d --name=orc-1 \
--hostname=orc-1 \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/cert.pem:ro \
--volume $HOME/ssl/ca/certificate.key:/ssl/keys/ca/key.pem:ro \
--volume $HOME/ssl/orc/trustStore.p12:/ssl/certs/orc/trustStore.p12:ro \
--volume $HOME/ssl/orc/keyStore.p12:/ssl/certs/orc/keyStore.p12:ro \
--volume $HOME/ssl/orc/cert.pem:/ssl/certs/orc/cert.pem:ro \
--volume $HOME/ssl/orc/key.pem:/ssl/keys/orc/key.pem:ro \
--volume orc_data:/data \
-p 8080:8080 \
--env=TZ=Europe/Moscow \
--env=KNAAS_EULA_AGREED=yes \
--env="JAVA_OPTS=-Xms2048m -Xmx3560m -Dspring.data.mongodb.database=knaas -Dorc.security.encryption.password=$ORC_ENC_PASS -Dspring.data.mongodb.uri=mongodb://knaas:$MONGO_KNAAS_PASS@$NODE_1:27017,$NODE_2:27017,$NODE_3:27017/knaas?replicaSet=knaas&tls=true -Dspring.redis.redisson.sentinel-servers-config.subscription-mode=master -Dspring.redis.redisson.sentinel-servers-config.master-name=mymaster -Dspring.redis.redisson.sentinel-servers-config.add-sentinel-address=rediss://$NODE_1:26379,rediss://$NODE_2:26379,rediss://$NODE_3:26379 -Dspring.redis.redisson.sentinel-servers-config.ssl-truststore=file:///ssl/certs/orc/trustStore.p12 -Dspring.redis.redisson.sentinel-servers-config.ssl-truststore-password=$ORC_KEY_PASS -Dspring.redis.redisson.sentinel-servers-config.ssl-keystore=file:///ssl/certs/orc/keyStore.p12 -Dspring.redis.redisson.sentinel-servers-config.ssl-keystore-password=$ORC_KEY_PASS -Dorc.openflow.tls.ca-private.certificate.path=/ssl/keys/ca/key.pem -Dorc.openflow.tls.ca-public.certificate.path=/ssl/certs/ca/cert.pem -Dgrpc.tls.certificate.path=/ssl/certs/orc/cert.pem -Dgrpc.tls.private.key.path=/ssl/keys/orc/key.pem -Dgrpc.tls.ca.certificate.path=/ssl/certs/ca/cert.pem -Dserver.ssl.enabled=true -Dserver.ssl.trust-store=/ssl/certs/orc/trustStore.p12 -Dserver.ssl.trust-store-password=$ORC_KEY_PASS -Dserver.ssl.trust-store-type=pkcs12 -Dserver.ssl.key-store=/ssl/certs/orc/keyStore.p12 -Dserver.ssl.key-store-password=$ORC_KEY_PASS -Dserver.ssl.key-store-type=pkcs12 -Dorc.sdn.grpc.timeout=60s" \
--network=knaas_aio_int \
--workdir=/opt/b4n/orc \
--restart=unless-stopped \
hub.brain4net.com/$ORC_CONTAINER_NAME
docker run -d --name=orc-2 \
--hostname=orc-2 \
--volume $HOME/ssl/ca/certificate.pem:/ssl/certs/ca/cert.pem:ro \
--volume $HOME/ssl/ca/certificate.key:/ssl/keys/ca/key.pem:ro \
--volume $HOME/ssl/orc/trustStore.p12:/ssl/certs/orc/trustStore.p12:ro \
--volume $HOME/ssl/orc/keyStore.p12:/ssl/certs/orc/keyStore.p12:ro \
--volume $HOME/ssl/orc/cert.pem:/ssl/certs/orc/cert.pem:ro \
--volume $HOME/ssl/orc/key.pem:/ssl/keys/orc/key.pem:ro \
--volume orc_data:/data \
-p 8080:8080 \
--env=TZ=Europe/Moscow \
--env=KNAAS_EULA_AGREED=yes \
--env="JAVA_OPTS=-Xms2048m -Xmx3560m -Dspring.data.mongodb.database=knaas -Dorc.security.encryption.password=$ORC_ENC_PASS -Dspring.data.mongodb.uri=mongodb://knaas:$MONGO_KNAAS_PASS@$NODE_1:27017,$NODE_2:27017,$NODE_3:27017/knaas?replicaSet=knaas&tls=true -Dspring.redis.redisson.sentinel-servers-config.subscription-mode=master -Dspring.redis.redisson.sentinel-servers-config.master-name=mymaster -Dspring.redis.redisson.sentinel-servers-config.add-sentinel-address=rediss://$NODE_1:26379,rediss://$NODE_2:26379,rediss://$NODE_3:26379 -Dspring.redis.redisson.sentinel-servers-config.ssl-truststore=file:///ssl/certs/orc/trustStore.p12 -Dspring.redis.redisson.sentinel-servers-config.ssl-truststore-password=$ORC_KEY_PASS -Dspring.redis.redisson.sentinel-servers-config.ssl-keystore=file:///ssl/certs/orc/keyStore.p12 -Dspring.redis.redisson.sentinel-servers-config.ssl-keystore-password=$ORC_KEY_PASS -Dorc.openflow.tls.ca-private.certificate.path=/ssl/keys/ca/key.pem -Dorc.openflow.tls.ca-public.certificate.path=/ssl/certs/ca/cert.pem -Dgrpc.tls.certificate.path=/ssl/certs/orc/cert.pem -Dgrpc.tls.private.key.path=/ssl/keys/orc/key.pem -Dgrpc.tls.ca.certificate.path=/ssl/certs/ca/cert.pem -Dserver.ssl.enabled=true -Dserver.ssl.trust-store=/ssl/certs/orc/trustStore.p12 -Dserver.ssl.trust-store-password=$ORC_KEY_PASS -Dserver.ssl.trust-store-type=pkcs12 -Dserver.ssl.key-store=/ssl/certs/orc/keyStore.p12 -Dserver.ssl.key-store-password=$ORC_KEY_PASS -Dserver.ssl.key-store-type=pkcs12 -Dorc.sdn.grpc.timeout=60s" \
--network=knaas_aio_int \
--workdir=/opt/b4n/orc \
--restart=unless-stopped \
hub.brain4net.com/$ORC_CONTAINER_NAME
После выполнения всех команд контейнеры должны быть запущены и не должны перезапускаться. Оркестратор отвечает по порту 8080 на заданном виртуальном IP. Вы можете убедиться, что оркестратор запущен и доступен по указанному виртуальному IP, выполнив простую проверку, при которой ответ будет пустым:
curl -k https://$NODES_VIP:8080
Чтобы проверить прохождение аутентификации на оркестраторе, вы можете выполнить такой скрипт на python:
test_auth.py
import requests
import sys
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
ip = sys.argv[1]
sess = requests.Session()
sess.verify = False
try:
response=sess.get(f'https://{ip}:8080/api/core/users/current')
response=sess.post((f'https://{ip}:8080/api/authentication'), data={'j_username': 'admin', 'j_password': 'admin'},headers={'X-CSRF-TOKEN': sess.cookies['CSRF-TOKEN']})
response=sess.get(f'https://{ip}:8080/api/core/users/current')
print(response.status_code)
print(response.content)
except Exception as e:
print(f"Error - {e}")
Запустите скрипт, выполнив:
python3 test_auth.py $NODES_VIP
Пример успешного ответа:
200
b'{"id":"9cb4bba3-6b82-472d-8347-4e217dac00cb","login":"admin","firstName":"Administrator","lastName":"Administrator","email":"admin@example.com","rbacPermission":{"id":"permission-0","name":"Full access"},"role":"ROLE_PLATFORM_ADMIN","requiredRequestConfirmation":false,"state":"ONLINE","currentTenants":[],"type":"LOCAL","groups":[],"enabled2fa":false,"initialized2fa":false}'
Для смены пароля администратора выполните скрипт change_password.py:
python3 change_password.py 192.168.200.100:8080
Код скрипта change_password.py:
import requests
import sys
import getpass
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
ip = sys.argv[1]
sess = requests.Session()
sess.verify = False
username = input("Enter the orchestrator user login: ")
password = getpass.getpass(f"Enter the current password for the user {username}: ")
try:
response=sess.get('https://'+ ip +'/api/core/users/current')
response=sess.post(('https://'+ ip +'/api/authentication'), data={'j_username': username, 'j_password': password},headers={'X-CSRF-TOKEN': sess.cookies['CSRF-TOKEN']})
if response.status_code != 200:
if response.status_code == 403 and response.json()[0]['code'] == "required_2fa_code":
secFA_code = getpass.getpass(f"Enter the two-factor authentication code: ")
response=sess.post(('https://'+ ip +'/api/authentication'), data={'j_username': username, 'j_password': password, 'code': secFA_code},headers={'X-CSRF-TOKEN': sess.cookies['CSRF-TOKEN']})
if response.status_code != 200:
print(f"Authentication failed.")
sys.exit(1)
else:
print(f"Authentication failed.")
sys.exit(1)
except Exception as e:
print(f"Authentication failed. Error: {e}")
sys.exit(1)
sess.get('https://'+ ip +'/api/core/users/current')
sess.headers.update({'Accept': 'application/json','content-type': 'application/json','X-CSRF-TOKEN': sess.cookies['CSRF-TOKEN']})
response.status_code = 400
while response.status_code != 200:
new_password = getpass.getpass(f"Enter a new password for the user {username}: ")
new_password2 = getpass.getpass(f"Repeat the new password for the user {username}: ")
if new_password != new_password2:
print()
print("The new password you entered does not match")
print()
else:
payload = {"password": new_password}
response=sess.post(('https://'+ ip +'/api/core/users/password/validate'), data=json.dumps(payload),headers={'X-CSRF-TOKEN': sess.cookies['CSRF-TOKEN']})
if response.status_code != 200:
print()
print("Weak password!")
print()
payload = {"password": new_password}
try:
response=sess.put(('https://'+ ip +'/api/core/users/current/password'), data=json.dumps(payload),headers={'X-CSRF-TOKEN': sess.cookies['CSRF-TOKEN']})
if response.status_code != 200:
print("Failed to change password!")
elif response.status_code == 200:
print()
print("Password successfully changed!")
print()
except Exception as e:
print("Failed to change password", e)