Добавить в корзинуПозвонить
Найти в Дзене

Пример проекта

mkdir -p /home/altlinux/Projects/Project_01 mkdir /home/altlinux/Projects/Project_01/terraform cd /home/altlinux/Projects/ export OS_AUTH_URL=https://cyberinfra.ssa2026.region:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_AUTH_TYPE=password
export OS_PROJECT_DOMAIN_NAME=
export OS_USER_DOMAIN_NAME=
export OS_PROJECT_NAME=
export OS_USERNAME=
export OS_PASSWORD= source cloudinit.conf Для корректной работы с Terraform, необходимо создадать файл конфигурации зеркала provider_installation {
network_mirror {
url = "https://terraform-mirror.mcs.mail.ru"
include = ["registry.terraform.io/*/*"]
}
direct {
exclude = ["registry.terraform.io/*/*"]
}
} cd Project_01/terraform/ terraform {
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "2.1.0"
}
}
}
provider "openstack" {
auth_url = "https://cyberinfra.ssa2026.region:5000/v3"
tenant_name = "Project0"
user_name = "User0"
Оглавление

Проект1

Все последующие действия выполняются из-под пользователя altlinux (не root)

  • Создаём директорию /home/altlinux/Projects/Project_01:

mkdir -p /home/altlinux/Projects/Project_01

  • Для скрипта deploy_project_01.sh будет использоваться Terraform
  • Создадим директорию terraform в ранее созданной директории для Project_01:

mkdir /home/altlinux/Projects/Project_01/terraform

  • Перейдём в директорию /home/altlinux/Projects/:

cd /home/altlinux/Projects/

  • Создадим файл с именем cloudinit.conf (имя произвольное) и поместим в него следующее содержимое:указав переменные окружения для работы OpenStack CLI с API облака

export OS_AUTH_URL=https://cyberinfra.ssa2026.region:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_AUTH_TYPE=password
export OS_PROJECT_DOMAIN_NAME=
export OS_USER_DOMAIN_NAME=
export OS_PROJECT_NAME=
export OS_USERNAME=
export OS_PASSWORD=

  • Применяем переменные окружения указанные в файле

source cloudinit.conf

  • Проверяем возможность взаимодействовать чере openstack-cli с облаком:например, выведем список инстансов командой openstack --insecure server list:

Для корректной работы с Terraform, необходимо создадать файл конфигурации зеркала

  • Файл должен иметь имя .terraformrc и быть расположен в домашнем каталоге пользователя
  • Файл ~/.terraformrc должен содержать в себе следующее:

provider_installation {
network_mirror {
url = "
https://terraform-mirror.mcs.mail.ru"
include = ["registry.terraform.io/*/*"]
}
direct {
exclude = ["registry.terraform.io/*/*"]
}
}

  • Перейдём в директорию Project_01/terraform/:

cd Project_01/terraform/

  • Создадим файл provider.tf и опишем параметры для подключения к провайдеру openstack для работы с облаком:
    в данном конкретном примере подразумевается что у участника:Внешний доступ к панели самообслуживания:
    https://cyberinfra.ssa2026.region:8800 Домен: Competence_SiSA
    Проект: Project0
    Учётная запись: User0
    Пароль от уч.записи: P@ssw0rd

terraform {
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "2.1.0"
}
}
}

provider "openstack" {
auth_url = "
https://cyberinfra.ssa2026.region:5000/v3"
tenant_name = "Project0"
user_name = "User0"
password = "P@ssw0rd"
insecure = true
}

  • Инициализируем текущий каталог для работы с terraform и провайдером openstack:

terraform init

  • Результат успешной инициализации Terraform провайдера:
-2

Чтобы с инстанса Cloud-ADM был доступ по SSH (для Ansible) до всех создаваемых инстансов (средствами Terraform), будет использоваться файл cloud-init.yml

  • Создадим ключевую пару:

ssh-keygen -t rsa

  • Поместим содержимое публичного ключа (id_rsa.pub) в файл cloud-init.yml:

cat ~/.ssh/id_rsa.pub > cloud-init.yml

  • Откроем файл cloud-init.yml на редактирование и добавим в самое начало (до содержимого ключа ssh):
    таким образом, на создаваемых в дальнейшем интстансах будут:создан пользователь 
    altlinux с паролем P@ssw0rd;
    задан для суперпользователя root пароль toor;
    передан публичный SSH-ключ 
    Cloud-ADM.

#cloud-config
chpasswd:
expire: false
users:
- {name: altlinux, password: P@ssw0rd, type: text}
- {name: root, password: toor, type: text}
ssh_pwauth: false

users:
- name: altlinux
sudo: ALL=(ALL) NOPASSWD:ALL
groups: wheel
shell: /bin/bash
ssh_authorized_keys:
- <СОДЕРЖИМОЕ_ПУБЛИЧНОГО_КЛЮЧА_SSH>

  • Создадим файл vm-game.tf и опишем конфигурацию для создаваемых инстансов game01, game02 и game03:
    для минимального написания строк кода (время на выполнения задания не резиновое,
    хардкод приветствуется, данный модуль не проверяет применение лучших практик для автоматизации):используем цикл по счётчику count;
    избавляемся от параметризации с использованием переменных (хардкодим все значения в данный файл).
    значение для параметра 
    flavor_id можно узнать используя команду openstack --insecure flavor list скопировав ID Типа ВМ с 1024 RAM и 1 VCPUs;
    значение для параметра 
    uuid можно узнать используя команду openstack --insecure image list скопировав ID образа alt-p11-cloud-x86_64.qcow2.

resource "openstack_compute_instance_v2" "game" {
count = "3"
name = "game0${count.index + 1}"
flavor_id = "03bf1b85-2f5f-4ada-a07b-8b994b6dcb57"
user_data = file("cloud-init.yml")

block_device {
uuid = "827e08fa-fd3c-41cd-92ca-845bb5018478"
source_type = "image"
volume_size = "10"
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}

network {
port = openstack_networking_port_v2.port_vm_game[count.index].id
}
}

  • Создадим файл vm-haproxy01.tf и опишем конфигурацию для создаваемого инстанса haproxy01:значение для параметра flavor_id можно узнать используя команду openstack --insecure flavor list скопировав ID Типа ВМ с 1024 RAM и 1 VCPUs;
    значение для параметра
    uuid можно узнать используя команду openstack --insecure image list скопировав ID образа alt-p11-cloud-x86_64.qcow2.

resource "openstack_compute_instance_v2" "haproxy" {
name = "haproxy01"
flavor_id = "03bf1b85-2f5f-4ada-a07b-8b994b6dcb57"
user_data = file("cloud-init.yml")

block_device {
uuid = "827e08fa-fd3c-41cd-92ca-845bb5018478"
source_type = "image"
volume_size = "10"
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}

network {
port = openstack_networking_port_v2.haproxy.id
}
}

  • Создадим файл network.tf и опишем конфигурацию сети в соответствие с топологией для Project_01:значение для параметра network_id можно узнать используя команду openstack --insecure network list скопировав ID виртуальной сети с именем cloud-net;
    значение для параметра 
    subnet_id можно узнать используя команду openstack --insecure subnet list скопировав ID виртуальной подсети 192.168.1.0/24;

resource "openstack_networking_port_v2" "port_vm_game" {
count = "3"
name = "port_vm_game0${count.index + 1}"
network_id = "61845892-f9cc-4fde-962c-34b59425a74d"
admin_state_up = true

fixed_ip {
subnet_id = "13592ca4-8782-410b-9bcc-90810ccab6fe"
ip_address = "192.168.1.10${count.index + 1}"
}
}

resource "openstack_networking_port_v2" "haproxy" {
name = "port_vm_haproxy"
network_id = "61845892-f9cc-4fde-962c-34b59425a74d"
admin_state_up = true

fixed_ip {
subnet_id = "13592ca4-8782-410b-9bcc-90810ccab6fe"
ip_address = "192.168.1.100"
}
}

  • Создадим файл floatingip.tf и опишем конфигурацию Плавающего IP-адреса в соответствие с топологией для Project_01:

resource "openstack_networking_floatingip_v2" "floatingip_haproxy" {
pool = "public"
}

resource "openstack_networking_floatingip_associate_v2" "association_haproxy" {
port_id = openstack_networking_port_v2.haproxy.id
floating_ip = openstack_networking_floatingip_v2.floatingip_haproxy.address
}

  • Выполняем проверку синтаксиса и структуры файлов конфигурации Terraform:

terraform validate

-3

Результат:

  • Перейдём в директорию /home/altlinux/Projects/Project_01:

cd /home/altlinux/Projects/Project_01

  • Создадим файл deploy_project_01.sh и укажем инструкции необходимые для запуска Terraform:

#!/bin/bash

cd /home/$USER/Projects
source cloudinit.conf
cd /home/$USER/Projects/Project_01/terraform
terraform init
terraform apply -auto-approve

sleep 60
echo "done"

  • Выдать права на исполнение для файла deploy_project_01.sh:

chmod +x deploy_project_01.sh

  • Запустить скрипт на исполнение:

./deploy_project_01.sh

  • Проверить автоматически созданные инстансы в облаке:
  • Проверить Плавающий IP-адрес для инстанса haproxy01:
  • Поскольку IP-адресация задаётся статическая, то для удобства работы редактируем конфигурационный файл /etc/hosts:
  • Создадим директорию ansible в ранее созданной директории для Project_01:

mkdir /home/altlinux/Projects/Project_01/ansible

  • Перейдём в директорию /home/altlinux/Projects/Project_01/ansible:

cd /home/altlinux/Projects/Project_01/ansible

  • Создадим файл конфигурации ansible.cfg поместим в него следующее содержимое:

[defaults]
inventory = ./inventory.yml
host_key_checking = False
callback_enabled = profile_tasks
callback_whitelist = profile_tasks

  • Создадим файл inventory.yml и опишем файл инвентаря для Ansible:
    описав 2 группы хостов с именами 
    proxys и games:группа proxys содержит в себе инстанс haproxy01;
    группа 
    games содержит в себе инстансы game01, game02 и game03;

all:
children:
proxys:
hosts:
haproxy01:

games:
hosts:
game01:
game02:
game03:

  • Создадим директорию group_vars где будем создавать файлы с переменными для групп хостов:

mkdir group_vars

  • Создадим файл 'all.yml' в директории group_vars:

---
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_user: altlinux
ansible_ssh_private_key_file: ~/.ssh/id_rsa

  • Проверяем возможность ansible подключиться к инстансам описанным в инвентарном файле:

ansible -m ping all

  • Скачиваем любым способом файлы https://disk.yandex.ru/d/uhpN6U6UYRK_Nw (у приложения есть README от программиста-разработчика)
  • Распаковываем архив в директорию /home/altlinux/Projects/Project_01/2048-game/:

unzip ~/Project_01.zip -d /home/altlinux/Projects/Project_01/2048-game/

  • В директории /home/altlinux/Projects/Project_01/ansible создаём файл Dockerfile:образ приложения нужно сделать легковесным через мультистейджинг

FROM node:16-alpine AS builder

WORKDIR /2048-game

COPY package*.json ./
RUN npm install --include=dev

COPY . .
RUN npm run build

EXPOSE 8080

FROM nginx:stable-alpine3.19
COPY --from=builder /2048-game/dist /usr/share/nginx/html

  • В директории /home/altlinux/Projects/Project_01/ansible создаём файл games_playbook.yml:
    таким образом, на группе хостов 
    games (на инстансах: game01, game02 и game03) будет настроено:Установлены пакеты: docker-engine и docker-buildx;
    Запущена и добавлена в автозагрузку служба 
    docker;
    Скопированы все файлы с 
    Cloud-ADM на удалённые хосты, необходимые для приложения;
    Скопирован с 
    Cloud-ADM на удалённые хосты файл Dockerfile;
    На удалённых хостах выполнена локальная сборка образа для приложения;
    На удалённых хостав выполнен запуск контейнеров с веб-приложением.

---
- hosts: games
become: true

tasks:
- name: Install docker
community.general.apt_rpm:
name:
- docker-engine
- docker-buildx
state: present
update_cache: true

- name: Started and enabled docker
ansible.builtin.systemd:
name: docker
state: started
enabled: true

- name: Copying the project files
ansible.builtin.copy:
src: ../2048-game/
dest: "/home/{{ ansible_ssh_user }}/2048-game/"

- name: Copying the Dockerfile
ansible.builtin.copy:
src: ./Dockerfile
dest: "/home/{{ ansible_ssh_user }}/2048-game/"

- name: Build docker image
community.docker.docker_image_build:
name: "2048-game"
tag: latest
path: "/home/{{ ansible_ssh_user }}/2048-game/"
dockerfile: Dockerfile

- name: Start docker container
community.docker.docker_container:
name: "2048-game"
image: "2048-game"
ports: "80:80"
state: started
restart: true

  • На текущем этап можно выполнить тестовый запуск созданного playbook-а games_playbook.yml:

ansible-playbook games_playbook.yml

  • Таким образом при обращении в браузере с Cloud-ADM по описанным ниже url должно открываться веб-приложение:
  • В директории /home/altlinux/Projects/Project_01/ansible создаём директорию files:

mkdir files

  • В директории /home/altlinux/Projects/Project_01/ansible/files создаём конфигурационный файл haproxy.cfg
    в данном файле стандартное содержимое haproxy.cfg за исключением блока frontend и backend для реализации необходимого функционаладля удобства можно найти конфигаруционный файл в сети Интернет;
    или же выполнить установку пакета 
    haproxy и забрать его из директории /etc/haproxy/haproxy.cfg (т.к. инстанс haproxy01 в любом случае будет удалён).

global
log /dev/log daemon
chroot /var/lib/haproxy
pidfile /run/haproxy.pid
maxconn 4000
user _haproxy
group _haproxy
daemon
stats socket /var/lib/haproxy/stats

defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000

frontend http_front
bind *:80
bind *:443 ssl crt /var/lib/ssl/game.pem
default_backend http_back

backend http_back
balance roundrobin
server game01 192.168.1.101:80 check
server game02 192.168.1.102:80 check
server game03 192.168.1.103:80 check

listen stats
bind :80
bind *:443 ssl crt /var/lib/ssl/game.pem
stats enable
stats uri /
stats refresh 5s
stats realm Haproxy\ Stats

  • Средствами утилиты openssl разворачиваем свой Удостоверяющий Центр сертификатов:

openssl req -x509 -sha256 -days 3653 -newkey rsa:2048 -keyout ca.key -out ca.crt

  • Добавляем корневой сертификат в хранилище на Cloud-ADM:

sudo cp ca.crt /etc/pki/ca-trust/source/anchors/ && sudo update-ca-trust

  • Перемещаем файлы сертификатов в директорию files:

mv ca.* files/

  • Генерируем ключи, запросы и сертификаты для веб:Ключ:

openssl genrsa -out files/game.key 2048

  • Запрос:

openssl req -key files/game.key -new -out files/game.csr

  • Результат:
  • Файл с расширениями для сертификата:

cat <<EOF > files/game.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName=@alt_names
[alt_names]
DNS.1=game.au.team
IP.1=192.168.1.100
EOF

  • Выпускаем сертификат:

openssl x509 -req -CA files/ca.crt -CAkey files/ca.key -in files/game.csr -out files/game.crt -days 365 -CAcreateserial -extfile files/game.ext

  • Создаём цепочку для haproxy:

cat files/game.key files/game.crt > files/game.pem

  • В директории /home/altlinux/Projects/Project_01/ansible создаём файл proxys_playbook.yml:
    таким образом, на группе хостов 
    games (на инстансах: game01, game02 и game03) будет настроено:Установлен пакет haproxy;
    Скопирован с 
    Cloud-ADM на удалённый хост файл haproxy.cfg;
    Скопирован с 
    CloudpADM на удалённый хост файл game.pem;
    Включена и добавлена в автозагрузку служба 
    haproxy.

---
- hosts: proxys
become: true

tasks:
- name: Install HAProxy
community.general.apt_rpm:
name: haproxy
state: present
update_cache: true

- name: Copy file 'haproxy.cfg'
ansible.builtin.copy:
src: files/haproxy.cfg
dest: /etc/haproxy/haproxy.cfg
notify:
- Restarted HAProxy

- name: Copy certificate for HAProxy
ansible.builtin.copy:
src: files/game.pem
dest: /var/lib/ssl/game.pem
notify:
- Restarted HAProxy

- name: Started and enabled HAProxy
ansible.builtin.systemd:
name: haproxy
state: restarted
enabled: true

handlers:
- name: Restarted HAProxy
ansible.builtin.systemd:
name: haproxy
state: restarted

  • На текущем этап можно выполнить тестовый запуск созданного playbook-а proxys_playbook.yml:

ansible-playbook proxys_playbook.yml

  • Таким образом при обращении в браузере с Cloud-ADM по описанным ниже url должно открываться веб-приложение:https://game.au.team (в файле /etc/hosts должна быть добавлена запись):

haproxy01.dev.au.team /haproxy?stats

  • Перейдём в директорию /home/altlinux/Projects/Project_01:

cd /home/altlinux/Projects/Project_01

  • Создадим файл configure_project_01.sh и укажем инструкции необходимые для запуска Ansible:

#!/bin/bash

export PATH=/home/altlinux/.local/bin:$PATH
cd /home/$USER/Projects/Project_01/ansible
sleep 10
ansible-playbook games_playbook.yml
sleep 5
ansible-playbook proxys_playbook.yml

  • Выдать права на исполнение для файла configure_project_01.sh:

chmod +x configure_project_01.sh

  • Запустить скрипт на исполнение:

./configure_project_01.sh

  • Создадим файл destroy_project_01.sh и укажем инструкции необходимые для запуска Ansible:

#!/bin/bash

cd /home/$USER/Projects
source cloudinit.conf
cd /home/$USER/Projects/Project_01/terraform
terraform destroy -auto-approve
rm -f ~/.ssh/known_hosts

echo "done"

  • Выдать права на исполнение для файла destroy_project_01.sh:

chmod +x destroy_project_01.sh

  • Запустить скрипт на исполнение:

./destroy_project_01.sh

  • Таким образом, структура для Project01 получилась следующая:
-4

Проект2

Развёртывание недостающих виртуальных машин

  • Допустимы любые способы, в том числе и ручное создание ВМ
  • Модернизирует ранее написанные файлы для Terraform чтобы ускорить процесс создания ВМ
  • Создадим директорию для Project02 и перейдём в неё:

cd ~/Projects/

mkdir -p Project_02/terraform

cd Project_02/terraform

  • Скопируем файл provider.tf из Project01:

cp ~/Projects/Project_01/terraform/provider.tf ./

  • Менять в данном файле ничего не следует, инициализируем текущий каталог для работы с Terraform:

terraform init

  • Скопируем файл network.tf из Project01:

cp ~/Projects/Project_01/terraform/network.tf ./

  • модернизируем файл network.tf в текущей директории для Project02:избавляемся от цикла через счётчик count
    копируем данный блок, создавая порты с фиксированными IP-адресами для каждой ВМ

resource "openstack_networking_port_v2" "port_vm_acm-server" {
name = "port_acm-server"
network_id = "61845892-f9cc-4fde-962c-34b59425a74d"
admin_state_up = true

fixed_ip {
subnet_id = "13592ca4-8782-410b-9bcc-90810ccab6fe"
ip_address = "192.168.1.104"
}
}

resource "openstack_networking_port_v2" "port_vm_db-server" {
name = "port_db-server"
network_id = "61845892-f9cc-4fde-962c-34b59425a74d"
admin_state_up = true

fixed_ip {
subnet_id = "13592ca4-8782-410b-9bcc-90810ccab6fe"
ip_address = "192.168.1.105"
}
}

resource "openstack_networking_port_v2" "port_vm_bar-agent01" {
name = "port_bar-agent01"
network_id = "61845892-f9cc-4fde-962c-34b59425a74d"
admin_state_up = true

fixed_ip {
subnet_id = "13592ca4-8782-410b-9bcc-90810ccab6fe"
ip_address = "192.168.1.106"
}
}

  • Скопируем файл network.tf из Project01:

cp ~/Projects/Project_01/terraform/vm-game.tf ./vm.tf

  • модернизируем файл vm.tf в текущей директории для Project02:избавляемся от цикла через счётчик count
    копируем данный блок, создавая ВМ с соответствующими параметрами (по требованию задания)

resource "openstack_compute_instance_v2" "acm-server" {
name = "ACM-Server"
flavor_id = "101"
user_data = file("cloud-init.yml")

block_device {
uuid = "827e08fa-fd3c-41cd-92ca-845bb5018478"
source_type = "image"
volume_size = "20"
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}

network {
port = openstack_networking_port_v2.port_vm_acm-server.id
}
}

resource "openstack_compute_instance_v2" "db-server" {
name = "DB-Server"
flavor_id = "03bf1b85-2f5f-4ada-a07b-8b994b6dcb57"
user_data = file("cloud-init.yml")

block_device {
uuid = "827e08fa-fd3c-41cd-92ca-845bb5018478"
source_type = "image"
volume_size = "20"
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}

network {
port = openstack_networking_port_v2.port_vm_db-server.id
}
}

resource "openstack_compute_instance_v2" "bar-agent01" {
name = "BAR-Agent01"
flavor_id = "03bf1b85-2f5f-4ada-a07b-8b994b6dcb57"
user_data = file("cloud-init.yml")

block_device {
uuid = "827e08fa-fd3c-41cd-92ca-845bb5018478"
source_type = "image"
volume_size = "10"
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}

network {
port = openstack_networking_port_v2.port_vm_bar-agent01.id
}
}

  • Скопируем файл network.tf из Project01:

cp ~/Projects/Project_01/terraform/cloud-init.yml ./

  • Запускаем автоматическое развёртывания ВМ для Project02 через Terraform:

terraform apply

  • Для удобства приводим конфигурационный файл /etc/hosts к следующему виду:
-5
  • Передаём файл для установки Кибер Бекап на ВМ (как файл попал на Cloud-ADM не рассматривается):

scp CyberBackup_18_64-bit.x86_64 acm-server:~/

scp CyberBackup_18_64-bit.x86_64 db-server:~/

scp CyberBackup_18_64-bit.x86_64 bar-agent01:~/

DB-Server:

  • Установим пакет postgresql17-server:

apt-get update && apt-get install -y postgresql17-server

  • Создаём системные базы данных:

/etc/init.d/postgresql initdb

  • Включаем и добавляе в автозагрузку PostgreSQL:

systemctl enable --now postgresql

  • Разрешаем доступ к PostgreSQL из сети отредактировав конфигаруционный файл /var/lib/pgsql/data/postgresql.conf:в конфигарционном файле находим строку "listen_addresses = 'localhost'" и приводим её к следующему виду: listen_addresses = '*'
  • Настраиваем парольную аутентификацию для удалённого доступа отредактировав конфигаруционный файл /var/lib/pgsql/data/pg_hba.conf:добавляем следующую запись:
-6

Перезапускаем PostgreSQL:

systemctl restart postgresql

  • Создадим пользователя cyberbackup с паролем cyberbackup с ролью superadmin:

createuser -U postgres --superuser --encrypted --pwprompt cyberbackup

ACM-Server:

  • Обновляем систему до актуального состояния и перезагружаем устройство:

apt-get update && apt-get dist-upgrade -y && update-kernel -y && apt-get clean && reboot

  • Должны быть установлены следующие пакеты:где <x.x> – версия ядра (uname -r)

apt-get install kernel-source-<x.x>

-7

apt-get install -y kernel-source-6.12

apt-get install -y kernel-headers-modules-6.12 gcc make kmod-sign

  • Задаём разрешение на исполнение установочному файлу с дистрибутивом Кибер Бэкап:для этого дистрибутив должен быть заранее скачен и помещён на виртуальную машину

cd /home/altlinux/

chmod +x CyberBackup_18_64-bit.x86_64

  • Из под суперпользователя запускаем файл установки:

./CyberBackup_18_64-bit.x86_64

  • Нажимаем Enter:
  • Принимаем Лицензионное соглашение и нажимаем Enter:
-8

Выбираем Использовать PostgreSQL и нажимаем Enter:

  • Заполняем Сведения о подключении PostgreSQL и нажимаем Enter:
  • Оставляем порт для веб-интерфейса управления по умолчанию и нажимаем Enter:
  • Оставляем порт по умолчанию и нажимаем Enter:
  • Ожидаем процесс установки:

Cloud-ADM:

  • Открываем веб-браузер и переходим в веб-интерфейс управления
  • Выполняем вход из-под пользователя root с паролем toor:
  • Активируем стартовую лицензию на 30-дней

DB-Server:

  • Обновляем систему до актуального состояния и перезагружаем устройство:

apt-get update && apt-get dist-upgrade -y && update-kernel -y && apt-get clean && reboot

  • Должны быть установлены следующие пакеты:

apt-get install -y kernel-source-6.12

apt-get install -y kernel-headers-modules-6.12 gcc make kmod-sign

  • Задаём разрешение на исполнение установочному файлу с дистрибутивом Кибер Бэкап:для этого дистрибутив должен быть заранее скачен и помещён на виртуальную машину

cd /home/altlinux/

chmod +x CyberBackup_18_64-bit.x86_64

  • Из под суперпользователя запускаем файл установки:

./CyberBackup_18_64-bit.x86_64

Bar-Agent01:

  • Обновляем систему до актуального состояния и перезагружаем устройство:

apt-get update && apt-get dist-upgrade -y && update-kernel -y && apt-get clean && reboot

  • Должны быть установлены следующие пакеты:

apt-get install -y kernel-source-6.12

apt-get install -y kernel-headers-modules-6.12 gcc make kmod-sign

  • Задаём разрешение на исполнение установочному файлу с дистрибутивом Кибер Бэкап:для этого дистрибутив должен быть заранее скачен и помещён на виртуальную машину

cd /home/altlinux/

chmod +x CyberBackup_18_64-bit.x86_64

Cloud-ADM:

  • Проверить наличие агентов в веб-интерфейсе управления:
-9

Проект3

Cloud-ADM:

Развёртывание недостающих виртуальных машин

  • Допустимы любые способы, в том числе и ручное создание ВМ
  • Модернизирует ранее написанные файлы для Terraform чтобы ускорить процесс создания ВМ

cd ~/Projects/

mkdir -p Project_03/terraform

cd Project_03/terraform

  • За основу возьмём файлы из Project02:

cp ~/Projects/Project_02/terraform/provider.tf ./

cp ~/Projects/Project_02/terraform/cloud-init.yml ./

cp ~/Projects/Project_02/terraform/network.tf ./

cp ~/Projects/Project_02/terraform/vm.tf ./

  • Инициализируем текущий каталог для работы с Terraform:

terraform init

  • Модернизируем файл network.tf в текущей директории для Project03:

resource "openstack_networking_port_v2" "port_vm_master01" {
name = "port_master01"
network_id = "61845892-f9cc-4fde-962c-34b59425a74d"
admin_state_up = true

fixed_ip {
subnet_id = "13592ca4-8782-410b-9bcc-90810ccab6fe"
ip_address = "192.168.1.107"
}
}

resource "openstack_networking_port_v2" "port_vm_worker01" {
name = "port_worker01"
network_id = "61845892-f9cc-4fde-962c-34b59425a74d"
admin_state_up = true

fixed_ip {
subnet_id = "13592ca4-8782-410b-9bcc-90810ccab6fe"
ip_address = "192.168.1.108"
}
}

resource "openstack_networking_port_v2" "port_vm_worker02" {
name = "port_worker02"
network_id = "61845892-f9cc-4fde-962c-34b59425a74d"
admin_state_up = true

fixed_ip {
subnet_id = "13592ca4-8782-410b-9bcc-90810ccab6fe"
ip_address = "192.168.1.109"
}
}

  • Модернизируем файл vm.tf в текущей директории для Project03:

resource "openstack_compute_instance_v2" "master01" {
name = "master01"
flavor_id = "03bf1b85-2f5f-4ada-a07b-8b994b6dcb57"
user_data = file("cloud-init.yml")

block_device {
uuid = "827e08fa-fd3c-41cd-92ca-845bb5018478"
source_type = "image"
volume_size = "10"
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}

network {
port = openstack_networking_port_v2.port_vm_master01.id
}
}

resource "openstack_compute_instance_v2" "worker01" {
name = "worker01"
flavor_id = "03bf1b85-2f5f-4ada-a07b-8b994b6dcb57"
user_data = file("cloud-init.yml")

block_device {
uuid = "827e08fa-fd3c-41cd-92ca-845bb5018478"
source_type = "image"
volume_size = "10"
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}

network {
port = openstack_networking_port_v2.port_vm_worker01.id
}
}

resource "openstack_compute_instance_v2" "worker02" {
name = "worker02"
flavor_id = "03bf1b85-2f5f-4ada-a07b-8b994b6dcb57"
user_data = file("cloud-init.yml")

block_device {
uuid = "827e08fa-fd3c-41cd-92ca-845bb5018478"
source_type = "image"
volume_size = "10"
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}

network {
port = openstack_networking_port_v2.port_vm_worker02.id
}
}

  • Запускаем автоматическое развёртывания ВМ для Project03 через Terraform:

terraform apply

  • Для удобства приводим конфигурационный файл /etc/hosts к следующему виду:
-10

master01, worker01 и worker02:

  • Установим пакет docker-engine:

apt-get update && apt-get install -y docker-engine

  • Включить и добавить в автозагрузку службу docker:

systemctl enable --now docker

-11

  • Внести изменения в конфигурационный файл /etc/docker/daemon.json:привести параметр live-restore к следующему виду:
  • Перезагрузить службу docker для применения изменений:

systemctl restart docker

master01:

  • Создаём кластер Docker Swarm:

docker swarm init

  • Результат:команда генерирует два случайных токена, рабочий токен и токен менеджера
    когда добавляется новый узел к swarm, узел присоединяется как рабочий или управляющий узел на основе токена

worker01 и worker02:

  • Добавляем узлы в кластер Docker Swarm:worker01:
-12

  • worker02:
-13

master01:

  • Проверить наличие нод в кластере:

docker node ls

  • Запускаем сервис для локального хранилища на базе образа registry:3:

docker service create \
--name registry \
--publish published=5000,target=5000 \
--constraint node.role==worker \
registry:3

  • Проверьте статус запущенного сервиса можно с помощью docker service ls:
  • Проверить что задача развернулась именно на ноде с ролью worker можно с помощью команды docker service ps registry:
-14

Cloud-ADM:

  • Любым возможным способом скачиваем файлы приложения Project03 и передаём их на master01:

scp Project03.zip master01:~/

master01:

  • Устанавливаем пакет unzip и docker-compose-v2:Docker Compose будет использоваться для тестирования сборки и запуска прилодения с последующим добавлением его в ранее развёрнутое локальное хранилище

apt-get install -y unzip docker-compose-v2

  • Расспаковываем архив с приложением и переходим в директорию:

unzip /home/altlinux/Project03.zip -d ./

cd School-site-project-main/

  • Создаём максимально минимальный Dockerfile для сборки образа приложения:

FROM nginx:1.29.3-alpine
COPY . /usr/share/nginx/html

  • Создадим файл compose.yaml и укажем в нём следующее содержимое:для сборки образа и тестирования приложения
    образ называем именно так, чтобы в дальнейшем можно было его добавить в ранее развёрнутое локальное хранилище обращов
    можно использовать 127.0.0.1, всё остальное за вас сделает маршрутизация в рамках кластера Docker Swarm

services:
app:
image: 127.0.0.1:5000/app
build: .
ports:
- "80:80"

  • Выполним сборку и запуск контейнера для проверки работоспособности:

docker compose up -d

  • Проверить сборку образа можно с помощью команды docker image ls:
-15

  • Проверить запущенный контейнер можно с помощью команды docker compose ps:
  • Проверить работоспособность веб-приложения с Cloud-ADM в браузере:обращаясь в веб-браузере на IP-адрес любой из нод:
  • Удаляем всё что было использовано для тестового запуска:

docker compose down --volumes

docker image rm 127.0.0.1:5000/app

Cloud-ADM:

  • Сгенерируем необходимые файлы сертификатов, через ранее развёрнутый ЦА:создаём ключ:

openssl genrsa -out site.key 2048

  • создаём запрос:

openssl req -key site.key -new -out site.csr

  • Файл с расширениями для сертификата site.ext:

cat <<EOF > site.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName=@alt_names
[alt_names]
DNS.1=school-site.au.team
IP.1=192.168.1.107
EOF

  • Выпускаем сертификат:

openssl x509 -req -CA Projects/Project_01/ansible/files/ca.crt -CAkey Projects/Project_01/ansible/files/ca.key -in site.csr -out site.crt -days 365 -CAcreateserial -extfile site.ext

  • Передаём ключ и сертификат на master01:

scp site.key master01:~/

scp site.crt master01:~/

master01:

  • Копируем ключ и сертификат в директорию с файлами приложения:

cp /home/altlinux/site.crt ./

cp /home/altlinux/site.key ./

  • Создаём свой конфигурационный файл для веб-сервера nginx, например custom.conf:

server {
listen 80;
server_name school-site.au.team;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}

server {
listen 443 ssl;
server_name school-site.au.team;

ssl_certificate /etc/nginx/site.crt;
ssl_certificate_key /etc/nginx/site.key;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}

  • Модернизируем ранее написанный Dockerfile для сборки образа с приложением:

FROM nginx:1.29.3-alpine
COPY site.crt site.key /etc/nginx/
COPY custom.conf /etc/nginx/conf.d/default.conf
COPY . /usr/share/nginx/html

  • Модернизируем ранее написанный compose.yaml:

services:
app:
image: 127.0.0.1:5000/app
build: .
ports:
- "80:80"
- "443:443"

  • Выполним сборку и запуск контейнера для проверки работоспособности:

docker compose up -d

  • Проверить доступ к приложению с Cloud-ADM как по http так и по https
  • Удаляем всё что было использовано для тестового запуска:

docker compose down --volumes

  • Отправляем средствами Docker Compose образ нашего приложения в ранее развёрнутое хранилище образов:

docker compose push

  • Удаляем образ собранный локально:

docker image rm 127.0.0.1:5000/app

  • Модернизируем ранее написанный compose.yaml:

services:
app:
image: 127.0.0.1:5000/app
ports:
- "80:80"
- "443:443"
deploy:
placement:
constraints:
- "node.role==worker"

redis:
image: redis:8.4.0-alpine
deploy:
placement:
constraints:
- "node.role==worker"

db:
image: postgres:18.1-alpine3.22
environment:
POSTGRES_PASSWORD: "P@ssw0rd"
deploy:
placement:
constraints:
- "node.role==worker"

  • Запускаем развёртывание стека с именем school-site-project:

docker stack deploy --compose-file compose.yaml school-site-project

  • Проверить созданные стек в кластере можно с помощью команды docker stack ls:
  • Проверить созданные сервисы в рамках стека можно с помощью команды docker stack services school-site-project:
  • Проверить на каких нодах запустились задачи сервивов в рамках стека можно с помощью команды docker stack ps school-site-project:

Cloud-ADM:

  • Добавляем в файл /etc/hosts следующую запись:
-16