Как сделать образ сервера удаленно

Добавил пользователь Алексей Ф.
Обновлено: 04.10.2024

2. Для резервирования СУБД в ней же есть замечательная опция Maintenance Plan (она же, если не ошибаюсь, в локализованной версии называется "План обслуживания", но могу ошибаться). Смело гугли фразу "microsoft sql server настройка резервного копирования", если ты уверен, что ты первый человек на этой планете, который хочет автоматически резервировать СУБД. Узнаешь много нового. Причём как в картинках, так и в видео со звуком (в моё время эту роскошь даже в обычном тексте найти было сложно, так что завидуй сам себе, как тебе повезло).

Озвуч пожалуйста, для каких целей тебе образ системного раздела? Для резервного копирования, или для переноса машины?
Если для резервного копирования то все делается стандартными BackUp менеджерами и стандартными средствами MSSql, благо все это подробно расписано в примерах.
А если для переноса или дублирования машины то как и писал выше посмотри в сторону VMWare, как снимать образ в режиме реального времени так же описано на просторах инета, если чтото будет не понятно то уже и спрашивай в профильную ветку. Если опосаешься изменения данных во время снятия образа то делай это ночью, и вдобавок сделай после создания образа бэкап sql. А вобще не разу небыло проблем с базами после переноса на виртуалку.

По данной инструкции мы настроим наш веб сервер в Docker следующим образом:

  • В качестве веб-сервера будет использоваться NGINX.
  • Будет поддержка приложений на PHP.
  • Мы создадим 2 контейнера Docker — один для NGINX + PHP, второй для СУБД (MariaDB).
  • Веб-приложение будет зашито в контейнере. Раздел для данных MariaDB будет монтироваться в качестве volume.

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

Мы будем работать в системе на базе Linux. Предполагается, что Docker уже установлен.

NGINX + PHP + PHP-FPM

Рекомендуется каждый микросервис помещать в свой отдельный контейнер, но мы (для отдельного примера) веб-сервер с интерпретатором PHP поместим в один и тот же имидж, на основе которого будут создаваться контейнеры.

Создание образа

Создадим каталог, в котором будут находиться файлы для сборки образа веб-сервера:

mkdir -p /opt/docker/web-server

Переходим в созданный каталог:

  1. FROM centos:8
  2. MAINTAINER Dmitriy Mosk
  3. ENV TZ=Europe/Moscow
  4. RUN dnf update -y
  5. RUN dnf install -y nginx php php-fpm php-mysqli
  6. RUN dnf clean all
  7. RUN echo "daemon off;" >> /etc/nginx/nginx.conf
  8. RUN mkdir /run/php-fpm
  9. COPY ./html/ /usr/share/nginx/html/
  10. CMD php-fpm -D ; nginx
  11. EXPOSE 80

* где:
1) указываем, какой берем базовый образ. В нашем случае, CentOS 8.
3) задаем для информации того, кто создал образ. Указываем свое имя и адрес электронной почты.
5) создаем переменную окружения TZ с указанием временной зоны (в нашем примере, московское время).
7) запускаем обновление системы.
8) устанавливаем пакеты: веб-сервер nginx, интерпретатор php, сервис php-fpm для обработки скриптов, модуль php-mysqli для работы php с СУБД MySQL/MariaDB.
9) удаляем скачанные пакеты и временные файлы, образовавшиеся во время установки.
10) добавляем в конфигурационный файл nginx строку daemon off, которая запретит веб-серверу автоматически запуститься в качестве демона.
11) создаем каталог /run/php-fpm — без него не сможет запуститься php-fpm.
13) копируем содержимое каталога html, который находится в том же каталоге, что и dockerfile, в каталог /usr/share/nginx/html/ внутри контейнера. В данной папке должен быть наше веб-приложение.
15) запускаем php-fpm и nginx. Команда CMD в dockerfile может быть только одна.
17) открываем порт 80 для работы веб-сервера.

В рабочем каталоге создаем папку html:

. а в ней — файл index.php:

* мы создали скрипт, который будет выводить информацию о php в браузере для примера. По идее, в данную папку мы должны положить сайт (веб-приложение).

Создаем первый билд для нашего образа:

docker build -t dmosk/webapp:v1 .

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

docker login --username dmosk

docker tag dmosk/webapp:v1 dmosk/web:nginx_php7

docker push dmosk/web:nginx_php7

* первой командой мы прошли аутентификацию на портале докер-хаба (в качестве id/login мы используем dmosk — это учетная запись, которую мы зарегистрировали в Docker Hub). Вторая команда создает тег для нашего образа, где dmosk — учетная запись на dockerhub; web — имя репозитория; nginx_php7 — сам тег. Последняя команда заливает образ в репозиторий.
* подробнее про загрузку образа в репозиторий докера.

Запуск контейнера и проверка работы

Запускаем веб-сервер из созданного образа:

docker run --name web_server -d -p 80:80 dmosk/webapp:v1

Информация о PHP

Наш веб-сервер из Docker работает.

MariaDB

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

Сначала создаем том для докера:

docker volume create --name mariadb

* в данном примере мы создали том с именем mariadb. Будет создан каталог /var/lib/docker/volumes/mariadb/_data/ на хостовом сервере, куда будут размещаться наши файлы базы.

Выполним первый запуск нашего контейнера с mariadb:

docker run --rm --name maria_db -d -e MYSQL_ROOT_PASSWORD=password -v mariadb:/var/lib/mysql mariadb

  • --rm — удалить контейнер после остановки. Это первый запуск для инициализации базы, после параметры запуска контейнера будут другими.
  • --name maria_db — задаем имя контейнеру, по которому будем к нему обращаться.
  • -e MYSQL_ROOT_PASSWORD=password — создаем системную переменную, содержащую пароль для пользователя root базы данных. Оставляем его таким, как в данной инструкции, так как следующим шагом мы его будем менять.
  • -v mariadb:/var/lib/mysql — говорим, что для контейнера мы хотим использовать том mariadb, который будет примонтирован внутри контейнера по пути /var/lib/mysql.
  • mariadb — в самом конце мы указываем имя образа, который нужно использовать для запуска контейнера. Это образ, который при первом запуске будет скачан с DockerHub.

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

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

docker exec -it maria_db /bin/bash

Подключаемся к mariadb:

Меняем пароль для учетной записи root:

> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('New_Password');

Выходим из командной строки СУБД:

Выходим из контейнера:

Останавливаем сам контейнер — он нам больше не нужен с данными параметрами запуска:

docker stop maria_db

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

docker run --name maria_db -d -v mariadb:/var/lib/mysql mariadb

Сервер баз данных готов к работе.

Подключение к базе из веб-сервера

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

Зайдем в контейнер с базой данных:

docker exec -it maria_db /bin/bash

Подключимся к mariadb:

Создадим базу данных, если таковой еще нет:

> CREATE DATABASE docker_db DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

* в данном примере мы создаем базу docker_db.

Создаем пользователя для доступа к нашей базе данных:

> GRANT ALL PRIVILEGES ON docker_db.* TO 'docker_db_user'@'%' IDENTIFIED BY 'docker_db_password';

* и так, мы дали полные права на базу docker_db пользователю docker_db_user, который может подключаться от любого хоста (%). Пароль для данного пользователя — docker_db_password.

Отключаемся от СУБД:

Выходим из контейнера:

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

Останавливаем работающие контейнеры и удаляем их:

docker stop maria_db web_server

docker rm maria_db web_server

docker network create net1

* мы создали сеть net1.

Создаем новые контейнеры из наших образов и добавляем опцию --net, которая указывает, какую сеть будет использовать контейнер:

docker run --name maria_db --net net1 -d -v mariadb:/var/lib/mysql mariadb

docker run --name web_server --net net1 -d -p 80:80 dmosk/webapp:v1

* указав опцию --net, наши контейнеры начинают видеть друг друга по своим именам, которые мы задаем опцией --name.

Готово. Для проверки соединения с базой данных в php мы можем использовать такой скрипт:

* в данном примере мы подключаемся к базе docker_db на сервере maria_db с использованием учетной записи docker_db_user и паролем docker_db_password.

После его запуска, мы увидим либо пустой вывод (если подключение выполнено успешно), либо ошибку.

Использование docker-compose

В отличие от docker, с помощью docker-compose можно разворачивать проекты, состоящие из нескольких контейнеров, одной командой.

И так, автоматизируем запуск наших контейнеров с использованием docker-compose. Необходимо, чтобы он был установлен в системе.

Сначала удалим контейнеры, которые создали на предыдущих этапах:

docker rm -f web_server maria_db

Переходим в каталог для наших сборок:

Создаем yml-файл с инструкциями сборки контейнеров через docker-compose:

web_server:
build:
context: ./web-server/
args:
buildno: 1
container_name: web_server
restart: always
environment:
TZ: "Europe/Moscow"
ports:
- 80:80

maria_db:
image: mariadb
container_name: maria_db
restart: always
environment:
TZ: "Europe/Moscow"
volumes:
- /var/lib/docker/volumes/mariadb/_data/:/var/lib/mysql

* в формате yml очень важное значение имеют отступы. Если сделать лишний пробел, то мы получим ошибку.
* где:

Запускаем сборку наших контейнеров с помощью docker-compose:

Запускаем контейнеры в режиме демона:

docker-compose up -d

Проверяем, какие контейнеры запущены:

При внесении изменений можно перезапускать контейнеры командой:

docker-compose up --force-recreate --build -d

Просто пересоздать контейнеры:

или только для одного из сервисов:

docker-compose restart web_server

* где web_server — название сервиса в файле docker-compose.

Возможные проблемы

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

1. Errors during downloading metadata for repository 'AppStream'

Ошибка возникает при попытке собрать имидж на Linux CentOS 8. Полный текст ошибки может быть такой:

Причина: система внутри контейнера не может разрешить dns-имена в IP-адрес.

Решение: в CentOS 8 запросы DNS могут блокироваться брандмауэром, когда в качестве серверной части (backend) стоит nftables. Переключение на iptables решает проблему. Открываем файл:

Бэкап VPS сервера создается пользователем вручную. Число сохраняемых снапшотов может различаться у разных хостинг-провайдеров. Например, на хостинге Eternalhost можно создать до 3 снимков. Все они хранятся на серверах Eternalhost, не занимая ресурсы клиента.

Перед началом работы

Как создать снимок

Возврат к выбранному снимку

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

Как удалить снимок

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

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

Образы контейнера

Если вы ранее использовали LXC, то помните понятие в LXC - шаблон (template). Это обычный shell скрипт, который оформлял файловую систему контейнера и немного конфигурацию. Большинство шаблонов генерировало файловую систему, делая полный bootstrapping на вашей машине. Это занимало время, не всегда работало на всех linux дистрибутивах и занимало сетевую полосу пропускания.

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

Взаимодействие с LXD образами

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

Прозрачный импорт образа

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

Примеры
lxc launch ubuntu:14.04 c1
lxc launch ubuntu:75182b1241be475a64e68a518ce853e800e9b50397d2f152816c24f038c94d6e c2
lxc launch ubuntu:75182b1241be c3

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

Следующие команды при своём запуске заставят LXD проверить образ на актуальность и если образ up-to-date, то контейнер будет создан, не скачивая ничего более. Теперь когда образ закэширован в локальном хранилище, вы можете запускать, не проверяя актуальность - lxc launch 75182b1241be c4

Если у вас есть собственный локальный образ по имени my-image, то просто командуйте - lxc launch my-image c5

Ручное импортирование образов

Копирование с удалённого сервера

Если вы просто хотите скопировать образ с удалённого сервера в локальное хранилище БЕЗ создания контейнера, то можете использовать команду lxc image copy - lxc image copy ubuntu:14.04 local: Это было простое копирование.

Если вы хотите в дальнейшем ссылаться на образ попроще, чем указывая его fingerprint, то можете создать алиас во время копирования.
lxc image copy ubuntu:12.04 local: --alias old-ubuntu
lxc launch old-ubuntu c6

Если хотите использовать алиасы, которые даны на исходном сервере, то можно попросить LXD скопировать их.
lxc image copy ubuntu:15.10 local: --copy-aliases
lxc launch 15.10 c7

Все команды, что мы делали выше, скачивают только текущую версию образа на день операции. Если вы хотите, чтобы LXD отслеживал актуальность копии, то используйте флаг --auto-update - lxc image copy images:gentoo/current/amd64 local: --alias gentoo --auto-update

Импорт тарбола

Если кто-то предоставил вам LXD образ как единый тарбол, вы можете импортировать его - lxc image import name-tarball

Если хотите сделать алиас при импортировании, то lxc image import name-tarball --alias random-image

Иногда вы можете встретить два тарбола, один из которых содержит LXD метаданные. Имя тарбола ничего не даст, ориентируйтесь на размер - тарбол с метаданными меньше. Импортировать оба - lxc image import metadata-tarball rootfs-tarball

Импорт из URL

Команда lxc image import так же работает со специальными URL. Если у вас есть веб-сервер, который обрабатывает заголовки LXD-Image-URL и LXD-Image-Hash, то LXD может брать образы с него.

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

Управление локальным хранилищем образов

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

Список образов

Список всего в вашем хранилище - lxc image list

Можно фильтровать по алиасу или fingerprint - lxc image list amd64

Можно фильтровать по ключ=значение свойств образа - lxc image list os=ubuntu

Посмотреть всё что знает LXD о данном образе можно командой - lxc image info ubuntu

Редактирование образов

Удобный способ редактировать свойства образа с помощью - lxc image edit alias-or-fingerprint
Вам откроют редактор по умолчанию с чем-то вроде:

Удаление образа

Удалить образ - lxc image delete alias-or-fingerprint
Вы можете не удалять принудительно кэшированные образы, так как они автоматически будут удалены LXD после истечения срока (по умолчанию 10 дней после последнего использования).

Экспорт образа

Если вы хотите получить тарболы из образа, который сейчас у вас в локальном хранилище, то поможет - lxc image export

lxc image export old-ubuntu .

Форматы образов

LXD поддерживает 2 формата образов: единый (unified) и разделённый (split). Оба эффективны, но split облегчает повторное использование файловой системы другими контейнерами. LXD фокусируется исключительно на контейнерах с системами (system container). Не поддерживает контейнеры приложений (application container) и не планирует. Образы в своей сути просты. В них файловая система контейнера и метаданные, описывающие когда сделано, когда истекает срок, архитектура и т.д.

Подробно в документации Image Format.

Единый образ. Unified image. Одиночный тарбол.

Один большой тарбол, содержащий файловую систему внутри rootfs каталога, файл metadata.yaml и шаблоны в каталоге templates. Сжатие тарбола любое, вплоть до его отсутствия. Хэш образа - это sha256 итогового тарбола.

Разделённый образ. Split image. Два тарбола.

Данный формат часто используется при развёртывании своих личных образов, обладая уже сжатым тарболом файловой системы. Второй тарбол хранит только метаданные в файле metadata.yaml и каталог шаблонов templates. Хэш образа в sha256 - это конкатенация обоих тарболов.

Метаданные образа

Типичный metadata.yaml файл выглядит схоже:

Свойства

Есть два обязательных поля: дата создания в формате UNIX EPOCH и архитектура. Всё остальное можно оставить без установленных значений и импорт образа будет успешен.

Шаблоны

Механизм шаблонов позволяет некоторым файлам внутри контейнера изменяться в какой-то момент во время жизненного цикла контейнера. Для этих целей используется pongo2 (templating engine). Таким образом, свойства, определённые пользователем, или LXD свойства могут менять содержимое определённых файлов. В примере, в Убунту мы вызываем cloud-init и выключаем некоторые скрипты инициализации.

Создание своих образов

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

Превращение контейнера в образ

Самый простой способ сделать образ в LXD - это превратить контейнер в образ.

lxc launch ubuntu:14.04 my-container
lxc exec my-container bash
ваши команды, изменяющие что-либо
lxc publish my-container --alias my-new-image

Можно последние наработки, сохранённые в снимке сохранить как образ - lxc publish my-container/some-snapshot --alias some-image

Ручное создание образа

Создание своего образа не сложно:
1) Создаётся файловая система контейнера. Этот шаг целиком зависит от используемого вами linux дистрибутива. Для Ubuntu и Debian можно использовать debootstrap.
2) Если нужно, то настройте необходимое в вашем дистрибутиве.
3) Создайте тарбол файловой системы контейнера, опционально сжав его.
4) Сделайте metadata.yaml, основываясь на описанном выше.
5) Создайте ещё тарбол из файла metadata.yaml.
6) Импортируйте два тарбола в итоговый образ LXD - lxc image import metadata-tarball rootfs-tarball --alias some-name

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

Публикация вашего образа

Все LXD демоны действуют как сервера образов. Если не сказано иного, все образы, загруженные с удалённых хранилищ, метятся как приватные и только доверенные (trust) клиенты могут их использовать. Но вы можете сделать сервер публичным: вы должны пометить (tag) образы как public и убедиться, что LXD демон слушает сеть.

Просто запуск публичного LXD сервера

Простой путь расшарить образы состоит в запуске публичного LXD. Наберите - lxc config set core.https_address "[::]:8443"

Удалённые пользователи могут добавить ваш сервер как публичный - lxc remote add имя-сервера IP-DNS --public
Добавленный сервер можно использовать так же, как и сервера образов, доступных по умолчанию. Так как сервер добавлен с ключём --public, то у клиента никакой аутентификации не требуется и ему доступны все образы, помеченные как public. Чтобы сделать образ публичным, используйте lxc image edit и выставьте флаг public в true.

Веб-сервер

Если хотите сделать всё динамичнее, то сервер можно обязать проверять LXD-Server-Architectures и LXD-Server-Version, которыми обеспечит демон LXD, что позволит реализовать скачивание образа с правильной архитектурой.

Создание сервера simplestreams

Удалённые сервера ubuntu: и ubuntu-daily: не используют LXD протокол (images:), а используют протокол simplestreams. Simplestreams - формат описания сервера образов, использующий JSON. Он используется в таких инструментах как OpenStack, Juju, MAAS для поиска, скачивания и зеркалирования образов систем. LXD использует его, как и основной протокол, для получения образов.

Возможно, это не самый простой способ предоставить образы, но за дополнительной информацией можете обратиться к Simple Streams.

Надеюсь, что статья дала хорошее представление о том, как LXD управляет образами, как создавать и распространять свои собственные. Способность легко получить бит-в-бит нужный образ в современном, глобальном мире является большим шагом по сравнению со старым LXC и ведёт к более воспроизводимой инфраструктуре.

Читайте также: