Pull to refresh
251.47
Инфосистемы Джет
российская ИТ-компания

Все об OpenShift Egress. Часть 2

Reading time6 min
Views2.5K
В первой части статьи про OpenShift Egress мы рассмотрели варианты организации фиксированных исходящих IP-адресов для POD в кластере. Но что делать, если надо предоставить доступ во внешние по отношению к кластеру сегменты сети, находящиеся в определенных VLAN?


Манипуляции с IP-адресацией здесь не помогут. Единственным решением в этом случае будет организация дополнительных интерфейсов на узлах кластера, которые будут находиться в нужных VLAN, и организация доступа к дополнительным интерфейсам с нужных нам проектов внутри кластера. И помочь в этом может проект под названием Multus CNI.

Multus CNI


Как известно, по умолчанию у POD в Kubernetes есть один интерфейс, через который и происходит все взаимодействие с ним. Multus позволяет создать в POD несколько интерфейсов помимо определенного по умолчанию. Фактически Multus сам является CNI-Plugin'ом, в свою очередь управляющий вызовом других CNI-Plugin'ов. За это Multus называют CNI meta Plugin. То, что делает Multus, хорошо показано на картинке из статьи Demystifing Multus:


Разумеется, количество дополнительных интерфейсов может быть больше чем один.

Настройка Multus CNI в OpenShift


Итак, попробуем решить задачу доступа в выделенный VLAN на нашем стенде. По умолчанию всем узлам кластера выделен один интерфейс, находящийся в VLAN OpenShift (IP: 192.168.111/24). Мы хотим организовать доступ из проекта multes-test в ресурсы сети 192.168.112/24, находящейся в VLAN Restricted. VLAN Restricted и VLAN OpenShift между собой не маршрутизируются.


Для начала добавим на ряд узлов (в нашем случае это Node1 и Node2) интерфейс из VLAN Restricted, и поставим на этих узлах метку node-role.kubernetes.io/multus-node='yes'. C узлов с меткой multus-node будут доступны ресурсы из Restricted VLAN. Создадим наш проект multus-test:

[ocp@shift-is01 macvlan]$ oc new-project multus-test

Поддержка Multus CNI давно присутствует в OpenShift, отдельно добавлять ее не надо. Управление конфигурацией Multus производится через CR в CRD networks.operator.openshift.io. Необходимо отредактировать этот ресурс, добавив конфигурацию CNI Plugin для нового интерфейса:

oc edit networks.operator.openshift.io cluster

spec:
  additionalNetworks:
    - name : net1
      namespace: multus-test
      type: Raw
      rawCNIConfig: |-
        { "cniVersion": "0.3.1",
          "type": "ipvlan",
          "mode": "l2",
          "master": "ens224",
          "ipam": {
            "type": "static"
           }
        }

Этот момент требует расшифровки. Что мы определили данной конфигурацией?

  1. Для POD в проекте multus-test добавится интерфейс с названием «net1»
  2. Конфигурация этого интерфейса будет определяться через CNI Plugin «ipvlan»;
  3. CNI Plugin ipvlan сконфигурируется в L2 Mode;
  4. В качестве основного интерфейса для net1 используется физический интерфейс узла ens224;
  5. И, наконец, для управления IP-адресацией будет применяться IPAM static plugin.

Выбор CNI Plugin


Для нашего дополнительного интерфейса нужно выбрать используемый CNI Plugin. Список возможных CNI Plugin можно посмотреть на сайте www.cni.dev. В своем примере мы используем ipvlan plugin. По сути это простейший bridge, который позволяет контейнерам взаимодействовать через внешний сетевой интерфейс хоста. При этом все исходящие соединения используют свой IP-адрес, но будут иметь MAC-адрес внешнего сетевого интерфейса. Картинка с сайта hicu.be хорошо иллюстрирует работу ipvlan plugin:


В продуктивных окружениях чаще выбирают macvlan plugin, который отличается от ipvlan тем, что исходящие соединения имеют уникальные MAC-адреса. Но в этом случае зачастую необходима подготовка сетевой инфраструктуры, чтобы сетевое оборудование позволило передачу пакетов с разными MAC-адресами с одного порта.

Выбор IPAM Plugin


Помимо организации сетевого интерфейса нам необходимо определить правила выдачи IP-адреса для нового интерфейса. Этим также занимается CNI Plugin, который реализует функции IP Address Management (или IPAM). Список возможных IPAM-plugin также можно посмотреть на сайте www.cni.dev. В данном примере мы использовали простейший static IPAM plugin, который присваивает фиксированный адрес нашему POD.

Если таких POD окажется много, использовать static IPAM станет неудобно. Хорошим выбором здесь будет либо использование dhcp plugin (он назначает IP адреса POD через запрос к внешнему DHCP-серверу), либо использование whereabouts plugin.

Поддержка этих IPAM Plugin также по умолчанию есть в OpenShift, отдельно устанавливать их не надо.

Доступ в restricted VLAN


После определения нашей конфигурации Multus в кластере должен появиться ресурс под названием Network Attachment Definition, в котором отражена текущая конфигурация Multus:

Network Attachment Definition

[ocp@shift-is01 macvlan]$ oc get network-attachment-definitions --all-namespaces
NAMESPACE     NAME   AGE
multus-test   net1   3m4s

[ocp@shift-is01 macvlan]$ oc get network-attachment-definitions.k8s.cni.cncf.io -n multus-test net1 -o yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  creationTimestamp: "2020-11-02T16:44:46Z"
  generation: 1
  managedFields:
  - apiVersion: k8s.cni.cncf.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:ownerReferences:
          .: {}
          k:{"uid":"01a4f46a-fc3c-495f-b196-b39352421e2a"}:
            .: {}
            f:apiVersion: {}
            f:blockOwnerDeletion: {}
            f:controller: {}
            f:kind: {}
            f:name: {}
            f:uid: {}
      f:spec:
        .: {}
        f:config: {}
    manager: cluster-network-operator
    operation: Update
    time: "2020-11-02T16:44:46Z"
  name: net1
  namespace: multus-test
  ownerReferences:
  - apiVersion: operator.openshift.io/v1
    blockOwnerDeletion: true
    controller: true
    kind: Network
    name: cluster
    uid: 01a4f46a-fc3c-495f-b196-b39352421e2a
  resourceVersion: "25898949"
  selfLink: /apis/k8s.cni.cncf.io/v1/namespaces/multus-test/network-attachment-definitions/net1
  uid: 7a7d718b-82c5-46fe-8f72-8fd4299508ec
spec:
  config: |-
    { "cniVersion": "0.3.1",
      "type": "ipvlan",
      "mode": "l2",
      "master": "ens224",
      "ipam": {
        "type": "static"
       }
    }

Создадим тестовый POD с дополнительным интерфейсом, который будет иметь доступ в наш restricted VLAN:

pod-ipvlan-static.yaml

[ocp@shift-is01 ipvlan]$ cat ./pod-ipvlan-static.yaml
apiVersion: v1
kind: Pod
metadata:
  namespace: multus-test
  name: test-multus-pod
  labels:
    app: test-multus-pod
  annotations:
    k8s.v1.cni.cncf.io/networks: '[
      {
        "name": "net1",
        "ips": ["192.168.112.250/24"]
      }
]'
spec:
  nodeSelector:
    node-role.kubernetes.io/multus-node: yes
  containers:
  - name: test-multus-pod
    image: centos/tools
    command: ["/bin/bash", "-c", "sleep 9000000"]

Зайдем в созданный POD, чтобы посмотреть его сетевую конфигурацию и проверить доступность адресов в restricted VLAN (в сети 192.168.112.0/24):

ocp@shift-is01 ipvlan]$ oc rsh test-multus-pod
sh-4.2# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
3: eth0@if2142: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
    link/ether 0a:58:0a:fe:04:a0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.254.4.160/24 brd 10.254.4.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::bc4b:abff:fe0b:91f8/64 scope link
       valid_lft forever preferred_lft forever
4: net1@if826: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 00:50:56:96:f3:02 brd ff:ff:ff:ff:ff:ff
    inet 192.168.112.250/24 brd 192.168.112.255 scope global net1
       valid_lft forever preferred_lft forever
    inet6 fe80::50:5600:196:f302/64 scope link
       valid_lft forever preferred_lft forever

sh-4.2# ping 192.168.112.1 -c 3
PING 192.168.112.1 (192.168.112.1) 56(84) bytes of data.
64 bytes from 192.168.112.1: icmp_seq=1 ttl=64 time=0.179 ms
64 bytes from 192.168.112.1: icmp_seq=2 ttl=64 time=0.230 ms
64 bytes from 192.168.112.1: icmp_seq=3 ttl=64 time=0.223 ms

--- 192.168.112.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2041ms
rtt min/avg/max/mdev = 0.179/0.210/0.230/0.028 ms

Как видно из вывода команды «ip a», POD получил дополнительный сетевой интерфейс net1@if826 и IP-адрес, который мы указали в его манифесте. Так как дополнительный интерфейс работает через ethernet адаптер, находящийся в restricted VLAN, с этого POD мы получили доступ в нужный нам сегмент сети.

Автор: Сергей Артемов, руководитель отдела DevOps-решений «Инфосистемы Джет»

Присоединяйтесь к нашему каналу в Telegram @DevSecOps Talks!

Список литературы


  1. OpenShift 4 with MacVLAN and whereabouts
  2. Demystifying Multus
  3. Macvlan vs Ipvlan
Tags:
Hubs:
+1
Comments0

Articles

Information

Website
jet.su
Registered
Founded
1991
Employees
1,001–5,000 employees
Location
Россия