Visitors have accessed this post 6258 times.

Docker Swarm: практическое использование

4
2
6258
20 ноября 2020 9:37
Автор: Rebrain Me
Docker

Visitors have accessed this post 6258 times.

Автор — Максим Рязанов

Всех приветствую! В этой статье мы познакомимся с преимуществами overlay-сети, а также попрактикуемся с деплоем сервисов и приложений. Будет интересно!

Замечание к статье: для примера будут использоваться три виртуальные машины под управлением Debian 10, развернутые на моем компьютере. Все команды, перечисленные в статье, будут выполняться от имени пользователя root, а управление виртуальными машинами — с помощью команд libvirt.

Перед прочтением статьи рекомендую ознакомиться с предыдущей статьей про Docker Swarm.

Напомню условия: в моих примерах используется три ноды docker swarm, все с ролью менеджера и разрешением на запуск и исполнение контейнеров. В примере используется домен в локальной сети, настроенный на Powerdns, находящемся там же.

Я обещал рассмотреть overlay-сеть в docker swarm. А так как я очень люблю практические занятия, давайте рассмотрим ее работу на практике!

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

version: '3.2'

services:

  postgres-server:
    image: postgres:11-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: PostSwarm77
      POSTGRES_DB: ryazanov
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - postgres-network
    deploy:
      mode: replicated
      replicas: 1

networks:
  postgres-network:
    driver: overlay
    attachable: true

volumes:
  postgres-data:

В нем описан сервис postgres-server в блоке services, который будет основан на образе postgres:11-alpine, трафик, поступающий на порт 5432 любого хоста, в swarm будет перенаправляться в контейнер на порт 5432.Environment задаст переменные окружения, из которых Postgres получит данные конфигурации (пароль к пользователю БД postgres, имя базы данных, каталог хранения данных).

Volumes позволит пробросить для ноды локальный том postgres-data.

В deploy мы указываем режим replicated и одну реплику.

В networks создаем нашу overlay сеть, если она еще не создана. Указываем, что она может использоваться службами swarm или автономными контейнерами для связи с другими автономными контейнерами на других нодах docker (attachable).

Объявляем под networks в volumes том postgres-data. Он будет доступен с исполняемой ноды  /var/lib/docker/volumes/.

Задеплоим стек первой командой.

docker stack deploy -c ./postgres-11.yml training

-c — путь до файла конфигурации стека.

Смотрим на результат.

docker stack ps training
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
npw3n4usnw8f training_postgres-server.1 postgres:11-alpine swr2.rpulse.locnet Running Running about a minute ago


У нас запустился сервис training_postgres-server на ноде swr2.rpulse.locnet.Теперь, чтобы объяснить преимущество overlay сети, я выполню подключение postgres клиентом через ноду swr3.rpulse.locnet и swr1.rpulse.locnet.

Итак, первое преимущество overlay сети заключается в том, что мы можем подключиться к контейнеру через любую ноду, несмотря на то, на какой ноде он работает фактически.

Мы также можем подключить к этой сети другой сервис, чтобы связать его внутри нее с уже существующим. Сервис может находиться вне стека. Можно даже воспользоваться standalone-контейнером (как я и сделаю в примере ниже). Главное, подключить его к сети (в нашем случае — postgres-network).

docker run -it --network training_postgres-network postgres:11-alpine psql -h training_postgres-server -U postgres -W


Обратите внимание, что аргументом для ключа -h (—host, к которому необходимо подключиться) я указал не внешний IP хоста и не внутренний IP работающего контейнера, а имя нашего сервиса training_postgres-server. У docker swarm есть своя реализация внутреннего DNS-сервера, которая создает для сервиса в сети DNS-имя = имени сервиса.
Таким образом, если вы захотите реализовать кластер не на уровне swarm, а на уровне сервисов — у вас есть такая возможность, благодаря реализации внутреннего DNS docker.

Создаем стек

Давайте попробуем еще кое-что интересное и приближенное к серьезному приложению. Мы создадим стек, в котором будет два сервиса: traefik и whoami.

version: "3.3"

services:
  traefik:
    image: traefik:v2.2
    ports:
      - "80:80"
      - "8080:8080"
      - "443:443"
    command:
      - --api.insecure=true
      - --api.dashboard=true
      - --api.debug=true
      - --log.level=DEBUG
      - --providers.docker=true
      - --providers.docker.swarmMode=true
      - --providers.docker.exposedbydefault=false
      - --providers.docker.network=traefik_external
      - --entrypoints.web.address=:80
      - --entrypoints.web-secured.address=:443
      - --providers.file.filename=/traefik.toml
    volumes:
      - cert:/ssl
      - /var/run/docker.sock:/var/run/docker.sock
    configs:
      - traefik
    networks:
      - external
    deploy:
      mode: global
      placement:
        constraints: [node.role == manager]
  whoami:
    image:
      containous/whoami
    networks:
      - external
    deploy:
      mode: replicated
      replicas: 4
      labels:
        - "traefik.enable=true"
        - "traefik.http.services.whoami.loadbalancer.server.port=80"
        - "traefik.http.routers.whoami.rule=Host(whoami.rpulse.locnet)"
        - "traefik.http.routers.whoami.entrypoints=web"
        - "traefik.http.routers.whoami-https.rule=Host(whoami.rpulse.locnet)"
        - "traefik.http.routers.whoami-https.entrypoints=web-secured"

networks:
  external:
    driver: overlay
    attachable: true

configs:
  traefik:
    file: traefik.toml

volumes:
  cert:

Traefik будет запускаться в режиме global (на каждой ноде) с сетью external. В этой же сети будет находиться сервис whoami в режиме replicated, реплик будет 4. В Traefik будет проброшен docker.sock, через который будут просматриваться все сервисы в swarm. Когда traefik будет находить новый сервис и принадлежащие ему лейблы, начинающиеся на traefik., он будет их считывать и изменять свою конфигурацию динамически. В конфигурации будут указаны доменные имена. В зависимости от того, по какому доменному имени обратится клиент, traefik будет перенаправлять трафик в тот или иной контейнер. В этом примере traefik будет перенаправлять на контейнер whoami все запросы, которые придут по доменному имени whoami.rpulse.locnet.

Я также сделал volume certs и конфиг traefik, чтобы в будущем была возможность добавить wildcard-сертификат.

version: "3.3"

services:
traefik:
image: traefik:v2.2
ports:
- "80:80"
- "8080:8080"
- "443:443"
command:
- --api.insecure=true
- --api.dashboard=true
- --api.debug=true
- --log.level=DEBUG
- --providers.docker=true
- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik_external
- --entrypoints.web.address=:80
- --entrypoints.web-secured.address=:443
- --providers.file.filename=/traefik.toml
volumes:
- cert:/ssl
- /var/run/docker.sock:/var/run/docker.sock
configs:
- traefik
networks:
- external
deploy:
mode: global
placement:
constraints: [node.role == manager]
whoami:
image:
containous/whoami
networks:
- external
deploy:
mode: replicated
replicas: 4
labels:
- "traefik.enable=true"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
- "traefik.http.routers.whoami.rule=Host(whoami.rpulse.locnet)"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.routers.whoami-https.rule=Host(whoami.rpulse.locnet)"
- "traefik.http.routers.whoami-https.entrypoints=web-secured"

networks:
external:
driver: overlay
attachable: true

configs:
traefik:
file: traefik.toml

volumes:
cert:

Деплоим сервис

docker stack deploy -c ./webapp.yml webapp

Заходим из браузера по адресу http://whoami.rpulse.locnet/

Увидим результат вроде этого:

Попробуйте пообновлять страницу. Наверняка, вы заметите, что hostname, ip, RemoteAddr и другие связанные параметры могут меняться. И это правильно — у нас есть 4 разных контейнера whoami на разных нодах и пара — на одной, а traefik запущен в режиме global — по экземпляру на каждой ноде. Между traefik community edition трафик в этом примере балансируется через DNS.

Балансировка на уровне traefik доступна, если не ошибаюсь, только в enterprise edition.

У меня настроена возможность входа в traefik на порту 8080. Я заранее создал записи swr.ryazanov.locnet, которые ссылаются на все мои ноды docker swarm также, как и домен выше.

Давайте сразу посмотрим на сервисы (Services -> Explore).

Мы увидим, что сервис whoami в docker присутствует в этом списке:

Самостоятельно зайдите в Routers. Вы увидите, что есть http router, перенаправляющий запросы на traefik.

Обратите внимание, что в моей версии whoami https отсутствует. Но настройка такова, что traefik будет пересылать все https запросы, полученные на порт 443, в тот же порт на сервис с тем же типом соединения (https).

Теперь, спроектировав приложение с микросервисной архитектурой, вы сможете самостоятельно развернуть его в кластере docker swarm.

На данный момент это все, что я хотел рассказать. Если вам понравилась серия статей по Docker Swarm, обязательно отметте свою признательность и нажмите лайк. Остались вопросы — задавайте в комментариях! Я и сообщество постараемся ответить.

От редакции

Если вам интересно посещать бесплатные онлайн-мероприятия по DevOps, Kubernetes, Docker, GitlabCI и др. и задавать вопросы в режиме реального времени, подключайтесь к каналу DevOps by REBRAIN

*Анонсы мероприятий каждую неделю

Практикумы для специалистов по инфраструктуре и разработчиков — https://rebrainme.com.

Наш Youtube-канал — https://www.youtube.com/channel/UC6uIx64IFKMVmj12gKtSgBQ.

Агентство Fevlake, проектируем и поддерживаем IT-инфраструктуры с 2012 года — https://fevlake.com.

Комментарии (3)
Введено символов из возможных
Не отвечать
LavrovAP

Максим день добрый!
Попробовал повторить, и столкнулся с ошибкой.
При попытке задеплоить стек получаю ошибку «yaml: line 44: did not find expected ‘-‘ indicator»
Полагаю проблема в 44 и 46 стоке
— «traefik.http.routers.whoami.rule=Host(whoami.rpulse.locnet

не заэкранированы кавычки.
Как правильно исправить стоку?
Заранее спасибо

LavrovAP

извиняюсь не ту стоку указал
— «traefik.http.routers.whoami.rule=Host(whoami.rpulse.locnet

Вам также может понравится

Как посмотреть открытые порты Linux
array(1) { [0]=> object(WP_Term)#11581 (16) { ["term_id"]=> int(6) ["name"]=> string(5) "Linux" ["slug"]=> string(5) "linux" ["term_group"]=> int(0) ["term_taxonomy_id"]=> int(6) ["taxonomy"]=> string(8) "category" ["description"]=> string(0) "" ["parent"]=> int(0) ["count"]=> int(28) ["filter"]=> string(3) "raw" ["cat_ID"]=> int(6) ["category_count"]=> int(28) ["category_description"]=> string(0) "" ["cat_name"]=> string(5) "Linux" ["category_nicename"]=> string(5) "linux" ["category_parent"]=> int(0) } } Linux

Во время устранения неполадок служб, работающих на ОС Linux, просмотр открытых портов является одной из задач, которую должен выполнять любой пользователь или администратор. Если служба должна по идее работать, но по какой-то причине она не работает, то, скорее всего, порт этой службы закрыт и его нужно открыть.

В этом туториале мы покажем, как...

6
0
28 мая 2020
Использование OpenSSL: хеши, цифровые подписи и многое другое
array(1) { [0]=> object(WP_Term)#988 (16) { ["term_id"]=> int(7) ["name"]=> string(6) "DevOps" ["slug"]=> string(6) "devops" ["term_group"]=> int(0) ["term_taxonomy_id"]=> int(7) ["taxonomy"]=> string(8) "category" ["description"]=> string(0) "" ["parent"]=> int(0) ["count"]=> int(19) ["filter"]=> string(3) "raw" ["cat_ID"]=> int(7) ["category_count"]=> int(19) ["category_description"]=> string(0) "" ["cat_name"]=> string(6) "DevOps" ["category_nicename"]=> string(6) "devops" ["category_parent"]=> int(0) } } DevOps

Перевод статьи - https://opensource.com/article/19/6/cryptography-basics-openssl-part-2

Детальный обзор шифрования в OpenSSL: хеши, цифровые подписи, цифровые сертификаты и многое другое

В первой статье из этой серии мы познакомились с хешами, шифрованием/дешифрованием, цифровыми подписями и сертификатами в библиотеках OpenSSL, утилитами...

3
0
18 сентября 2020
30 псевдонимов оболочки Bash в ОС Linux / Unix / Mac OS X
array(1) { [0]=> object(WP_Term)#11582 (16) { ["term_id"]=> int(6) ["name"]=> string(5) "Linux" ["slug"]=> string(5) "linux" ["term_group"]=> int(0) ["term_taxonomy_id"]=> int(6) ["taxonomy"]=> string(8) "category" ["description"]=> string(0) "" ["parent"]=> int(0) ["count"]=> int(28) ["filter"]=> string(3) "raw" ["cat_ID"]=> int(6) ["category_count"]=> int(28) ["category_description"]=> string(0) "" ["cat_name"]=> string(5) "Linux" ["category_nicename"]=> string(5) "linux" ["category_parent"]=> int(0) } } Linux

Оригинал статьи - https://www.cyberciti.biz/tips/bash-aliases-mac-centos-linux-unix.html

Псевдоним (он же алиас) bash - это ярлык для команд. Команда alias позволяет пользователю запускать любую команду или группу команд (включая параметры и имена файлов), вводя одно слово. Используйте команду alias, чтобы отобразить список всех определенных...

8
1
9 октября 2020