
Астрологи объявили месяц статей о домашних NAS на хабре, так что поделюсь и своей историей успеха…
Не так давно я попробовал новый FreeNAS Coral. Понравилось мне в нем если не все, то очень многое: это и новый гипервизор bhyve, и повсеместное использование 9P для проброса файловой системы на гостя, а так же идея с docker и многое другое.
Кроме того я ещё больше влюбился в ZFS со всеми её плюшками, такими как дедупликация и сжатие на лету.
Но к сожалению не все было так гладко как хотелось бы и, к тому же, флешка с установленной системой приказала долго жить, так что настало время для новых экспериментов!
На этот раз я задумал реализовать что-то похожее, но только лучше и целиком на Linux.
В статье так же будет немного рассказано про Docker и автоматический прокси с автоматическим получением сертификатов Letsencrypt.
Для начала расскажу что же мне все таки не понравилось в FreeNAS Corral:
- Не готов для production. (недавно этот релиз вообще отозвали)
- Работа с docker удобна только в случае единичных контейнеров, в случае когда контейнеров много управление через веб-морду становится крайне неэффективным.
- Контейнеры запускаются внутри виртуальных машин с Linux, а порты проксируются через хост, что в принципе не плохо, но подразумевает некий оверхед в сравнении если бы они запускались прямо на хосте.
- Гипервизор bhyve пока не поддерживает live-snapshots.
- Нет возможности создавать виртуальные машины не из шаблонов. (по крайней мере в GUI)
- Система установленая на флешку ужасно тормозила.
В принципе со всем этим можно было бы жить, но как я говорил флешка с системой сдохла и теперь у меня есть новые идеи:
-
Систему нужно устанавливать на жёсткий диск, пусть даже самый простой, но на диск, а не на флешку.
Идея с установленной системы отдельно от данных хороша, но сколько я флешек не перепробовал (включая USB 3.0) всё равно работает очень плохо и безбожно тормозит. Так что ставить будем на отдельный HDD. -
ZFS в качестве основанной файловой системы. ZFS позволяет не думать как мне распределять ресурсы хранилища между файловыми системами и виртуальными машинами, она поддерживает моментальные снимки (снапшоты), дедупликацию и сжатие на лету, а также известный RAIDZ.
- Proxmox в качестве системы управления виртуализацией. Здесь есть все что необходимо: это поддержка как полной так и контейнерный виртуализации, снапшоты, автоматические бекапы и многое другое, а главное ZFS тут предлагается по умолчанию и работает прямо из коробки.
Proxmox целиком и полностью управляется через современный веб-интерфейс на ExtJS:


для этого используется HTML5 клиент noVNC
- OpenMediaVault в качестве системы управления хранилищем.
При выборе хранилища основным критерием была поддержка ZFS и работа на linux, а не на FreeBSD т.к. его хотелось установить на хостовую систему вместе с Proxmox а не на отдельную виртуальную машину.
Я рассматривал несколько софтин на эту роль, пробовал даже openATTIC — к сожалению поддержка ZFS там оказалась довольно слаба и на данный момент многих опций там просто нет, хотя я уверен что с CEPH дело предстоит несколько иначе.
В поисках я наткнулся на замечательный плагин добавляющмй поддержку zfs для OpenMediaVault — он даёт полный контроль над ZFS. Вместе с самим OpenMediaVault он полностью реализует все те функции, чего я так долго хотел получить от хранилища.
OpenMediaVault, как и Proxmox, целиком и полностью управляется через современный веб-интерфейс на ExtJS:

Proxmox и OpenMediaVault будут составлять ядро нашей системы, в результате чего мы получим многофункциональный комбайн продвинутой системы хранилища и продвинутой системы виртуализации в одной коробке, все данные при этом, как и диски виртуальных машин будут храниться на ZFS.
В случае если понадобится развернуть какой то новый сервис, всегда можно создать отдельную
виртуальную машину или контейнер для этого. Об этом я раскскажу чуть позже.
Обе системы поставляются и работают на Debian, что с одной стороны должно существенно упростить задачу, но с другой стороны обе системы несут в себе огромное количество пакетов и зависимостей, которые периодически могут пересекаться и конфликтовать между ссобой.
И специально для вас я написал небольшую инструкцию о том как сделать это.
Как установить OpenMediaVault на Proxmox
Установка Proxmox
Вам понадобится установочный диск, взять его можно на официальном сайте:
- https://www.proxmox.com/en/downloads/category/iso-images-pve
(нам нужна 4 версия, так как она основана на Debian 8 Jessie)
Установка проста и интуитивно понятна, так что думаю, не вызовет у вас лишних вопросов.
Скажу только что желательно иметь отдельный физический диск под систему, чтобы в случае чего её всегда можно было бы безболезненно переустановить, не затрагивая при этом диски с данными.
При установке Proxmox можно так же выбрать файловую систему ZFS или даже настроить програмный RAID.
Установка OpenMediaVault
Установим репозитроий OpenMediaVault 3.0 Erasmus:
echo "deb http://packages.openmediavault.org/public erasmus main" > /etc/apt/sources.list.d/openmediavault.list
Как я говорил ранее, пакет openmediavault имеет некоторые неразрешимые зависимости с компонентами Proxmox, в часности это качается пакета watchdog, который в Proxmox начиная с версии 4.0 является fencing-демоном по умолчанию. В нашем случае он установлен по умолчанию как зависимость от proxmox-ve, но мы его не используем т.к. не используем кластеризацию.
В любом случае эти зависимости нам нужно как-то разрешить, и поэтому мы пересоберем deb-пакет для openmediavault.
Подготовим окружение для сборки:
apt install build-essentials
Скачаем исходники OpenMediaVault 3.0 Erasmus, и перейдем в директорию для сборки:
wget https://github.com/openmediavault/openmediavault/archive/3.x.tar.gz -O - | tar xzvf - cd openmediavault-3.x/deb/openmediavault
Эта команда покажет нам необходимые зависимости, которые мы должны установить в системе перед сборкой пакета:
dpkg-checkbuilddeps
Исходя из вывода предыдущей команды установим необходимые пакеты:
apt install debhelper fakeroot gettext dh-systemd doxygen
Теперь нам нужно удалить watchdog из зависимостей, для этого отредактируем debian/control и удалим оттуда watchdog:
vim debian/control # remove: watchdog
Проверим зависимости для сборки еще раз:
dpkg-checkbuilddeps
И запустим саму сборку:
dpkg-buildpackage -us -uc
После сборки вы получите готовый deb-пакет, который мы и установим в систему:
cd .. dpkg -i openmediavault_*.deb
Теперь установим остальные зависимости, для этого запустим:
aptitude -f install
Теперь можно запустить скрипт для начальной конфигурации, поменять пароль администратора / порт веб-сервера и что-нибудь еще:
omv-firstaid
Установка плагина ZFS:
Плагин openmediavault-zfs устанавливается отдельно от OpenMediaVault и так как он тоже имеет неразрешимые зависимости мы тоже соберем его вручную:
Скачаем исходники, и перейдем в директорию для сборки:
wget https://github.com/OpenMediaVault-Plugin-Developers/openmediavault-zfs/archive/master.tar.gz -O - | tar xzvf - cd openmediavault-zfs-master
Подправим зависимости, удалим zfs-dkms так-как в Proxmox начиная с версии 4.0, ZFS уже идет в комплекте с ядром, до кучи за ненадобностью удалим так же linux-headers-* / pve-headers :
vim debian/control # remove: zfs-dkms # remove: linux-headers-amd64 | pve-headers | linux-headers-3.16.0-4-all
Проверим зависимости для сборки:
dpkg-checkbuilddeps
Запустим сборку:
dpkg-buildpackage -us -uc
После сборки установим полученный пакет и зависимости для него:
cd .. dpkg -i openmediavault-zfs_*.deb aptitude -f install
Если возникнут трудности со сброкой пакетов, в документации Debian есть неплохая статья на русском языке:
- [https://www.debian.org/doc/manuals/maint-guide/build.ru.html](Глава 6. Сборка пакета)
На этом пожалуй все, теперь вы имеете Proxmox и OpenMediaVault установленные на одной системе, самое время перейти в GUI создать и настроить пулы ZFS и подключить их в Proxmox.
Как это сделать я описывать не буду, об этом и так полно информации в интернете.
Что дальше?
Дальше самое интересное, теперь можно приступить к настройке дополнительных сервисов.
Из них я хочу показать как настроить:
- WordPress — это один из самых простых и распространненых движков для построения сайтов.
- Nextcloud — ваше личное облако и интерфейс для доступа к файлам.
- Deluge — на мой взгляд лучшая торрентокачалка.
- Emby — свободный медиа сервер, позволяет стримить мультимедиа прямо в браузере или через DLNA.
- nginx-proxy — который будет автоматически генерировать конфиг и все эти сервисы проксировать.
- nginx-proxy-companion — будет получать и обновлять сертификаты в автоматическом порядке.
Каждый из этих сервисов будет доступен на субдомене и защищен SSL, с валидным сертификатом от Letsencrypt. На помощь нам придет Docker, думаю что это гораздо проще чем вы могли бы себе это представить.
Я полагаю вы уже настроили хранилище ZFS и подключили его в интерфейс Proxmox.
В моем конкретном случае есть два пула:
rpool— это тот что создал proxmox при установкеtank— это RAIDZ пул из трех дисков с данными
Также я создал четыре основных датастора:
tank/pve— для виртуальных машин Proxmoxtank/docker— здесь будут храниться данные сервисов запущенных в dockertank/cloud— для данных nextcloudtank/data— основная файлопосойка, внутри есть еще несколько датасторов, таких какMusic,Photos,Movies, каждый со своими настройками, например дляMusicиPhotosвключена дедупликация, так как у меня большое количество повторяющихся файлов, которые я неизвсестно когда разгребу…
Теперь я хочу создать отдельную виртуальную машину в Proxmox, а точнее контейнер и запускать все в нем, что бы больше не издеваться над основной системой, и по возможности изолировать эти сервисы от нее.
В конфигурацию контейнера я добавил следующий строки:
lxc.aa_profile: unconfined lxc.cap.drop: mp0: /tank/data,mp=/data mp1: /tank/cloud,mp=/cloud mp2: /tank/docker,mp=/docker
Первые две выдают контейнеру больше прав, так что становится возможным запустить другие конейнеры внутри него, это необходимо для функционирования docker.
Остальные строки подключают необходимые директории к файловой системе гостя.
Внутри контейнера нам необходимо установить docker и docker-compose, а после этого я покажу как у меня все организованно.
В директории /docker у меня созданы директории для каждого отдельного сервиса:
# ls /docker/ deluge emby nextcloud nginx-proxy wordpress
В каждой директории лежит отдельный docker-compose.yml файл и данные каждого отдельного контейнера.
К примеру так выглядит docker-compose.yml:
nginx-proxy: restart: on-failure:5 image: jwilder/nginx-proxy:alpine ports: - "80:80" - "443:443" volumes: - ./certs:/etc/nginx/certs:ro - ./vhost.d:/etc/nginx/vhost.d - ./html:/usr/share/nginx/html - /var/run/docker.sock:/tmp/docker.sock:ro labels: - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true" nginx-proxy-companion: restart: on-failure:5 image: jrcs/letsencrypt-nginx-proxy-companion volumes: - ./certs:/etc/nginx/certs:rw - /var/run/docker.sock:/var/run/docker.sock:ro volumes_from: - nginx-proxy
Вы можете зайти в директорию с nginx-proxy и выполнив docker-compose up вы проучите готовый запущенный сервис, это очень удобно!
- Контейнер
nginx-proxyв двух словах работает следующим образом, он запускается слушаетdocker.sockи в случае если обраружит запущенный контейнер с переменнойVIRTUAL_HOST, то сгенерирует конфиг для этого виртуального хоста, с проксированием на виртуальный ip контейра. - Контейнер
nginx-proxy-companionработает схожим образом, если обнаруживает запущенный контейнер с переменнойLETSENCRYPT_HOSTон автоматически получает для него сертификат.
Для более подробной информации совертую обратиться к официальной страничке проектов:
- nginx-proxy — который будет автоматически генерировать конфиг и все эти сервисы проксировать.
- nginx-proxy-companion — будет получать и обновлять сертификаты в автоматическом порядке.
Сразу должен предупредить, nginx-proxy не работает с Compose file version 2, т.к. требует чтобы между контейнерами была одна общая сеть.
Так что необходимо использлвать только Compose file version 1, либо держать все сервисы в одном конфиге.
Теперь сами конфиги:
mysql: restart: on-failure:5 image: mariadb:10.0 hostname: mysql volumes: - /etc/localtime:/etc/localtime:ro - ./mysql:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=seekac7aexoh2eithut6sie1eYaeNgei - MYSQL_DATABASE=example_org - MYSQL_USER=example_org - MYSQL_PASSWORD=imieth7iev4dah6eeraik6Ohz6oiVup7 wordpress: restart: on-failure:5 image: wordpress hostname: example.org volumes: - /etc/localtime:/etc/localtime:ro - ./wordpress:/var/www/html links: - mysql:mysql environment: - "VIRTUAL_HOST=example.org,www.example.org" - "LETSENCRYPT_HOST=example.org,www.example.org" - "LETSENCRYPT_EMAIL=admin@example.org"
nextcloud: restart: on-failure:5 image: nextcloud hostname: cloud domainname: example.org volumes: - /etc/localtime:/etc/localtime:ro - ./nextcloud:/var/www/html - /cloud:/cloud - /data:/data links: - mysql:mysql - redis:redis environment: - "VIRTUAL_HOST=cloud.example.org" - "LETSENCRYPT_HOST=cloud.example.org" - "LETSENCRYPT_EMAIL=admin@example.org" redis: restart: on-failure:5 image: redis hostname: redis volumes: - /etc/localtime:/etc/localtime:ro mysql: restart: on-failure:5 image: mariadb:10.0 hostname: mysql volumes: - /etc/localtime:/etc/localtime:ro - ./mysql:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=ei8aiWaeDaeDoo8aida0woaNaiy8deer - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud - MYSQL_PASSWORD=rahGhied8lei6ogh2keitie1chaiheex
deluge: restart: on-failure:5 image: linuxserver/deluge hostname: torrent domainname: example.org volumes: - /etc/localtime:/etc/localtime:ro - ./config:/config - /data:/data ports: - 53160:53160 - 53160:53160/udp - 8112:8112 - 58846:58846 - 6881:6881 expose: - 8112 environment: - PUID=33 - PGID=33 - "VIRTUAL_HOST=torrent.example.org" - "VIRTUAL_PORT=8112" - "LETSENCRYPT_HOST=torrent.example.org" - "LETSENCRYPT_EMAIL=admin@example.org"
emby: restart: on-failure:5 image: emby/embyserver volumes: - /etc/localtime:/etc/localtime:ro - ./config:/config - /data:/data environment: - APP_UID=33 - APP_GID=33 net: host
Для emby я использлвал net: host — это означает что контейнер будет использовать хостовую сеть вместо виртуальной сети для docker. Этот шаг необходим для работы DLNA-сервера. По той же причине не указанны VIRTUAL_HOST и LETSENCRYPT_HOST переменные.
Но стойте, как же быть? — как добавить такой контейнер к nginx-proxy?
А как быть если я хочу иметь доступ к веб-интерфейсам Proxmox и OpenMediaVault снаружи? — а они запущены вообще не в docker и даже не на этом хосте.
Решение не заставило себя долго искать, для подключений такого типа можно создать еще один отдельный прокси контейнер:
nginx-local: restart: on-failure:5 image: nginx expose: - 80 environment: - "VIRTUAL_HOST=media.example.org,pve.example.org,nas.example.org" - "LETSENCRYPT_HOST=media.example.org,pve.example.org,nas.example.org" - "LETSENCRYPT_EMAIL=admin@example.org" volumes: - ./local-config:/etc/nginx/conf.d
С таким конфигом:
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the # scheme used to connect to this server map $http_x_forwarded_proto $proxy_x_forwarded_proto { default $http_x_forwarded_proto; '' $scheme; } # If we receive X-Forwarded-Port, pass it through; otherwise, pass along the # server port the client connected to map $http_x_forwarded_port $proxy_x_forwarded_port { default $http_x_forwarded_port; '' $server_port; } # Set appropriate X-Forwarded-Ssl header map $scheme $proxy_x_forwarded_ssl { default off; https on; } access_log off; # HTTP 1.1 support proxy_http_version 1.1; proxy_buffering off; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ""; server { server_name _; # This is just an invalid value which will never trigger on a real hostname. listen 80; return 503; } # media.example.org server { server_name media.example.org; listen 80 ; location / { proxy_pass http://192.168.225.20:8096/; } } # pve.example.org server { server_name pve.example.org; listen 80 ; location / { proxy_pass https://192.168.225.10:8006/; } } # nas.example.org server { server_name nas.example.org; listen 80 ; location / { proxy_pass http://192.168.225.10:8080/; } }
На этом все, спасибо за внимание и удачи в экспериментах 🙂
ссылка на оригинал статьи https://habrahabr.ru/post/328048/
Добавить комментарий