- PVSM.RU - https://www.pvsm.ru -
На прошлой неделе фонд CNCF (Cloud Native Computing Foundation) объявил [1] о принятии под своё крыло 10-го Open Source-проекта — CNI (Container Networking Interface). Его задача — обеспечить всё необходимое для стандартизированного управления сетевыми интерфейсами в Linux-контейнерах и гибкого расширения сетевых возможностей. В CNCF объяснили необходимость такого проекта активным распространением контейнеризированных приложений в мире production и утверждают, что «подобно тому, как Kubernetes позволяет разработчикам массово запускать контейнеры на тысячах машинах, этим контейнерам в больших масштабах требуется сетевое управление [и реализующий его фреймворк]».
Как же появился 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 этого не произошло.
Взгляд проекта Calico на сети для контейнеров в марте 2016 года
Дополнительное сравнение CNI и CNM по состоянию на сентябрь 2016 года можно также найти в англоязычной статье на The New Stack [9].
Авторы CNI пошли путём создания минимально возможной спецификации, предназначение которой — стать лёгкой прослойкой между исполняемой средой контейнера и плагинами. Все необходимые сетевые функции реализуются именно в плагинах, взаимодействие с которыми определено схемой в формате JSON.
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 можно и без контейнеров. Для этого достаточно загрузить себе файлы из репозитория проекта (и, по желанию, нужных плагинов), собрать их с ./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, конечно же, являются сторонние плагины, обеспечивающие поддержку различных современных решений для Linux-контейнеров. Среди них:
К сожалению, какого-либо каталога или постоянно обновляемого их списка пока нет, но для общего представления о текущем распространении 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/
Нажмите здесь для печати.