
Продолжаем настройку кластера swarm.
В предыдущих статьях https://slyweb.ru/docker/docker-swarm-mysql и https://slyweb.ru/docker/swarm-and-web-server-clusters мы рассмотрели настройку docker swarm, php, mysql.
В этой статье мы попробуем добавить Traefik к уже существующему стэку Docker Swarm.
В предыдущей статье если Вы внимательно читали её, ip адрес отображается как ip адрес сети Docker, в реальных условиях это не совсем то, что надо.
В процессе выяснения вопроса как получить реальный ip, оказалось это не достаточно тривиальная задача.
В Docker Swarm можно использовать в секции port method: HOST, но тогда не будут работать реплики сервисов, которых больше чем одна.
Поэтому для решения этого вопроса, предлагаю использовать Traefik. Также у нас будет подключена стандартная dashboar от Traefik по https.
В прошлой статье мы закончили на файле index.php:
<?php
echo '<html><head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body><div class="container">';
echo '<h2>Hello title</h2>';
echo '<p>Hello body <br/>';
echo '<p style="float:left;">
<img src="http://eapsite.ru/benjamin-voros-phIFdC6lA4E-unsplash.jpg" alt="Featued image for: Tutorial: Deploy a Full-Stack Application to a Docker Swarm" width="620" height="414"></p>
';
try {
$dbh = new PDO('mysql:dbname=swtest_docker;host=0.0.0.0:4307', 'swtest', 'swtest');
} catch (PDOException $e) {
die($e->getMessage());
}
$sth = $dbh->prepare("SELECT * FROM `Staff` WHERE `id` = ?");
$sth->execute(array('1'));
$array = $sth->fetch(PDO::FETCH_ASSOC);
function getUserIP()
{
// Get real visitor IP behind CloudFlare network
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
$_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
}
$client = @$_SERVER['HTTP_CLIENT_IP'];
$forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
$remote = $_SERVER['REMOTE_ADDR'];
if(filter_var($client, FILTER_VALIDATE_IP))
{
$ip = $client;
}
elseif(filter_var($forward, FILTER_VALIDATE_IP))
{
$ip = $forward;
}
else
{
$ip = $remote;
}
return $ip;
}
$user_ip = getUserIP();
echo '<div style="clear:both;"><h2>Mysql</h2></div>';
echo '<br/>';
echo $user_ip; // Output IP address [Ex: 177.87.193.134]
//
echo '<br/>';
echo 'id ' . $array['id'] . '<br/>';
echo 'name ' . $array['name'] . '<br/>';
echo 'birthday ' . $array['birthday'] . '<br/>';
echo '<pre>';
print_r($_SERVER);
echo '</pre>';
echo '</div></body></html>';
?>
Как видно в нём есть функция getUserIP и вывод переменной $_SERVER, при отсутствии traefik, реальный ip адрес не удастся получить.
В docker-compose.yml необходим добавить новый сервис traefik:
traefik:
image: "traefik:v3.1"
container_name: "traefik"
command:
# Включите Docker Swarm в Traefik, чтобы он считывал метки из служб Docker
- --providers.swarm.endpoint=unix:///var/run/docker.sock
- --providers.swarm.network=backend
# Добавьте ограничение на использование только сервисов с меткой "traefik.constraint-label=backend".
- --providers.swarm.constraints=Label(`traefik.constraint-label`, `backend`)
# Не предоставляйте доступ ко всем службам Docker, только к тем, которые явно доступны
- --providers.swarm.exposedbydefault=false
# Создайте точку входа "https", прослушивающую адрес 80
- --entrypoints.http.address=:80
# Создайте точку входа "https", прослушивающую адрес 443
- --entrypoints.https.address=:443
#- "--log.level=DEBUG"
- --entryPoints.http.forwardedHeaders.trustedIPs=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,fc00::/7
- --entrypoints.http.proxyProtocol.trustedIPs=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,fc00::/7
ports:
- "8080:8080"
- target: 80
published: 80
protocol: tcp
mode: host
- "443:443"
#- "80:80"
#- "8080:8080"
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
labels:
#Включите Traefik для этого сервиса, чтобы сделать его доступным в общедоступной сети
- traefik.enable=true
# Используйте общедоступную сеть backend(указанную ниже).
- traefik.docker.network=backend
# Используйте пользовательскую метку "traefik.constraint-label=backend" # Этот общедоступный
# Traefik будет использовать только службы с этой меткой
# Таким образом, при необходимости вы можете
# добавить другие внутренние экземпляры Traefik в стек.
- traefik.constraint-label=backend
- traefik.http.routers.backend-http.rule=Host(`site.ru`)
- traefik.http.routers.backend-http.entrypoints=web
# Определите порт внутри используемой службы Docker
- traefik.http.services.backend.loadbalancer.server.port=8080
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- backend
Давайте подробней разберем каждую опцию:
- traefik.enable=true
Взаимосвязана с опцией exposedByDefault, которая в свою очередь предоставляет доступ к контейнерам по умолчанию через Traefik. Если у exposedByDefault установлено значение false, контейнеры, у которых нет метки traefik.enable=true, игнорируются в результирующей конфигурации маршрутизации
- traefik.docker.network=backend
Определяет сеть docker по умолчанию, используемую для подключений ко всем контейнерам.
- traefik.constraint-label=backend
ограничивает применение определённых сервисов, в нашем случае в маршрутизации участвует контейнеры котрые помечены как backend
- traefik.http.routers.backend-http.rule=Host(`site.ru`)
Создаёт новый маршрут под названием “backend-http”, которому соответствует определенный хост
- traefik.http.routers.backend-http.entrypoints=web
Точки входа - это сетевые точки входа в Traefik. Они определяют порт, который будет принимать пакеты, и то, следует ли прослушивать TCP или UDP.
Точки входа у нас определены в разделе command “http” и “https”.
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
Подробная информация о точках входа указана по адресу: https://doc.traefik.io/traefik/routing/entrypoints/
- traefik.http.services.backend.loadbalancer.server.port=8080
По умолчанию Traefik использует первый открытый порт контейнера. Установка метки traefik.http.services.xxx.loadbalancer.server.port переопределяет это поведение.
Сейчас, как можно заметить, будет доступен реальный ip:
42 просмотра
Взаимосвязанные материалы
Типичный пример быстрой настройки Docker и Nginx c доступом по https. читать...
Небольшая статья - продолжение предыдущих трёх статей:
читать...Продолжаем настройку кластера Swarm. В этой статье мы попробуем добавить Traefik к уже существующему стэку Docker Swarm. читать...
Docker Swarm и Nginx, PHP. Вебсервер в кластере Docker Swarm. Часть 2. Mysql. В этой статье мы попробуем добавить сервер mysql к уже существующему стэку Docker Swarm. читать...
С помощью Docker можно быстро развернуть рабочее web приложение с различными настройками и версиями. Docker Swarm выступает инструментом «оркестрации» контейнеров Docker, который позволяет управлять контейнерами как единое целое. читать...