Интеграция flannel и docker

04/17/2017

Прежде чем начать, убедитесь, что у вас есть установленный и готовый к запуску docker - эта статья описывает только процедуру установки и конфигурации flannel, а также его интеграции с docker.

Для вашего удобства, все описанное ниже доступно в скриптах автоматизации ansible в нашем gitlab репозитории

Установить flannel можно как минимум 3-мя способами. В некоторых дистрибутивах он есть в репозиториях; так же прекомпилированный flannel доступен для скачивания с github, ну и, конечно же, никто не отменял сборку из исходный текстов. Выбор всегда за вами, но мы будем рассматривать пока только второй способ, так как он на наш взгляд наименее трудозатратен и позволяет получить всегда свежую версию flannel.

Создайте папку для размещения flannel. В нашей лаборатории принято размещать стороннее ПО в папке /opt, но вы вольны изменить путь, как захотите:

mkdir /opt/flannel/0.7.0

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

Перейдите в только что созданную папку

cd /opt/flannel/0.7.0

Откройте новую вкладку в вашем браузере и перейдите по ссылке https://github.com/coreos/flannel/releases/. С помощью, например, wget скачайте tar.gz архив с flannel. На момент написания статьи flannel был доступен в версии 0.7.0

wget https://github.com/coreos/flannel/releases/download/v0.7.0/flannel-v0.7.0-linux-amd64.tar.gz

Распакуйте архив

tar -xzvf flannel-v0.7.0-linux-amd64.tar.gz

Удалите архив

rm flannel-v0.7.0-linux-amd64.tar.gz

Создайте альтернативу (символическую ссылку) на flanneld - демона, обеспечивающего основной функционал

update-alternatives --install \
  /usr/bin/flanneld \
  flanneld \
  /opt/flannel/0.7.0/flanneld 20

Эта команда создаст символическую ссылку в /usr/bin/flanneld, указывающую на /opt/flannel/0.7.0/flanneld через промежуточную ссылку - альтернативу. Текущий приоритет алтернативы - 20. В дальнейшем, например при обновлении, логично будет повысить приоритет.

Проверьте, что вы можете получить информацию о текущей альтернативе для flanneld

update-alternatives --display flanneld
 
 flanneld - manual mode
  link best version is /opt/flannel/0.7.0/flanneld
  link currently points to /opt/flannel/0.7.0/flanneld
  link flanneld is /usr/bin/flanneld
 /opt/flannel/0.7.0/flanneld - priority 20

Теперь вы можете работать без абсолютных путей, просто выполните в терминале

flanneld --version
v0.7.0

Самое время попытаться запустить демон и настроить его автозагрузку. В этом нам поможет systemd. Создайте unit в /etc/systemd/system/flanneld.service следующего содержания

[Unit]
Description=Kube subnet manager
Documentation=https://github.com/coreos/flannel
Requires=network-online.target
After=network-online.target
 
[Service]
 
EnvironmentFile=-/etc/default/flannel
 
Type=notify
ExecStart=/usr/bin/flanneld \
  --etcd-endpoints=${ETCD_HOSTS} \
  --etcd-prefix=${ETCD_PREFIX} \
  --logtostderr=true \
  --subnet-dir=/run/flannel/networks \
  --subnet-file=/run/flannel/subnet.env $FLANNELD_OPTS
 
RuntimeDirectory=flannel
 
[Install]
WantedBy=multi-user.target

Очень много строчек, но они все необходимы. Давайте разбираться. С первыми 4-мя строчками должно быть понятно: описание юнита и установка зависимостей от наличия сети (действительно, flannel не сможет работать без сети). Дальше идет указания на файл, хранящий значения переменных, используемых в ExecStart. Нужно это для того, чтобы при изменениях параметров запуска, вам не было необходимости править unit-файл - достаточно поменять значение переменной в этом файле. "ExecStart=" собственно указывает на то, что запускать и с какими параметрами (их мы рассмотрим подробнее чуть позже). "RuntimeDirectory=" по-настоящему волшебная директива - она заставляет systemd перед стартом демона создать папку с указанным именем в /run. Это отличное решение для хранения временных файлов, которые после остановки демона или перезагрузки системы уничтожаются. Ну и директива "WantedBy=" в секции "[Install]" позволяет нам запускать flannel автоматически при старте системы.

Перечитайте конфигурацию systemd

systemctl daemon-reload

Активируйте демон, но пока не запускайте

systemctl enable flanneld

Давайте разбираться с параметрами запуска flanneld. Самый главный аргумент без которого ничего работать не будет - это месторасположение кластера etcd. etcd - это хранилище конфигурации, как и текстовые файлы, однако доступное по сети с интегрированной поддержкой кластеризации и кучей других плюшек. Там должен быть указан как минимум адресный диапазон, который будет задействован flanneld. Установка и настройка etcd - это тема для другой статьи, но вам он нужен запущенный и готовый принимать соединения. Без этого flanneld не взлетит. Указать адресный диапазон для flanneld можно с помощью, например, etcdctl -  стандартной программы управления etcd

etcdctl set /flannel/config '{"Network": "172.16.0.0/12"}'

Как видите, мы использовали кастомный префикс - "/flannel", так как префикс по-умолчанию, нам показался странным и не очевидным - "/coreos.com/network". 172.16.0.0/12 - адресное пространство, которое будет использовать flanneld для настройки интерфейсов и маршрутизации трафика. "--subnet-dir=" и "--subnet-file=" указывают на некоторые временные файлы, и вы скоро поймете для чего они нужны, а $FLANNELD_OPTS на любые другие возможные опции запуска

Последний штрих перед запуском - это создать тот самый файл с переменными, необходимыми нам для разыменования опций запуска. Исходя из unit-файла размещаться такой файл должен по пути /etc/default/flannel. Настроим его содержимое:

ETCD_HOSTS="http://192.168.8.2:2379"
ETCD_PREFIX="/flannel"
FLANNELD_OPTS=""

Все переменные получили свое значение. Первая указывает на адрес etcd сервера (или серверов, через запятую), а вторая на префикс - путь относительно которого в etcd начинаются записи конфигурации flannel. Запустите демон

systemctl start flanneld

Вы должны увидеть в системе новый интерфейс

ip addr show flannel0
 
32: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none
    inet 172.16.21.0/12 scope global flannel0
       valid_lft forever preferred_lft forever
    inet6 fe80::42a8:293:a7e2:70ac/64 scope link flags 800

Как видите на интерфейс "навешан" адрес сети. Однако его маска меньше чем маска, заданная нами в предыдущей конфигурации, да и третий октет поменялся... Так и должно быть - flanneld сходил в etcd, узнал, какую сеть ему нужно дробить (каждый новый flanneld забирает свой кусок сети), создал интерфейс а назначил на него адрес этого "куска" сети. Обратите внимание также на файлик с переменными, создаваемый flanneld при старте. Помните опцию "--subnet-file="? Давайте посмотрим, что в нем:

cat /run/flannel/subnet.env
 
FLANNEL_NETWORK=172.16.0.0/12
FLANNEL_SUBNET=172.16.21.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false

Некоторые данные об интерфейсе flannel. Эти данные нам позволят изменить docker так, чтобы трафик генерируемый им (фактически контейнерами за ним) ядром linux перенаправлялся в сеть flannel. Взгляните на unit-файл docker, сейчас установленный в вашей системе. Скорее всего он будет похож на то, что приведено ниже

cat /lib/systemd/system/docker.service
 
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target docker.socket firewalld.service
Requires=docker.socket
 
[Service]
Type=notify
 
ExecStart=/usr/bin/dockerd -H fd://
ExecReload=/bin/kill -s HUP $MAINPID
 
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
 
[Install]
WantedBy=multi-user.target

Не меняйте его. Создайте аналогичный файл, но не в каталоге "/lib/systemd/system", а в каталоге "/etc/systemd/system" - юниты, размещенные в "/etc/systemd/system" имеют приоритет над юнитами, размещенными в "/lib/systemd/system". Приведите юнит к следующему виду:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
Requires=flanneld.service After=flanneld.service
 
[Service]
Type=notify
 
EnvironmentFile=-/etc/default/docker
EnvironmentFile=-/run/flannel/subnet.env
ExecStart=/usr/bin/dockerd
   --host fd:// \
   --bip=${FLANNEL_SUBNET} \
   --mtu=${FLANNEL_MTU} $DOCKER_OPTS
 
ExecReload=/bin/kill -s HUP $MAINPID
 
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
 
RuntimeDirectory=docker
 
[Install]
WantedBy=multi-user.target

Как видите мы добавили файл, созданный flannel в качестве дополнительного EnvironmantFile для docker и указали ряд опций, позволяющий докер задействовать адресное пространство flannel, а именно "--bip", указывающий docker какой IP адрес повесть на интерфейс docker0, "--mtu" соответственно задает максимальный размер IP пакета, который можно через этот интерфейс передать. Не удивительно, что его размер уменьшился до 1472, ведь flannel, получив пакет с интерфейса docker0 упаковывает его в другой IP пакет для отравки через сеть.

Не забудьте перечитать конфигурацию systemd

systemctl daemon-reload

Запустите/перезапустите docker

systemctl restart docker

Убедитесь, что docker начал использовать параметры, сконфигурированные flanneld:

ps aux | grep docker
 
root 19520 2.1 11.5 392304 55212 ? Ssl 22:40 0:00 /usr/bin/dockerd --host fd:// --bip=172.16.21.1/24 --mtu=1472

ip addr show docker0
 
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP group default
    link/ether 02:42:33:5f:6b:95 brd ff:ff:ff:ff:ff:ff
    inet 172.16.21.1/24 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:33ff:fe5f:6b95/64 scope link
       valid_lft forever preferred_lft forever

Повторите процедуру на всех хостах docker, разверните тестовые контейнеры и убедитесь, что теперь вы можете пинговать контейнер одного хоста из контейнера другого хоста.

Добавить комментарий