Использование Consul Connect для реализации Service Mesh

Обновлено Обновлено: Опубликовано Опубликовано:

Используемые термины: ConsulService Mesh, NGINX, PHP, MariaDB, Linux.

В данной инструкции мы рассмотрим простой, но пошаговый пример обращения веб-сервера nginx + php к серверу баз данных MariaDB в сети Service Mesh, реализованной с помощью Consul Connect.

Предполагается, что у нас уже есть понимание работы с Consul, а также развернута серверная инфраструктура. Ссылки на полезную информацию по ее настройке будут приведены в конце данной инструкции. Работать мы будем на Linux.

Обращение к базе данных

Мы напишем небольшой скрипт на PHP, который будет обращаться к базе данных на другом сервере напрямую. После мы будем модернизировать нашу инфраструктуру, чтобы подключение выполнялось в сети Service Mesh.

Подготовка сервера баз данных

Для наших целей мы будем использовать тестовую базу. Создадим ее, а также настроим доступ.

Допустим, что у нас веб-сервер имеет IP-адрес 192.168.0.10, а сервер баз данных — 192.168.0.20. Это будет важно для предоставления удаленного доступа.

Подключимся к оболочке sql пользователем root:

mysql -uroot -p

Создаем новую базу, например, с именем mesh_db:

> CREATE DATABASE mesh_db DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

Создадим тестовую таблицу и внесем в нее немного данных:

> USE mesh_db

> CREATE TABLE `users` (
`username` VARCHAR(128) NOT NULL ,
`password` CHAR(41) NOT NULL ,
UNIQUE (`username`)           
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;

> INSERT INTO `users` VALUES ('user1', ENCRYPT('12345678')), ('user2', ENCRYPT('87654321'));

Мы должны увидеть:

Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

Создадим пользователя и предоставим ему доступ к базе:

> CREATE USER 'mesh'@'192.168.0.10' IDENTIFIED BY 'mesh!password$123';

* в нашем примере мы предоставим доступ пользователю mesh, который будет подключаться с компьютера 192.168.0.10. Пароль будет mesh!password$123.

> GRANT ALL PRIVILEGES ON mesh_db.* TO 'mesh'@'192.168.0.10';

* созданному пользователю мы дали все разрешения к базе mesh_db.

Подробнее процесс настройки сетевого доступа к СУБД MariaDB представлен в инструкции Создание пользователей MySQL/MariaDB и предоставление прав доступа, разделе настройки доступа по сети.

Выходим из оболочки SQL:

> quit

Если на веб-сервере установлен клиент mysql, то мы можем проверить наше подключение командой:

mysql -umesh -p -h192.168.0.20

Система запросит пароль — вводим тот, что использовали при создании пользователя mesh. В итоге, мы должны увидеть строку SQL, например:

MariaDB [(none)]>

Скрипт PHP

Теперь напишем небольшой скрипт на php, который будет делать запрос к базе данных. Напомню, что серверная инфраструктура уже должна работать, поэтому мы не будет подробно рассматривать установку и настройку веб-сервера.

Предположим, что мы хотим создать скрипт в каталоге /usr/share/nginx/html:

vi /usr/share/nginx/html/mesh.php

<?php

$conn = mysqli_connect('192.168.0.20', 'mesh', 'mesh!password$123', 'mesh_db') or die("MySQL connect error");
mysqli_query($conn, "SET NAMES 'utf8'");

$result = mysqli_query($conn, "SELECT * FROM users");
while ($mass = mysqli_fetch_assoc($result)) {
  print_r($mass);
}

?>

* в данном скрипте мы подключаемся к серверу 192.168.0.20 под созданным пользователем mesh. Далее из таблицы users базы mesh_db мы делаем выборку всех данных.

Для запуска скрипта нам не обязательно открывать браузер. Можно выполнить скрипт из командной строки:

php -f /usr/share/nginx/html/mesh.php

Мы должны получить, примерно, такой ответ:

Array
(
    [username] => user1
    [password] => uTDSMpyBcqITE
)
Array
(
    [username] => user2
    [password] => uTDaI03vUeVpQ
)

Первый шаг пройден. У нас есть небольшая инфраструктура, где один сервис обращается к другому.

Настройка Consul Connect

Переходим к созданию сервисной сети Mesh. Напомню, что у нас должна быть готовая инфраструктура:

  • Кластер консул.
  • На серверах веб и СУБД должны быть установлены консул агенты.

Ссылки на инструкции по настройке консула и установке агентов приведены в конце инструкции.

На серверах консул

Создаем конфигурационный файл для включения коннекта:

vi /etc/consul.d/connect.json

{
    "connect": {
        "enabled": true
    }
}

Проверяем корректность настроек:

consul validate /etc/consul.d/

Мы должны увидеть:

...
Configuration is valid!

Перезагружаем consul:

systemctl restart consul

На агентах

Еще раз напомню, что у нас должны быть зарегистрированы сервисы для веб и mysql. Информация о регистрации содержится в конфигурационных файлах. Для настройки connect нам нужно отредактировать данные конфигурационные файлы.

Предположим, что регистрация сервисов описана следующим образом:

vi /etc/consul.d/web.json

{
  "service": {
    "name": "web",
    "tags": [
      "front"
    ],
    "port": 80,
    "check": {
      "args": [ "curl", "localhost" ],
      "interval": "10s"
    }
  }
}

vi /etc/consul.d/mysql.json

{
  "service": {
    "name": "db",
    "port": 3306,
    "check": {
      "args": [ "mysqladmin", "ping" ],
      "interval": "10s"
    }
  }
}

Открываем и редактируем файлы регистрации.

На сервере веб

Открываем файл и дописываем:

vi /etc/consul.d/web.json

{
  "service": {
    "name": "web",
    "tags": [
      "front"
    ],
    "port": 80,
    "check": {
      "args": [ "curl", "localhost" ],
      "interval": "10s"
    },
    "connect": {
      "sidecar_service": {
        "proxy": {
          "upstreams": [{
            "destination_name": "db",
            "local_bind_port": 33306
          }]
        }
      }
    }

  }
}

* в раздел service мы добавили новую директиву connect, которая описывает mesh-взаимодействие:

  • sidecar_service — описание прокси для службы. В нашем примере для web.
  • upstreams — объекты для описания служб service mesh.
  • destination_name — имя службы, зарегистрированной в consul, куда нужно будет отправлять запрос.
  • local_bind_port — локальный порт, на котором consul connect будет ожидать запросов, чтобы потом передавать их на destination_name.

** итого, будет создан коннектор на порту 33306. При получении запросов он будет отправлять их сервису db, который нами зарегистрирован на сервере с MySQL.

Перезапускаем консул:

systemctl restart consul

Запускаем sidecar командой:

consul connect proxy -sidecar-for web

Мы должны увидеть что-то на подобие:

... proxy: Starting listener: listener=127.0.0.1:33306->service:default/db ...
...
... proxy: Starting listener: listener="public listener" bind_addr=0.0.0.0:21000

* на порту 21000 поднялся листенер для прокси connect.

Идем дальше.

На сервере баз данных

Открываем файл и дописываем:

vi /etc/consul.d/mysql.json

{
  "service": {
    "name": "db",
    "port": 3306,
    "check": {
      "args": ["mysqladmin", "ping"],
      "interval": "10s"
    },
    "connect": {
      "sidecar_service": {}
    }

  }
}

* в раздел service мы добавили новую директиву connect без указания конкретных настроек. Это нужно, чтобы поднять прокси на порту 21000. Так как нам не нужно отправлять запросов с сервера баз данных, можно не описывать proxy.

Проверяем конфиг консула:

consul validate /etc/consul.d/

Перезапускаем консул:

systemctl restart consul

Consul connect proxy должен слушать запросы на порту 21000/tcp. Необходимо, что брандмауэр системы разрешал его.

В зависимости от утилиты управления правилами фаервола, наши действия будут отличаться.

а) Для iptables (как правило, в системах на основе deb):

iptables -I INPUT -p tcp --dport 21000 -j ACCEPT

Чтобы сохранить правила, можно использовать iptables-persistent:

apt install iptables-persistent

netfilter-persistent save

б) Для firewalld (как правило, в системах на основе rpm):

firewall-cmd --permanent --add-port=21000/tcp

firewall-cmd --reload

Запускаем sidecar командой:

consul connect proxy -sidecar-for db

Мы должны увидеть что-то на подобие:

...
... proxy: Starting listener: listener="public listener" bind_addr=0.0.0.0:21000

* на порту 21000 поднялся листенер для прокси connect.

Веб-консоль consul

Взаимосвязь между веб-сервером и базой данных описана. Зайдем в графическую консоль consul и увидим:

Сервисы в consul с поднятыми proxy для connect

Обратите внимание на появившиеся значки, обозначающие, что сервисы используют прокси для Service Mesh.

Кликаем по сервису web — мы увидим графическую схему взаимодействия наших сервисов:

Сервис web будет отправлять запросы сервису db

Теперь обратите внимание на красный крест, который говорит, что что-то не так.

Если на него кликнуть, мы увидим, что связи существует, но запрещена политиками consul intension. Для решения проблемы просто кликаем по Create:

Создаем intension для разрешения взаимодействия между web и db

Красный крестик пропадет.

Мы также можем создать intention в командной строке. Для этого на одном из серверов consul вводим:

consul intention create web db

* означает, что мы создаем разрешение в направлении от сервиса web к сервису db.

Service Mesh на базе consul connect построен. Переходим к проверке.

Выполняем SQL-запрос в сети Mesh

Заходим на сервер баз данных новой сессией ssh (старая занята командой consul connect) и подключаемся к оболочке sql:

mysql -uroot -p

Создаем пользователя и даем ему права на базу mesh_db:

> CREATE USER 'mesh'@'localhost' IDENTIFIED BY 'mesh!password$123';

> GRANT ALL PRIVILEGES ON mesh_db.* TO 'mesh'@'localhost';

* данные запросы похожи на те, что мы делали ранее. Только на этот раз мы разрешаем подключение пользователю mesh с локального хоста (localhost).

Удаленное подключение в сети Service Mesh будет отправлять запрос в базу не с веб-сервера, а локального прокси, который установлен на один сервер с MariaDB. Таким образом, последняя будет принимать запрос с локального хоста и для подключения будет выполнять проверку для @localhost.

Таким образом, созданная в начале учетная запись 'mesh'@'192.168.0.10', как бы, лишняя и ее нужно удалить. Мы ее создали, чтобы выполнить проверку подключения и наши действия были пошаговыми. Для удаления записи с аннулированием прав используйте команды:

> REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mesh'@'192.168.0.10';

> DROP USER 'mesh'@'192.168.0.10';

Теперь переходим на веб-сервер (также открываем новую сессию ssh) и правим наш скрипт:

vi /usr/share/nginx/html/mesh.php

<?php

$conn = mysqli_connect('localhost', 'mesh', 'mesh!password$123', 'mesh_db', 33306) or die("MySQL connect error");
mysqli_query($conn, "SET NAMES 'utf8'");

$result = mysqli_query($conn, "SELECT * FROM users");
while ($mass = mysqli_fetch_assoc($result)) {
  print_r($mass);
}

?>

* в нашем скрипте мы поменяли сервер подключения — теперь мы отправляем запрос на локальный хост. Также мы добавили порт для подключения 33306, на котором висит connect proxy.

Можно снова запустить скрипт:

php -f /usr/share/nginx/html/mesh.php

Мы должны получить уже знакомую нам картину:

Array
(
    [username] => user1
    [password] => uTDSMpyBcqITE
)
Array
(
    [username] => user2
    [password] => uTDaI03vUeVpQ
)

Почти все.

Запуск proxy как служб systemd

Ранее на серверах веб и СУБД мы запускали прокси командами:

consul connect proxy -sidecar-for web

consul connect proxy -sidecar-for db

Данные команды перестанут работать, как только мы перезагрузим сервер или закроем SSH. Для решения проблемы создадим юнит в systemd и настроим его на автозапуск.

Сначала прервем выполнение ранее запущенных процессов consul connect комбинацией Ctrl + C. После создаем файл на обоих серверах (веб и СУБД):

vi /etc/systemd/system/connect@.service

[Unit]
Description=Consul Connect Service
Documentation=https://www.consul.io/
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=consul
Group=consul
ExecStart=/usr/bin/consul connect proxy -sidecar-for %i
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGINT
TimeoutStopSec=5
Restart=on-failure
SyslogIdentifier=consul

[Install]
WantedBy=multi-user.target

Теперь на сервере с nginx и php выполняем:

systemctl enable connect@web

systemctl start connect@web

systemctl status connect@web

* после знака @ идет указание на имя сервиса, для которого мы запустим systemd. В нашем случае это web.

На сервере с MariaDB

systemctl enable connect@db

systemctl start connect@db

systemctl status connect@db

* после знака @ идет указание на имя сервиса, для которого мы запустим systemd. В нашем случае это db.

Можно проверять SQL-запрос и пользоваться Service Mesh.

Читайте также

Данные материалы также могут быть полезны:

1. Установка MariaDB-server на Rocky Linux или Ubuntu.

2. Создание и удаление баз в MySQL/MariaDB.

3. Создание пользователей MySQL/MariaDB и предоставление прав доступа.

4. Настройка полноценного веб-сервера на CentOS 7 / Rocky Linux (CentOS 8) / Ubuntu Server.

5. Установка и настройка кластера Consul Hashicorp на Linux Ubuntu.

6. Установка и настройка кластера Consul Hashicorp на CentOS.

7. Установка агента Consul и примеры регистрации сервисов.

# DevOps # Linux # Серверы # Сети # Управление
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет