1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/kingofhua-docker-lnmp

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Это зеркальный репозиторий, синхронизируется ежедневно с исходного репозитория.
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

LNMP — взаимодействие между контейнерами Docker

Описание

Это пример взаимодействия между несколькими контейнерами Docker. В данном случае используется популярная технологическая стэк LNMP (Nginx + PHP + MySQL).

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

Сервисы

В файле docker-compose.yml определены три сервиса: nginx, php и mysql.

services:
    nginx:
        image: "${DOCKER_USER}/lnmp-nginx:v1.2"
        build:
            context: .
            dockerfile: Dockerfile.nginx
        ...
    php:
        image: "${DOCKER_USER}/lnmp-php:v1.2"
        build:
            context: .
            dockerfile: Dockerfile.php
        ...
    mysql:
        image: mysql:5.7
        ...

Здесь mysql сервис использует образ mysql:5.7. А образы для nginx и php имеют более сложное значение. Это указывает на использование образа с таким названием, а если такого образа нет, то он будет автоматически собран с помощью команд в секции build. В одиночной среде наличие image не обязательно, достаточно указать только build. Однако при использовании Swarm требуется одинаковый образ для всех узлов, поэтому указание image позволяет собирать его локально и пушить в реестр, чтобы затем автоматически скачать нужные образы при запуске.

Имена образов могут содержать переменные окружения:

image: "${DOCKER_USER}/lnmp-nginx:v1.2"

Переменная ${DOCKER_USER} заменяется значением переменной окружения DOCKER_USER. Эта переменная может быть установлена либо в Shell через export, либо в специальном файле .env, который поддерживает Docker Compose.

DOCKER_USER=twang2218

Каждый раз при выполнении команд Docker Compose этот файл .env автоматически загружается, что удобно для настройки файла compose. Здесь определена одна переменная окружения DOCKER_USER, но можно добавить больше переменных одной на строку.

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

Образы

Образ mysql сервиса

Образ mysql сервиса использует официальный Docker образ.

    mysql:
        image: mysql:5.7
        ...
        environment:
            TZ: 'Asia/Shanghai'
            MYSQL_ROOT_PASSWORD: Passw0rd
        command: ['mysqld', '--character-set-server=utf8']
        ...

В этом примере MySQL база данных инициализируется паролем Passw0rd, а также устанавливается часовой пояс через переменную окружения TZ.

Также переопределён командный вызов контейнера, добавив параметр --character-set-server=utf8, который устанавливает дефолтное кодировочное пространство.

Образ nginx сервиса

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

FROM nginx:1.11
ENV TZ=Asia/Shanghai
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY ./site /usr/share/nginx/html

Настройка образа очень проста: устанавливаем часовой пояс и копируем конфигурационные файлы и директорию сайтов в соответствующие места.

Образ php сервиса

Образ php сервиса отличается тем, что официальные образы PHP не предоставляют плагины для подключения к MySQL. Поэтому здесь показывается как создать свой собственный образ на основе официального, добавив необходимые плагины.

См. соответствующий файл Dockerfile.php:

FROM php:7-fpm

ENV TZ=Asia/Shanghai

COPY sources.list /etc/apt/sources.list

RUN set -xe \
    && echo "Building dependencies" \
    && buildDeps=" \
        build-essential \
        php5-dev \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng12-dev \
    " \
    && echo "Runtime dependencies" \
    && runtimeDeps=" \
        libfreetype6 \
        libjpeg62-turbo \
        libmcrypt4 \
        libpng12-0 \
    " \
    && echo "Installing PHP and building components" \
    && apt-get update \
    && apt-get install -y ${runtimeDeps} ${buildDeps} --no-install-recommends \
    && echo "Compiling PHP extensions" \
    && docker-php-ext-install iconv mcrypt mysqli pdo pdo_mysql zip \
    && docker-php-ext-configure gd \
        --with-freetype-dir=/usr/include/ \
        --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install gd \
    && echo "Cleaning up" \
    && apt-get purge -y --auto-remove \
        -o APT::AutoRemove::RecommendsImportant=false \
        -o APT::AutoRemove::SuggestsImportant=false \
        $buildDeps \
    && rm -rf /var/cache/apt/* \
    && rm -rf /var/lib/apt/lists/*

COPY ./php.conf /usr/local/etc/php/conf.d/php.conf
COPY ./site /usr/share/nginx/html

Первая часть просто указывает базовый образ php:7-fpm, устанавливает часовой пояс и заменяет источники пакетов на китайский источник, чтобы избежать проблем с блокировками доступа к интернету. Далее следует длинная команда RUN, которая выполняет установку и сборку PHP расширений.

Новички Docker часто путают Dockerfile с shell скриптами и используют много команд RUN, каждая из которых представляет отдельную команду. Это неверный подход, так как приводит к увеличению размера образа. Каждая команда в Dockerfile должна быть направлена на изменение текущего слоя, следуя лучшим практикам, чтобы минимизировать количество слоёв и очистить лишние файлы после завершения сборки.

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

В конце Dockerfile копируются конфигурационные файлы и директория сайта в соответствующие места.

Сеть

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

В конце файла docker-compose.yml определяются два пользовательских сети: frontend и backend.

networks:
    frontend:
    backend:

Пользовательские сети могут иметь множество настроек, таких как тип драйвера сети и диапазон адресов. Но здесь они остаются пустыми, что означает использование стандартных настроек: bridge для одиночной машины и overlay для Swarm.

Для каждого сервиса в разделе services указывается, какие сети он использует.

services:
    nginx:
        ...
        networks:
            - frontend
    php:
        ...
        networks:
            - frontend
            - backend
    mysql:
        ...
        networks:
            - backend

В этом примере:

  • nginx подключается к сети frontend;
  • mysql подключается к сети backend;
  • php подключается к обоим сетям.Контейнеры, подключённые к одной сети, могут взаимодействовать друг с другом, тогда как контейнеры из разных сетей будут изолированы.

В этом примере nginx может взаимодействовать с php, а php — с mysql, потому что они находятся в одной сети. nginx и mysql же находятся в разных сетях, поэтому они не могут взаимодействовать, обеспечивая изоляцию.

Контейнеры, находящиеся в одной сети, могут обращаться друг к другу по имени сервиса. Например, в файле ./site/index.php используется имя сервиса mysql для подключения к серверу базы данных.

<?php
// Установление соединения
$conn = mysqli_connect("mysql", "root", $_ENV["MYSQL_PASSWORD"]);
...
?>

В этой части кода пароль для базы данных берётся из переменной окружения $_ENV["MYSQL_PASSWORD"], что позволяет передавать актуальные значения пароля при запуске контейнера. В данном примере пароль передаётся через переменную окружения в файле docker-compose.yml.

версия: '2'
сервисы:
...
    php:
...
        окружение:
            MYSQL_PASSWORD: Passw0rd
...

Чтобы узнать больше о пользовательских сетях Docker, можно обратиться к официальной документации: https://docs.docker.com/engine/userguide/networking/dockernetworks/#/user-defined-networks

Для получения информации о том, как использовать пользовательские сети в Docker Compose, рекомендуется ознакомиться с этой частью документации: https://docs.docker.com/compose/networking/

Хранение данных

В этих трёх сервисах, nginx и php являются бессостоятельными службами, они не требуют локального хранения данных. Однако, mysql является базой данных, которая нуждается в хранении динамических данных. В контейнерах Docker все состояние должно быть вынесено за пределы хранимых данных, поэтому все динамические данные должны быть сохранены через использование томов.

тома:
    mysql-data:

В конфигурационном файле docker-compose.yml, есть глобальная секция тома, где мы определяем названные тома. Здесь мы определили том mysql-data. Можно указывать дополнительные параметры для тома, такие как драйвер тома или его конфигурацию, но здесь используются значения по умолчанию. Это значит, что используется простой локальный драйвер тома local, и созданный названный том может находиться в директории /var/lib/docker/volumes.

В разделе конфигурации сервиса mysql, также присутствует секция тома, где указывается, какие тома должны быть смонтированы в контейнер при запуске. Мы используем ранее определенный названный том mysql-data, который монтируется в папку /var/lib/mysql внутри контейнера.

mysql:
    образ: mysql:5.7
    тома:
        - mysql-data:/var/lib/mysql
...

Зависимости

Порядок запуска сервисов иногда имеет значение. Compose позволяет контролировать порядок запуска до некоторой степени. Например, в этом примере, я использовал зависимость depends_on для настройки.


сервисы:
    nginx:
        ...
        зависит_от:
            - php
    php:
        ...
        зависит_от:
            - mysql
    mysql:
        ...

Здесь nginx зависит от php сервиса, а php сервис зависит от mysql. При выполнении команды docker-compose up -d, сервисы будут запущены в порядке зависимости: mysql -> php -> nginx.

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

Если требуется более строгое управление зависимостями между сервисами, следует использовать скрипты типа entrypoint.sh, чтобы обеспечить ожидание готовности зависимых сервисов перед запуском основного сервиса. Также можно использовать параметр restart: always, чтобы обеспечить повторную попытку запуска сервиса, если он был остановлен из-за ошибки.

Одиночные операции

Запуск

docker-compose up -d

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

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

Просмотр состояния сервисов

docker-compose ps

Просмотр журналов сервисов

docker-compose logs

Доступ к сервисам

Сервер nginx будет слушать порт 80,

  • если используется Linux или Docker for Mac, то можно обращаться к нему по адресу http://localhost
  • если используется Docker Toolbox, то следует использовать адрес виртуальной машины, такой как http://192.168.99.100. Адрес можно найти с помощью команды docker-machine ip default.
  • если используется собственная установка Ubuntu, CentOS и т.д., то следует проверять адреса внутри виртуальной машины.

Если после обращения видите сообщение «Успешное соединение с сервером MySQL», значит база данных подключена корректно.

Остановка сервисов

docker-compose down

Управление кластером Swarm

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

В кластерной среде, Swarm может распределить контейнеры на любую машину. Если одна машина выйдет из строя, контейнеры могут быть переназначены на другую машину, чтобы гарантировать продолжение работы сервиса. В таких условиях, использование привязки к каталогам хоста требует наличия и синхронизации содержимого каталогов на всех машинах. Это не лучший подход.Поэтому для удобства развертывания в кластерной среде лучше всего помещать код приложения и конфигурационные файлы прямо в образ. Как в данном примере, мы видим, что в образах nginx и php службы включены файлы конфигурации и код приложения.

Файл Dockerfile для сервиса nginx

...
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY ./site /usr/share/nginx/html

Файл Dockerfile для сервиса php

...
COPY ./php.conf /usr/local/etc/php/conf.d/php.conf
COPY ./site /usr/share/nginx/html

Docker Swarm существует в двух поколениях. Первое поколение представляет собой раннюю попытку Docker команды по организации кластеров, работающее в виде контейнера, известное как Docker Swarm; второе поколение — это версия начиная с 1.12, основанная на SwarmKit и интегрированная в docker, называемая Docker Swarm Mode.

Первое поколение Swarm

Первое поколение Swarm (https://docs.docker.com/swarm/) было первой попыткой Docker команды по организации кластеров, работавшей в виде контейнера, требовала внешнего ключ-значения хранилища (например, etcd, consul, zookeeper) и необходимости вручную настраивать overlay сети. Её конфигурация была проще, чем Kubernetes, но всё же сложнее, чем последующее поколение.

В этом примере предоставлен скрипт run1.sh, который помогает создать кластер первого поколения Swarm, запустить сервисы и масштабировать их.

Создание кластера Swarm

На машине с установленным docker-machine и VirtualBox (например, с Docker Toolbox для Mac/Windows), можно использовать скрипт run1.sh для создания кластера:

./run1.sh create

Запуск

./run1.sh up

Масштабирование

./run1.sh scale 3 5

Первый параметр указывает количество контейнеров nginx, второй — количество контейнеров php.

Доступ к сервисам

Сервер nginx будет слушать порт OnClickListener. Используйте команду docker ps, чтобы получить информацию о конкретном узле кластера, где работает nginx, и его IP-адрес.

$ eval $(./run1.sh env)
$ docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                                NAMES
d85a2c26dd7d        twang2218/lnmp-php:v1.2     "php-fpm"                9 минут назад       Up 9 минут          9000/tcp                             node1/dockerlnmp_php_5
c81e169c164d        twang2218/lnmp-php:v1.2     "php-fpm"                9 минут назад       Up 9 минут          9000/tcp                             node1/dockerlnmp_php_2
b43de77c9340        twang2218/lnmp-php:v1.2     "php-fpm"                9 минут назад       Up 9 минут          9000/tcp                             master/dockerlnmp_php_4
fdcb718b6183        twang2218/lnmp-php:v1.2     "php-fpm"                9 минут назад       Up 9 минут          9000/tcp                             node3/dockerlnmp_php_3
764b10b17dc4        twang2218/lnmp-nginx:v1.2   "nginx -g 'daemon off"   9 минут назад       Up 9 минут          192.168.99.104:80->80/tcp, 443/tcp   master/dockerlnmp_nginx_3
e92b34f998bf        twang2218/lnmp-nginx:v1.2   "nginx -g 'daemon off"   9 минут назад       Up 9 минут          192.168.99.106:80->80/tcp, 443/tcp   node2/dockerlnmp_nginx_2
077ee73c8148        twang2218/lnmp-nginx:v1.2   "nginx -g 'daemon off"   22 минут назад      Up 22 минут         192.168.99.105:80->80/tcp, 443/tcp   node3/dockerlnmp_nginx_1
1931249a66c1        e8920543aee8                "php-fpm"                22 минут назад      Up 22 минут         9000/tcp                             node2/dockerlnmp_php_1
cf71bca309dd        mysql:5.7                   "docker-entrypoint.sh"   22 минут назад      Up 22 минут         3306/tcp                             node1/dockerlnmp_mysql_1

В таком случае, можно использовать http://192.168.99.104, http://192.168.99.105, http://192.168.99.106 для доступа к сервисам.

Остановка сервисов

./run1.sh down

Удаление кластера

./run1.sh remove

Второе поколение Swarm (Swarm Mode)

Второе поколение Swarm (https://docs.docker.com/engine/swarm/), или Docker Swarm Mode, было введено с версии 1.12 и представляет собой встроенную систему управления кластерами Docker. Она значительно отличается от первого поколения Swarm и существенно упрощает процесс создания кластера. Внутренний дистрибутивный базовый набор данных заменил необходимость настройки внешних ключ-значения хранилищ; внутренняя нагрузочная балансировка уровня ядра заменила необходимость настройки внешней нагрузочной балансировки; и внутренняя граница нагрузочной балансировки заменила необходимость настройки внешней границы нагрузочной балансировки.

Как и в примере с первым поколением Swarm, для удобства объяснения здесь представлен скрипт run2.sh, который поможет создать кластер, запустить сервисы и масштабировать их.

Создание кластера Swarm

На машине с установленным docker-machine и VirtualBox (например, с Docker Toolbox для Mac/Windows), можно использовать скрипт run2.sh для создания кластера:

./run2.sh create

Использование облачных сервисов, таких как DigitalOcean, AWS, не требует использования VirtualBox, однако необходимо предварительно настроить соответствующие переменные окружения для docker-machine.

Запуск

./run2.sh up

Масштабирование

./run2.sh scale 10 5

Первый параметр указывает количество контейнеров nginx, второй — количество контейнеров php.

Выбор сервисов и их состояние

Можно использовать стандартные команды для выбора всех сервисов и их состояния:

docker service ls

Мы также можем использовать следующие команды для вывода состояния каждого контейнера, связанного с каждым сервисом:

docker container ls --all
``````bash
$ ./run2.sh ps
+ docker service ps -f desired-state=running nginx
ID                         NAME      IMAGE                      NODE     DESIRED STATE  CURRENT STATE           ERROR
87xr5oa577hl9amelznpy7s7z  nginx.1   twang2218/lnmp-nginx:v1.2  node2    Running        Running 3 hours ago
7dwmc22qaftz0xrvijij9dnuw  nginx.2   twang2218/lnmp-nginx:v1.2  node3    Running        Running 22 minutes ago
00rus0xed3y851pcwkbybop80  nginx.3   twang2218/lnmp-nginx:v1.2  manager  Running        Running 22 minutes ago
5ypct2dnfu6ducnokdlk82dne  nginx.4   twang2218/lnmp-nginx:v1.2  manager  Running        Running 22 minutes ago
7qshykjq8cqju0zt6yb9dkktq  nginx.5   twang2218/lnmp-nginx:v1.2  node2    Running        Running 22 minutes ago
e2cux4vj2femrb3wc33cvm70n  nginx.6   twang2218/lnmp-nginx:v1.2  node1    Running        Running 22 minutes ago
9uwbn5tm49k7vxesucym4plct  nginx.7   twang2218/lnmp-nginx:v1.2  node1    Running        Running 22 minutes ago
6d8v5asrqwnz03hvm2jh96rq3  nginx.8   twang2218/lnmp-nginx:v1.2  node1    Running        Running 22 minutes ago
eh44qdsiv7wq8jbwh2sr30ada  nginx.9   twang2218/lnmp-nginx:v1.2  node3    Running        Running 22 minutes ago
51l7nirwtv4gxnzbhkx6juvko  nginx.10  twang2218/lnmp-nginx:v1.2  node2    Running        Running 22 minutes ago
+ docker service ps -f desired-state=running php
ID                         NAME   IMAGE                    NODE     DESIRED STATE  CURRENT STATE           ERROR
4o3pqdva92vjdbfygdn0agp32  php.1  twang2218/lnmp-php:v1.2  manager  Running        Running 3 hours ago
bf3d6g4rr8cax4wucu9lixgmh  php.2  twang2218/lnmp-php:v1.2  node3    Running        Running 22 minutes ago
9xq9ozbpea7evllttvyxk7qtf  php.3  twang2218/lnmp-php:v1.2  manager  Running        Running 22 minutes ago
8umths3p8rqib0max6b6wiszv  php.4  twang2218/lnmp-php:v1.2  node2    Running        Running 22 minutes ago
0fxe0i1n2sp9nlvfgu4xlc0fx  php.5  twang2218/lnmp-php:v1.2  node1    Running        Running 22 minutes ago
+ docker service ps -f desired-state=running mysql
ID                         NAME     IMAGE      NODE   DESIRED STATE  CURRENT STATE        ERROR
3ozjwfgwfcq89mu7tqzi1hqeu  mysql.1  mysql:5.7  node3  Running        Running 3 hours ago

Доступ к сервисам

Сервис nginx будет прослушивать порт 80. Поскольку второе поколение Swarm имеет сетевую маршрутизацию (Routing Mesh) и балансировку нагрузки, все узлы в кластере будут прослушивать порт 80, будь то менеджеры или рабочие ноды, даже если нет контейнеров nginx, запущенных на этих нодах. Когда какой-либо узел получает запрос на порт 80, он автоматически перенаправляет его на нужный контейнер через overlay-сети. Поэтому доступ к любому узлу по порту 80 должен показывать работу сервиса.

Используйте следующую команду для получения списка всех узлов. Адрес любого из этих узлов должен отображать страницу приложения:

$ ./run2.sh nodes
manager   http://192.168.99.101
node1     http://192.168.99.103
node2     http://192.168.99.102
node3     http://192.168.99.104

Остановка сервиса

./run2.sh down

Удаление кластера

./run2.sh remove

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Создайте LNMP-среду с помощью контейнера Docker. Развернуть Свернуть
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://gitlife.ru/oschina-mirror/kingofhua-docker-lnmp.git
git@gitlife.ru:oschina-mirror/kingofhua-docker-lnmp.git
oschina-mirror
kingofhua-docker-lnmp
kingofhua-docker-lnmp
master