Авторские статьи

LXD 2.0: Удалённые хосты и миграция контейнеров [6/12].


6 статья из 12. Экватор. Поймём как безопасно общаются клиенты с удалёнными хостами и мигрируем первый контейнер на другой хост в offline режиме. Live Migration будет рассмотрена в следующих статьях.

Протоколы удалённого доступа

LXD 2.0 поддерживает 2 протокола:

  • LXD 1.0 API. Этот REST API используется при копировании/перемещении образов и контейнеров между клиентом и LXD демоном, а также между LXD демонами.
  • Simplestreams. Протокол Simplestreams - протокол только-для-чтения, только-для-образов используется клиентами и LXD демонами для получения информации об образах и при импорте образов из публичных серверов хранилищ образов.

Всё описанное ниже использует какой-либо из этих двух.

Безопасность

Аутентификация для LXD API осуществляется с помощью проверки подлинности сертификата клиента через TLS 1.2. Когда два LXD демона должны обменяться информацией, то временный токен генерирует демон source и передаётся через клиент демону target. Токен используется только для доступа к конкретному потоку и немедленно отзывается для предотвращения повторного использования.

Чтобы избежать атак "человек по середине" (Man In The Middle), клиентский инструментарий отсылает сертификат сервера source на сервер target. Это означает, что для конкретной операции сервер target обеспечивается URL сервера source, одноразовым токеном для доступа к требуемому ресурсу и сертификатом. Это предотвращает атаки MitM и даёт временный доступ для передачи объекта.

Требования к сети

LXD 2.0 использует модель, где целевая сторона (target) подключается напрямую к source для получения данных (fetch). Это означает, что вы должны убедиться в возможности пройти через правила файрвола target серверу к source серверу. Сейчас рассматривается вопрос о возможности реверса общения - source к target или проксировании через клиента в особо тяжёлых случаях, когда драконовские правила файрвола предотвращают общение между двумя узлами.

Взаимодействие с удалёнными хостами

Вместо того, чтобы заставлять пользователей каждый раз вводить имена хостов или их IP адреса, LXD вводит понятие remotes. По умолчанию единственным настроенным LXD remote является "local:", который так же является дефолтным. Данный local remote использует LXD REST API для общения с локальным демоном через unix сокет.

Добавление remote

Представим, что у вас две машины с установленным LXD. Ваша локальная машина и удалённый хост по имени foo. Прежде вам нужно убедиться, что foo слушает сеть и имеет пароль. Зайдите доступным способом на foo и командуйте:
lxc config set core.https_address [::]:8443
lxc config set core.trust_password something-secure-password

Теперь на локальном LXD нужно просто сделать его видимым сеть, чтобы передавать контейнеры и образы - lxc config set core.https_address [::]:8443

Когда оба демона видят сеть, с локальной машины можно добавить foo - lxc remote add foo 1.2.3.4
Замените 1.2.3.4 на IP адрес или FQDN сервера.

Вы увидите что-то подобное

lxc remote add foo 2607:f2c0:f00f:2770:216:3eff:fee1:bd67
Certificate fingerprint: fdb06d909b77a5311d7437cabb6c203374462b907f3923cefc91dd5fce8d7b60
ok (y/n)? y
Admin password for foo: 
Client certificate stored at server: foo

Можно посмотреть свои remotes, в том числе добавленный только что foo.
lxc remote list

+-----------------+-------------------------------------------------------+---------------+--------+--------+
|      NAME       |                         URL                           |   PROTOCOL    | PUBLIC | STATIC |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| foo             | https://[2607:f2c0:f00f:2770:216:3eff:fee1:bd67]:8443 | lxd           | NO     | NO     |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| images          | https://images.linuxcontainers.org:8443               | lxd           | YES    | NO     |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| local (default) | unix://                                               | lxd           | NO     | YES    |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| ubuntu          | https://cloud-images.ubuntu.com/releases              | simplestreams | YES    | YES    |
+-----------------+-------------------------------------------------------+---------------+--------+--------+
| ubuntu-daily    | https://cloud-images.ubuntu.com/daily                 | simplestreams | YES    | YES    |
+-----------------+-------------------------------------------------------+---------------+--------+--------+

Взаимодействуем с добавленным

Итак, у нас есть удалённый сервер, который только что добавили, и что с ним делать? Ну, почти всё, что вы видели в постах ранее, только указать на каком LXD хосте это делается. Пример: lxc launch ubuntu:14.04 c1 запустит контейнера на дефолтном remote (lxc remote get-default), которым является ваш локальный хост.

Можно запустить контейнер на хосте foo - lxc launch ubuntu:14.04 foo:c1

Что мы запустили на хосте foo? lxc list foo:

+------+---------+---------------------+-----------------------------------------------+------------+-----------+
| NAME |  STATE  |         IPV4        |                     IPV6                      |    TYPE    | SNAPSHOTS |
+------+---------+---------------------+-----------------------------------------------+------------+-----------+
| c1   | RUNNING | 10.245.81.95 (eth0) | 2607:f2c0:f00f:2770:216:3eff:fe43:7994 (eth0) | PERSISTENT | 0         |
+------+---------+---------------------+-----------------------------------------------+------------+-----------+

Одну вещь вы должны помнить - нужно указывать удалённый хост для образов и контейнеров. То есть если есть локальный образ my-image на foo и вы хотите на нём создать контейнер с2, то нужно указывать так:
lxc launch foo:my-image foo:c2

Запустить bash в контейнере на удалённом хосте foo - lxc exec foo:c1 bash

Копирование контейнеров

Копирование контейнеров между хостами делается просто, как и звучит: lxc copy foo:c1 c2
Вы получите новый контейнер c2 из c1, работающий на foo. Команда требует остановки c1 перед копированием, но можно воспользоваться механизмом снимка и создания контейнера из снимка в реалтайм.
lxc snapshot foo:c1 current
lxc copy foo:c1/current c3

Перемещение контейнеров

Сейчас мы не рассматриваем живую миграцию (live migration), которая будет раскрыта в следующих постах. Вы должны остановить исходный контейнер до его перемещения, остальное работает как ожидается.
lxc stop foo:c1
lxc move foo:c1 local:

Пример идентичен вышеописанному
lxc stop foo:c1
lxc move foo:c1 c1

Как это всё работает?

Взаимодействие с удалёнными контейнерами работает через REST API с помощью HTTPS транспорта. Чуток всё посложнее при взаимодействии между двумя демонами LXD, например при копировании или перемещении.

Что происходит:
1) Пользователь командует - lxc move foo:c1 c1
2) Клиент обращается к local: на предмет существования контейнера c1
3) Клиент забирает (fetch) информацию о контейнере с foo
4) Клиент запрашивает токен для миграции с демона на foo, который выступает сервером source.
5) Клиент посылает токен, URL и сертификат foo локальному демону LXD c информацией о контейнере и устройствах.
6) Локальный демон LXD соединяется напрямую к foo, используя токен:
    a) соединяемся к websocket
    b) согласовывается метод передачи файловой системы (родная send/receive zfs, родная send/receive btrfs, обычный rsync)
    c) Если доступен локально образ, из которого был создан контейнер, то просто он распаковывается для создания черновика-контейнера. Это позволяет избежать ненужной передачи данных.
    d) Передаётся контейнер и все его снимки как делта между текущим состоянием и черновиком-контейнером.
7) Если всё закончилось успехом, то клиент посылает инструкцию foo на удаление исходного контейнера.

Оглавление цикла статей про LXD 2.0.
Предыдущая статья LXD 2.0: Управление образами [5/12].
Следующая статья LXD 2.0: Docker в LXD [7/12].

Дата последней правки: 2016-05-22 20:35:54

RSS vasilisc.com   


Разделы

Главная
Новости
Ворох бумаг
Видео Linux
Игры в Linux
Безопасность
Статьи об Astra Linux
Статьи о FreeBSD
Статьи об Ubuntu
Статьи о Snappy
Статьи об Ubuntu Phone
Статьи о Kubuntu
Статьи о Xubuntu
Статьи о Lubuntu
Статьи об Open Source
Карта сайта