Вступ
Передумови
Хто я
Налаштування Traefik
Як це працює
Вступ
Docker Swarm перетворює ваші окремі сервери в кластер комп’ютерів; полегшення масштабування, висока доступність і балансування навантаження. Балансувальник навантаження Swarm реалізує стратегію кругового балансування навантаження, і це може перешкодити правильному функціонуванню (застарілих) програм із збереженням стану, які вимагають певної форми фіксованих сеансів, щоб забезпечити високодоступне налаштування з кількома екземплярами. Docker Enterprise Edition підтримує фіксований сеанс Layer-7, але в цьому посібнику ми зосередимося на безкоштовній (CE) версії Docker. Для реалізації фіксованих сеансів ми будемо використовувати Traefik.
Передумови
- Принаймні два щойно розгорнуті та оновлені екземпляри Debian 9 в одній підмережі з увімкненою приватною мережею
- Docker CE інстальовано на цих екземплярах
- Примірники повинні бути частиною одного Swarm і повинні мати можливість спілкуватися один з одним через приватну мережу
- Попередні знання Docker та Docker Swarm
- Користувач без root з
sudo
правами (необов’язково, але настійно не рекомендується використовувати користувача root)
У цьому підручнику ми будемо використовувати два екземпляри Vultr з приватними IP-адресами 192.168.0.100
та 192.168.0.101
. Обидва вони є вузлами менеджера Docker Swarm (що не ідеально для виробництва, але достатньо для цього підручника).
Хто я
У цьому підручнику використовується jwilder/whoami
зображення Docker як демонстраційна програма. Цей простий контейнер відповідатиме на виклик REST з назвою контейнера, що відповідає, що робить його дуже легким для перевірки, чи працюють фіксовані сеанси. Очевидно, що це зображення використовується лише для демонстраційних цілей і його потрібно замінити зображенням вашого власного додатка.
Послуга whoami налаштовується наступним чином:
sudo docker network create whoaminet -d overlay
sudo docker service create --name whoami-service --mode global --network whoaminet --publish "80:8000" jwilder/whoami
sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
Якщо ми згодом ми бачимо curl
кінцеву точку whoami REST на http://192.168.0.100/
, ми зможемо побачити, як працює циклове балансування навантаження Docker Swarm:
curl http://192.168.0.100
I'm a6a8c9294fc3
curl http://192.168.0.100
I'm ae9d1763b4ad
curl http://192.168.0.100
I'm a6a8c9294fc3
curl http://192.168.0.100
I'm ae9d1763b4ad
curl http://192.168.0.100
I'm a6a8c9294fc3
Немає сенсу тестувати це за допомогою сучасних браузерів, таких як Chrome або Firefox, оскільки вони створені для підтримки з’єднань, а балансувальник навантаження Docker Swarm лише перемикається на інший контейнер при кожному новому з’єднанні. Якщо ви хочете перевірити це за допомогою веб-переглядача, вам доведеться зачекати принаймні 30 секунд, поки з’єднання закриється, перш ніж оновлювати його знову.
Налаштування Traefik
Traefik ізначально підтримує Docker Swarm, він може виявляти та реєструвати або скасувати реєстрацію контейнерів «на льоту», а також спілкується з вашим додатком через внутрішню мережу накладання. Traefik потребує певної інформації про вашу програму, перш ніж вона зможе почати обробляти запити на неї. Ця інформація надається Traefik шляхом додавання міток до вашої служби Swarm:
sudo docker service update --label-add "traefik.docker.network=whoaminet" --label-add "traefik.port=8000" --label-add "traefik.frontend.rule=PathPrefix:/" --label-add "traefik.backend.loadbalancer.stickiness=true" whoami-service
У наведеному нижче списку описано, що означає кожна мітка:
traefik.docker.network
: мережа накладання Docker, через яку Traefik буде спілкуватися з вашим сервісом
traefik.port
: порт, на якому ваша служба прослуховує (це внутрішньо відкритий порт, а не опублікований порт)
traefik.frontend.rule
: PathPrefix:/
прив'язує корінь контексту " /
" до цієї служби
traefik.backend.loadbalancer.stickiness
: вмикає фіксовані сеанси для цієї служби
Тепер, коли whoami-service
налаштовано необхідні мітки, ми можемо додати службу Traefik до роя:
sudo docker service create --name traefik -p8080:80 -p9090:8080 --mount type=bind,source=/var/run/docker.sock,destination=/var/run/docker.sock --mode=global --constraint 'node.role == manager' --network whoaminet traefik --docker --docker.swarmmode --docker.watch --web --loglevel=DEBUG
Ця команда виконує досить багато речей одночасно, як показано в наступному списку:
--name traefik
: Наша нова служба Docker називається Traefik
-p8080:80
Ми публікуємо порт Traefik в 80
порт , 8080
оскільки порт 80
вже використовуються нашим WHOAMI-сервіс
-p9090:8080
: Ми публікуємо власний веб-інтерфейс Traefik для портування 9090
--mount ...
: Ми монтуємо Docker Socket в контейнер, щоб Traefik міг отримати доступ до середовища виконання Docker хоста
--global
: Нам потрібні контейнери Traefik на кожному вузлі менеджера з міркувань високої доступності
--constraint 'node.role == manager'
: Ми хочемо, щоб Traefik працював лише на вузлах менеджера, тому що робочі вузли не можуть надати Traefik необхідну інформацію. Наприклад, docker service ls
на робочому вузлі не працює, тому Traefik навіть не зможе дізнатися, які служби запущені
--network whoaminet
: Підключіть Traefik до тієї ж мережі, що й наш whoami-service
, інакше він не зможе підключитися до неї. Раніше ми сказали Traefik підключитися до нашої служби через цю мережу за допомогою traefik.docker.network
мітки
traefik
: скажіть docker використовувати найновіший образ докера Traefik для цієї служби
--docker --docker.swarmmode --docker.watch --web --loglevel=DEBUG
: аргументи командного рядка передаються безпосередньо Traefik, щоб дозволити йому працювати в режимі Docker Swarm. DEBUG
тут необов’язковий, але цікавий під час налаштування та для цього підручника
Все, що залишилося зробити, це відкрити необхідні порти в брандмауері Debian:
sudo iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT
sudo iptables -I INPUT 1 -p tcp --dport 9090 -j ACCEPT
Як це працює
Щойно Traefik запуститься, ви побачите в журналах, що Traefik виявив два whoami
контейнери. Він також виводить ім’я cookie, яке буде використовуватися для обробки фіксованого сеансу:
time="2018-11-25T13:17:30Z" level=debug msg="Configuration received from provider docker: {\"backends\":{\"backend-whoami-service\":{\"servers\":{\"server-whoami-service-1-a179b2e38a607b1127e5537c2e614b05\":{\"url\":\"http://10.0.0.5:8000\",\"weight\":1},\"server-whoami-service-2-df8a622478a5a709fcb23c50e689b5b6\":{\"url\":\"http://10.0.0.4:8000\",\"weight\":1}},\"loadBalancer\":{\"method\":\"wrr\",\"stickiness\":{}}}},\"frontends\":{\"frontend-PathPrefix-0\":{\"entryPoints\":[\"http\"],\"backend\":\"backend-whoami-service\",\"routes\":{\"route-frontend-PathPrefix-0\":{\"rule\":\"PathPrefix:/\"}},\"passHostHeader\":true,\"priority\":0,\"basicAuth\":null}}}"
time="2018-11-25T13:17:30Z" level=debug msg="Wiring frontend frontend-PathPrefix-0 to entryPoint http"
time="2018-11-25T13:17:30Z" level=debug msg="Creating backend backend-whoami-service"
time="2018-11-25T13:17:30Z" level=debug msg="Adding TLSClientHeaders middleware for frontend frontend-PathPrefix-0"
time="2018-11-25T13:17:30Z" level=debug msg="Creating load-balancer wrr"
time="2018-11-25T13:17:30Z" level=debug msg="Sticky session with cookie _a49bc"
time="2018-11-25T13:17:30Z" level=debug msg="Creating server server-whoami-service-1-a179b2e38a607b1127e5537c2e614b05 at http://10.0.0.5:8000 with weight 1"
time="2018-11-25T13:17:30Z" level=debug msg="Creating server server-whoami-service-2-df8a622478a5a709fcb23c50e689b5b6 at http://10.0.0.4:8000 with weight 1"
time="2018-11-25T13:17:30Z" level=debug msg="Creating route route-frontend-PathPrefix-0 PathPrefix:/"
time="2018-11-25T13:17:30Z" level=info msg="Server configuration reloaded on :80"
time="2018-11-25T13:17:30Z" level=info msg="Server configuration reloaded on :8080"
Якщо ми згорнуємося до, http://192.168.0.100:8080
то побачимо, що було встановлено новий файл cookie _a49bc
:
curl -v http://192.168.0.100:8080
* About to connect() to 192.168.0.100 port 8080 (#0)
* Trying 192.168.0.100...
* Connected to 192.168.0.100 (192.168.0.100) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.0.100:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 17
< Content-Type: text/plain; charset=utf-8
< Date: Sun, 25 Nov 2018 13:18:40 GMT
< Set-Cookie: _a49bc=http://10.0.0.5:8000; Path=/
<
I'm a6a8c9294fc3
* Connection #0 to host 192.168.0.100 left intact
Якщо під час наступних викликів ми надішлемо цей файл cookie Traefik, ми завжди будемо перенаправлені в той самий контейнер:
curl http://192.168.0.100:8080 --cookie "_a49bc=http://10.0.0.5:8000"
I'm a6a8c9294fc3
curl http://192.168.0.100:8080 --cookie "_a49bc=http://10.0.0.5:8000"
I'm a6a8c9294fc3
curl http://192.168.0.100:8080 --cookie "_a49bc=http://10.0.0.5:8000"
I'm a6a8c9294fc3
curl http://192.168.0.100:8080 --cookie "_a49bc=http://10.0.0.5:8000"
I'm a6a8c9294fc3
Файл cookie не містить нічого, крім внутрішньої IP-адреси контейнера, на який Traefik має надіслати запит. Якщо змінити значення cookie на http://10.0.0.4:8000
, запит буде фактично перенаправлено до іншого контейнера. Якщо файл cookie ніколи не буде повторно надіслано до Traefik, фіксований сеанс не працюватиме, і запити будуть збалансовані між контейнерами програми та контейнерами Traefik.
Це все, що потрібно, щоб налаштувати липкі сеанси рівня 7 в Docker CE на Debian 9.