Микрооблако. Второй шаг. Создание виртуальной сети
Мы живем в мире, где зависимость от того или иного вендора может привести к катастрофе. Если базировать свой бизнес на Google Cloud, AWS или Azure, или даже каком-то отечественном аналоге, то в любой момент тебе могут сказать, что твоё облако больше не твоё. А ты уже привык или привыкла (я очень надеюсь тут на женский взгляд на проблему) к их гитлабу, нексусу и прочим плюшкам, которые доступны из коробки и заинтегрированы между собой и твоим проектом. Как быть?
Решение тут одно. Нам не нужно одно гигантское облако, как нам не нужны моносервисы. Ими сложно управлять. Нужны микросервисы и микрооблака. Представьте, что вы хотите создать своё приложение для знакомств. Разве вам для его работы нужны ксеоны и прочие суперпроцессоры? Вряд ли. Нужен ли вам гигантский дата-центр? Ответ тот же. Скорее всего, вам достаточно 2-4 виртуалок обычного типа, на которых нужно запустить ваше приложение и небольшую инфраструктурную обвязку вроде api-gateway и sso, а также гитлабов и нексусов, если речь идет о контуре разработки. И обойдется это вам гораздо дешевле. Проблема только в том, что хостингов виртуалок на рынке полно, а вот удобно инструмента превращения этих виртуалок в своё небольшое облако - нет. А теперь представьте, что такой инструмент есть. Тогда если хостинг скажет вам "прости-прощай и собирай манатки", то мы просто берем и переезжаем со словами "а ну и пожалуйста, не очень то и хотелось".
Я уже начал вести разработки в этом направлении. В этой статье я показал, как можно взять сеть виртуалок и сравнять на них операционные системы. Это был первый шаг к подготовке такого микрооблака. Вторым шагом будет связка этих виртуалок в единую сеть, для чего нам понадобится OpenVPN. В целом, я хочу создать серию скриптов, запускаемых из докера, которые последовательно подготовят такое микрооблако.
Тут важно, чтобы такие скрипты были идемпотентны, тогда можно будет расширять сеть виртуалок, и меняя лишь конфиг состава сети, подключать в облако новые машины. Мою реализацию таких скриптов, о которой пойдет речь ниже, можно найти в гитлабе по этой ссылке.
Точкой запуска такого скрипта является докер-компоуз, который получит на вход параметры сети. Пока это виртуалки в моем VirtualBox, но со временем я расширю его параметрами реальных виртуальных машин, когда подберу себе хостера. Исходим из того, что у меня есть 5 виртуальных машин и запущенный докер-контейнер, который настраивает виртуалки и себя для объединения всех 6 машин в виртуальную сеть. Таким образом, по итогу отработки скрипта в моем распоряжении будет сеть из 6 машин. Но нужно помнить, что докер-контейнер - это не совсем обычная виртуальная машина. Она ограничена в правах, поэтому при старте через докер-компоуз придется применить несколько расширяющих возможности контейнера настроек. Чтобы понимать, что происходит, важно читать комментарии по коду вставок
version: "3.9"
services:
# kubos - это просто название данного микрооблачного проекта
kubos:
# devices и cap_add дают право контейнеру задействовать возможности
# хост-машины по настройке виртуальных сетевых устройств
devices:
- /dev/net/tun
cap_add:
- NET_ADMIN
# докер файл, который поместит в образ все необходимые shell-
# и ansible-скрипты
build:
context: docker
dockerfile: Dockerfile
image: kubos
environment:
# адрес машины, выбранной в качестве сервера OpenVPN
MASTER_IP: 10.0.2.2
# ssh-порты всех машин сети
# в данном случае, они все запущены на локальной машине, поэтому
# указываются только порты, но в будущем добавим и IP
MASTER_PORT: 10022
WORKER1_PORT: 10122
WORKER2_PORT: 10322
WORKER3_PORT: 10522
WORKER4_PORT: 10722
# параметры создаваемой виртуальной сети
VIRTUAL_NETWORK_CIDR: 10.10.0.0/16
# логин и пароль пользователя с sudo-правами, от имени которого
# будут производиться все манипуляции на виртуалках в ansible-скриптах
USER_NAME: admin
USER_PASSWORD: 3
Коротко рассмотрим Dockerfile. В нем нет ничего сверхестественного - просто копирование 4-х ansible-скриптов и 1-го bash-скрипта оркестратора этих ансиблов.
FROM debian:bullseye
# копируем папку с ансибл скриптами
COPY ansible /root/ansible
# делаем эту папку текущей папкой
WORKDIR /root/ansible
# копируем скрипт-оркестратор ансиблов
COPY entrypoint.sh /root/entrypoint.sh
ENTRYPOINT ~/entrypoint.sh
Давайте теперь пройдемся по скрипту оркестратору entrypoint.sh и рассмотрим его составные блоки. В самом начале идет установка всех необходимых пакетов
apt update;
# dnsmasq - локальный DNS-сервер, котоый нужен, чтобы после подключения к
# виртуальной сети, докер-контейнер смог не потерять связь с интернетом
# ipcalc - инструмент превращения CIDR адресов сетей в отдельные адрес сети и
# сетевую маску
# fping - инструмент для произведения широковещательного ping-а
apt install -y ansible openvpn dnsmasq ipcalc fping;
Далее при помощи ансибл скрипта common-dependencies.yml идёт установка всех основных зависимостей на все тачки сети. Для запуска этой установки сначала в скрипте оркестраторе entrypoint.sh создается файл инвентаризации всех машин. Единственное, что там может вызывать вопросы - это имя хоста host.docker.internal, которое используется в докере, запускаемом из Windows, где я и работаю, для обращения к портам хост-машины. Именно этот адрес в будущем будет переделан на параметр докер компоуза. Все остальные настройки файла инвентаризации уже параметризованы.
# подготовка файла инвентаризации хостов для установки общих зависимостей
{
echo "[all]";
echo "master ansible_host=host.docker.internal ansible_port=${MASTER_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
echo "worker1 ansible_host=host.docker.internal ansible_port=${WORKER1_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
echo "worker2 ansible_host=host.docker.internal ansible_port=${WORKER2_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
echo "worker3 ansible_host=host.docker.internal ansible_port=${WORKER3_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
echo "worker4 ansible_host=host.docker.internal ansible_port=${WORKER4_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
} > hosts;
# установка общих зависимостей
ansible-playbook -i hosts common-dependencies.yml;
Пора глянуть сам ансибл скрипт common-dependencies.yml
- hosts: all
become: true
gather_facts: no
tasks:
# проверяем установлен ли питон на машине
# без него можно использовать только raw-модуль ансибла
# и не получится задействовать всю ансибл-мощь
- name: Check python3 installed
raw: python3 --version
ignore_errors: true
register: python3_installed
# если питон не установлен, то устанавливаем
- name: Install python3
raw: |
# подправляем файл репозиториев, чтобы не морочиться
# с валидацией сертификатов устанавливаемых пакетов
sed -i 's/https/http/g' /etc/apt/sources.list;
apt update;
apt install -y python3 python3-apt;
when: python3_installed.failed
# устанавливаем dbus для работы timedatectl
# это нужно, чтобы перед началом работы синхронизовать системное время
# если этого не сделать, то время будет непредсказуемо, что
# может привести к ошибкам при проверке сертификатов
# а именно, дат их выпуска и дат их окончания
- name: Install dbus and starting systemd-logind
shell: >
apt install -y dbus;
service systemd-logind start;
echo "" > dbus.working;
args:
chdir: $HOME
creates: dbus.working
# принудительно проводим синхронизацию системного времени с NTP
- name: Update time and date from ntp
shell: |
timedatectl set-ntp false;
timedatectl set-ntp true;
# создаем фиктивный файл завершения ансибл-таски
# он позволит не повторять данную таску при повторном запуске скрипта
# это моя костыльная реализация идемпотентности :)
echo "" > timedate.corrected;
args:
chdir: $HOME
creates: timedate.corrected
Когда питон установлен, а системное время синхронизировано, у нас все готово, чтобы запустить основной ансибл-скрипт создания виртуальной openvpn-сети. Для этого в скрипте оркестраторе entrypoint.sh создается новый файл инвентаризации серверов и запускается скрипт раскатки виртуальной сети openvpn/playbook.yml
# подготовка файла инвентаризации хостов для настройки vpn
{
echo "[servers]";
echo "master ansible_host=host.docker.internal ansible_port=${MASTER_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
echo "";
echo "[clients]";
echo "worker1 ansible_host=host.docker.internal ansible_port=${WORKER1_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
echo "worker2 ansible_host=host.docker.internal ansible_port=${WORKER2_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
echo "worker3 ansible_host=host.docker.internal ansible_port=${WORKER3_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
echo "worker4 ansible_host=host.docker.internal ansible_port=${WORKER4_PORT} ansible_user=${USER_NAME} ansible_password=${USER_PASSWORD} ansible_sudo_pass=${USER_PASSWORD}";
} > openvpn/hosts;
# установка openvpn
VIRTUAL_NETWORK_ADDRESS=$(ipcalc --nobinary "$VIRTUAL_NETWORK_CIDR" | grep Address: | sed 's/^Address:\s\+\([0-9.]\+\)\s*$/\1/');
VIRTUAL_NETWORK_NETMASK=$(ipcalc --nobinary "$VIRTUAL_NETWORK_CIDR" | grep Netmask: | sed 's/^Netmask:\s\+\([0-9.]\+\) = .*/\1/');
VIRTUAL_NETWORK_GATEWAY=$(ipcalc --nobinary "$VIRTUAL_NETWORK_CIDR" | grep HostMin: | sed 's/^HostMin:\s\+\([0-9.]\+\)\s*$/\1/');
ansible-playbook -i openvpn/hosts openvpn/playbook.yml --extra-vars \
"master_ip=$MASTER_IP virtual_network_cidr=$VIRTUAL_NETWORK_CIDR virtual_network_address=$VIRTUAL_NETWORK_ADDRESS virtual_network_netmask=$VIRTUAL_NETWORK_NETMASK";
Выше можно видеть, что в ансибл скрипт передается ряд параметров создаваемой сети.
Теперь обратимся к ансибл скрипту openvpn/playbook.yml
---
- hosts: master
become: true
become_user: root
become_method: sudo
roles:
- openvpn-server
- hosts: all,!master
become: true
become_user: root
become_method: sudo
roles:
- openvpn-client
В нем по сути просто прописано соответствие машин из файла инвентаризации с ролями ансибла. В нашем случае master-машина будет использоваться как сервер openvpn, а остальные машины как клиенты openvpn. Все достаточно просто. Основной код данного ансибла скрипта скрыт в файлах ролей. Начнем с рассмотрения файла настройка сервера openvpn openvpn/roles/openvpn-server/tasks/main.yml.
# Установка инструментов подготовки сертификтов, openvnp и таблиц маршрутизации
- name: Install easy-rsa, openvpn, iptables
package:
name: "{{ item }}"
state: present
with_items:
- easy-rsa
- openvpn
- iptables
# Создается рабочая папка, в которой будут генериться все сертификаты сети
- name: Create CA directory
become: true
command: make-cadir openvpn-ca
args:
chdir: $HOME
creates: openvpn-ca
# Установим переменные, отвечающие за сроки выпуска сертификатов
# Очень не хочется перевыпускать сертификаты каждый 2 года,
# поэтому сразу установим срок в тысячелетие и закроем это вопрос
# для нас и наших ближайших потомков :)
- name: Customize CA variable configuration
lineinfile:
dest: $HOME/openvpn-ca/vars
regexp: "^{{ item.regex | regex_escape() }}"
line: "{{ item.value }}"
with_items:
- { regex: '#set_var EASYRSA_CA_EXPIRE', value: 'set_var EASYRSA_CA_EXPIRE 365000' }
- { regex: '#set_var EASYRSA_CERT_EXPIRE', value: 'set_var EASYRSA_CERT_EXPIRE 365000' }
# Генерим сертификат и ключ, которым будем подписывать все остальные сертификаты
- name: Build the certificate authority
become: true
shell: >
echo "yes" | ./easyrsa --vars=./vars init-pki;
printf "\n" | ./easyrsa --vars=./vars build-ca nopass;
echo "" > $HOME/ca.built;
args:
chdir: $HOME/openvpn-ca
creates: $HOME/ca.built
# Генерим служебные ключи
- name: Build Diffie-Hellman parameters and TLS key generation
become: true
shell: >
openssl dhparam -out pki/dh2048.pem 2048;
openvpn --genkey --secret pki/ta.key;
echo "" > $HOME/dh_and_ta.built;
args:
chdir: $HOME/openvpn-ca
creates: $HOME/dh_and_ta.built
# Генерим ключ и сертификат сервера
- name: Build server certificate and key
become: true
shell: |
# команде "./easyrsa gen-req" передается имя CN для поля Subject
# в выпускаемом сертификате
echo "vpn-server" | ./easyrsa --vars=./vars gen-req vpn-server nopass;
echo "yes" | ./easyrsa --vars=./vars sign-req server vpn-server;
echo "" > $HOME/vpn_server_crt_and_key.built;
args:
chdir: $HOME/openvpn-ca
creates: $HOME/vpn_server_crt_and_key.built
# Генерим ключ и сертификат клиентов
- name: Build clients certificates and keys
become: true
shell: |
# команде "./easyrsa gen-req" передается имя CN для поля Subject
# в выпускаемом сертификате
echo "{{ item }}" | ./easyrsa --vars=./vars gen-req {{ item }} nopass;
echo "yes" | ./easyrsa --vars=./vars sign-req client {{ item }};
echo "" > $HOME/{{ item }}_crt_and_key.built;
args:
chdir: $HOME/openvpn-ca
creates: $HOME/{{ item }}_crt_and_key.built
with_items: "{{ groups['clients'] }}"
# Генерим ключ и сертификат для докер контейнера,
# который тоже станет клиентом сети
- name: Build docker certificate and key
become: true
shell: |
# команде "./easyrsa gen-req" передается имя CN для поля Subject
# в выпускаемом сертификате
echo "docker" | ./easyrsa --vars=./vars gen-req docker nopass;
echo "yes" | ./easyrsa --vars=./vars sign-req client docker;
echo "" > $HOME/docker_crt_and_key.built;
args:
chdir: $HOME/openvpn-ca
creates: $HOME/docker_crt_and_key.built
# Копируем созданные серверные ключи и сертификаты туда,
# где им и место на сервере openvpn
- name: Copy key and certificates to /etc/openvpn/server/
become: true
copy:
remote_src: yes
src: "$HOME/openvpn-ca/pki/{{ item }}"
dest: /etc/openvpn/server/
with_items:
- "ca.crt"
- "issued/vpn-server.crt"
- "private/vpn-server.key"
- "ta.key"
- "dh2048.pem"
# Создаем файл конфигурации openvpn-сервера
- name: Generate server configuration from sample config
become: true
copy:
remote_src: yes
src: /usr/share/doc/openvpn/examples/sample-config-files/server.conf
dest: /etc/openvpn/server/vpn-server.conf
force: no
# Коррекция параметров openvpn-сервера
- name: Adjust OpenVPN server configuration
lineinfile:
dest: /etc/openvpn/server/vpn-server.conf
regexp: "^{{ item.regex | regex_escape() }}"
line: "{{ item.value }}"
with_items:
# сократить количество привелегий у openvpn
- { regex: ';user nobody', value: 'user nobody' }
- { regex: ';group nogroup', value: 'group nogroup' }
# настройка сертификатов
- { regex: 'cert ', value: 'cert vpn-server.crt' }
- { regex: 'key ', value: 'key vpn-server.key' }
# включение логирования
- { regex: ';log ', value: 'log /var/log/openvpn/openvpn.log' }
# нужно раскомментить, чтобы клиенты могли достучаться друг до друга
# (иначе говоря, чтобы ping заработал)
- { regex: ';client-to-client', value: 'client-to-client' }
# без этого на клиентах не будут создаваться виртуальные сетевые устройства
# для openvpn
- { regex: ';push "redirect-gateway def1 bypass-dhcp"', value: 'push "redirect-gateway def1 bypass-dhcp"' }
# протокол ставим tcp, с udp настроить не удалось
- { regex: 'proto ', value: 'proto tcp-server' }
- { regex: 'explicit-exit-notify 1', value: ';explicit-exit-notify 1' }
# FIXME переделать на 10.8.0.1 после установки на нем сервера BIND
- { regex: ';push "dhcp-option DNS ', value: 'push "dhcp-option DNS 8.8.8.8"' }
- { regex: ';push "dhcp-option DNS ', value: 'push "dhcp-option DNS 8.8.4.4"' }
# устанавливаем параметры создаваемой виртуальной сети
- { regex: 'server ', value: 'server {{ virtual_network_address }} {{ virtual_network_netmask }}' }
# Включаем vpn-сервер как шлюз в интернет для всех vpn-клиентов (№ 1)
- name: Configuration IP forwarding
become: true
sysctl:
name: net.ipv4.ip_forward
value: '1'
state: present
# Включаем vpn-сервер как шлюз в интернет для всех vpn-клиентов (№ 2)
- name: Configuration IP routing
become: true
shell: |
iptables -t nat -A POSTROUTING -s {{ virtual_network_cidr }} -o enp0s3 -j MASQUERADE;
echo "" > internet.switched_on;
args:
chdir: $HOME
creates: internet.switched_on
# Запускаем openvpn сервер
- name: Start openvpn systemd service
become: true
systemd:
name: openvpn-server@vpn-server
state: started
daemon_reload: yes
enabled: yes
# Следующие команды забирают в докер-контейнер нужные ключи и сертификаты
# Они нужны, чтобы раздать их всем клиентам виртуальной сети
# в том числе, и самомму докер-контейнеру
- name: Fetch server CA cert and TLS key
fetch:
src: "/etc/openvpn/server/{{ item }}"
dest: "{{ playbook_dir }}/share/server/"
flat: yes
with_items:
- "ca.crt"
- "ta.key"
- name: Fetch clients certs
fetch:
src: "$HOME/openvpn-ca/pki/issued/{{ item }}.crt"
dest: "{{ playbook_dir }}/share/clients/"
flat: yes
with_items: "{{ groups['clients'] }}"
- name: Fetch clients keys
fetch:
src: "$HOME/openvpn-ca/pki/private/{{ item }}.key"
dest: "{{ playbook_dir }}/share/clients/"
flat: yes
with_items: "{{ groups['clients'] }}"
- name: Fetch docker cert and key
fetch:
src: "$HOME/openvpn-ca/pki/{{ item }}"
dest: "{{ playbook_dir }}/share/clients/"
flat: yes
with_items:
- private/docker.key
- issued/docker.crt
Теперь, когда мы настроили сервер openvpn, осталось настроить всех клиентов при помощи ансибл скрипта openvpn/roles/openvpn-client/tasks/main.yml.
# Устанавливаем openvpn и resolvcof, который используется,
# чтобы настроить на openvpn клиенте те DNS-сервера, которые передаст сервер
- name: Install openvpn, resolvconf
package:
name: "{{ item }}"
state: present
with_items:
- openvpn
# должен быть последним в этом списке,
# потому что его установка временно ломает работу dns
# и последующие тулзы поставить не получится
- resolvconf
# Копируем из докер-контейнера схороненные там
# ключи и сертификаты общего назначения
- name: Copy common certs and keys from server
become: true
copy:
src: "{{ item }}"
dest: "/etc/openvpn/client/"
with_fileglob:
- "{{ playbook_dir }}/share/server/*"
# Копируем из докер-контейнера схороненные там
# ключи и сертификаты для текущего клиента
- name: Copy client certs and keys from server
become: true
copy:
src: "{{ playbook_dir }}/share/clients/{{ item }}"
dest: "/etc/openvpn/client/"
with_items:
- "{{inventory_hostname}}.crt"
- "{{inventory_hostname}}.key"
# Создаем конфигурацию openvpn клиента
- name: Generate client configuration from sample config
become: true
copy:
remote_src: yes
src: /usr/share/doc/openvpn/examples/sample-config-files/client.conf
dest: "/etc/openvpn/client/{{inventory_hostname}}.conf"
force: no
# Поднастраиваем параметры конфигурации openvpn клиента
- name: Adjust OpenVPN client configuration
lineinfile:
dest: "/etc/openvpn/client/{{inventory_hostname}}.conf"
regexp: "^{{ item.regex | regex_escape() }}"
line: "{{ item.value }}"
with_items:
# адрес сервера openvpn
- { regex: 'remote my-server-1 1194', value: 'remote {{ master_ip }} 1194' }
# сократить количество привелегий у openvpn
- { regex: ';user nobody', value: 'user nobody' }
- { regex: ';group nogroup', value: 'group nogroup' }
# настройка сертификатов
- { regex: 'cert ', value: 'cert {{inventory_hostname}}.crt' }
- { regex: 'key ', value: 'key {{inventory_hostname}}.key' }
# включение логирования
- { regex: 'log ', value: 'log /var/log/openvpn/openvpn.log' }
# протокол ставим tcp, с udp настроить не удалось
- { regex: 'proto ', value: 'proto tcp4' }
# для того чтобы работали директивы ниже, выше был установлен resolvconf
- { regex: 'script-security ', value: 'script-security 2' }
- { regex: 'up ', value: 'up /etc/openvpn/update-resolv-conf' }
- { regex: 'down ', value: 'down /etc/openvpn/update-resolv-conf' }
# Запуск демона openvpn клиента
- name: Start openvpn systemd service
become: true
systemd:
name: openvpn-client@{{inventory_hostname}}
state: started
daemon_reload: yes
enabled: yes
И вот мы пришли к тому, что у нас все машины объединились в виртуальную сеть. Осталось подключить в эту сеть и сам докер-контейнер. Для этого снова взглянем на скрипт оркестратор entrypoint.sh
# подключение докера в созданную openvpn сеть
## Copy common certs and keys from server
cp openvpn/share/server/* /etc/openvpn/client/;
## Copy docker cert and key from server
cp openvpn/share/clients/docker.key /etc/openvpn/client/;
cp openvpn/share/clients/docker.crt /etc/openvpn/client/;
## Generate client configuration from sample config
cd /etc/openvpn/client/;
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf docker.conf;
## Adjust OpenVPN client configuration
sed -i "s/^remote my-server-1 1194$/remote host.docker.internal 1194/g" docker.conf;
sed -i "s/^;user nobody$/user nobody/g" docker.conf;
sed -i "s/^;group nogroup$/group nogroup/g" docker.conf;
sed -i "s/^cert .*$/cert docker.crt/g" docker.conf;
sed -i "s/^key .*$/key docker.key/g" docker.conf;
sed -i "s/^proto .*$/proto tcp4/g" docker.conf;
echo "" >> docker.conf;
echo "log /var/log/openvpn/openvpn.log" >> docker.conf;
Тут идет стандартная настройка openvpn-клиента, которую мы видели в ансибл скрипте выше, за исключением момента, связанного с доменными именами. К сожалению, докер-контейнер наглухо блокирует файл /etc/resolv.conf и не позволит обновить в нем DNS-сервера, которые прислал openvpn сервер. Поэтому делаем финт ушами, а именно, поднимаем локальный DNS-сервер (dnsmasq) и прописываем все что там хотим видеть руками.
echo "nameserver 127.0.0.1" > /etc/resolv.conf;
{
echo "no-resolv";
# 127.0.0.11 - внутренний докерный DNS
echo "server=/host.docker.internal/127.0.0.11";
echo "rev-server=$VIRTUAL_NETWORK_CIDR,$VIRTUAL_NETWORK_GATEWAY";
echo "server=8.8.8.8";
echo "server=8.8.4.4"
} > /etc/dnsmasq.conf;
dnsmasq;
Теперь у нас все готово, для запуска openvpn клиента в докер-контейнере.
openvpn --config docker.conf &
Профит)
Заключение
Медленно, но верно, я продвигаюсь в направлении создания микрооблаков. Многие со мной не согласятся, но именно так я вижу будущее развития интернета и появление так называемого WEB 3.0. Но даже если я не прав, то у меня на примете уже есть несколько команд разработки, которым данная технология будет полезна.
Так или иначе, будущее нас рассудит.
Желающие ознакомиться со скриптом настройки сети могут взять его тут.
Также предлагаю всех присоединяться в телеграм-канал и телеграм-чат данного проекта, где я периодически пишу о продвижении в создаваемых скриптах.
В целом подход у меня такой: я заявляю следующую цель проекта, готовлю код ее реализующий, а потом описываю статью на хабре в качестве отчета о проделанной работе и для закрепления результата в своей собственной голове.
Всех призываю следить за проектом и при возникновении каких-либо идей по развитию не стесняться их излагать в комментариях тут и в телеграм-чате.
Следующим шагом в создании микрооблака, я буду раскатывать кубер по созданной виртуальной сети.
Всем удачи! И до связи...