OpenStack – El Servicio de Red (Neutron)

Neutron proporciona el Servicio de Red en OpenStack, gracias al cual, podemos tener redes externas, redes internas, enrutarlas entre sí, asignar direcciones IP externas (floating IPs) a nuestras Instancias para acceder a ellas desde el exterior, filtrar el tráfico de red mediante reglas de los Security Groups, y muchas cosas más. En este Post vamos a ver la teoría y arquitectura de Neutron, para continuar con un laboratorio en el que crearemos nuestra primera Instancia en OpenStack, disponible y accesible desde el exterior, y configurarlo todo de forma programática a través de OpenStack CLI.

Continuando con la serie de Posts sobre OpenStack, después de que tratáramos hace unos días cómo instalar OpenStack en CentOS 7 con PackStack así como un breve introducción a OpenStack, viéramos una introducción al Dashboard y CLI de OpenStack, y conociéramos el Servicio de Identidad (Keystone), y también el Servicio de Imágenes (Glance), ahora llega el momente de conocer el Servicio de Red (Neutron) y de crear nuestra red y nuestra primera Instancia en OpenStack. Comenzamos.

Introducción a Neutron: El Servicio de Red de OpenStack

Neutron proporciona Networking como Servicio dentro de OpenStack, a la vez que pretende simplificar la gestión de la red, ofreciendo una capa de abstracción para las Redes, Subredes, NICs o Ports, Routers, y Direcciones IP usadas por las Intancias de OpenStack, es gestionable de forma sencilla por los usuarios y administradores a través de una API, del Dashboard, y de OpenStack CLI, y extensible mediante Plugins y Agentes. Neutron es capaz de proporcionar comunicación entre las Instancias de OpenStack, segmentación de redes (por seguridad y escalabilidad), y también con el mundo exterior, además de permitir servicios avanzandos de red como Load Balancing, Firewall, VPN, etc..

A continuación se puede ver un sencillo diagrama de arquitectura de Neutron, donde se representa entre otras cosas, la base de datos que almacena su estado y configuración, un sistema de colas de mensajes para una comunicación asíncrona con los Agentes, y su soporte para Plugins (ej: Open vSwitch ó OVS, Linux Bridge, fabricantes de hardware de red, etc.) que permite convivencia de dispositivos de red físicos y virtuales. Para más info: OpenStack – Neutron – Networking architecture

El siguiente diagrama representa otra visión de la arquitectura de Neutron, donde podemos apreciar algunos detalles como los siguientes.

  • Habitualmente tendremos un Controller Node, es decir, un servidor que ejecuta los principales servicios centrales como Keystone, Glance, Nova API, etc., incluir Neutron Server (gestiona las llamadas API a Neutron).
  • También tendremos varios Network Node, dedicados a las tareas relacionadas con la red, capaz de proporcionar servicios de red como DHCP, enrutamiento, etc. En una instalación pequeña para pruebas y laboratorios, podríamos tener un único servidor actuando de Controller Node y Network Node.
  • Tendremos varios Compute Node, dedicados a ejecutar las Instancias, las máquinas virtuales que arrancan los usuarios en OpenStack.

En Neutron la Redes se categorizan entre los siguientes dos tipos:

  • Project Networks (AKA Tenant Networks). Son creadas por los usuarios de OpenStack dentro de un Proyecto o Tenant para utilizarlas con sus Instancias dentro de su Proyecto, completamente aisladas y no compartidas con otros Proyectos, están completamente definidas a nivel de SW (son virtuales, no tienen relación con las redes físicas de los Data Centers), y su enrutamiento se realiza mediante los Routers virtuales de Neutron. Tipos:
    • Local
    • Flat (untagged)
    • VLAN (tagged)
    • VXLAN – Virtual Extensible LAN (tunneling)
    • GRE (tunneling)
  • Provider Networks. Son creadas por los administradores de OpenStack, y suelen estar relacionadas/mapeadas con las redes físicas de los Data Centers, con el único propósito de proporcionar conectividad a las Instancias al mundo exterior, mediante un Default Gateway o enrutamiento (first hop), pero no soportan servicios como floating IPs ó los Routers virtuales de Neutron. Tipos:
    • Flat (untagged)
    • VLAN (tagged)
    • VXLAN – Virtual Extensible LAN (tunneling)
    • GRE (tunneling)

Como se puede ver, como Admin, al realizar el Diseño de Red de nuestro entorno OpenStack, es muy importante conocer bien la red física sobre la que vamos a construir nuestro entorno, y asegurarse que no vamos a exceder ningún límite de la misma (ej: direccionamiento de red, VLANs, etc.)

La segmentación del tráfico de red en un entorno Cloud es fundamental, tanto por seguridad como por escalabilidad. OpenStack se apoya en los siguientes mecanismos de segmentación de tráfico.

  • Local Network. Sólo puede ser creada sobre un Nodo o Servidor particular, por lo que está aislada y sólo se suele utilizar para pruebas.
  • Flat Network. No proporciona ningún tipo de segmentación, actuando como un único dominio de broadcast (no es escalable).
  • VLAN Network. Permite la segmentación mediante VLAN tagging (cada VLAN es un dominio de broadcast), siendo una opción más escalable y segura que las anteriores. Al crear una nueva VLAN Network en Neutron, se le asignará un VLAN ID del rango que hemos configurado (el límite son 4096 VLAN IDs), y requiere que la electrónica de red (ej: Switches, Routers) esté configurada acorde. Para que dos Instancias configuradas sobre diferentes VLANs se puedan comunicar entre sí, es necesario configurar el enrutamiento entre las mismas.
  • Tunneling (VXLAN y GRE). Escala mejor y es más fácilmente mantenible que las soluciones basadas en VLAN, especialmente en grandes nubes.
    • Underlay Network (VLAN relacionadas con la red física).
    • Overlay Network (VXLAN ó GRE). Definidas a nivel de Software, para proporcionar comunicación entre Servidores dentro del Data Center (East-West communication) de forma escalable. Una Overlay Network es construida sobre otra red (Underlay Network). Para ellos, se crean «Peer to Peer mesh channels» entre los Hosts, para permitir el overlay. VXLAN define una MAC que es encapsulada en paquetes UDP. Los túneles GRE y VXLAN permiten solapamiento de subnets y de rangos de IP, al encapsular el tráfico dentro de los túneles. Neutron junto con OVS (Open vSwitch) proporciona un mesh de tunnels entre todos los Nodos, para permitir el tráfico entre las Instancias que se ejecutan entre los diferentes Nodos de OpenStack.

Como hemos comentado antes, Neutron se apoya en el uso de determinados Agentes. Los principales son los siguientes:

  • L2 Agent. Se ejecuta en el Hypervisor o Compute Node, y se comunica con el Neutron Server a través de RPC. Su función principal es observar y notificar cuándo un dispositivo es añadido o retirado de la red.
  • OVS L2 Agent. Al menos la mitad de las instalaciones de OpenStack, utilizan OVS, y soporta segmentación mediante VLAN, GRE, y VXLAN. El agente OVS utiliza el protocolo OVSDB para comunicarse con OVS.
  • L3 Agent. Se ejecuta en un Network Node, y su función es enrutar el tráfico dentro de OpenStack, así como otras funcionalidades como Floating IP Addresses, NAT. Se pueden montar uno o varios Network Nodes para proporcionar HA.

Neutron proporciona Security Groups, que permiten aislar las Instancias en diferentes Tenants o Proyectos, y configurar reglas de filtrado (iptables) para el tráfico saliente y entante (por defecto todo el tráfico saliente es permitido y el entrante bloqueado), que se aplica sobre la Virtual Interface (VIF). Cuando un VIF se crea en OpenStack, es asociado con un Security Group.

Neutron también proporciona el concepto de DVR (Distributed Virtual Routing)., que permite implementar los Virtual Routers en los propios Compute Nodes, en lugar de centralizado en los Network Nodes, para así mejorar el rendimiento evitando que los Netowrk Nodes actúen de cuello de botella.

Neutron y la CLI

Ya vimos en el anterior Post sobre el Dashboard de OpenStack, como realizar varias tareas en OpenStack a través del Dashboard, que en general resulta bastante intuitivo. Ahora vamos a ver cómo trabajar con Neutron desde OpenStack CLI.

Podemos listar todos los comando que proporciona OpenStack CLI relacionados con Neutron, con los siguientes comandos. Son un montón, así que veremos algunos ejemplos, el resto es cuestión de trastear y revisar la Doc..

source keystonerc_admin
openstack command list | grep openstack.network -A 130
openstack command list | grep openstack.neutronclient -A 130

Los siguientes comandos, nos permiten comprobar qué Agentes tenemos instalador (y en qué estado se encuentran, que será UP), así como comprobar el estado del servicio Neutron Server (que será Running).

openstack network agent list
systemctl status neutron-server

A continuación, vamos a comprobar el estado de OVS (Open vSwitch) con el comando ovs-vsctl show, para ver los OVS Switch que tenemos configurados y los puertos, teniendo en cuenta la instalación que hicimos en el anterior Post de instalación de OpenStack en CentOS con PackStack, es decir, que no tenemos nada creado excepto una red externa con una subnet sin DHCP:

  • br-tun (tunnel bridge). Permite la creación de túneles VXLAN o GRE entre Nodos.
  • br-int (integration bridge). Conecta el tráfico de las Instancias con el tunnel bridge (br-tun) y external bridge (br-ex)
  • br-ex (external bridge). Permite conectarse a la red externa (red física).
ovs-vsctl show

Continuamos creando una red interna con un segmento de red (con un rango de IPs y su DHCP asociado), teniendo en cuenta, que durante la instalación de OpenStack creamos una red externa con su segmento de red. Para ello ejecutamos los siguientes dos comandos.

openstack network create internal_network
openstack subnet create private_subnet --subnet-range 10.10.0.0/24 --dns-nameserver 8.8.8.8 --network internal_network

Neutron se apoya en los Network Namespaces de Linux (al igual que Docker y que Kubernetes), una característica del Kernel de Linux que permite crear entornos de red completamente aislados a través de técnicas de virtualización dentro de un servidor Linux. Los Network Namespaces de Linux se gestionan con el comando ip netns. A continuación podemos ver:

  • Cómo listar los Network Namespaces que tenemos en nuestro servidor OpenStack. Tendremos sólo uno, ya que en OpenStack para cada servidor DHCP asigna un namespace para garantizar el aislamiento de red, y que no se mezcle el tráfico y las asignaciones DHCP de diferentes redes.
  • Cómo ejecutar comandos dentro de un Network Namespace, en particular, dentro del namespace utilizado por OpenStack visto en el comando anterior.
    • En este caso, el servidor DHCP tiene la dirección IP 10.10.0.2, a la cual no llegaremos desde el propio servidor OpenStack, pero si ejecutamos el ping dentro de su propio Network Namespace, entonces si qué nos responderá el ping.
    • También comprobaremos qué interfaces de red existen dentro del namespace, en este caso, la de loopback y la DHCP tap (es como la Virtual Interface del propio servidor DHCP dentro del Network Namespace).
ip netns
ip netns exec qdhcp-7b82b593-2d84-43f2-b115-b5abcc170c31 ping 10.10.0.2
ip netns exec qdhcp-7b82b593-2d84-43f2-b115-b5abcc170c31 ip address show

Si ahora volvemos a comprobar el estado de OVS (Open vSwitch) y los puertos existente, con el comando ovs-vsctl show, veremos que hay un puerto nuevo, relacionado con la nueva interfaz tap del servidor DHCP de la red interna que acabamos de crear.

ovs-vsctl show

Lo siguiente que vamos a hacer es crear un Router para nuestro segmento de red. Lo crearemos vacío (sin interfaces), para seguidamente asignarle el segmento de red privado que creamos antes. Al crear el Router, podremos ver que aparece un nuevo Network Namespace y que tiene una interfaz asociada (la del propio Router), que igual que nos pasó con el DHCP la podremos hacer ping si lo intentamos desde dentro de su propio Network Namespace. Finalmente asociaremos al Router la red externa, y con esto habremos finalizado la configuración básica de nuestro Router a través de OpenStack CLI.

openstack router create virtual_router
openstack router add subnet virtual_router private_subnet
ip netns
ip netns exec qrouter-2384e9e4-e71a-484a-b6c8-277b3c4861f7 ip address show
ip netns exec qrouter-2384e9e4-e71a-484a-b6c8-277b3c4861f7 ping 10.10.0.1
neutron router-gateway-set virtual_router external_network

Ahora que ya tenemos nuestra red externa, nuestra red interna, y nuestro router, podemos crear nuestra primera Instancia en OpenStack, para lo cual emparemos con los siguientes pasos:

  • Primero listamos las diferentes redes, para obtener el ID de nuestra red interna.
  • Seguidamente creamos una nueva Instancia, sobre la red interna, utilizando la imagen de CirrOS. En un rato, estará levantada y disponible, pero deberíamos añadir reglas al Security Group para permitir tráfico entrante, al menos ICMP y SSH.
  • Listamos los Security Groups y los Proyectos, para identificar cuál es el Security Group del Proyecto actual (defaul).
openstack network list
openstack flavor list
openstack image list
openstack server create --image cirros-0.5.1-x86_64 --flavor 2 --nic net-id=7b82b593-2d84-43f2-b115-b5abcc170c31 cirros01
openstack security group list
openstack project list

Lo siguiente, una ver creada la Instancia e identificado su Security Group, es crear las reglas para permitir el tráfico entrante ICMP y SSH en el Security Group, y en consencuencia, en la Instancia. Hecho eso, podemos comprobar la conectividad a través del Network Namespace asociado al Router, lo que nos permitirá acceder por ICMP tanto a la dirección IP del Router como a la dirección IP de la Instancia que acabamos de crear.

openstack security group rule create --remote-ip 0.0.0.0/0 --protocol icmp --ingress 926fe98e-4037-4779-811c-c95b517f7dd9
openstack security group rule create --remote-ip 0.0.0.0/0 --dst-port 22 --protocol tcp --ingress 926fe98e-4037-4779-811c-c95b517f7dd9
ip netns exec qrouter-2384e9e4-e71a-484a-b6c8-277b3c4861f7 ping 10.10.0.246
ip netns exec qrouter-2384e9e4-e71a-484a-b6c8-277b3c4861f7 ping 10.10.0.1

Ya tenemos nuestra Instancia arranca, conectada a nuestra red interna de OpenStack, y permitimos el tráfico entrante en el Security Group (de momento sólo ICMP y SSH). El siguiente paso es crear una Floating IP address con una IP de nuestra red externa (necesitaremos primero obtener el ID del segmento de red externa), y asociársela a la Instancia, para que sea accesible desde fuera de OpenStack. Hecho esto, deberíamos poder conectarnos por ICMP y/o SSH a nuestra Instancia.

openstack subnet list
openstack floating ip create --subnet 2a13b700-3561-4383-a89c-696af768f0f7 982652ae-3f67-4e23-8e31-407607403b4e
openstack server add floating ip cirros01 192.168.10.171
ping 192.168.10.171

Con esto ya hemos conseguido el objetivo de este Post. Hay un montón de comandos ofrecidos por Neutron a través de OpenStack CLI, verlos todos está fuera del alcance de este Post, por comentar uno que puede ser útil (además de los ya vistos), sería el siguiente, que nos permite ver el direccionamiento disponible de nuestras redes, de forma sencilla.

openstack ip availability list --project admin

Despedida y Cierre

Hasta aquí llega este Post de OpenStack, en el que hemos podido ver bastante teoría y también bastante práctica sobre el Servicio (Neutron), además de tomar contacto con los Network Namespaces de Linux (importante no sólo en OpenStack, sino también en Docker y Kubernetes), con la satisfacción de haber podido realizar un laboratorio que nos ha permitido no sólo configurar nuestra red en OpenStack, sino también crear una Instancia, a la que poder conectarnos desde el exterior, y todo ello de forma programática con OpenStack CLI.

Poco más por hoy. Como siempre, confío que la lectura resulte de interés.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

seis + dieciocho =