Я пытаюсь настроить Traefik так, чтобы у меня был доступ к сервисам через доменные имена, и чтобы мне не приходилось устанавливать разные порты. Например, две службы MongoDB, оба на порте по умолчанию, но в разных доменах, example.localhost
и example2.localhost
. Только этот пример работает. Я имею в виду, что другие случаи, вероятно, работают, но я не могу подключиться к ним, и я не понимаю, в чем проблема. Это, вероятно, даже не проблема с Traefik.
Я подготовил хранилище с примером, который работает. Вам просто нужно сгенерировать свой собственный сертификат с помощью mkcert . Страница at example.localhost
возвращает 403 Forbidden
ошибку, но вы не должны беспокоиться об этом, потому что цель этой конфигурации - показать, что SSL работает (замок, зеленый статус). Так что не зацикливайтесь на 403
.
mongo
Работает только SSL-соединение с сервисом. Я проверил это с программой Robo 3T . После выбора SSL-соединения работает предоставление хоста example.localhost
и выбор сертификата для самоподписанного (или собственного) соединения. И это единственное, что работает таким образом. Соединения с redis
( Redis Desktop Manager ) и с pgsql
( PhpStorm , DBeaver , DbVisualizer ) не работают, независимо от того, предоставляю я сертификаты или нет. Я не пересылаю SSL на сервисы, я только подключаюсь к Traefik. Я провел долгие часы на этом. Я искал в интернете. Я еще не нашел ответ. Кто-нибудь решил это?
PS. Я работаю на Linux Mint, поэтому моя конфигурация должна работать в этой среде без каких-либо проблем. Я бы попросил решения для Linux.
Если вы не хотите просматривать репозиторий , я прилагаю самые важные файлы:
докер-compose.yml
version: "3.7"
services:
traefik:
image: traefik:v2.0
ports:
- 80:80
- 443:443
- 8080:8080
- 6379:6379
- 5432:5432
- 27017:27017
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config.toml:/etc/traefik/traefik.config.toml:ro
- ./certs:/etc/certs:ro
command:
- --api.insecure
- --accesslog
- --log.level=INFO
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
- --entrypoints.traefik.address=:8080
- --entrypoints.mongo.address=:27017
- --entrypoints.postgres.address=:5432
- --entrypoints.redis.address=:6379
- --providers.file.filename=/etc/traefik/traefik.config.toml
- --providers.docker
- --providers.docker.exposedByDefault=false
- --providers.docker.useBindPortIP=false
apache:
image: php:7.2-apache
labels:
- traefik.enable=true
- traefik.http.routers.http-dev.entrypoints=http
- traefik.http.routers.http-dev.rule=Host(`example.localhost`)
- traefik.http.routers.https-dev.entrypoints=https
- traefik.http.routers.https-dev.rule=Host(`example.localhost`)
- traefik.http.routers.https-dev.tls=true
- traefik.http.services.dev.loadbalancer.server.port=80
pgsql:
image: postgres:10
environment:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
labels:
- traefik.enable=true
- traefik.tcp.routers.pgsql.rule=HostSNI(`example.localhost`)
- traefik.tcp.routers.pgsql.tls=true
- traefik.tcp.routers.pgsql.service=pgsql
- traefik.tcp.routers.pgsql.entrypoints=postgres
- traefik.tcp.services.pgsql.loadbalancer.server.port=5432
mongo:
image: mongo:3
labels:
- traefik.enable=true
- traefik.tcp.routers.mongo.rule=HostSNI(`example.localhost`)
- traefik.tcp.routers.mongo.tls=true
- traefik.tcp.routers.mongo.service=mongo
- traefik.tcp.routers.mongo.entrypoints=mongo
- traefik.tcp.services.mongo.loadbalancer.server.port=27017
redis:
image: redis:3
labels:
- traefik.enable=true
- traefik.tcp.routers.redis.rule=HostSNI(`example.localhost`)
- traefik.tcp.routers.redis.tls=true
- traefik.tcp.routers.redis.service=redis
- traefik.tcp.routers.redis.entrypoints=redis
- traefik.tcp.services.redis.loadbalancer.server.port=6379
config.toml
[tls]
[[tls.certificates]]
certFile = "/etc/certs/example.localhost.pem"
keyFile = "/etc/certs/example.localhost-key.pem"
Построить и запустить
mkcert example.localhost # in ./certs/
docker-compose up -d
Подготовить шаг за шагом
- Установите mkcert (запустите также
mkcert -install
для CA) - Клонировать мой код
- В
certs
папке запуститьmkcert example.localhost
- Начать контейнер с
docker-compose up -d
- Откройте страницу https: //example.localhost/ и убедитесь, что это безопасное соединение
- Если адрес http: //example.localhost/ недоступен, добавьте
127.0.0.1 example.localhost
в/etc/hosts
Certs:
- Общественность:
./certs/example.localhost.pem
- Частный:
./certs/example.localhost-key.pem
- CA:
~/.local/share/mkcert/rootCA.pem
Тест MongoDB
- Установить Robo 3T
- Создать новое соединение:
- Адрес:
example.localhost
- Использовать протокол SSL
- Сертификат CA:
rootCA.pem
(или самоподписанный сертификат)
- Адрес:
- Тестовый инструмент:
Тест Redis
- Установите RedisDesktopManager
- Создать новое соединение:
- Адрес:
example.localhost
- SSL
- Открытый ключ:
example.localhost.pem
- Закрытый ключ:
example.localhost-key.pem
- Орган власти:
rootCA.pem
- Адрес:
- Тестовый инструмент:
Уже:
- Можно подключиться к Postgres через IP (информация от Traefik)
jdbc:postgresql://172.21.0.4:5432/postgres?sslmode=disable
jdbc:postgresql://172.21.0.4:5432/postgres?sslfactory=org.postgresql.ssl.NonValidatingFactory
Попробуйте telet (IP изменяет каждый перезапуск докера):
> telnet 172.27.0.5 5432
Trying 172.27.0.5...
Connected to 172.27.0.5.
Escape character is '^]'.
^]
Connection closed by foreign host.
> telnet example.localhost 5432
Trying ::1...
Connected to example.localhost.
Escape character is '^]'.
^]
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close
400 Bad RequestConnection closed by foreign host.
Если я подключаюсь напрямую к postgres, данные хороши. Если я подключаюсь через Traefik, то при закрытии соединения появляется Bad Request. Я понятия не имею, что это значит и должно ли это что-то значить.
Connections to redis (Redis Desktop Manager) ... do not work
, но скриншот показывает Successful connection
-? Почему вы не тестируете на низком уровне curl, openssl, telnet, ...
? Почему вы не проверяете netstat
, действительно ли эти порты приложений привязаны к traefik на 127.0.0.1
интерфейсе?
I can't connect to them
-> как ты это проверял и в чем была ошибка?