- PVSM.RU - https://www.pvsm.ru -

Container Networking Interface (CNI) — сетевой интерфейс и стандарт для Linux-контейнеров

Container Networking Interface (CNI) — сетевой интерфейс и стандарт для Linux-контейнеров - 1

На прошлой неделе фонд CNCF (Cloud Native Computing Foundation) объявил [1] о принятии под своё крыло 10-го Open Source-проекта — CNI (Container Networking Interface). Его задача — обеспечить всё необходимое для стандартизированного управления сетевыми интерфейсами в Linux-контейнерах и гибкого расширения сетевых возможностей. В CNCF объяснили необходимость такого проекта активным распространением контейнеризированных приложений в мире production и утверждают, что «подобно тому, как Kubernetes позволяет разработчикам массово запускать контейнеры на тысячах машинах, этим контейнерам в больших масштабах требуется сетевое управление [и реализующий его фреймворк]».

Как же появился CNI и что он предлагает?

Предыстория CNI

Проект Container Network Interface (CNI) зародился в компании CoreOS, известной по движку для контейнеров rkt (недавно был тоже передан в CNCF, одновременно с containerd [2]), NoSQL-хранилищу etcd, активной работе над Kubernetes и другими Open Source-проектами, связанными с контейнерами и DevOps. Первая подробная демонстрация CNI состоялась ещё в конце 2015 года (см. видео в октябре [3], презентацию в ноябре [4]). С самого начала проект позиционировался в качестве «предлагаемого стандарта для конфигурации сетевых интерфейсов для Linux-контейнеров», а использовать его первым делом начали, конечно же, в rkt. Первыми «сторонними пользователями» CNI стали Project Calico, Weaveworks, а в скором времени к ним примкнул Kubernetes.

Адаптация CNI в платформе Kubernetes стоит отдельного внимания. Поскольку потребность в стандартизации сетевой конфигурации Linux-контейнеров была очевидной и всё более актуальной на тот момент (~2015 год), CNI оказался не единственным таким проектом. Конкурирующий продукт — Container Network Model (CNM) от Docker, представленный [5] в том же 2015-м, — решал те же задачи и получил свою эталонную реализацию в виде libnetwork [6] — библиотеки, которая выросла из сетевого кода в libcontainer и Docker Engine. И важным этапом в противостоянии CNI и CNM стал выбор, сделанный Kubernetes. В статье «Почему Kubernetes не использует libnetwork? [7]» (январь 2016 года) разработчики подробно описывают все технические и иные причины, объясняющие их решение. Основная же суть (помимо ряда технических моментов) сводится к следующему:

CNI ближе к Kubernetes с философской точки зрения. Он гораздо проще CNM, не требует демонов и его кроссплатформенность по меньшей правдоподобна (исполняемая среда контейнеров CoreOS rkt поддерживает его) [… а Kubernetes стремится поддерживать разные реализации контейнеров — прим. перев.]. Быть кроссплатформенным означает возможность использования сетевых конфигураций, которые будут одинаково работать в разных исполняемых средах (т.е. Docker, Rocket, Hyper). Этот подход следует философии UNIX делать одну вещь хорошо.

По всей видимости, именно это (не только выбор Kubernetes, но и сторонний взгляд технических специалистов на существующие реализации) предопределило будущее CNI и его принятие в CNCF. Для сравнения, другие конкурирующие продукты CoreOS и Docker: среды исполнения контейнеров rkt и conatinerd — были приняты в фонд вместе и одновременно [8], а вот с CNI/CNM этого не произошло.

Container Networking Interface (CNI) — сетевой интерфейс и стандарт для Linux-контейнеров - 2
Взгляд проекта Calico на сети для контейнеров в марте 2016 года

Дополнительное сравнение CNI и CNM по состоянию на сентябрь 2016 года можно также найти в англоязычной статье на The New Stack [9].

Устройство CNI

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

Container Networking Interface (CNI) — сетевой интерфейс и стандарт для Linux-контейнеров - 3

CNI состоит из трёх частей:

1. Спецификации (см. GitHub [10]), определяющей API между исполняемой средой контейнера и сетевыми плагинами: обязательные поддерживаемые операции (добавление контейнера в сеть и удаление его оттуда), список параметров, формат конфигурации сети и их списков (хранятся в JSON), а также известных структур (IP-адресов, маршрутов, DNS-серверов).

Пример конфигурации сети в CNI:

{
  "cniVersion": "0.3.1",
  "name": "dbnet",
  "type": "bridge",
  "bridge": "cni0",
  "ipam": {
    "type": "host-local",
    "subnet": "10.1.0.0/16",
    "gateway": "10.1.0.1"
  },
  "dns": {
    "nameservers": [ "10.1.0.1" ]
  }
}

2. Официальных плагинов, предоставляющих сетевые конфигурации для разных ситуаций и служащих примером соответствия спецификации CNI. Они доступны в containernetworking/plugins [11] и разбиты на 4 категории: main (loopback, bridge, ptp, vlan, ipvlan, macvlan), ipam (dhcp, host-local), meta (flannel, tuning), sample. Все написаны на Go. (Про сторонние плагины см. в следующем разделе статьи.)

3. Библиотеки (libcni [12]), предлагающей реализацию спецификации CNI (тоже на языке Go) для удобного использования в исполняемых средах контейнеров.

Весь имеющийся код (и спецификация) опубликованы под свободной лицензией Apache License v2.0.

Быстро попробовать CNI

«Потрогать руками» CNI можно и без контейнеров. Для этого достаточно загрузить себе файлы из репозитория проекта (и, по желанию, нужных плагинов), собрать их с ./build.sh (или скачать уже бинарную сборку), после чего — воспользоваться исполняемым файлом плагина (например, ./bin/bridge), передав ему необходимые для функционирования аргументы через переменные окружения CNI_*, а сетевую конфигурацию — прямо JSON-данными через STDIN (так предусмотрено в спецификации CNI).

Подробности о таком эксперименте можно найти в этой статье [13], автор которой делает приблизительно следующее (на хосте в Ubuntu):

$ cat > mybridge.conf <<"EOF"
{
    "cniVersion": "0.2.0",
    "name": "mybridge",
    "type": "bridge",
    "bridge": "cni_bridge0",
    "isGateway": true,
    "ipMasq": true,
    "ipam": {
        "type": "host-local",
        "subnet": "10.15.20.0/24",
        "routes": [
            { "dst": "0.0.0.0/0" },
            { "dst": "1.1.1.1/32", "gw":"10.15.20.1"}
        ]
    }
}
EOF
$ sudo ip netns add 1234567890
$ sudo CNI_COMMAND=ADD CNI_CONTAINERID=1234567890 
 CNI_NETNS=/var/run/netns/1234567890 CNI_IFNAME=eth12 
 CNI_PATH=`pwd` ./bridge <mybridge.conf
$ ifconfig
cni_bridge0 Link encap:Ethernet  HWaddr 0a:58:0a:0f:14:01
          inet addr:10.15.20.1  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::3cd5:6cff:fef9:9066/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:536 (536.0 B)  TX bytes:648 (648.0 B)
…

Дополнительные примеры для быстрого запуска CNI и сетевых плагинов представлены в README проекта [14] (раздел «How do I use CNI?»).

Сторонние плагины для CNI

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

  • Project Calico [15] (виртуальная сеть L3, интегрированная с инструментами оркестровки и облачными платформами);
  • Weave [16] (простая сеть для multi-host Docker-инсталляций);
  • Contiv Netplugin [17] (политики/ACL/QoS и другие возможности для контейнеров в кластерных установках типа multi-host);
  • Flannel [18] (сетевая фабрика для контейнеров от CoreOS);
  • SR-IOV [19], Cilium [20] (BPF/XDP), Multus [21] (плагин Multi для Kubernetes от Intel), VMware NSX [22] и другие…

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

Дополнительным индикатором зрелости проекта является его интеграция в существующие исполняемые среды для контейнеров: rkt и Kurma, — и платформы для работы с контейнерами: Kubernetes, OpenShift, Cloud Foundry, Mesos.

Заключение

Текущий статус CNI позволяет уже сейчас говорить не только о «больших перспективах» проекта, но и ощутимых реалиях его практической применимости. Принятие в CNCF — официальное признание индустрией и гарантия для дальнейшего развития. А всё это означает, что самое время как минимум узнать про CNI, с которым скорее всего рано или поздно придётся встретиться.

Не забывайте также подписываться на хаб нашей компании, чтобы не пропустить новые статьи и рецепты по темам DevOps и системного администрирования GNU/Linux! ;-)

Автор: shurup

Источник [23]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/seti/256659

Ссылки в тексте:

[1] объявил: https://www.cncf.io/blog/2017/05/23/cncf-hosts-container-networking-interface-cni/

[2] containerd: https://habrahabr.ru/company/flant/blog/325358/

[3] видео в октябре: https://www.youtube.com/watch?v=_-9kItVUUCw

[4] презентацию в ноябре: https://www.slideshare.net/kubecon/container-network-interface-network-plugins-for-kubernetes-and-beyond

[5] представленный: https://blog.docker.com/2015/04/docker-networking-takes-a-step-in-the-right-direction-2/

[6] libnetwork: https://github.com/docker/libnetwork

[7] Почему Kubernetes не использует libnetwork?: http://blog.kubernetes.io/2016/01/why-Kubernetes-doesnt-use-libnetwork.html

[8] вместе и одновременно: https://www.nixp.ru/news/13965.html

[9] The New Stack: https://thenewstack.io/container-networking-landscape-cni-coreos-cnm-docker/

[10] см. GitHub: https://github.com/containernetworking/cni/blob/master/SPEC.md

[11] containernetworking/plugins: https://github.com/containernetworking/plugins

[12] libcni: https://github.com/containernetworking/cni/tree/master/libcni

[13] этой статье: http://www.dasblinkenlichten.com/understanding-cni-container-networking-interface/

[14] README проекта: https://github.com/containernetworking/cni/blob/master/README.md

[15] Project Calico: https://github.com/projectcalico/cni-plugin

[16] Weave: https://github.com/weaveworks/weave

[17] Contiv Netplugin: https://github.com/contiv/netplugin

[18] Flannel: https://coreos.com/flannel/docs/latest/

[19] SR-IOV: https://github.com/hustcat/sriov-cni

[20] Cilium: https://github.com/cilium/cilium

[21] Multus: https://github.com/Intel-Corp/multus-cni

[22] VMware NSX: https://blogs.vmware.com/networkvirtualization/2017/03/kubecon-2017.html/

[23] Источник: https://habrahabr.ru/post/329830/