Въведение
Предпоставки
Кой съм аз
Настройка на Traefik
Как работи
Въведение
Docker Swarm превръща вашите отделни сървъри в клъстер от компютри; улесняване на мащабиране, висока наличност и балансиране на натоварването. Балансирането на натоварването на Swarm прилага стратегия за кръгово балансиране на натоварването и това може да попречи на правилното функциониране на (наследени) приложения с състояние, които изискват някаква форма на лепкави сесии, за да позволят високодостъпна настройка с множество екземпляри. Docker Enterprise Edition поддържа лепкава сесия на Layer-7, но в това ръководство ще се съсредоточим върху безплатната (CE) версия на Docker. За да реализираме лепкави сесии, ще използваме Traefik.
Предпоставки
- Най-малко две наскоро внедрени и актуализирани екземпляра на Debian 9 в една и съща подмрежа с активирана частна мрежа
- Docker CE, инсталиран на тези екземпляри
- Екземплярите трябва да са част от един и същи рояк и трябва да могат да комуникират помежду си през частната мрежа
- Предварителни познания за 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 да използва най-новото изображение на Docker Traefik за тази услуга
--docker --docker.swarmmode --docker.watch --web --loglevel=DEBUG
: Аргументите на командния ред се предават директно на Traefik, за да му позволят да работи в Docker рояк режим. 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
контейнера. Той също така извежда името на бисквитката, което ще използва за обработка на лепкавата сесия:
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
можем да видим, че _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
Ако при последващи обаждания изпратим тази бисквитка до 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
Бисквитката не съдържа нищо освен вътрешния IP адрес на контейнера, до който Traefik трябва да изпрати за заявка. Ако промените стойността на бисквитката на http://10.0.0.4:8000
, тогава заявката ефективно ще бъде препратена към другия контейнер. Ако бисквитката никога не бъде изпратена повторно до Traefik, тогава лепкавата сесия няма да работи и заявките ще бъдат балансирани между контейнерите на приложението и контейнерите Traefik.
Това е всичко, което е необходимо, за да настроите Layer 7 Sticky Sessions в Docker CE на Debian 9.