One place for hosting & domains

      помощью

      Создание резервного пула хранения данных с помощью GlusterFS в Ubuntu 20.04


      Предыдущая версия данного обучающего руководства была написана Джастином Эллингвудом.

      Введение

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

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

      Цели

      В этом обучающем руководстве мы создадим резервный кластерный массив хранилищ, известный также как распределенная файловая система, или, как указано в документации GlusterFS, доверенный пул хранения данных (Trusted Storage Pool).​​​ Это обеспечит функциональность, аналогичную зеркальной конфигурации RAID в сети: каждый независимый сервер будет содержать свою собственную копию данных, позволяя приложениям получать доступ к любой копии, тем самым облегчая распределение нагрузки чтения.

      Этот избыточный кластер GlusterFS будет состоять из двух серверов Ubuntu 20.04. И будет действовать примерно так же, как сервер NAS с зеркальным RAID. Затем вы получите доступ к кластеру с третьего сервера Ubuntu 20.04, настроенного для работы в качестве клиента GlusterFS.

      Примечание о безопасном функционировании GlusterFS

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

      По этой причине, если вы собираетесь использовать GlusterFS в производственной среде, рекомендуется использовать его в изолированной сети. Например, вы можете настроить его для запуска в виртуальном частном облаке (VPC) или с помощью VPN, работающей между каждым из узлов.

      Если вы планируете развернуть GlusterFS в DigitalOcean, можно настроить его в изолированной сети, добавив инфраструктуру вашего сервера в виртуальное частное облако DigitalOcean. Дополнительную информацию о настройке смотрите в документации по VPC.

      Предварительные требования

      Для выполнения данного обучающего руководства вам понадобится три сервера, работающих на Ubuntu 20.04. Каждый сервер должен иметь пользователя non-root user с правами администратора, а также брандмауэр, настроенный с помощью UFW. Чтобы выполнить настройку, воспользуйтесь руководством по начальной настройке сервера Ubuntu 20.04.

      Примечание. Как указано в разделе «Цели», это обучающее руководство покажет вам, как настроить два ваших сервера Ubuntu для работы в качестве серверов пула хранения данных, а оставшийся сервер — в качестве клиента, который вы будете использовать для доступа к этим узлам.

      Для ясности в этом обучающем модуле будут использоваться компьютеры со следующими именами хостов:

      Имя хоста Роль в пуле хранения данных
      gluster0 Сервер
      gluster1 Сервер
      gluster2 Клиент

      Команды, которые следует запускать в gluster0 или gluster1, записываются на голубом или розовом фоне соответственно:

      Команды, которые следует запускать исключительно на клиенте (gluster2), имеют зеленый фон:

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

      Шаг 1 — Настройка разрешения DNS на каждом компьютере

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

      Если у вас нет свободного доменного имени, а также если вы хотите быстро что-то настроить, вы можете отредактировать файл /etc/host на каждом компьютере. Это специальный файл на компьютерах с ОС Linux, где вы можете статически настроить систему для разрешения любых имен хоста, содержащихся в файле, в статические IP-адреса.

      Примечание. Если вы хотите настроить ваши серверы для аутентификации доменом, которым владеете, сначала вам понадобится получить доменное имя у регистратора, например у Namecheap или Enom, и настроить соответствующие записи DNS.

      После настройки записи A для каждого сервера вы можете перейти к шагу 2. По мере выполнения данного руководства не забывайте менять glusterN.example.com и glusterN на доменное имя, которое указывает на соответствующий сервер, упоминаемый в примере команды.

      Если вы взяли инфраструктуру из DigitalOcean, вы можете добавить ваше доменное имя в DigitalOcean, а затем настроить уникальную запись А для каждого сервера.

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

      По умолчанию файл будет выглядеть примерно так, если удалить комментарии:

      /etc/hosts

      127.0.1.1 hostname hostname
      127.0.0.1 localhost
      
      ::1 ip6-localhost ip6-loopback
      fe00::0 ip6-localnet
      ff00::0 ip6-mcastprefix
      ff02::1 ip6-allnodes
      ff02::2 ip6-allrouters
      ff02::3 ip6-allhosts
      

      На одном из ваших серверов Ubuntu добавьте сначала IP-адрес каждого сервера, а затем любые имена, которые вы хотите использовать для указания в командах под определением локального хоста.

      В следующем примере каждому серверу дается длинное имя хоста, соответствующее glusterN.example.com и короткое имя, соответствующее glusterN. Вы можете менять в каждой строке части glusterN.example.com и glusterN на любое имя или имена, отделенные одиночным интервалом, которые вы бы хотели использовать для доступа к каждому серверу. Однако обратите внимание, что в данном обучающем руководстве будут использоваться следующие примеры:

      Примечание. Если ваши серверы являются частью пула инфраструктуры виртуального частного облака, вам следует использовать частный IP-адрес каждого сервера в файле /etc/hosts, а не публичные IP-адреса.

      /etc/hosts

      . . .
      127.0.0.1       localhost
      first_ip_address gluster0.example.com gluster0
      second_ip_address gluster1.example.com gluster1
      third_ip_address gluster2.example.com gluster2
      
      . . .
      

      После того, как вы добавите все новые строки в файл /etc/hosts одного компьютера, скопируйте их и добавьте в файлы /etc/hosts других компьютеров. Каждый файл /etc/host должен содержать одинаковые строки, которые привязывают IP-адреса ваших серверов к именам, которые вы выбрали.

      Сохраните и закройте каждый файл после завершения. Для этого, если вы используете nano, нажмите CTRL+X, Y, затем ENTER.

      Теперь, когда вы настроили разрешение имени хоста между каждым сервером, вам будет проще в последствии запускать команды, так как вы установили пул и том хранения данных. Далее вы можете переходить к следующему шагу, который нужно выполнить для каждого сервера. Добавьте в каждый из трех серверов Ubuntu официальный архив персональных пакетов (PPA) проекта Gluster, чтобы обеспечить возможность установки новейшей версии GlusterFS.

      Шаг 2 — Настройка источников программного обеспечения на каждом компьютере

      Хотя репозитории APT по умолчанию для Ubuntu 20.04 содержат пакеты GlusterFS, на момент написания данного руководства они не являются последними версиями. Один из способов установки последней стабильной версии GlusterFS (версия 7.6 на момент написания) — добавление официального архива персонального пакета (РРА) проекта Gluster для каждого из трех серверов Ubuntu.

      Добавьте PPA для пакетов GlusterFS путем запуска следующей команды на каждом сервере:

      • sudo add-apt-repository ppa:gluster/glusterfs-7

      Нажмите ENTER, когда вам будет предложено подтвердить намерение добавить РРА.

      После добавления PPA, обновите локальный индекс пакетов каждого сервера. Это сообщит системе о наличии новых пакетов:

      После добавления официального PPA проекта Gluster для каждого сервера и обновления локального индекса пакетов вы сможете установить необходимые пакеты GlusterFS. Однако поскольку два из трех компьютеров будут работать как серверы Gluster, а третий — как клиент, вам понадобится выполнить две отдельные процедуры установки и настройки. Сначала вы установите и настроите компоненты сервера.

      Шаг 3 — Установка компонентов сервера и создание доверенного пула хранения данных

      Пул хранения данных — это любой объем емкости хранения данных от более чем одного ресурса хранения. На этом шаге вы настроите два сервера — gluster0 и gluster1 — в качестве компонентов кластера.

      Установите пакет сервера GlusterFS на gluster0 и на gluster1 с помощью команды:

      • sudo apt install glusterfs-server

      При запросе нажмите Y, а затем ENTER, чтобы подтвердить установку.

      Процесс установки автоматически настроит GlusterFS для запуска в качестве службы systemd. Однако он не запускает службу автоматически и не обеспечивает запуск при загрузке.

      Для запуска glusterd, службы GlusterFS, запустите команду systemctl start на gluster0 и на gluster1:

      • sudo systemctl start glusterd.service

      Затем запустите следующую команду на обоих серверах. Это позволит запускать службу при каждой загрузке сервера:

      • sudo systemctl enable glusterd.service

      После этого вы сможете проверить статус службы на каждом или на обоих серверах:

      • sudo systemctl status glusterd.service

      Если служба активирована и работает, вы получите следующий вывод:

      Output

      ● glusterd.service - GlusterFS, a clustered file-system server Loaded: loaded (/lib/systemd/system/glusterd.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2020-06-02 21:32:21 UTC; 32s ago Docs: man:glusterd(8) Main PID: 14742 (glusterd) Tasks: 9 (limit: 2362) CGroup: /system.slice/glusterd.service └─14742 /usr/sbin/glusterd -p /var/run/glusterd.pid --log-level INFO

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

      Демон Gluster использует порт 24007, поэтому вам нужно разрешить каждому узлу доступ к этому порту через брандмауэр каждого из узлов в пуле хранения данных. Для этого запустите следующую команду на gluster0. Не забудьте поменять gluster1_ip_address на IP-адрес gluster1:

      • sudo ufw allow from gluster1_ip_address to any port 24007

      Запустите следующую команду на gluster1. Снова не забудьте поменять gluster0_ip_address на IP-адрес gluster0:

      • sudo ufw allow from gluster0_ip_address to any port 24007

      Также вам потребуется разрешить вашему клиентскому компьютеру (gluster2) доступ к этому порту. Иначе позже вы столкнетесь с проблемами, когда попытаетесь смонтировать том. Запустите следующую команду на gluster0 и на gluster1, чтобы открыть этот порт для вашего клиентского компьютера:

      • sudo ufw allow from gluster2_ip_address to any port 24007

      Затем добавьте общее правило deny на gluster0 и на gluster1, чтобы закрыть доступ любым другим компьютерам к порту Gluster на любом из серверов.

      Теперь вы готовы к установке связи между gluster0 и gluster1. Для этого вам нужно запустить команду gluster peer probe на одном из узлов. Не имеет значения, какой из узлов вы будете использовать, но в следующем примере команда запускается на gluster0:

      • sudo gluster peer probe gluster1

      Фактически эта команда сообщает gluster0 доверять gluster1 и регистрирует его как часть пула хранения данных. Если зондирование пройдет успешно, вы получите следующий вывод:

      Output

      peer probe: success

      Вы можете проверить связь узлов в любое время путем запуска команды gluster peer status на любом из них. В этом примере команда выполняется на gluster1:

      Если вы запустите эту команду из gluster1, вы увидите следующий вывод:

      Output

      Number of Peers: 1 Hostname: gluster0.example.com Uuid: a3fae496-c4eb-4b20-9ed2-7840230407be State: Peer in Cluster (Connected)

      На этом этапе два ваших сервера взаимодействуют и готовы к созданию томов хранения друг с другом.

      Шаг 4 — Создание тома хранения

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

      Для создания тома вы будете использовать команду gluster volume create с таким общим синтаксисом:

      sudo gluster volume create volume_name replica number_of_servers domain1.com:/path/to/data/directory domain2.com:/path/to/data/directory force
      

      Вот что означают аргументы и опции команды gluster volume create:

      • volume_name: это имя, которое вы будете использовать для ссылки на том после его создания. Следующий пример команды создает том с именем volume1.
      • replica number_of_servers: после имени тома вы можете указать, какой тип тома вы хотите создать. Напомним, что цель данного обучающего руководства — создать резервный пул хранения данных, поэтому мы будем использовать тип тома replica. Для этого требуется аргумент с указанием количества серверов, на которые будут воспроизводиться данные (2 в нашем примере).
      • domain1.com:/… и domain2.com:/…: определяют расположение компьютеров и каталогов блоков (термин GlusterFS, используемый для обозначения базовой единицы хранения, включающей любой каталог, используемый в качестве части или копии большего тома, на любом компьютере), которые составят volume1. В следующем примере будет создан каталог с именем gluster-storage в корневом каталоге на обоих серверах.
      • force: эта опция отменяет любые предупреждения или опции, которые могли бы возникнуть и остановить создание тома.

      Используя правила, установленные ранее в данном обучающем руководстве, вы можете запустить эту команду для создания тома. Обратите внимание, что вы можете запускать ее либо с gluster0, либо с gluster1:

      • sudo gluster volume create volume1 replica 2 gluster0.example.com:/gluster-storage gluster1.example.com:/gluster-storage force

      Если том был создан успешно, вы увидите следующий вывод:

      Output

      volume create: volume1: success: please start the volume to access data

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

      • sudo gluster volume start volume1

      Вы получите следующий вывод, если том запущен корректно:

      Output

      volume start: volume1: success

      Затем проверьте, находится ли том в сети. Запустите следующую команду с любого из ваших узлов:

      • sudo gluster volume status

      В результате вы увидите вывод, аналогичный данному:

      Output

      Status of volume: volume1 Gluster process TCP Port RDMA Port Online Pid ------------------------------------------------------------------------------ Brick gluster0.example.com:/gluster-storage 49152 0 Y 18801 Brick gluster1.example.com:/gluster-storage 49152 0 Y 19028 Self-heal Daemon on localhost N/A N/A Y 19049 Self-heal Daemon on gluster0.example.com N/A N/A Y 18822 Task Status of Volume volume1 ------------------------------------------------------------------------------ There are no active volume tasks

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

      В качестве последнего шага по настройке тома вам нужно будет открыть брандмауэр на обоих серверах, чтобы ваш клиентский компьютер смог подключиться и смонтировать том. Согласно выводу предыдущего примера команды volume1 работает на порту 49152 на обоих компьютерах. Это порт GlusterFS по умолчанию, который используется для первоначального тома, а следующий том, который вы создадите, будет использовать порт 49153, затем 49154 и т. д.

      Запустите следующую команду на gluster0 и gluster1, чтобы разрешить gluster2 доступ к этому порту через соответствующий брандмауэр каждого из них:

      • sudo ufw allow from gluster2_ip_address to any port 49152

      Затем для дополнительной защиты добавьте другое общее правило deny для порта тома на обоих серверах gluster0 и gluster1. Это закроет доступ к тому на любом из двух серверов каким-либо другим компьютерам, кроме вашего клиентского компьютера:

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

      Шаг 5 — Установка и настройка компонентов клиента

      Теперь ваш том настроен и доступен для использования клиентским компьютером. Но перед тем, как начать работу, вам нужно установить пакет glusterfs-client из архива РРА, загруженного на клиентский компьютер на шаге 1. Зависимости этого пакета включают некоторые из общих библиотек и модулей переводчиков GlusterFS, а также необходимые для работы инструменты FUSE.

      Запустите следующую команду на gluster2:

      • sudo apt install glusterfs-client

      Вскоре вы сможете монтировать удаленный том хранения на клиентском компьютере. Однако перед этим вам нужно создать точку монтирования. Традиционно она находится в каталоге /mnt, но может использоваться, где вам удобно.

      Для удобства создайте каталог с именем /storage-pool на клиентском компьютере для использования в качестве точки монтирования. Имя каталога начинается с косой черты (/), которая помещает его в корневой каталог, поэтому вам нужно создать его с привилегиями sudo:

      Теперь вы можете монтировать удаленный том. Но прежде обратите внимание на синтаксис команды mount, которая используется для этого:

      sudo mount -t glusterfs domain1.com:volume_name /path/to/mount/point
      

      mount — это утилита, которая встречается во многих операционных системах типа Unix. Она используется для монтирования файловых систем — от внешних устройств хранения (таких как SD-карты или USB-накопители) и сетевых систем хранения (как в случае данного обучающего модуля) до каталогов в существующей файловой системе компьютера. В синтаксис команды mount входит опция -t, требующая трех аргументов: тип монтируемой файловой системы, устройство, где находится монтируемая файловая система, и каталог на клиентском компьютере, куда будет монтироваться том.

      Обратите внимание, что в синтаксисе данного примера, аргумент устройства указывает на имя хоста, после которого стоит двоеточие, а затем имя тома. GlusterFS извлекает фактические каталоги хранения на каждом хосте, что означает, что данная команда предназначена для монтирования не каталога /gluster-storage, а тома volume1.

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

      Запустите следующую команду на клиентском компьютере (gluster2) для монтирования тома в созданный вами каталог /storage-pool:

      • sudo mount -t glusterfs gluster0.example.com:/volume1 /storage-pool

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

      Эта команда покажет, что том GlusterFS смонтирован в правильном расположении:

      Output

      Filesystem 1K-blocks Used Available Use% Mounted on . . . gluster0.example.com:/volume1 50633164 1938032 48695132 4% /storage-pool

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

      Шаг 6 — Тестирование функций резервирования

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

      На клиентском компьютере (gluster2) перейдите к точке монтирования, которая была определена на предыдущем шаге:

      Затем создайте несколько тестовых файлов. Следующая команда создает десять отдельных пустых файлов в пуле хранения данных:

      • sudo touch file_{0..9}.test

      Если вы посмотрите на каталоги хранения, которые вы определили ранее на каждом хосте хранения, вы обнаружите, что все эти файлы присутствуют на каждой системе.

      На gluster0:

      Output

      file_0.test file_2.test file_4.test file_6.test file_8.test file_1.test file_3.test file_5.test file_7.test file_9.test

      Также на gluster1:

      Output

      file_0.test file_2.test file_4.test file_6.test file_8.test file_1.test file_3.test file_5.test file_7.test file_9.test

      Как показывают эти выводы, тестовые файлы, которые вы добавили на клиентском компьютере, также были записаны на обоих узлах.

      Если один из узлов кластера хранения не будет работать, он может выйти из синхронизации с пулом хранения при внесении каких-либо изменений в файловую систему. Операция чтения в точке монтирования на клиентском компьютере после возвращения узла в режим онлайн предупредит узел о необходимости получить недостающие файлы:

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

      Шаг 7 — Ограничение функций резервирования

      На этом этапе любой компьютер может подключаться к вашему тому хранения данных без каких-либо ограничений. Это можно изменить, настроив опцию auth.allow, определяющую IP-адреса клиентов, которые должны иметь доступ к тому.

      Если вы используете конфигурацию /etc/host, имена, которые вы установили для каждого сервера,будут отслеживаться некорректно. Вместо этого следует использовать статический IP-адрес. С другой стороны, если вы используете записи DNS, настроенное вами доменное имя будет работать.

      На одном из узлов хранения (gluster0 или gluster1) запустите следующую команду:

      • sudo gluster volume set volume1 auth.allow gluster2_ip_address

      Если команда выполняется успешно, вы увидите следующий вывод:

      Output

      volume set: success

      Если вам нужно удалить ограничение в любой точке, вы можете ввести следующее:

      • sudo gluster volume set volume1 auth.allow *

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

      Если у вас несколько клиентских компьютеров, вы можете одновременно указать их IP-адреса или доменные имена (в зависимости от того, используете ли вы /etc/hosts или разрешение имени хоста DNS), разделенные запятыми:

      • sudo gluster volume set volume1 auth.allow gluster_client1_ip,gluster_client2_ip

      Теперь ваш пул хранения настроен, защищен и готов к использованию. Далее мы рассмотрим несколько команд, которые помогут вам получить информацию о состоянии вашего пула хранения данных.

      Шаг 8 — Получение информации о пуле хранения данных с помощью команд GlusterFS

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

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

      Если вам нужна информация о каждом томе, запустите команду gluster volume info:

      Output

      Volume Name: volume1 Type: Replicate Volume ID: a1e03075-a223-43ab-a0f6-612585940b0c Status: Started Snapshot Count: 0 Number of Bricks: 1 x 2 = 2 Transport-type: tcp Bricks: Brick1: gluster0.example.com:/gluster-storage Brick2: gluster1.example.com:/gluster-storage Options Reconfigured: auth.allow: gluster2_ip_address transport.address-family: inet storage.fips-mode-rchecksum: on nfs.disable: on performance.client-io-threads: off

      Также для получения информации о подключениях данного узла, вы можете ввести:

      Number of Peers: 1
      
      Hostname: gluster0.example.com
      Uuid: cb00a2fc-2384-41ac-b2a8-e7a1793bb5a9
      State: Peer in Cluster (Connected)
      

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

      • sudo gluster volume profile volume_name start

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

      • sudo gluster volume profile volume_name info

      Output

      Brick: gluster0.example.com:/gluster-storage -------------------------------------------- Cumulative Stats: %-latency Avg-latency Min-Latency Max-Latency No. of calls Fop --------- ----------- ----------- ----------- ------------ ---- 0.00 0.00 us 0.00 us 0.00 us 30 FORGET 0.00 0.00 us 0.00 us 0.00 us 36 RELEASE 0.00 0.00 us 0.00 us 0.00 us 38 RELEASEDIR Duration: 5445 seconds Data Read: 0 bytes Data Written: 0 bytes Interval 0 Stats: %-latency Avg-latency Min-Latency Max-Latency No. of calls Fop --------- ----------- ----------- ----------- ------------ ---- 0.00 0.00 us 0.00 us 0.00 us 30 FORGET 0.00 0.00 us 0.00 us 0.00 us 36 RELEASE 0.00 0.00 us 0.00 us 0.00 us 38 RELEASEDIR Duration: 5445 seconds Data Read: 0 bytes Data Written: 0 bytes . . .

      Как показано ранее, чтобы получить список всех связанных компонентов GlusterFS, работающих на каждом узле, запустите команду gluster volume status:

      • sudo gluster volume status

      Output

      Status of volume: volume1 Gluster process TCP Port RDMA Port Online Pid ------------------------------------------------------------------------------ Brick gluster0.example.com:/gluster-storage 49152 0 Y 19003 Brick gluster1.example.com:/gluster-storage 49152 0 Y 19040 Self-heal Daemon on localhost N/A N/A Y 19061 Self-heal Daemon on gluster0.example.com N/A N/A Y 19836 Task Status of Volume volume1 ------------------------------------------------------------------------------ There are no active volume tasks

      Если вы собираетесь управлять томами хранения GlusterFS, было бы неплохо перейти на консоль GlusterFS. Это позволит вам взаимодействовать со средой GlusterFS без необходимости ввода каждый раз команды sudo gluster:

      Будет выдана подсказка, где вводить команды. Команда help поможет вам сориентироваться:

      Output

      peer help - display help for peer commands volume help - display help for volume commands volume bitrot help - display help for volume bitrot commands volume quota help - display help for volume quota commands snapshot help - display help for snapshot commands global help - list global commands

      После завершения запустите команду exit для выхода из консоли Gluster:

      Теперь вы готовы к интеграции GlusterFS с вашим следующим приложением.

      Заключение

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



      Source link

      Развертывание Laravel 7 и MySQL в Kubernetes с помощью Helm


      Автор выбрал Diversity in Tech Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Laravel — одна из самых популярных в настоящее время инфраструктур приложений PHP с открытым исходным кодом. Обычно она развертывается с СУБД MySQL, но ее можно настроить и для других решений хранения данных. Laravel отличается использованием преимуществ современных возможностей PHP и обширной экосистемой пакетов.

      Kubernetes — платформа оркестровки контейнеров, которую можно размещать на кластерах DigitalOcean Kubernetes для упрощения администрирования, настройки и использования контейнеров в производственной среде. Helm — это диспетчер пакетов Kubernetes, упрощающий настройку и установку служб и подов в Kubernetes.

      В этом обучающем модуле вы создадите приложение Laravel PHP, добавите приложение в образ Docker и развернете этот образ в кластере DigitalOcean Kubernetes, используя чарт LAMP Helm. Затем вы настроите контроллер Ingress для добавления SSL и собственного доменного имени вашего приложения. После прохождения вы получите работающее приложение Laravel, подключенноек базе данных MySQL, запущенной на кластере Kubernetes.

      Предварительные требования

      • Система Docker, установленная на компьютере, с которого вы будете подключаться к кластеру. Подробные инструкции по установке Docker для большинства дистрибутивов Linux можно найти здесь или на сайте Docker для других операционных систем.
      • В этом обучающем модуле вы создадите учетную запись Docker Hub для хранения образов Docker.
      • Кластер DigitalOcean Kubernetes с конфигурацией подключения, настроенной с помощью kubectl по умолчанию. Процесс создания кластера Kubernetes в DigitalOcean, описан в документе «Быстрое начало работы с Kubernetes». Процедура подключения к кластеру описана в руководстве «Подключение к кластеру DigitalOcean Kubernetes».
      • Диспетчер пакетов Helm 3, установленный на локальном компьютере. Выполните первый шаг и добавьте репозиторий stable из второго шага обучающего модуля «Установка программного обеспечения в кластерах Kubernetes с помощью диспетчера пакетов Helm 3».
      • Полностью зарегистрированное доменное имя с доступной записью A. В этом обучающем руководстве мы будем использовать your_domain. Вы можете купить доменное имя на Namecheap, получить его бесплатно на Freenom или воспользоваться услугами любого предпочитаемого регистратора доменных имен. Сейчас не нужно думать о привязке записи A вашего домена к IP-адресу. Когда вы дойдете до шага 5 и ваш контроллер Ingress будет установлен, вы подключите your_domain к правильному IP-адресу.

      Шаг 1 — Создание нового приложения Laravel

      На этом шаге мы используем Docker для создания нового приложения Laravel 7, но у вас должна быть возможность выполнить эту же процедуру с существующим приложением Laravel, которое использует MySQL в качестве опорной базы данных. Создаваемое новое приложение подтверждает подключение Laravel к базе данных и отображает имя базы данных.

      Перейдите в домашний каталог и создайте новое приложение Laravel с использованием контейнера composer Docker:

      • cd ~
      • docker run --rm -v $(pwd):/app composer create-project --prefer-dist laravel/laravel laravel-kubernetes

      Когда контейнер будет готов и все пакеты Composer будут установлены, вы увидите новую установку Laravel в текущем каталоге laravel-kubernetes/. Перейдите в этот каталог:

      Остальные команды этого обучающего модуля должны выполняться в нем.

      Цель этого приложения — протестировать подключение к базе данных и вывести ее имя в браузере. Чтобы протестировать подключение к базе данных, откройте файл ./resources/views/welcome.blade.php в текстовом редакторе:

      • nano ./resources/views/welcome.blade.php

      Найдите раздел <div class="links">...</div> и замените его содержимое следующим:

      ./resources/views/welcome.blade.php

      ...
      <div class="links">
         <strong>Database Connected: </strong>
          @php
              try {
                  DB::connection()->getPDO();
                  echo DB::connection()->getDatabaseName();
                  } catch (Exception $e) {
                  echo 'None';
              }
          @endphp
      </div>
      ...
      

      Сохраните и закройте файл.

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

      На следующем шаге мы используем Docker для создания образа, содержащего это приложение Laravel, и Docker Compose для тестирования локального запуска и подключения к базе данных MySQL.

      Шаг 2 — Контейнеризация вашего приложения Laravel

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

      Вначале используйте nano или другой предпочитаемый текстовый редактор для создания в корневом каталоге вашего приложения Laravel файла с именем Dockerfile:

      Добавьте в файл следующее: Docker будет использовать этот файл для встраивания кода в образ:

      ./Dockerfile

      FROM php:7.4-apache
      
      # Install packages
      RUN apt-get update && apt-get install -y 
          git 
          zip 
          curl 
          sudo 
          unzip 
          libicu-dev 
          libbz2-dev 
          libpng-dev 
          libjpeg-dev 
          libmcrypt-dev 
          libreadline-dev 
          libfreetype6-dev 
          g++
      
      # Apache configuration
      ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
      RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
      RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
      RUN a2enmod rewrite headers
      
      # Common PHP Extensions
      RUN docker-php-ext-install 
          bz2 
          intl 
          iconv 
          bcmath 
          opcache 
          calendar 
          pdo_mysql
      
      # Ensure PHP logs are captured by the container
      ENV LOG_CHANNEL=stderr
      
      # Set a volume mount point for your code
      VOLUME /var/www/html
      
      # Copy code and run composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      COPY . /var/www/tmp
      RUN cd /var/www/tmp && composer install --no-dev
      
      # Ensure the entrypoint file can be run
      RUN chmod +x /var/www/tmp/docker-entrypoint.sh
      ENTRYPOINT ["/var/www/tmp/docker-entrypoint.sh"]
      
      # The default apache run command
      CMD ["apache2-foreground"]
      

      Сохраните и закройте файл.

      Этот файл Dockerfile начинает с образа PHP 7.4 Apache Docker из Docker Hub, а затем устанавливает несколько пакетов Linux, которые обычно требуются для приложений Laravel. Затем он создает файлы конфигурации Apache и включает перезапись заголовков. Dockerfile устанавливает несколько общих расширений PHP и добавляет переменную среды для обеспечения трансляции журналов Laravel в контейнер через stderr. Это позволяет просматривать журналы Laravel через журналы Docker Compose или Kubernetes.

      В заключение, Dockerfile копирует весь код приложения Laravel в каталог /var/www/tmp и устанавливает зависимости Composer. Затем он устанавливает ENTRYPOINT, но нам еще нужно создать этот файл, что мы сейчас и сделаем.

      Создайте в корневом каталоге проекта новый файл с именем docker-entrypoint.sh. Этот файл будет запускаться при запуске контейнера в локальном режиме или в кластере Kubernetes и будет копировать код приложения Laravel из каталога /var/www/tmp в каталог /var/www/html, где его будет обслуживать Apache.

      • nano ./docker-entrypoint.sh

      Добавьте следующий скрипт:

      ./docker-entrypoint.sh

      #!/bin/bash
      
      cp -R /var/www/tmp/. /var/www/html/
      chown -R www-data:www-data /var/www/html
      
      exec "$@"
      

      Заключительная строка exec "$@" предписывает оболочки запустить любую команду, которая будет передана следующей в качестве входного аргумента. Это важно, потому что нам нужно, чтобы Docker продолжал выполнять команду запуска Apache (apache2-foreground) после выполнения этого скрипта. Сохраните и закройте файл.

      Создайте файл .dockerignore в корневом каталоге вашего приложения. С этим файлом при сборке образа Docker он не будет загрязнен пакетами или файлами среды, которые не следует в него копировать:

      ./.dockerignore

      .env
      /vendor
      

      Сохраните и закройте файл.

      Теперь перед локальным запуском приложения с помощью Docker Compose осталось только создать файл docker-compose.yml. Во время настройки этого файла YAML нужно будет ввести ключ APP_KEY, сгенерированный Laravel во время установки. Чтобы найти его, нужно открыть и запустить поиск файла . /.env или запустить следующие команды cat и grep:

      Результат должен будет выглядеть следующим образом:

      Output

      APP_KEY=base64:0EHhVpgg ... UjGE=

      Скопируйте ключ в буфер обмена. Обязательно добавьте префикс base64:. Теперь создайте файл docker-compose.yml в корневом каталоге вашего приложения:

      • nano ./docker-compose.yml

      Здесь мы включим образ PHP вашего приложения Laravel и контейнер MySQL для запуска вашей базы данных. Добавьте следующее содержимое:

      ./docker-compose.yml

      version: '3.5'
      services:
        php:
          image: your_docker_hub_username/laravel-kubernetes:latest
          restart: always
          ports:
            - 8000:80
          environment:
            - APP_KEY="your_laravel_app_key"
            - APP_ENV=local
            - APP_DEBUG=true
            - DB_PORT=3306
            - DB_HOST=mysql
            - DB_DATABASE
            - DB_USERNAME
            - DB_PASSWORD
        mysql:
          image: mysql:5.7
          restart: always
          environment:
            - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
            - MYSQL_DATABASE=${DB_DATABASE}
            - MYSQL_USER=${DB_USERNAME}
            - MYSQL_PASSWORD=${DB_PASSWORD}
      

      Используйте скопированную вами в буфер обмена переменную APP_KEY для переменной your_laravel_app_key и используйте свое имя пользователя Docker Hub для переменной your_docker_hub_username. Сохраните и закройте файл.

      Первый образ вы создадите локально с помощью docker build. Второй образ — это официальный образ MySQL Docker, доступный в Docker Hub. Для обоих из них требуется несколько переменных среды, которые добавляются при запуске контейнеров.

      Запустите следующую команду для сборки образа Docker, содержащего ваше приложение Laravel. Обязательно замените your_docker_hub_username своим именем пользователя или именем пользователя команды Docker Hub, где будет храниться этот образ:

      • docker build -t your_docker_hub_username/laravel-kubernetes:latest .

      Затем вы можете запустить два контейнера с помощью Docker Compose, используя требуемые учетные данные БД:

      • DB_ROOT_PASSWORD=rootpassword DB_DATABASE=local_db DB_USERNAME=admin DB_PASSWORD=password docker-compose up -d

      Вы можете изменять четыре используемых здесь переменных среды (DB_ROOT_PASSWORD, DB_DATABASE, DB_USERNAME, DB_PASSWORD) , но поскольку вы только тестируете приложение на локальной системе, вам не нужно беспокоиться об их защите.

      Инициализация базы данных MySQL и подготовка контейнеров могут занять до 30 секунд. Когда контейнеры будут готовы, вы можете просмотреть свое приложение Laravel на локальном компьютере по адресу localhost:8000.

      Приложение Laravel, запущенное локально с помощью Docker Compose

      Ваше приложение PHP подключится к вашей базе данных MySQL. После успешного подключения под логотипом Laravel появится текст «Database Connected: local_db».

      Мы протестировали образ Docker на локальной системе с помощью Docker Compose и теперь можем остановить контейнеры с помощью команды docker-compose down:

      В следующем разделе мы отправим образ Docker в Docker Hub, чтобы чарт Helm мог использовать его для развертывания вашего приложения в вашем кластере Kubernetes.

      Шаг 3 — Отправка образа Docker в Docker Hub

      Чарт LAMP Helm, который мы будем использовать для развертывания кода в Kubernetes, требует, чтобы код был доступен в реестре контейнеров. Хотя вы можете отправить свой образ в частный или собственный реестр, в этом обучающем модуле мы будем использовать общедоступный бесплатный реестр Docker в Docker Hub.

      Откройте в браузере свою учетную запись на Docker Hub и создайте новый репозиторий с именем laravel-kubernetes.

      Создание нового репозитория в Docker Hub

      Затем если вы не подключились к Docker Hub с локального компьютера, вам нужно будет войти в Docker Hub. Это можно сделать через командную строку:

      • docker login -u your_docker_hub_username

      Введите в диалоге свои учетные данные. Обычно это нужно делать только один раз на каждом компьютере, поскольку Docker сохраняет ваши учетные данные в каталоге ~/.docker/config.json в вашем домашнем каталоге.

      В заключение отправьте свой образ в Docker Hub:

      • docker push your_docker_hub_username/laravel-kubernetes:latest

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

      Output

      latest: digest: sha256:df4bdeda91484c8c26a989b13b8f27ab14d93ab2e676e3c396714cb3811c4086 size: 4918

      Мы поместили ваше приложение Laravel в контейнер и отправили образ в Docker Hub, и теперь вы можете использовать этот образ для развертывания чарта Helm или Kubernetes. На следующем шаге мы зададим персонализированные значения на базе чарта LAMP Helm и развернем его в вашем кластере DigitalOcean Kubernetes.

      Шаг 4 — Настройка и развертывание приложения с помощью чарта LAMP Helm

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

      Прежде всего, вам потребуется каталог для хранения всех ваших файлов конфигурации Helm. Создайте в корневом каталоге вашего проекта Laravel новый каталог с именем helm/:

      В каталоге helm/ мы создадим два новых файла: values.yml и secrets.yml. Вначале создайте и откройте файл values.yml:

      Файл values.yml будет содержать несекретные параметры конфигурации, которые будут заменять значения по умолчанию в чарте LAMP Helm. Добавьте следующие конфигурации, заменив your_docker_hub_username своим именем пользователя:

      ./helm/values.yml

      php:
        repository: "your_docker_hub_username/laravel-kubernetes"
        tag: "latest"
        fpmEnabled: false
        envVars:
          - name: APP_ENV
            value: production
          - name: APP_DEBUG
            value: false
          - name: DB_PORT
            value: 3306
          - name: DB_HOST
            value: localhost
      

      Сохраните и закройте файл.

      Теперь создайте файл secrets.yml:

      secrets.yml не регистрируется в системе контроля версий. Он будет содержать важные данные конфигурации, в том числе ваш пароль базы данных и ключ приложения Laravel. Добавьте следующие конфигурации с вашими учетными данными:

      ./helm/secrets.yml

      mysql:
        rootPassword: "your_database_root_password"
        user: your_database_user
        password: "your_database_password"
        database: your_database_name
      
      php:
        envVars:
          - name: APP_KEY
            value: "your_laravel_app_key"
          - name: DB_DATABASE
            value: your_database_name
          - name: DB_USERNAME
            value: your_database_user
          - name: DB_PASSWORD
            value: "your_database_password"
      

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

      • docker run --rm -v $(pwd):/app php:cli php /app/artisan key:generate

      Сохраните и закройте файл secrets.yml.

      Чтобы ваш файл secrets.yml не добавлялся в образ Docker и не сохранялся в системе контроля версий, обязательно добавьте следующую строку в ваши файлы .dockerignore и .gitignore. Откройте и добавьте /helm/secrets.yml в каждый файл или запустите следующую команду для добавления в оба файла:

      • echo '/helm/secrets.yml' >> ./.dockerignore && echo '/helm/secrets.yml' >> ./.gitignore

      Вы создали файлы конфигурации Helm для вашего приложения и образа Docker и теперь можете установить этот чарт Helm как новый релиз в вашем кластере Kubernetes. Установите чарт из корневого каталога вашего приложения:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      Результат должен будет выглядеть следующим образом:

      Output

      NAME: laravel-kubernetes LAST DEPLOYED: Mon May 18 13:21:20 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      Ваше приложение будет доступно через одну-две минуты, но вы можете запустить следующую команду для мониторинга служб Kubernetes в вашем кластере:

      Поищите имя вашего приложения:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) laravel-kubernetes-lamp LoadBalancer your_cluster_ip your_external_ip 80:32175/TCP,3306:32243/TCP

      Когда новая служба laravel-kubernetes-lamp отображает IP-адрес под EXTERNAL-IP, вы можете открыть your_external_ip, чтобы увидеть приложение, запущенное в кластере Kubernetes. Ваше приложение подключится к вашей базе данных, и вы увидите имя базы данных под логотипом Laravel, как при локальном запуске приложения с помощью Docker Compose.

      Приложение Laravel, запущенное в Kubernetes с помощью чарта LAMP Helm

      Для концептуальных испытаний веб-приложение можно запустить с незащищенного IP-адреса, но ваш сайт не будет готов для производственной среды без сертификата SSL и персонализированного доменного имени. На следующем шаге мы настроим их, но предварительно нужно удалить релиз через командную строку:

      • helm delete laravel-kubernetes

      На следующем шаге мы расширим первую конфигурацию Helm, добавив контроллер Ingress, сертификат SSL и персонализированный домен в наше приложение Laravel.

      Шаг 5 — Добавление контроллера Ingress и SSL в кластер Kubernetes

      В Kubernetes контроллер Ingress отвечает за предоставление доступа к службам вашего приложения через интернет. На предыдущем шаге чарт LAMP Helm создал балансировщик нагрузки DigitalOcean и открыл прямой доступ к вашему приложению через IP-адрес балансировщика.

      Вы можете вывести SSL и доменное имя напрямую на балансировщик нагрузки, но поскольку мы работаем в Kubernetes, будет удобнее управлять всем в одном месте. Дополнительную информацию о контроллерах Ingress и подробные сведения о следующих шагах можно найти в руководстве «Настройка Nginx Ingress в DigitalOcean Kubernetes с помощью Helm».

      Чарт LAMP Helm включает опцию конфигурации для поддержки Ingress. Откройте ваш файл helm/values.yml:

      Добавьте в него следующие строки:

      ./helm/values.yml

      ...
      # Use Ingress Controller
      service:
        type: ClusterIP
        HTTPPort: 80
      ingress:
        enabled: true
        domain: your_domain
      

      Данная опция указывает, что при развертывании не нужно устанавливать балансировщик нагрузки и что нужно предоставить доступ к приложению через порт 80 кластера Kubernetes, доступ к которому контроллер Ingress откроет через Интернет. Сохраните и закройте файл values.yml.

      Запустите команду helm install, которую вы запускали ранее, чтобы снова запустить приложение Laravel. Команду нужно запускать из корневого каталога вашего приложения:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      Затем установите контроллер nginx-ingress в своем кластере Kubernetes, используя обслуживаемый Kubernetes-контроллер Nginx Ingress:

      • helm install nginx-ingress stable/nginx-ingress --set controller.publishService.enabled=true

      После установки вы увидите следующий результат:

      Output

      NAME: nginx-ingress LAST DEPLOYED: Mon May 18 13:28:34 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      Чтобы открыть доступ к развертыванию вашего приложения Laravel, вам также потребуется ресурс Ingress. Создайте в корневом каталоге вашего приложения новый файл с именем ingress.yml:

      В этом файле определяются хост приложения, диспетчер сертификатов SSL, серверная служба и имя порта. Добавьте следующие конфигурации, заменив your_domain выбранным именем домена:

      ./ingress.yml

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: laravel-kubernetes-ingress
        annotations:
          kubernetes.io/ingress.class: nginx
          cert-manager.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
          - hosts:
              - your_domain
            secretName: laravel-kubernetes-tls
        rules:
          - host: your_domain
            http:
              paths:
                - backend:
                    serviceName: laravel-kubernetes-lamp
                    servicePort: 80
      

      Сохраните и закройте файл.

      Затем необходимо установить Cert-Manager и создать центр, который позволит вам создавать производственные сертификаты SSL с помощью Let’s Encrypt. Для Cert-Manager требуются персонализированные определения ресурсов, которые вы можете применить из репозитория Cert-Manager через командную строку:

      • kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.crds.yaml

      При этом будет создан ряд ресурсов Kubernetes, которые будут выведены в командной строке:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io create

      Cert-Manager также требуется пространство имен для его изоляции в кластере Kubernetes:

      • kubectl create namespace cert-manager

      Вы увидите следующее:

      Output

      namespace/cert-manager created

      Поскольку Jetstack Cert-Manager не входит в число чартов, обслуживаемых Kubernetes, вам нужно будет также добавить репозиторий Jetstack Helm. Запустите следующую команду, чтобы сделать ее доступной в Helm:

      • helm repo add jetstack https://charts.jetstack.io

      При успешном добавлении вывод будет выглядеть так:

      Output

      "jetstack" has been added to your repositories

      Теперь мы готовы установить Cert-Manager в пространство имен cert-manager в кластере Kubernetes:

      • helm install cert-manager --version v0.15.0 --namespace cert-manager jetstack/cert-manager

      После выполнения этой операции вы увидите сводную информацию о развертывании:

      Output

      NAME: cert-manager LAST DEPLOYED: Mon May 18 13:32:08 2020 NAMESPACE: cert-manager STATUS: deployed REVISION: 1

      В заключение нужно добавить в корневой каталог приложения Laravel файл конфигурации Kubernetes с именем production_issuer.yml. Создайте файл:

      • nano ./production_issuer.yml

      Добавьте следующее:

      apiVersion: cert-manager.io/v1alpha2
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      spec:
        acme:
          # Email address used for ACME registration
          email: your_email_address
          server: https://acme-v02.api.letsencrypt.org/directory
          privateKeySecretRef:
            # Name of a secret used to store the ACME account private key
            name: letsencrypt-prod-private-key
          # Add a single challenge solver, HTTP01 using nginx
          solvers:
            - http01:
                ingress:
                  class: nginx
      

      Сохраните и закройте файл.

      Let’s Encrypt будет отправлять на адрес your_email_address все важные уведомления и предупреждения об окончании срока действия сертификата, так что укажите адрес, который вы будете регулярно проверять. Сохраните этот файл и создайте новый ресурс для вашего ресурса Ingress и производственного центра сертификации в вашем кластере Kubernetes:

      • kubectl create -f ingress.yml
      • kubectl create -f production_issuer.yml

      В заключение обновите записи DNS вашего доменного имени, чтобы запись A указывала на IP-адрес вашего балансировщика нагрузки. Чтобы найти IP-адрес вашего контроллера Ingress, введите следующую команду:

      • kubectl get service nginx-ingress-controller

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-controller LoadBalancer your_cluster_ip your_external_ip 80:30187/TCP,443:31468/TCP 6m10s

      Используйте адрес your_external_ip в качестве IP-адреса вашей записи DNS A. Процесс обновления записей DNS зависит от того, где вы управляете доменными именами и хостингом DNS, но если вы используете DigitalOcean, вы можете сослаться на наше руководство по управлению записями DNS.

      После обновления ваших записей DNS и генерирования сертификата SSL ваше приложение будет доступно по адресу your_domain с включенным SSL.

      Приложение Laravel с SSL и персонализированным доменным именем

      Хотя ваше приложение PHP и база данных уже связаны, вам все равно необходимо провести миграцию базы данных. На последнем шаге мы увидим, как запускать команды Artisan в поде Kubernetes для миграции базы данных и выполнения других распространенных задач технического обслуживания.

      Шаг 6 — Дистанционный запуск команд

      Хотя ваше приложение Laravel уже запущено и подключено к базе данных MySQL в Kubernetes, вам нужно выполнить несколько стандартных операций после установки приложения Laravel. В частности, вам следует провести миграцию баз данных.

      Прежде чем запускать команду Artisan для вашего приложения Laravel, вам нужно знать имя пода, где запущен контейнер вашего приложения Laravel. Для просмотра всех подов в вашем кластере Kubernetes используйте следующую команду:

      Результат должен будет выглядеть следующим образом:

      Output

      NAME READY STATUS RESTARTS AGE laravel-kubernetes-lamp-77fb989b46-wczgb 2/2 Running 0 16m

      Выберите под для развертывания laravel-kubernetes-lamp-... Обязательно используйте выведенное имя, а не указанное выше. Теперь вы можете запустить для него команду kubectl exec. Например, для проведения миграции базы данных используйте команду artisan migrate. Мы добавляем флаг --force, поскольку команда выполняется на поде в производственной среде:

      • kubectl exec laravel-kubernetes-lamp-77fb989b46-wczgb -- php artisan migrate --force

      Эта команда выводит следующее:

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.16 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.05 seconds)

      Мы успешно развернули Laravel 7 и MySQL в Kubernetes и выполнили необходимую задачу по обслуживанию базы данных.

      Заключение

      В этом обучающем модуле мы научились выполнять контейнеризацию приложения Laravel PHP, подключать его к базе данных MySQL, отправлять образ Docker с кодом в Docker Hub, а затем использовать чарт Helm для развертывания этого образа в кластере DigitalOcean Kubernetes. В заключение мы добавили SSL и персонализированное доменное имя и научились запускать инструменты командной строки в работающих подах.

      Kubernetes и Helm дают ряд преимуществ по сравнению с традиционными вариантами хостинга стека LAMP: масштабируемость, возможность замены служб без прямого входа на сервер, инструменты для обновления во время работы и контроль над средой хостинга. При этом сложность начальной контейнеризации и настройки приложения делает начало работы непростой задачей. С этим руководством развертывание Laravel в кластере Kubernetes станет более достижимой задачей. Теперь вы можете изучить дополнительную информацию о возможностях Laravel и добавлении в Kubernetes инструментов мониторинга, таких как Linkerd, которые вы можете установить вручную с помощью нашего руководства или системы DigitalOcean 1-Click.



      Source link

      Установка и настройка Laravel с помощью Docker Compose в Ubuntu 20.04


      Введение

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

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

      • Служба app с PHP7.4-FPM;
      • Служба db с MySQL 5.7;
      • Служба nginx, использующая службу app для синтаксического анализа кода PHP перед предоставлением приложения Laravel конечному пользователю.

      Чтобы ускорить разработку и упростить отладку приложения, мы обеспечим синхронизацию файлов приложения с использованием общих томов. Также мы узнаем, как использовать команды docker-compose exec для запуска Composer и Artisan в контейнере app.

      Предварительные требования

      Шаг 1 — Получение демонстрационного приложения

      Для начала работы мы получим демонстрационное приложение Laravel из его репозитория на Github. Нас интересует раздел tutorial-01, содержащий базовое приложение Laravel, которое мы создали в первом обучающем руководстве этой серии.

      Чтобы получить код приложения, совместимый с настоящим обучающим руководством, загрузите версию tutorial-1.0.1 в свою домашнюю директорию с помощью следующей команды:

      • cd ~
      • curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip -o travellist.zip

      Нам потребуется команда unzip для распаковки кода приложения. Если вы еще не установили этот пакет, сделайте это с помощью следующей команды:

      • sudo apt update
      • sudo apt install unzip

      Теперь распакуйте содержимое приложения и переименуйте распакованную директорию для удобства доступа:

      • unzip travellist.zip
      • mv travellist-laravel-demo-tutorial-1.0.1 travellist-demo

      Перейдите в директорию travellist-demo:

      На следующем шаге мы создадим файл конфигурации .env для настройки приложения.

      Шаг 2 — Настройка файла .env приложения

      Файлы конфигурации Laravel располагаются в директории config внутри корневой директории приложения. Также файл .env используется для настройки конфигурации, зависимой от среды, в том числе учетных данных и любой информации, которая может изменяться между операциями развертывания. Этот файл не включен в систему контроля версий.

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

      Значения в файле .env имеют приоритет по отношению к значениям в обычных файлах конфигурации, расположенных в директории config. Для каждого случая установки в новую среду требуется персонализированный файл среды, где будут определены такие настройки, как параметры подключения к базе данных, параметры отладки, URL приложения и другие параметры, в зависимости от используемой приложением среды.

      Теперь мы создадим новый файл .env для настройки индивидуальных параметров конфигурации для создаваемой нами среды разработки. В комплектацию Laravel входит образец файла .env, который мы скопируем для создания собственного файла:

      Откройте этот файл с помощью nano или другого текстового редактора на ваш выбор:

      Текущий файл .env из демонстрационного приложения travellist содержит настройки использования локальной базы данных MySQL с адресом хоста базы данных 127.0.0.1. Нам нужно обновить переменную DB_HOST, чтобы она указывала на службу базы данных, которую мы создадим в нашей среде Docker. В этом обучающем руководстве мы присвоим службе базы данных имя db. Замените указанное значение DB_HOST именем службы базы данных:

      .env

      APP_NAME=Travellist
      APP_ENV=dev
      APP_KEY=
      APP_DEBUG=true
      APP_URL=http://localhost:8000
      
      LOG_CHANNEL=stack
      
      DB_CONNECTION=mysql
      DB_HOST=db
      DB_PORT=3306
      DB_DATABASE=travellist
      DB_USERNAME=travellist_user
      DB_PASSWORD=password
      ...
      

      При желании вы также можете изменить название базы данных, имя пользователя и пароль. Эти переменные будут использоваться на последующем шаге, когда мы настроим файл docker-compose.yml для настройки наших служб.

      Сохраните файл после завершения редактирования. Если вы использовали nano, нажмите Ctrl+x, а затем Y и Enter для подтверждения.

      Шаг 3 — Настройка файла Dockerfile для приложения

      Хотя наши службы MySQL и Nginx будут основаны на образах по умолчанию, полученных из Docker Hub, нам все равно потребуется создать персонализированный образ контейнера приложения. Для этого мы создадим новый файл Dockerfile.

      Наш образ travellist будет основан на php:7.4-fpm, официальном образе PHP из Docker Hub. Поверх базовой среды PHP-FPM мы установим несколько дополнительных модулей PHP и инструмент Composer для управления зависимостями.

      Также мы создадим нового пользователя системы, что необходимо для выполнения команд artisan и composer при разработке приложения. Параметр uid обеспечивает соответствие uid пользователя внутри контейнера и системного пользователя на хосте, где работает Docker. Любые файлы, созданные этими командами, воспроизводятся на хосте с соответствующими разрешениями. Также это означает, что вы можете использовать предпочитаемый редактор кода на хосте для разработки приложения, работающего внутри контейнеров.

      Создайте новый файл Dockerfile:

      Скопируйте следующие строки в файл Dockerfile:

      Dockerfile

      FROM php:7.4-fpm
      
      # Arguments defined in docker-compose.yml
      ARG user
      ARG uid
      
      # Install system dependencies
      RUN apt-get update && apt-get install -y 
          git 
          curl 
          libpng-dev 
          libonig-dev 
          libxml2-dev 
          zip 
          unzip
      
      # Clear cache
      RUN apt-get clean && rm -rf /var/lib/apt/lists/*
      
      # Install PHP extensions
      RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
      
      # Get latest Composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      
      # Create system user to run Composer and Artisan Commands
      RUN useradd -G www-data,root -u $uid -d /home/$user $user
      RUN mkdir -p /home/$user/.composer && 
          chown -R $user:$user /home/$user
      
      # Set working directory
      WORKDIR /var/www
      
      USER $user
      
      

      Не забудьте сохранить файл после завершения работы.

      Вначале наш файл Dockerfile определяет базовый образ, который мы используем: php:7.4-fpm.

      После установки системных пакетов и расширений PHP мы установим Composer, скопировав исполняемый файл composer из последнего официального образа в образ нашего приложения.

      При этом создается новый пользователь системы и выполняется настройка его параметров с помощью аргументов user и uid в начале файла Dockerfile. Эти значения вставляются Docker Compose во время сборки.

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

      Шаг 4 — Настройка конфигурации Nginx и файлов дампа базы данных

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

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

      Для настройки Nginx мы будем использовать файл travellist.conf, настраивающий обслуживание приложения. Создайте папку docker-compose/nginx с помощью следующей команды:

      • mkdir -p docker-compose/nginx

      Откройте в этой директории новый файл с именем travellist.conf:

      • nano docker-compose/nginx/travellist.conf

      Скопируйте следующую конфигурацию Nginx в этот файл:

      docker-compose/nginx/travellist.conf

      
      server {
          listen 80;
          index index.php index.html;
          error_log  /var/log/nginx/error.log;
          access_log /var/log/nginx/access.log;
          root /var/www/public;
          location ~ .php$ {
              try_files $uri =404;
              fastcgi_split_path_info ^(.+.php)(/.+)$;
              fastcgi_pass app:9000;
              fastcgi_index index.php;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param PATH_INFO $fastcgi_path_info;
          }
          location / {
              try_files $uri $uri/ /index.php?$query_string;
              gzip_static on;
          }
      }
      

      Этот файл настраивает Nginx для прослушивания порта 80 и использования index.php в качестве страницы индекса по умолчанию. Это задаст корневую директорию документа /var/www/public, а затем Nginx будет настроен для использования службы app на порту 9000 для обработки файлов *.php.

      Сохраните и закройте файл после завершения редактирования.

      Чтобы настроить базу данных MySQL, мы откроем для общего доступа дамп базы данных, который будет импортирован при инициализации контейнера. Эта возможность обеспечивается образом MySQL 5.7, который мы будем использовать в этом контейнере.

      Создайте новую папку для файлов инициализации MySQL в папке docker-compose:

      • mkdir docker-compose/mysql

      Откройте новый файл .sql:

      • nano docker-compose/mysql/init_db.sql

      Следующий дамп MySQL основан на базе данных, которую мы настроили в обучающем руководстве по Laravel на LEMP. Она создаст новую таблицу с именем places. Затем таблица будет заполнена местами на основе образца.

      Добавьте в файл следующий код:

      docker-compose/mysql/db_init.sql

      DROP TABLE IF EXISTS `places`;
      
      CREATE TABLE `places` (
        `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
        `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
        `visited` tinyint(1) NOT NULL DEFAULT '0',
        PRIMARY KEY (`id`)
      ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
      
      INSERT INTO `places` (name, visited) VALUES ('Berlin',0),('Budapest',0),('Cincinnati',1),('Denver',0),('Helsinki',0),('Lisbon',0),('Moscow',1),('Nairobi',0),('Oslo',1),('Rio',0),('Tokyo',0);
      

      Таблица places содержит три поля: id, name и visited. Поле visited — это флаг, используемый для отметки мест со статусом to go. Вы можете свободно изменять или добавлять места в образец. Сохраните и закройте файл после завершения.

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

      Шаг 5 — Создание мультиконтейнерной среды с Docker Compose

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

      Для настройки наших определений служб мы создадим новый файл с именем docker-compose.yml. Обычно этот файл располагается в корневой папке приложения и определяет контейнеризованную среду, в том числе базовые образы, используемые для построения контейнеров, и взаимодействие между службами.

      Мы определим в файле docker-compose.yml три разные службы: app, db и nginx.

      Служба app построит образ с именем travellist на базе ранее созданного файла Dockerfile. Определяемый этой службой контейнер запустит сервер php-fpm для синтаксической проверки кода PHP и возврата результатов в службу nginx, которая будет работать в отдельном контейнере. Служба mysql определяет контейнер, где запущен сервер MySQL 5.7. Наши службы будут использовать общую соединительную сеть с именем travellist.

      Файлы приложения будут синхронизироваться в службах app и nginx посредством монтирования привязок. Монтирование привязок — это полезный инструмент в средах разработки, позволяющий организовать эффективную двустороннюю синхронизацию между хостом и контейнерами.

      Создайте новый файл docker-compose.yml в корневой папке приложения:

      Обычно файл docker-compose.yml начинается с определения версии, после которого идет узел services, где определяются все службы. Общие сети обычно определяются в конце этого файла.

      Для начала скопируйте этот шаблонный код в файл docker-compose.yml:

      docker-compose.yml

      version: "3.7"
      services:
      
      
      networks:
        travellist:
          driver: bridge
      

      Теперь мы отредактируем узел services и добавим в него службы app, db и nginx.

      Служба app

      Служба app настраивает контейнер с именем travellist-app. Она строит новый образ Docker на базе файла Dockerfile в той же директории, что и файл docker-compose.yml. Новый образ сохраняется на локальном компьютере с именем travellist.

      Хотя корневая директория документов выдается приложением в контейнере nginx, нам нужно, чтобы файлы приложения находились внутри контейнера app, поскольку мы хотим выполнять задачи командной строки с помощью инструмента Laravel Artisan.

      Скопируйте следующее определение службы в узел services в файле docker-compose.yml:

      docker-compose.yml

        app:
          build:
            args:
              user: sammy
              uid: 1000
            context: ./
            dockerfile: Dockerfile
          image: travellist
          container_name: travellist-app
          restart: unless-stopped
          working_dir: /var/www/
          volumes:
            - ./:/var/www
          networks:
            - travellist
      

      Эти параметры имеют следующее назначение:

      • build: данная конфигурация предписывает Docker Compose построить локальный образ службы app с использованием заданного пути (контекста) и указаний из файла Dockerfile. Аргументы user и uid вставляются в файл Dockerfile для настройки команд создания пользователя во время сборки.
      • image: имя, которое будет использоваться для создаваемого образа.
      • container_name: задает имя контейнера для этой службы.
      • restart: всегда выполнять перезапуск, если служба не остановлена.
      • working_dir: задает для этой службы директорию по умолчанию /var/www.
      • volumes: создает общий том, который будет синхронизировать содержимое текущей директории с директорией /var/www внутри контейнера. Следует отметить, что это не корневая директория документов, поскольку она находится в контейнере nginx.
      • networks: настраивает службу для использования сети с именем travellist.

      Служба db

      Служба db использует готовый образ MySQL 5.7 из Docker Hub. Поскольку Docker Compose автоматически загружает файлы переменных .env, находящиеся в той же директории, что и файл docker-compose.yml, мы можем получить параметры базы данных из файла Laravel .env, созданного на предыдущем шаге.

      Добавьте следующее определение служб в узел services сразу же после определения службы app:

      docker-compose.yml

        db:
          image: mysql:5.7
          container_name: travellist-db
          restart: unless-stopped
          environment:
            MYSQL_DATABASE: ${DB_DATABASE}
            MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
            MYSQL_PASSWORD: ${DB_PASSWORD}
            MYSQL_USER: ${DB_USERNAME}
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
          volumes:
            - ./docker-compose/mysql:/docker-entrypoint-initdb.d
          networks:
            - travellist
      

      Эти параметры имеют следующее назначение:

      • image: определяет образ Docker, который следует использовать для этого контейнера. В данном случае мы используем образ MySQL 5.7 из Docker Hub.
      • container_name: задает имя контейнера для этой службы: travellist-db.
      • restart: всегда перезапускать службу, если она явно не остановлена.
      • environment: определяет переменные среды в новом контейнере. Мы используем полученные из файла Laravel .env значения для настройки нашей службы MySQL, которая автоматически создаст новую базу данных и пользователя на базе заданных переменных среды.
      • volumes: создает том для общего доступа к дампу базы данных .sql, который будет использоваться для инициализации базы данных приложения. Образ MySQL будет автоматически импортировать файлы .sql, расположенные в директории /docker-entrypoint-initdb.d внутри контейнера.
      • networks: предписывает службе использовать сеть с именем travellist.

      Служба nginx

      Служба nginx использует готовый образ Nginx на базе облегченного дистрибутива Linux под названием Alpine. Она создает контейнер с именем travellist-nginx, и он использует определение ports для создания переадресации с порта 8000 системы хоста на порт 80 внутри контейнера.

      Добавьте следующее определение службы в узел services сразу после службы db:

      docker-compose.yml

        nginx:
          image: nginx:1.17-alpine
          container_name: travellist-nginx
          restart: unless-stopped
          ports:
            - 8000:80
          volumes:
            - ./:/var/www
            - ./docker-compose/nginx:/etc/nginx/conf.d
          networks:
            - travellist
      

      Эти параметры имеют следующее назначение:

      • image: определяет образ Docker, который следует использовать для этого контейнера. В данном случае мы используем образ Alpine Nginx 1.17.
      • container_name: задает имя контейнера для этой службы: travellist-nginx.
      • restart: всегда перезапускать эту службу, если она явно не остановлена.
      • ports: задает переадресацию портов, разрешающую внешний доступ через порт 8000 к веб-серверу на порту 80 внутри контейнера.
      • volumes: создает два общих тома. Первый из них синхронизирует содержимое текущей директории с директорией /var/www внутри контейнера. При внесении локальных изменений в файлы приложения эти изменения быстро отражаются в приложении, обслуживаемом Nginx внутри контейнера. Второй том обеспечивает копирование нашего файла конфигурации Nginx docker-compose/nginx/travellist.conf в папку конфигурации Nginx контейнера.
      • networks: предписывает этой службе использовать сеть с именем travellist.

      Готовый файл docker-compose.yml

      Так выглядит готовый файл docker-compose.yml:

      docker-compose.yml

      version: "3.7"
      services:
        app:
          build:
            args:
              user: sammy
              uid: 1000
            context: ./
            dockerfile: Dockerfile
          image: travellist
          container_name: travellist-app
          restart: unless-stopped
          working_dir: /var/www/
          volumes:
            - ./:/var/www
          networks:
            - travellist
      
        db:
          image: mysql:5.7
          container_name: travellist-db
          restart: unless-stopped
          environment:
            MYSQL_DATABASE: ${DB_DATABASE}
            MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
            MYSQL_PASSWORD: ${DB_PASSWORD}
            MYSQL_USER: ${DB_USERNAME}
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
          volumes:
            - ./docker-compose/mysql:/docker-entrypoint-initdb.d
          networks:
            - travellist
      
        nginx:
          image: nginx:alpine
          container_name: travellist-nginx
          restart: unless-stopped
          ports:
            - 8000:80
          volumes:
            - ./:/var/www
            - ./docker-compose/nginx:/etc/nginx/conf.d/
          networks:
            - travellist
      
      networks:
        travellist:
          driver: bridge
      

      Обязательно сохраните файл после завершения.

      Шаг 6 — Запуск приложения с помощью Docker Compose

      Теперь мы используем команды docker-compose для сборки образа приложения и запуска заданных нами служб.

      Выполните сборку образа app с помощью следующей команды:

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

      Output

      Building app Step 1/11 : FROM php:7.4-fpm ---> fa37bd6db22a Step 2/11 : ARG user ---> Running in f71eb33b7459 Removing intermediate container f71eb33b7459 ---> 533c30216f34 Step 3/11 : ARG uid ---> Running in 60d2d2a84cda Removing intermediate container 60d2d2a84cda ---> 497fbf904605 Step 4/11 : RUN apt-get update && apt-get install -y git curl libpng-dev libonig-dev ... Step 7/11 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer ---> e499f74896e3 Step 8/11 : RUN useradd -G www-data,root -u $uid -d /home/$user $user ---> Running in 232ef9c7dbd1 Removing intermediate container 232ef9c7dbd1 ---> 870fa3220ffa Step 9/11 : RUN mkdir -p /home/$user/.composer && chown -R $user:$user /home/$user ---> Running in 7ca8c0cb7f09 Removing intermediate container 7ca8c0cb7f09 ---> 3d2ef9519a8e Step 10/11 : WORKDIR /var/www ---> Running in 4a964f91edfa Removing intermediate container 4a964f91edfa ---> 00ada639da21 Step 11/11 : USER $user ---> Running in 9f8e874fede9 Removing intermediate container 9f8e874fede9 ---> fe176ff4702b Successfully built fe176ff4702b Successfully tagged travellist:latest

      После завершения сборки вы можете запустить среду в фоновом режиме с помощью следующей команды:

      Output

      Creating travellist-db ... done Creating travellist-app ... done Creating travellist-nginx ... done

      Так ваши контейнеры будут работать в фоновом режиме. Чтобы вывести информацию о состоянии активных служб, запустите команду:

      Вывод будет выглядеть следующим образом:

      Output

      Name Command State Ports -------------------------------------------------------------------------------- travellist-app docker-php-entrypoint php-fpm Up 9000/tcp travellist-db docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp travellist-nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:8000->80/tcp

      Теперь ваша среда работает, но для завершения настройки приложения нам нужно выполнить еще несколько команд. Вы можете использовать команду docker-compose exec для выполнения команд в контейнерах служб, например ls -l для отображения подробной информации о файлах в директории приложения:

      • docker-compose exec app ls -l

      Output

      total 260 -rw-rw-r-- 1 sammy sammy 737 Jun 9 11:19 Dockerfile -rw-rw-r-- 1 sammy sammy 101 Jan 7 08:05 README.md drwxrwxr-x 6 sammy sammy 4096 Jan 7 08:05 app -rwxr-xr-x 1 sammy sammy 1686 Jan 7 08:05 artisan drwxrwxr-x 3 sammy sammy 4096 Jan 7 08:05 bootstrap -rw-rw-r-- 1 sammy sammy 1501 Jan 7 08:05 composer.json -rw-rw-r-- 1 sammy sammy 179071 Jan 7 08:05 composer.lock drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 config drwxrwxr-x 5 sammy sammy 4096 Jan 7 08:05 database drwxrwxr-x 4 sammy sammy 4096 Jun 9 11:19 docker-compose -rw-rw-r-- 1 sammy sammy 965 Jun 9 11:27 docker-compose.yml -rw-rw-r-- 1 sammy sammy 1013 Jan 7 08:05 package.json -rw-rw-r-- 1 sammy sammy 1405 Jan 7 08:05 phpunit.xml drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 public -rw-rw-r-- 1 sammy sammy 273 Jan 7 08:05 readme.md drwxrwxr-x 6 sammy sammy 4096 Jan 7 08:05 resources drwxrwxr-x 2 sammy sammy 4096 Jan 7 08:05 routes -rw-rw-r-- 1 sammy sammy 563 Jan 7 08:05 server.php drwxrwxr-x 5 sammy sammy 4096 Jan 7 08:05 storage drwxrwxr-x 4 sammy sammy 4096 Jan 7 08:05 tests drwxrwxr-x 41 sammy sammy 4096 Jun 9 11:32 vendor -rw-rw-r-- 1 sammy sammy 538 Jan 7 08:05 webpack.mix.js

      Теперь мы выполним команду composer install для установки зависимостей приложения:

      • docker-compose exec app composer install

      Вывод будет выглядеть следующим образом:

      Output

      Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Package operations: 85 installs, 0 updates, 0 removals - Installing doctrine/inflector (1.3.1): Downloading (100%) - Installing doctrine/lexer (1.2.0): Downloading (100%) - Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%) - Installing erusev/parsedown (1.7.4): Downloading (100%) - Installing symfony/polyfill-ctype (v1.13.1): Downloading (100%) - Installing phpoption/phpoption (1.7.2): Downloading (100%) - Installing vlucas/phpdotenv (v3.6.0): Downloading (100%) - Installing symfony/css-selector (v5.0.2): Downloading (100%) … Generating optimized autoload files > IlluminateFoundationComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully.

      В последнюю очередь перед тестированием приложения нам нужно сгенерировать уникальный ключ приложения с помощью artisan, инструмента командной строки Laravel. Этот ключ используется для шифрования пользовательских сеансов и других важных данных:

      • docker-compose exec app php artisan key:generate

      Output

      Application key set successfully.

      Откройте браузер и введите в адресную строку доменное имя вашего сервера или IP-адрес с портом 8000:

      http://server_domain_or_IP:8000
      

      Примечание. Если вы запускаете эту демонстрацию на локальном компьютере, используйте http://localhost:8000 для доступа к приложению через браузер.

      Страница будет выглядеть следующим образом:

      Демонстрационное приложение Laravel

      Вы можете использовать команду logs для проверки журналов, сгенерированных вашими службами:

      • docker-compose logs nginx
      Attaching to travellist-nginx
      …
      travellist-nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
      travellist-nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
      travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:34 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
      travellist-nginx | 192.168.0.1 - - [09/Jun/2020:11:46:35 +0000] "GET / HTTP/1.1" 200 627 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
      

      Если вы хотите приостановить среду Docker Compose, сохраняя состояние всех служб, используйте команду:

      Output

      Pausing travellist-db ... done Pausing travellist-nginx ... done Pausing travellist-app ... done

      Вы можете возобновить работу служб с помощью команды:

      Output

      Unpausing travellist-app ... done Unpausing travellist-nginx ... done Unpausing travellist-db ... done

      Чтобы закрыть среду Docker Compose и удалить все ее контейнеры, сети и тома, используйте команду:

      Output

      Stopping travellist-nginx ... done Stopping travellist-db ... done Stopping travellist-app ... done Removing travellist-nginx ... done Removing travellist-db ... done Removing travellist-app ... done Removing network travellist-laravel-demo_travellist

      Обзор всех команд Docker Compose можно найти в справочном материале по командной строке Docker Compose.

      Заключение

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

      Теперь вы можете работать над своим приложением Laravel без необходимости устанавливать и настраивать локальный веб-сервер для целей разработки и тестирования. Вы будете работать в одноразовой среде, которую можно легко дублировать и распространять. Это полезно как на этапе разработки приложения, так и на этапе его использования в производственной среде.



      Source link