Skip to content

Commit 1df0dfc

Browse files
committed
add network virtualization
Signed-off-by: ViniRodrig <vmarquesrodrigues25@gmail.com>
1 parent 2b1f4c8 commit 1df0dfc

File tree

2 files changed

+330
-0
lines changed

2 files changed

+330
-0
lines changed

config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ menu:
1616
- name: Security
1717
url: /sec
1818
weight: 1
19+
- name: Virtualization
20+
url: /virt
21+
weight: 2
1922

2023
params:
2124
brand: HOME
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
+++
2+
date = 2025-02-17T02:17:31-03:00
3+
lastmod = 2025-02-18T18:40:04-03:00
4+
draft = false
5+
title = "Virtualização de Redes"
6+
description = "Laboratório de virtualização de redes usando qemu/kvm, network namespaces e openvSwitch"
7+
tags = ['Virtualização', 'Redes', 'qemu', 'openvswitch']
8+
categories = []
9+
featured = true
10+
+++
11+
12+
## O que é virtualização
13+
A virtualização é a tecnologia que permite rodar múltiplos sistemas operacionais ou aplicações em um único hardware, criando versões virtuais de servidores, redes ou armazenamento. Isso otimiza recursos, reduz custos e é a base da computação em nuvem.
14+
## Linha do tempo de tecnologias de virtualização
15+
- **2002** - Surgimento do VMware Workstation, solução proprietária que popularizou a virtualização de sistemas, inspirando futuros projetos open source.
16+
- **2005** - Lançamento do Virtuozzo (posteriormente OpenVZ), pioneiro em virtualização via containers Linux, introduzindo isolamento de recursos em nível de sistema operacional.
17+
- **2006–2007** - Integração do KVM (Kernel-based Virtual Machine) ao kernel Linux, estabelecendo-se como hypervisor tipo 1 open source para criação de máquinas virtuais de alto desempenho.
18+
- **2008** - Lançamento do Microsoft Hyper-V, solução proprietária que impulsionou a competição e o aprimoramento de alternativas open source como KVM e Xen.
19+
- **2010** - Criação do OpenStack, incluindo o componente Neutron para virtualização de redes em nuvens, integrando redes virtuais, armazenamento e computação.
20+
- **2011** - Surgimento do oVirt, plataforma open source derivada do Red Hat Enterprise Virtualization, focada em orquestração de VMs baseadas em KVM.
21+
- **2013** - Revolução com o Docker, que popularizou containers leves, impactando a arquitetura de redes distribuídas através de microserviços isolados.
22+
- **2014** - Lançamento do Kubernetes pelo Google, padrão para orquestração de containers, com projetos posteriores como KubeVirt (2016) unindo VMs e containers.
23+
- **2015** - Padronização da NFV (Virtualização de Funções de Rede) pela ETSI, impulsionando projetos como OpenStack e OPNFV para substituir hardware dedicado por VMs.
24+
- **2016–2020** - Expansão de ecossistemas como KubeVirt (integração de VMs ao Kubernetes) e Cilium (redes baseadas em eBPF), aprimorando redes em ambientes cloud-native.
25+
- **2023** - Consolidação de tecnologias como KVM e OpenStack após a aquisição da VMware pela Broadcom, com foco em SDN, automação via IaC e edge computing.
26+
27+
## Maquinas virtuais e containeres
28+
| Característica | **Máquinas Virtuais (VMs)** | **Contêineres** |
29+
| -------------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------- |
30+
| **Isolamento** | Cada VM tem seu próprio sistema operacional completo | Compartilham o mesmo kernel do host, isolando apenas processos e bibliotecas |
31+
| **Uso de Recursos** | Mais pesado, pois cada VM precisa de um SO próprio | Mais leve, pois compartilha recursos do SO do host |
32+
| **Tempo de Inicialização** | Lento, pois precisa iniciar um SO completo | Rápido, pois roda como um processo do host |
33+
| **Escalabilidade** | Requer mais recursos para escalar | Altamente escalável e eficiente para microsserviços |
34+
| **Casos de Uso** | Aplicações legadas, múltiplos SOs no mesmo hardware | Desenvolvimento ágil, cloud computing e microsserviços |
35+
![vm/container](https://www.researchgate.net/publication/369061128/figure/fig2/AS:11431281125201275@1678232029210/Docker-Container-vs-Virtual-Machine.png)
36+
37+
## Interface de rede físicas
38+
Uma **interface física de rede** é um hardware, como uma placa de rede (NIC), porta Ethernet ou adaptador Wi-Fi, que conecta um dispositivo a uma rede. Seu papel é transmitir e receber dados entre computadores, servidores e outros dispositivos, garantindo a comunicação na rede local ou na internet.
39+
40+
![NIC](https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Network_card.jpg/1280px-Network_card.jpg)
41+
42+
43+
## Interfaces de rede virtuais
44+
Uma **interface virtual de rede** é uma interface criada por software que simula uma conexão de rede sem a necessidade de hardware físico. Ela é usada para comunicação entre máquinas virtuais, contêineres ou diferentes processos dentro de um sistema.
45+
Exemplos incluem **veth (Virtual Ethernet)** para comunicação entre namespaces no Linux, **bridge interfaces** para conectar VMs a redes físicas, e **tun/tap interfaces**, que criam conexões de rede tuneladas.
46+
47+
## [Virtual Interfaces](# Virtual Networking Devices - TUN, TAP and VETH Pairs Explained)
48+
### Tap/Tun
49+
[What is the TAP](https://vtun.sourceforge.net/tun/faq.html#1.2)
50+
```
51+
 The TAP is a Virtual Ethernet network device.
52+
 TAP driver was designed as low level kernel support for
53+
 Ethernet tunneling. It provides to userland application
54+
 two interfaces:
55+
   - /dev/tapX - character device;
56+
   - tapX - virtual Ethernet interface.
57+
58+
 Userland application can write Ethernet frame to /dev/tapX
59+
 and kernel will receive this frame from tapX interface.
60+
 In the same time every frame that kernel writes to tapX
61+
 interface can be read by userland application from /dev/tapX
62+
 device.
63+
```
64+
65+
O driver TUN/TAP fornece recepção e transmissão de pacotes para programas em espaço de usuário. Ele pode ser visto como um dispositivo simples de Ponto-a-Ponto ou Ethernet que, em vez de receber pacotes de uma mídia física, os recebe de um programa em espaço de usuário, e em vez de enviar pacotes por uma mídia física, os escreve para o programa em espaço de usuário.[^1]
66+
67+
Em outras palavras, o driver TUN/TAP cria uma interface de rede virtual no seu host Linux. Essa interface funciona como qualquer outra, ou seja, você pode atribuir um IP a ela, analisar o tráfego, rotear tráfego para ela, etc. Quando o tráfego é enviado para a interface, ele é entregue ao programa em espaço de usuário em vez de ser encaminhado para a rede real.[^1]
68+
### veth
69+
Dispositivos Veth são criados em pares de interfaces Ethernet virtuais conectadas e podem ser vistos como um cabo de rede virtual. O que entra em uma extremidade sai pela outra.
70+
Isso torna os pares veth ideais para conectar diferentes componentes de rede virtual, como bridges do Linux, bridges OVS e contêineres LXC.[^1]
71+
72+
73+
![Comparison of virtual interfaces](https://www.packetcoders.io/content/images/2020/10/image1.png)
74+
75+
76+
## Setup da VM com qemu
77+
Vamos realizar o download de uma Ubuntu Cloud Image. Essa img é otimizada para uso em cloud (utilizando hypervisors) e não vem com senha por padrão. Será necessário fornecer o arquivo para prover configuração de usuários e rede em uma próxima etapa.
78+
### Criar qcow2 overlay com qemu-img
79+
Queremos criar duas máquinas virtuais com base na imagem que fizemos download, porém não queremos alterar a imagem base, dessa maneira criamos uma imagem overlay qcow2 com base na imagem original utilizando *qemu-img*: `qemu-img create -f qcow2 -b ubuntu-24.04-server-cloudimg-amd64.img -F qcow2 vm.qcow2`
80+
### cloud-init
81+
Em ambientes Cloud, geralmente existe um componente dedicado a fornecer esse arquivo para as VMs, ocorrendo como um servidor web que fornece os metadados ou o próprio hypervisor adiciona um driver semelhante ao que será feito de maneira local no lab.
82+
O conteúdo do cloud init está em [[network-virtualization#Apêndice#Cloud Init]], os arquivos de rede devem estar separados do user-data.
83+
O pacote [cloud-utils](https://github.com/canonical/cloud-utils) deve ser instalado para gerar localmente a imagem.
84+
`cloud-localds --network-config=./config-data/network-config my-seed.img ./config-data/user-data.yaml`
85+
Adicionalmente, o pacote cloud-init tem um validator para conferir se o schema desses dois arquivos são válidos:
86+
`cloud-init schema --config-file user-data.yaml`
87+
`cloud-init schema -c network-config-dns --schema-type network-config`
88+
### Execução da VM com qemu:
89+
A primeira VM será criada executando o seguinte comando:
90+
```
91+
# Create machine using e1000 driver
92+
qemu-system-x86_64 \
93+
-name "Legacy-Net-Driver" \
94+
-cpu host \
95+
-enable-kvm \
96+
-drive if=virtio,format=qcow2,file=e1000.qcow2 \
97+
-drive if=virtio,format=raw,file=my-seed.img \
98+
-m 2048 -smp 2 \
99+
-netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no \
100+
-device e1000,netdev=mynet0,mac=52:54:00:12:34:56 \
101+
-nographic -serial mon:stdio
102+
```
103+
Explicação dos argumentos mais relevantes:
104+
- -enable-kvm -> habilita o KVM (utiliza instruções do processador de virtualização para melhor desempenho)
105+
- -drive if=virtio,format=qcow2,file=e1000.qcow2 -> carrega o driver com a imagem que foi criada a partir da cloudimg original, virtio é especificado como driver para melhor desempenho.
106+
- -drive if=virtio,format=raw,file=my-seed.img -> carrega a imagem de cloud-init que foi criada
107+
- -m 2048 -> 2gb de memória ram
108+
- -smp 2 -> 2 cores virtuais
109+
- -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no
110+
- netdev especifica que uma interface tap será utilizada para conectar a vm a rede
111+
- id é um identificador para essa interface
112+
- ifname será o nome do tap que foi criado manualmente
113+
- -device e1000,netdev=mynet0,mac=52:54:00:12:34:56
114+
- adiciona um dispositivo de rede virtual usando o driver e1000
115+
- netdev conecta a interface ao backend no comando anterior
116+
- mac define um endereço mac para a interface
117+
A diferença entre as duas VMs criadas é que invés de usar o driver e1000, virtio será utilizado como driver de rede, permitindo maior largura de banda.
118+
## Linux Bridges
119+
Uma bridge Linux se comporta como um switch de rede. Ela encaminha pacotes entre interfaces conectadas a ela. Normalmente é utilizada para encaminhar pacotes em roteadores, em gateways ou entre máquinas virtuais e namespaces de rede em um host.[^2]
120+
### Por que Open vSwitch no lugar de Linux Bridges?
121+
Open vSwitch está direcionado para implantações de virtualização multi-servidor, um cenário para o qual a stack anterior não era bem adequada. Estes ambientes são frequentemente caracterizados por pontos finais altamente dinâmicos, a manutenção de abstrações lógicas, e (às vezes) integração com ou offloading para hardware de switching especializado.[^3]
122+
## Linux Network Namespaces
123+
Namespaces de rede são uma característica do kernel Linux que permite criar ambientes de rede isolados dentro de um único sistema. Cada namespace de rede tem sua própria pilha de rede e conjunto de recursos de networking, como interfaces de rede virtuais, tabelas de roteamento, regras de firewall e mais. Isso possibilita criar múltiplos contextos de networking independentes em um único sistema, cada um com seu próprio conjunto de configurações de networking.
124+
125+
Namespaces de rede são frequentemente utilizados em conjunto com outros tipos de namespaces, como PID namespaces, para criar ambientes isolados para execução de processos. Este é um aspecto fundamental da containerização e virtualização, pois permite criar ambientes leves, portáteis e seguros para execução de aplicações.[^4]
126+
127+
## Laboratório
128+
129+
Será construído uma topologia de rede semelhante ao exemplo de bridge nesse artigo sobre [interfaces virtuais da Red Hat](https://developers.redhat.com/blog/2018/10/22/introduction-to-linux-interfaces-for-virtual-networking#). Duas VMs serão criadas (para usar diferentes drivers de rede virtuais) e um namespace Linux.
130+
131+
![Bridge](https://developers.redhat.com/blog/wp-content/uploads/2018/10/bridge.png)
132+
133+
```
134+
# ------------ core componentes installation -------------
135+
# Download KVM
136+
# - Arch: pacman -S qemu
137+
# - Debian: apt install qemu-system
138+
139+
# Download Open vSwitch
140+
# - Arch: pacman -S openvswitch
141+
# - Debian: apt install openvswitch-switch openvswitch-common
142+
143+
# Start ovs server
144+
# - sudo /usr/share/openvswitch/scripts/ovs-ctl start
145+
146+
147+
# ------------ vm and ovs setup -------------
148+
# Download ubuntu cloudimg
149+
wget https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img
150+
151+
# Create two overlays of the base image
152+
qemu-img create -f qcow2 -b ubuntu-24.04-server-cloudimg-amd64.img -F
153+
qcow2 e1000.qcow2
154+
qemu-img create -f qcow2 -b ubuntu-24.04-server-cloudimg-amd64.img -F
155+
qcow2 virtio.qcow2
156+
157+
# Create TAP devices
158+
sudo ip tuntap add mode tap user $USER name tap0
159+
sudo ip tuntap add mode tap user $USER name tap1
160+
sudo ip link set tap0 up
161+
sudo ip link set tap1 up
162+
163+
# Create OVS bridge and add ports
164+
sudo ovs-vsctl add-br ovs-br
165+
sudo ovs-vsctl add-port ovs-br tap0
166+
sudo ovs-vsctl add-port ovs-br tap1
167+
168+
# Assign IP to bridge for host communication
169+
sudo ip addr add 192.168.100.1/24 dev ovs-br
170+
sudo ip link set ovs-br up
171+
172+
# Enable ip forwarding
173+
sudo sysctl -w net.ipv4.ip_forward=1
174+
175+
# Use nat to provide vms virtual connection, wlp2s0 should
176+
# be your internet connected interface and ovs-br should be your bridge
177+
sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o wlp2s0 -j MASQUERADE
178+
sudo iptables -A FORWARD -i ovs-br -o wlp2s0 -j ACCEPT
179+
sudo iptables -A FORWARD -i wlp2s0 -o ovs-br -m state --state RELATED,ESTABLISHED -j ACCEPT
180+
181+
# Set up a DHCP server to provide IPs to VMs
182+
# install dnsmasq
183+
sudo apt install dnsmasq
184+
185+
# Edit the /etc/dnsmasq.conf file
186+
sudo vim /etc/dnsmasq.conf
187+
188+
# Enable the service
189+
sudo systemctl start dnsmasq.service
190+
191+
# Allow dhcp traffic [may not be necessary]
192+
# sudo iptables -A INPUT -p udp --dport 67 -j ACCEPT
193+
# sudo iptables -A INPUT -p udp --dport 68 -j ACCEPT
194+
195+
# Create cloud-init.yaml using cloud-init yaml
196+
# Install cloud-image-utils on arch or cloud-utils on apt-based
197+
sudo apt install cloud-utils
198+
cloud-localds --network-config=./config-data/network-config-dns my-seed2.img ./config-data/user-data.yaml
199+
200+
# Generate cloud-init img
201+
cloud-localds --network-config=./config-data/network-config my-seed.img ./c
202+
onfig-data/user-data.yaml
203+
204+
# Start VMs
205+
# Create machine using e1000 driver
206+
qemu-system-x86_64 \
207+
-name "Legacy-Net-Driver" \
208+
-cpu host \
209+
-enable-kvm \
210+
-drive if=virtio,format=qcow2,file=e1000.qcow2 \
211+
-drive if=virtio,format=raw,file=my-seed.img \
212+
-m 2048 -smp 2 \
213+
-netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no \
214+
-device e1000,netdev=mynet0,mac=52:54:00:12:34:56 \
215+
-nographic -serial mon:stdio
216+
217+
# Create machine using virtio driver
218+
qemu-system-x86_64 \
219+
-name "Virtio-Net-Driver" \
220+
-cpu host \
221+
-enable-kvm \
222+
-drive if=virtio,format=qcow2,file=virtio.qcow2 \
223+
-drive if=virtio,format=raw,file=my-seed2.img \
224+
-m 2048 -smp 2 \
225+
-netdev tap,id=mynet1,ifname=tap1,script=no,downscript=no \
226+
-device virtio-net-pci,netdev=mynet1,mac=52:54:00:12:34:57 \
227+
-nographic -serial mon:stdio
228+
229+
# if dhcp with dnsmasq fail for some reason, you can configure manually IP,
230+
# routes and dns inside the virtual machines/namespace:
231+
# inside vms, set up network interface ip, a default gw to internet
232+
# through the bridge and change the dns to 8.8.8.8 manually editing
233+
# /etc/resolv.conf
234+
# sudo ip a add 192.168.100.3/24 dev ens3
235+
# sudo ip r add default via 192.168.100.1 dev ens3
236+
# sudo vim /etc/resolv.conf
237+
238+
# ------------ linux namespaces -------------
239+
# on the host system, create a linux network namespace
240+
sudo ip netns add ns1
241+
242+
# create a veth pair and move one end to the namespace
243+
sudo ip link add veth-host type veth peer name veth-ns
244+
sudo ip link set veth-ns netns ns1
245+
246+
# activate both ends
247+
sudo ip netns exec ns1 ip link set veth-ns up
248+
sudo ip link set veth-host up
249+
250+
# add the host-side to the bridge
251+
sudo ovs-vsctl add-port ovs-br veth-host
252+
253+
# run bash inside the namespace
254+
sudo ip netns exec ns1 bash
255+
256+
# if dnsmasq is providing dhcp, get an ip using dhclient
257+
# if dnsmasq is not providing, configure ip, routes and dns manually
258+
dhclient -v
259+
260+
261+
# ------------ benchmarking -------------
262+
263+
# install iperf3 on the hosts and the vms
264+
sudo apt update
265+
sudo pat install iperf3
266+
267+
# Benchmarking bandwidth
268+
# on the host, start iperf3 server
269+
iperf3 -s -B 192.168.100.1
270+
# on the virtual machines/namespaces connect to the server
271+
iperf3 -c 192.168.100.1
272+
273+
274+
# ------------ cleanup -------------
275+
sudo ovs-vsctl del-br ovs-br
276+
sudo ip link del tap0
277+
sudo ip link del tap1
278+
sudo ip netns del ns1
279+
sudo ip link del veth-host
280+
```
281+
282+
## Apêndice
283+
### Cloud Init
284+
Será necessário criar os dois arquivos para adicionar ao cloud-init:
285+
286+
``` network-config.yaml
287+
version: 2
288+
ethernets:
289+
ens3:
290+
dhcp4: true
291+
```
292+
293+
``` user-data.yaml
294+
#cloud-config
295+
ssh_pwauth: True
296+
chpasswd:
297+
expire: false
298+
users:
299+
- {name: ubuntu, password: ubuntu, type: text}
300+
users:
301+
- name: ubuntu
302+
ssh-authorized-keys:
303+
- <your public key here>
304+
sudo: ['ALL=(ALL) NOPASSWD:ALL']
305+
groups: users, sudo
306+
shell: /bin/bash
307+
```
308+
309+
### Servidor dhcp
310+
dnsmasq será utilizado para prover dhcp, edite o arquivo de configurações em `/etc/dnsmasq.conf` com o conteúdo a seguir:
311+
``` dnsmasq.conf
312+
interface=ovs-br
313+
dhcp-range=192.168.100.2,192.168.100.200,12h
314+
dhcp-option=option:dns-server,8.8.8.8
315+
```
316+
317+
## Referências
318+
319+
[^1]: https://www.packetcoders.io/virtual-networking-devices-tun-tap-and-veth-pairs-explained/
320+
321+
[^2]: https://developers.redhat.com/blog/2018/10/22/introduction-to-linux-interfaces-for-virtual-networking#bridge
322+
323+
[^3]: https://docs.openvswitch.org/en/latest/intro/why-ovs/#why-open-vswitch
324+
325+
[^4]: https://abdelouahabmbarki.com/linux-namespaces-network-ns/
326+
327+

0 commit comments

Comments
 (0)