Как оркестровать микросервисы с помощью Docker Compose

Как оркестровать микросервисы с помощью Docker Compose

https://nuancesprog.ru/p/16396/

Большинство современных программных систем имеют микросервисную архитектуру. Для стека микросервисных технологий Spring Cloud характерно содержание в прикладной системе нескольких прикладных микросервисов.

Перед запуском приложения необходимо запустить шлюз, центр регистрации, центр конфигурации, базу данных (даже при наличии внедренного в систему межплатформенного ПО, такого как Redis, RabbitMQ, системы управления логами ELK, системы визуализации Grafana и других сервисов).

При развертывании приложения с микросервисной архитектурой необходимо упаковать разработанный сервис Spring Boot в образ Docker, импортировать его в Docker, а затем запустить развертывание.

Межплатформенное ПО, база данных и другие сервисы также должны получить соответствующую версию образа из удаленного хранилища Docker для развертывания. Это довольно громоздкий процесс, занимающий много времени.

Уменьшить рабочую нагрузку позволяет использование Docker Compose — официального инструмента оркестрации контейнеров, предоставляемого компанией Docker.


Что такое оркестрация контейнеров?

Использование различных инструментов для автоматизации развертывания контейнеров, управления ими, адаптивного масштабирования, управления сетью и других функций — это и есть оркестрация контейнеров.

Всем известный Kubernetes (K8s) — продвинутый инструмент оркестрации контейнеров. Кроме него, широко используемыми инструментами оркестрации являются Docker Swarm и Docker Compose. Обе эти платформы — проекты официального инструмента оркестрации контейнеров Docker, однако роли их различны.

Docker Compose — это инструмент для определения и запуска многоконтейнерных приложений Docker. В основном он используется для создания контейнеров на одной машине.

Docker Swarm применяется в качестве платформы для управления кластерами Docker, которые можно использовать для создания контейнерных сервисов на нескольких серверах.

Предназначение K8s собственно такое же, как и у Docker Swarm. Это платформа для эксплуатации и обслуживания контейнеров, разработанная компанией Google. Она стала основным инструментом оркестрации контейнеров.

Dockerfile

Чтобы понимать, как работает Docker Compose, необходимо разбираться в Dockerfile. Сервис Spring Boot после компиляции представляет собой JAR-пакет. Перед развертыванием сервиса в контейнере Docker нужно собрать JAR-пакет в Docker-образ с помощью Dockerfile.

Dockerfile — это текстовый файл, используемый для создания образа. Содержимое файла — инструкции и указания по сборке образа.

Следует отметить, что каждая инструкция строит свой слой образа. Инструкций Dockerfile не так много, достаточно освоить те из них, которые используются в повседневной практике.

FROM

Задает базовый образ. Обычно это первая инструкция файла. Но можно также использовать ARG в качестве первой инструкции.

# Формат
FROM [--platform=<platform>] <image> [AS <name>]  
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>] 
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

# Использование
FROM centos
FROM openjdk:8-jre
FROM node:12.18.4-alpine@sha256:757574c5a2...

Описание параметра:

  • [ — platform=<platform>]  — необязательный параметр, с помощью которого можно указать платформу образа, например Linux/amd64, Linux/arm64 и windows/amd64, обычно по умолчанию.
  • <image>  — это имя образа, за которым следует номер версии :tag, используемый для указания образа, и контекстно-адресуемый идентификатор @digest (подробности об этих параметрах читайте на официальном сайте). Как правило, используются только теги. Если ни один из них не указан, будет получена последняя версия.
  • [as <name>]  — имя текущего этапа сборки, поскольку в Dockerfile можно использовать несколько FROM для создания нескольких образов. Поэтому as <name> можно применять в следующей команде COPY. С помощью — from=<name> можно ссылаться на образ, собранный ранее, например для копирования файлов, созданных предыдущим образом, и т. д.

ARG

Эта директива используется для указания переменной, которая передается во время выполнения сборки. Она может задавать значение по умолчанию. При сборке контейнера с помощью команды docker build используйте — build-arg <varname> = <value> для передачи параметров.

# Формат
ARG <name>[=<default value>]

# Использование
ARG CODE_VERSION=laster
ARG testArg=123

# Параметр
FROM centos:7
ARG parameter=123
RUN echo $parameter

docker build --build-arg parameter=234 -t test:1.0

# Примечание
# ARG можно использовать до FROM, вне фазы сборки FROM, поэтому данную директиву нельзя использовать ни в одной инструкции после FROM. 
ARG CENTOS_VERSION=laster
FROM centos:${CENTOS_VERSION}

ENV

Эта директива используется для установки переменных среды контейнера как в процессе сборки, так и в запущенном контейнере.

# Формат
ENV <key>=<value> ...

# Примечание
# Можно задать более одного или использовать другой синтаксис ENV <ключ> <значение>. На официальном сайте рекомендуется использовать первый вариант, а второй может быть удален в будущих версиях. 
# Переменные ENV переопределяют переменные ARG

# Использование
ENV APP_VERSION=1.1.0
ENV WEB_HOME /opt/webapps

Copy

Эта директива используется для копирования файлов и каталогов из пути в контейнер.

# Формат
COPY <src>... <dest>
COPY "<src>",... "<dest>"

# Использование
COPY test.jar /opt/web/

ADD

Эта команда используется для копирования файлов, каталогов и удаленных файлов в образ. При этом сжатый пакетный файл типа TAR будет автоматически распакован.

# Формат
ADD <src>... <dest>
ADD "<src>",... "<dest>"

# Использование
ADD test.txt /tmp/test

WORKDIR

Эта директива устанавливает рабочий каталог для последующих директив. Если каталог не существует, он будет создан автоматически.

# Формат
WORKDIR /path/to/workdir

# Использование
WORKDIR /build

LABEL

Эта директива используется для указания информации тега метаданных образа.

# Формат
LABEL <key>=<value> <key>=<value> <key>=<value> ...

# Использование
LABEL version="1.0"
LABEL description="This text illustrates"

CMD

Эта инструкция задает команду, которая будет выполняться при запуске контейнера после сборки образа.

# Формат
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2

# Использование
CMD sleep 40; java -jar secondkill-order.jar
CMD ["java", "-jar", "secondkill-order.jar"]

RUN

Эта инструкция используется для указания команды, которая должна быть выполнена при сборке образа. Основное различие между RUN и CMD заключается в том, что CMD выполняется при запуске контейнера, а RUN — во время построения контейнера.

# Формат
RUN <command>
RUN ["executable", "param1", "param2"]

# Использование
RUN yum install -y net-tools
RUN ["/bin/bash", "-c", "echo hello"]

EXPOSE

Эта команда указывает на то, что контейнер запущен на определенном порте. Вы можете указать протокол прослушивания. Если он не указан, по умолчанию используется протокол TCP.

# Формат
EXPOSE <port> [<port>/<protocol>...]

# Использование
EXPOSE 80/udp
EXPOSE 80 443

VOLUME

Эта директива используется для создания точки монтирования с указанным именем, которая может сопоставлять каталог за пределами контейнера.

# Формат
VOLUME ["/data"]

# Использование
VOLUME /myvol

Здесь приведены лишь наиболее часто используемые команды Dockerfile. Чтобы ознакомиться с ними более детально, обратитесь к документации на официальном сайте.


Создание приложения Spring Boot с помощью Dockerfile

Использовать Dockerfile для упаковки Spring Boot достаточно просто. Для этого нужно использовать образ Jdk8, скопировать локально упакованный JAR-пакет в образ, открыть порт сервиса и запустить сервис.

# Зеркало, использующее openjdk8
FROM openjdk:8-jre

# Установка рабочего каталога
WORKDIR /build

# Скопируйте пакет JAR в контейнер
ADD ./test-springboot-docker-1.0.jar ./test.jar

# Откройте порт 8080
EXPOSE 8080

# Запустите пакет JAR
CMD java -jar test.jar

Как обычно помещаем Dockerfile в каталог проекта.

Фото автора

Затем развернем пакет maven для упаковки JAR-пакета. Поместим JAR-пакет и Dockerfile в один каталог на сервере со средой Docker и с помощью команды docker build превратим микросервис Spring Boot в образ.

Фото автора

Затем запустим контейнер, чтобы проверить, может ли он успешно включиться в работу.

Фото автора

Поскольку порт 8080 используется другими сервисами, выполним маппинг на порт 80. Если получить доступ непосредственно к этому порту прямо сейчас, можно увидеть, что контейнер успешно запущен.

Фото автора

Docker Compose

На данном этапе JAR-пакет можно собрать в образ Docker. Но если приложение микросервисной архитектуры содержит несколько сервисов, его нельзя каждый раз вручную упаковывать и развертывать на сервере. Поэтому на данном этапе необходимо применить Docker Compose для управления контейнером.

Docker Compose использует файл docker-compose.yml для определения нескольких сервисов. Формат файла — YAML. Для начала нужно определить структуру всего файла.

Файловая структура docker-compose.yml

Docker Compose предоставляет множество синтаксических шаблонов. Ниже перечислены только элементы синтаксиса, необходимые для данной структуры, остальные можно изучить на официальном сайте.

Официальная документация довольно подробна и представлена в формате docker-compose.yml.

version: указание версии сборки, соответствующей текущему файлу; в основном это 1, 2.x и 3.x
service: список сервисов
 <service-name>: имя сервиса
  image: указание запущенного образа; можно напрямую извлекать  существующий образ для обработки
  build: установка папки, где находится Dockerfile, способный обрабатывать образы, которые должны быть собраны с помощью Dockerfile.
   content: путь для хранения Dockerfile
   dockerfile: указывает имя файла Dockerfile для сборки
   args: аргументы сборки, доступные только в процессе сборки
  container_name: установка имени контейнера
  restart: стратегия перезапуска; есть такие опции, как no, always, no-failure и unless-stopped
  ports: открытие порта контейнера, формат: порт хоста: порт контейнера
   - 8080:8080
  hostname: установка имени хоста контейнера
  volumes: установка точки монтирования контейнера, который может быть смонтирован на хосте; основной формат: путь к хосту: путь к контейнеру [: режим доступа]
   - /opt/data:/opt/data
   - /var/lib/mysql:/var/lib/mysql:rw
  volumes_from: монтирование объемов информации другого сервиса или контейнера
   - service_name
   - container_name
  environment: установка переменных среды
    - RACK_ENV=development
networks: настройка сетей
 app_netwotk:

Команды Docker compose

Ниже перечислены часто используемые команды с их общими описаниями (подробные описания команд и используемых параметров представлены на официальном сайте).

  • build: построить контейнер.
  • ps: вывести список всех контейнеров текущего проекта.
  • up: построить и запустить контейнер, общие параметры: -d : фоновый старт, -: указать конфигурационный файл.
  • exec: войти в указанный контейнер.
  • top: просмотреть текущее состояние каждого контейнера в проекте.
  • logs: просмотреть выходные данные контейнера.
  • down: остановить и удалить все контейнеры и соответствующую сеть.
  • rm: удалить все остановленные контейнеры.
  • start/stop/restart: запустить контейнер/остановить контейнер/перезапустить контейнер.

Развертывание микросервисов Docker Compose

В качестве примера воспользуемся проектом торгового центра с разделением на фронтенд и бэкенд. Он включает в себя 5 сервисов:

  • шлюз;
  • сервис аутентификации;
  • пользовательский сервис;
  • сервис товаров;
  • сервис заказов.

Кроме того, есть реестр Nacos, а также проект использует Rabbitmq, Redis и базу данных Mysql. Таким образом, всего необходимо развернуть 8 контейнеров.

Установка Docker Compose

Хотя Docker Compose является инструментом оркестрации на официальном сайте, он не включен по умолчанию и должен быть установлен вручную.

Метод установки относительно прост: достаточно загрузить бинарный файл Docker Compose и установить разрешение на запуск исполняемого файла.

  1. Скачайте файл Docker Compose.
sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

2. Добавьте к файлу разрешение на выполнение.

sudo chmod +x /usr/local/bin/docker-compose

3. Протестируйте результаты установки.

$ docker-compose --version
docker-compose version 1.18.0, build 8dd22a96

Общая структура файла

Общая структура файла docker-compose.yml выглядит следующим образом: указывается версия файла (здесь используется версия 3), далее следуют сервисы (названия сервисов соответствуют нижеуказанным).

Составная часть сетевой конфигурации — это создание network. Иначе по умолчанию будет создано имя сети с текущей папкой + _default.

Например, если имя папки проекта —  second kill, а суффикс сети указан как app, будет создана сеть secondkill_app.

version: '3'
services:
  secondkill-register:
 ...
  secondkill-mysql:
 ...
  secondkill-redis:
 ...
  secondkill-rabbitmq:
 ...
  secondkill-zuul:
 ...
  secondkill-auth:
 ...
  secondkill-goods:
 ...
  secondkill-order:
 ...
  secondkill-user:
 ...
networks:
  app:

Развертывание реестра

Развертывание реестра — относительно простой процесс. Извлеките образ nacos/nacos-server:1.4.2, но обратите внимание на установку режима запуска nacos.

Поскольку по умолчанию Nacos запускается в кластере, необходимо увеличить MODE среды до автономного режима.

Кроме того, следует отметить, что здесь nacos используется только как центр регистрации и соединение с базой данных не настроено.

Если понадобится сохранить данные Nacos в базе данных, обратите внимание на настройку информации о базе данных.

secondkill-register:
  # Извлечение образа 
  image: nacos/nacos-server:1.4.2
  # Метод перезапуска (Restart): always
  restart: always
  # Маппинг портов 
  ports:
    - 8848:8848
  # Имя контейнера 
  container_name: secondkill-register
  # Имя хоста, которое требует от других контейнеров доступа к сети через вторичное имя
  hostname: secondkill-register
  # Переменная среды, установка режима запуска на автономный запуск
  environment:
    - MODE: standalone
    # конфигурация информации mysql
    # - SPRING_DATASOURCE_PLATFORM=mysql
    # - MYSQL_MASTER_SERVICE_HOST=127.0.0.1
    # - MYSQL_MASTER_SERVICE_PORT=3306
    # - MYSQL_MASTER_SERVICE_USER=root
    # - MYSQL_MASTER_SERVICE_PASSWORD=123456
    # - MYSQL_MASTER_SERVICE_DB_NAME=nacos
    # - MYSQL_SLAVE_SERVICE_HOST=122.112.152.188
    # - MYSQL_SLAVE_SERVICE_PORT=3306
  # Добавление в сеть
  networks:
    - app

Развертывание Rabbitmq и Redis

Развернуть очереди сообщений и Redis относительно легко. Однако следует отметить, что для удобства собственного развертывания для временной демонстрации я не перенаправлял постоянные данные и конфигурационные файлы Redis и Rabbitmq, что крайне не рекомендуется. Следует развертывать сервисы с фиксацией состояния и не хранить данные.

Когда контейнер развертывает сервисы, пригодные для конфигурирования и выполнения операций, конфигурационный файл и каталог данных следует монтировать на хосте.

secondkill-redis:
  # Образ redis
  image: redis:3.2
  # Маппинг портов
  ports:
    - 6379:6379
  # Метод перезапуска (Restart): always
  restart: always
  # Имя контейнера
  container_name: secondkill-redis
  # Имя хоста
  hostname: secondkill-redis
  # Присоединение к сети приложения 
  networks:
    - app

secondkill-rabbitmq:
  # Образ rabbitmq 
  image: rabbitmq:3.8.4
  # Маппинг портов
  ports:
    - 5672:5672
    - 15672:15672
  # Метод перезапуска (Restart): always
  restart: always 
  # Имя контейнера
  container_name: secondkill-rabbitmq
  # Имя хоста
  hostname: secondkill-rabbitmq
  # Присоединение к сети приложения 
  networks:
    - app

Развертывание базы данных

Как и сервис Redis, развертывание базы данных не монтирует конфигурационные файлы и данные (не рекомендуется, обратите на это внимание).

Поскольку при запуске базы данных здесь необходимо установить пароль базы данных, а также импортировать скрипт базы данных в базу данных, для создания образа здесь используется Dockerfile.

# Извлечение образа myql8 
FROM mysql:8.0.14
# Установка переменной часового пояса
ENV TZ=Asia/Shanghai
# Установка часового пояса
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# Импорт скрипта базы данных
COPY ./choy_ms.sql /docker-entrypoint-initdb.d

Поместим скрипт базы данных и Dockerfile в один и тот же каталог, затем укажем каталог через build.content в docker-compose.yml.

Фото автора
secondkill-mysql:
  # Установка каталога для скрипта сборки dockerfile
  build:
    context: ./db
  environment:
   # Установка пароля базы данных 
    MYSQL_ROOT_PASSWORD: 86598659yu
  restart: always
  container_name: secondkill-mysql
  image: secondkill-mysql
  ports:
    - 3306:3306
  networks:
    - app

Развертывание микросервисов

Развертывание микросервисов должно начинаться после запуска вышеуказанных контейнеров, а также должно быть подключено к сервисам вышеуказанных контейнеров.

Поэтому в конфигурационном файле application.yml необходимо заменить IP базы данных, очередь, реестра и Redis на имя хоста вышеуказанного контейнера, то есть на определенное имя хоста.

Наконец, соответствующий IP-адрес может быть найден автоматически после запуска контейнера.

spring:
  cloud:
    nacos:
      discovery:
        # secondkill-register - это имя хоста реестра
        server-addr: secondkill-register:8848
  datasource:
    druid:
      # Имя хоста базы данных: secondkill-mysql
      url: jdbc:mysql://secondkill-mysql:3306/choy_ms...
...
  redis:
    # Имя хоста redis: secondkill-redis
    host: secondkill-redis:127.0.0.1
...
  rabbitmq:
    # Имя хоста rabbitmq: secondkill-rabbitmq
    host: secondkill-rabbitmq
    port: 5672

При работе с Dockerfile необходимо обращать внимание на связь между местом хранения Dockerfile и целевым каталогом.

Поскольку весь проект извлекается, упаковывается и разворачивается на сервере через git, поместим Dockerfile под каждый микросервис, а JAR-пакет, в соответствии с командой ADD, должен предоставить целевой каталог.

Важно также при запуске микросервисов дождаться запуска сервисов центра регистрации, базы данных, Redis и очереди. Иначе запуск микросервисов будет неудачным. Для отсрочки запуска следует использовать команду sleep или конфигурацию шаблона docker-compose.ymldepends_on.

Фото автора
# Извлечение образа java8 
FROM openjdk:8-jre
# Установка рабочего каталога
WORKDIR /build
# Копирование JAR-пакета 
ADD ./target/secondkill-order-1.1.0.jar ./secondkill-order.jar
# Открытый порт 
EXPOSE 8010
# Чтобы запустить пакет JAR, необходимо отложить запуск и подождать, пока запустятся другие сервисы
CMD sleep 40; java -jar secondkill-order.jar

Следующим будет файл docker-compose.ymldocker-compose.yml хранится в корневом каталоге всего проекта.

В build.content необходимо задать относительный путь к Dockerfile под каждым сервисом.

Фото автора
secondkill-order:
  # Установка относительного пути к сервису, соответствующему Dockerfile
  build:
    context: ./secondkill-service/secondkill-order
  ports:
    - 8010:8010
  restart: always
  container_name: secondkill-order
  hostname: secondkill-order
  networks:
    - app

Установим относительный путь к сервису, соответствующему Dockerfile.

# Указание номера версии 
version: '3'
services:
  # Сервис реестра
  secondkill-register:
    # Образ nacos-1.4.2
    image: nacos/nacos-server:1.4.2
    # Метод перезапуска (Restart): always
    restart: always
    # Маппинг портов
    ports:
      - 8848:8848
    # Имя контейнера 
    container_name: secondkill-register
    # Имя хоста
    hostname: secondkill-register
    # Переменная среды, установка режима запуска на автономный запуск
    environment:
      MODE: standalone
    # Добавление в веб-приложение
    networks:
      - app

  # Сервис базы данных 
  secondkill-mysql:
    # База данных соответствует каталогу Dockerfile
    build:
      context: ./db
    # Установка пароля базы данных
    environment:
      MYSQL_ROOT_PASSWORD: 86598659yu
    restart: always
    container_name: secondkill-mysql
    image: secondkill-mysql
    ports:
      - 3306:3306
    networks:
      - app

  # Сервис redis
  secondkill-redis:
    # Образ redis-3.2
    image: redis:3.2
    ports:
      - 6379:6379
    restart: always
    container_name: secondkill-redis
    hostname: secondkill-redis
    networks:
      - app

  # Сервис rabbitmq
  secondkill-rabbitmq:
    # Образ rabbitmq-3.8.4
    image: rabbitmq:3.8.4
    ports:
      - 5672:5672
      - 15672:15672
    restart: always
    container_name: secondkill-rabbitmq
    hostname: secondkill-rabbitmq
    networks:
      - app

# Далее следуют микросервисы 

  # Сервис шлюза 
  secondkill-zuul:
    # Сервис шлюза соответствует пути Dockerfile
    build:
      context: ./secondkill-zuul
    ports:
      - 8000:8000
    restart: always
    container_name: secondkill-zuul
    hostname: secondkill-zuul
    networks:
      - app

  # Сервис аутентификации 
  secondkill-auth:
    # Сервис аутентификации соответствует пути Dockerfile
    build:
      context: ./secondkill-auth
    ports:
      - 8002:8002
    restart: always
    container_name: secondkill-auth
    hostname: secondkill-auth
    networks:
      - app

  # Сервис продукта
  secondkill-goods:
    # Сервис продукта соответствует пути Dockerfile
    build:
      context: ./secondkill-service/secondkill-goods
    ports:
      - 8021:8021
    restart: always
    container_name: secondkill-goods
    hostname: secondkill-goods
    networks:
      - app

  # Сервис заказов
  secondkill-order:
    # Сервис заказов соответствует пути Dockerfile
    build:
      context: ./secondkill-service/secondkill-order
    ports:
      - 8010:8010
    restart: always
    container_name: secondkill-order
    hostname: secondkill-order
    networks:
      - app

  # Пользовательский сервис 
  secondkill-user:
    # Пользовательский сервис соответствует пути Dockerfile
    build:
      context: ./secondkill-service/secondkill-user
    ports:
      - 8001:8001
    restart: always
    container_name: secondkill-user
    hostname: secondkill-user
    networks:
      - app

# Установка app в качестве сети
networks:
  app:

Развертывание сервиса

Сначала нужно извлечь проект на сервер. В данном случае берем его прямо из репозитория Github, затем входим в проект и выполняем mvn clean && mvn package для упаковки и компиляции проекта.

Фото автора

Затем выполняем docker-compose up -d для оркестрации и запуска контейнера.

Фото автора

На этом сервере установлен portainer. Можно напрямую войти в portainer для просмотра состояния контейнеров. Нажмите на имя каждого контейнера, чтобы посмотреть вывод запуска сервера.

Фото автора
Фото автора

Можно также напрямую войти в центр регистрации Nacos, чтобы просмотреть статус регистрации сервиса.

Если же потребуется остановить все сервисы и удалить контейнер, используйте команду docker-compose down.

https://t.me/ai_machinelearning_big_data

источник

Report Page