주뇽's 저장소
[Mininet] 가상환경에서 미니넷 시물레이션 돌리기 본문
728x90
반응형
1. 우분투 환경을 설치해서 미니넷을 테스트
우분투 환경에서 테스트를 진행하는 경우 호스트별로 IP가 달라야 테스트가 가능한데 IP가 동일한 오류 발생
2. 이미 환경이 구축된 미니넷 VM을 다운로드 하여 사용
- CLI 환경으로 제어해야 한다는 단점이 존재하지만 IP가 동일한 오류는 해결
- 버츄얼 박스에서 미니넷 vm을 설치하는 방법https://github.com/mininet/mininet/releases/
- 위 깃허브에서 20.04 LTS버전 설치
- Steps for download Mininet to virtual box
미니넷 테스트 조건
노드 설정
- 노드1 : 디바이스 노드(단말 노드)
- 노드2 : 클라우드 노드(클라우드 서버)
- 랜덤하게 클라우드 서버의 CPU 제한 (0.1에서 1.0 사이)
- 스위치 : 디바이스 노드와 클라우드 노드를 연결
# 클라우드 서버
clouds = []
for i in range(num_clouds):
cloud = self.addHost(f'cloud{i+1}', cpu=cloud_resources[i]['cpu'])
clouds.append(cloud)
# 단말 노드
devices = []
for i in range(num_devices):
device = self.addHost(f'device{i+1}')
devices.append(device)
# 스위치
switches = []
for i in range(num_switches):
switch = self.addSwitch(f's{i+1}')
switches.append(switch)
엣지 설정
- 랜덤하게 클라우드 노드랑 스위치를 연결
- 1ms에서 10ms 사이의 랜덤 지연 시간
- 5% 확률로 1%에서 10% 사이의 랜덤 패킷 손실
- 랜덤하게 클라우드 서버의 대역폭 제한 (10Mbps에서 1000Mbps 사이)
# 랜덤하게 클라우드 서버와 스위치 연결
for cloud in clouds:
switch = random.choice(switches)
delay = f'{random.uniform(1, 10)}ms' # 1ms에서 10ms 사이의 랜덤 지연 시간
loss = random.uniform(1, 10) if random.random() < 0.05 else 0
self.addLink(cloud, switch, bw=cloud_resources[clouds.index(cloud)]['bw'], use_htb=True, delay=delay, loss=loss)
- 랜덤하게 단말노드랑 스위치를 연결
- 1ms에서 10ms 사이의 랜덤 지연 시간
- 5% 확률로 1%에서 10% 사이의 랜덤 패킷 손실
# 랜덤하게 단말 노드와 스위치 연결
for device in devices:
switch = random.choice(switches)
delay = f'{random.uniform(1, 10)}ms' # 1ms에서 10ms 사이의 랜덤 지연 시간
loss = random.uniform(1, 10) if random.random() < 0.05 else 0
self.addLink(device, switch, use_htb=True,
delay=delay, loss=loss)
- 랜덤하게 스위치 간 연결
- 1ms에서 10ms 사이의 랜덤 지연 시간
- 5% 확률로 1%에서 10% 사이의 랜덤 패킷 손실
for i in range(len(switches) - 1):
delay = f'{random.uniform(1, 10)}ms' # 1ms에서 10ms 사이의 랜덤 지연 시간
loss = random.uniform(1, 10) if random.random() < 0.05 else 0
self.addLink(switches[i], switches[i + 1], use_htb=True,
delay=delay, loss=loss)
네트워크 크기 설정
- small
- 클라우드 서버 : 2
- 단말노드 : 100
- 스위치 : 1
- medium
- 클라우드 서버 : 2
- 단말노드 : 100
- 스위치 : 1
- large
- 클라우드 서버 : 10
- 단말노드 : 1000
- 스위치 : 5
- custom
- 클라우드 서버 : 1
- 단말노드 : 10
- 스위치 : 1
# 네트워크 규모에 따른 설정 함수
def configure_network(scale):
if scale == 'small':
num_clouds = 1
num_devices = 100
num_switches = 1
elif scale == 'medium':
num_clouds = 5
num_devices = 500
num_switches = 2
elif scale == 'large':
num_clouds = 10
num_devices = 1000
num_switches = 5
elif scale == 'custom':
num_clouds = 1
num_devices = 10
num_switches = 1
else:
raise ValueError("scale 값을 확인해주세요 'small', 'medium', 'large', 'custom' 중 선택 ")
cloud_resources = []
for _ in range(num_clouds):
cloud_resources.append({
'cpu': random.uniform(0.1, 1.0), # 클라우드 서버의 CPU 제한 (0.1에서 1.0 사이)
'bw': random.uniform(10, 1000) # 클라우드 서버의 대역폭 제한 (10Mbps에서 1000Mbps 사이)
})
return num_clouds, num_devices, num_switches, cloud_resources
성능 테스트(대역폭, 딜레이, 로스)
def measure_performance(src, dst):
band_result = net.iperf([src, dst])
band_string = band_result[0]
print(band_string)
#-- 대역폭에서 숫자만 추출
band_value = re.findall(r'\d+\.\d+', band_string)
#-- 대역폭에서 단위만 추출
band_unit = re.findall(r'\d+\.\d+\s*([a-zA-Z]+)', band_string)[0][0]
print("band_value is {}, band_unit is {}".format(band_value, band_unit))
if band_value:
band_value = float(band_value[0])
if band_unit == 'Mbits':
bandwidth = band_value
elif band_unit =='Kbits':
bandwidth = band_value / 1000
elif band_unit =='Gbits':
bandwidth = band_value * 1000
else:
bandwidth = 0.0
else:
bandwidth = 0.0
print(bandwidth)
# 지연 시간 및 패킷 손실률 측정
ping_full_result = src.cmd(f'ping -c 10 {dst.IP()}')
delay_lines = [line for line in ping_full_result.split('\n') if 'avg' in line]
delay = float(delay_lines[0].split('/')[4]) if delay_lines else 0.0
loss_lines = [line for line in ping_full_result.split('\n') if 'packet loss' in line]
loss = float(loss_lines[0].split('%')[0].split()[-1]) if loss_lines else 100.0
# 종합 평점 계산 (예시: 각 조건의 가중치를 다르게 부여)
# 대역폭은 0~1000Mbps 사이로 정규화, 지연 시간은 0~100ms 사이로 정규화, 패킷 손실은 0~100% 사이로 정규화
norm_bandwidth = bandwidth / 1000 # 대역폭을 0에서 1 사이로 정규화
norm_delay = delay / 1 # 지연 시간을 0에서 1 사이로 정규화
norm_loss = loss / 100 # 패킷 손실을 0에서 1 사이로 정규화
rating = 5 * (0.05 * norm_bandwidth + 0.5 * (1- norm_delay) + 0.45 * (1 - norm_loss))
rating = round(max(0, min(5, rating), 2)) # 평점은 0에서 5 사이로 제한
return bandwidth, delay, loss, rating
실시간 모니터링
- save 모드 실행시 csv로 저장
# 실시간 모니터링 함수
def monitor_network(devices, clouds, interval=10, duration=10, mode='test'):
print("네트워크 모니터링 시작...")
start_time = time.time()
if mode == 'save':
with open('network_performance.csv', mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['Device', 'Cloud Server', 'Bandwidth (Mbps)', 'Delay (ms)', 'Packet Loss (%)', 'Rating'])
while time.time() - start_time < duration * 60: # duration 값을 분 단위로 변환
ratings = []
for device in devices:
for cloud in clouds:
bandwidth, delay, loss, rating = measure_performance(device, cloud)
ratings.append((device.name, cloud.name, bandwidth, delay, loss, rating))
print(f"{device.name} -> {cloud.name}: Bandwidth {bandwidth} Mbps, Delay {delay} ms, Packet Loss {loss} %, Rating {rating}")
for row in ratings:
writer.writerow(row)
time.sleep(interval)
print(f"네트워크 모니터링이 {duration}분 후 종료되었습니다.")
else:
while time.time() - start_time < duration * 60: # duration 값을 분 단위로 변환
ratings = []
for device in devices:
for cloud in clouds:
bandwidth, delay, loss, rating = measure_performance(device, cloud)
ratings.append((device.name, cloud.name, bandwidth, delay, loss, rating))
print(f"{device.name} -> {cloud.name}: Bandwidth {bandwidth} Mbps, Delay {delay} ms, Packet Loss {loss} %, Rating {rating}")
time.sleep(interval)
print(f"네트워크 모니터링이 {duration}분 후 종료되었습니다.")
단말노드 3 → 클라우드1와 연결시 (TCLink 사용X)
- 대역폭 : 26.7 Gbits/sec
- 딜레이 : 0.352 ms,
- 손실 패킷 : 0(개선 필요)
- 평가 : 4.54(평가 지침 필요)
단말노드 6 → 클라우드1 연결시 (TCLink 사용O)
- 대역폭 : 268 Mbits/sec
- 딜레이 : 34.111.ms
- 손실 패킷 : 0
- 평가 : 4.12
테스트 실행
# 네트워크 초기화 및 설정
scale = 'custom' # 'small', 'medium', 'large', 'custom' 중 선택
num_clouds, num_devices, num_switches, cloud_resources = configure_network(scale)
net = Mininet(topo=ScalableTopo(num_clouds, num_devices, num_switches, cloud_resources), controller=OVSController)
net.start()
clouds = [net.get(f'cloud{i+1}') for i in range(num_clouds)]
devices = [net.get(f'device{i+1}') for i in range(num_devices)]
try:
monitor_network(devices, clouds, interval=10, mode = "save", duration = 10)
except KeyboardInterrupt:
print("사용자에 의해 모니터링이 종료되었습니다.")
net.stop()
결과
원격으로 데이터 보내는 코드
scp data.csv username@192.168.1.5:/Users/username/Desktop/
전체 코드
import re
import random
import csv
import time
from mininet.net import Mininet
from mininet.node import OVSController
from mininet.topo import Topo
from mininet.link import TCLink
class ScalableTopo(Topo):
def build(self, num_clouds, num_devices, num_switches, cloud_resources):
# 클라우드 서버
clouds = []
for i in range(num_clouds):
cloud = self.addHost(f'cloud{i+1}', cpu=cloud_resources[i]['cpu'])
clouds.append(cloud)
# 단말 노드
devices = []
for i in range(num_devices):
device = self.addHost(f'device{i+1}')
devices.append(device)
# 스위치
switches = []
for i in range(num_switches):
switch = self.addSwitch(f's{i+1}')
switches.append(switch)
# 랜덤하게 클라우드 서버와 스위치 연결
for cloud in clouds:
switch = random.choice(switches)
delay = f'{random.uniform(1, 10)}ms' # 1ms에서 10ms 사이의 랜덤 지연 시간
loss = random.uniform(0, 10) if random.random() < 0.8 else 0 # 0%에서 10% 사이의 랜덤 패킷 손실
self.addLink(cloud, switch, bw=cloud_resources[clouds.index(cloud)]['bw'], use_htb=True, delay=delay, loss=loss, quantum=1500)
# 랜덤하게 단말 노드와 스위치 연결
for device in devices:
switch = random.choice(switches)
delay = f'{random.uniform(1, 10)}ms' # 1ms에서 10ms 사이의 랜덤 지연 시간
loss = random.uniform(0, 10) if random.random() < 0.8 else 0 # 0%에서 10% 사이의 랜덤 패킷 손실
self.addLink(device, switch, use_htb=True, delay=delay, loss=loss, quantum=1500)
# 스위치 간 연결
for i in range(len(switches) - 1):
delay = f'{random.uniform(1, 10)}ms' # 1ms에서 10ms 사이의 랜덤 지연 시간
loss = random.uniform(0, 10) if random.random() < 0.8 else 0
self.addLink(switches[i], switches[i + 1], use_htb=True, delay=delay, loss=loss, quantum=1500)
# 네트워크 규모에 따른 설정 함수
def configure_network(scale):
if scale == 'small':
num_clouds = 10
num_devices = 100
num_switches = 5
elif scale == 'medium':
num_clouds = 50
num_devices = 500
num_switches = 20
elif scale == 'large':
num_clouds = 100
num_devices = 1000
num_switches = 50
elif scale == 'custom':
num_clouds = 70
num_devices = 700
num_switches = 30 # 예시로 커스텀 값을 설정
else:
raise ValueError("scale 값을 확인해주세요 'small', 'medium', 'large', 'custom' 중 선택 ")
cloud_resources = []
for _ in range(num_clouds):
cloud_resources.append({
'cpu': random.uniform(0.1, 1.0), # 클라우드 서버의 CPU 제한 (0.1에서 1.0 사이)
'bw': random.uniform(10, 1000) # 클라우드 서버의 대역폭 제한 (10Mbps에서 1000Mbps 사이)
})
return num_clouds, num_devices, num_switches, cloud_resources
# 성능 테스트 함수
def measure_performance(src, dst):
band_result = net.iperf([src, dst])
band_string = band_result[0]
print(band_string)
#-- 대역폭에서 숫자만 추출
band_value = re.findall(r'\d+\.\d+', band_string)
#-- 대역폭에서 단위만 추출
band_unit = re.findall(r'\d+\.\d+\s*([a-zA-Z]+)', band_string)[0][0]
print("band_value is {}, band_unit is {}".format(band_value, band_unit))
if band_value:
band_value = float(band_value[0])
if band_unit == 'Mbits':
bandwidth = band_value
elif band_unit =='Kbits':
bandwidth = band_value / 1000
elif band_unit =='Gbits':
bandwidth = band_value * 1000
else:
bandwidth = 0.0
else:
bandwidth = 0.0
print(bandwidth)
# 지연 시간 및 패킷 손실률 측정
ping_full_result = src.cmd(f'ping -c 10 {dst.IP()}')
delay_lines = [line for line in ping_full_result.split('\n') if 'avg' in line]
delay = float(delay_lines[0].split('/')[4]) if delay_lines else 0.0
loss_lines = [line for line in ping_full_result.split('\n') if 'packet loss' in line]
loss = float(loss_lines[0].split('%')[0].split()[-1]) if loss_lines else 100.0
# 종합 평점 계산 (예시: 각 조건의 가중치를 다르게 부여)
# 대역폭은 0~1000Mbps 사이로 정규화, 지연 시간은 0~100ms 사이로 정규화, 패킷 손실은 0~100% 사이로 정규화
norm_bandwidth = bandwidth / 1000 # 대역폭을 0에서 1 사이로 정규화
norm_delay = delay / 1 # 지연 시간을 0에서 1 사이로 정규화
norm_loss = loss / 100 # 패킷 손실을 0에서 1 사이로 정규화
rating = 5 * (0.05 * norm_bandwidth + 0.5 * (1- norm_delay) + 0.45 * (1 - norm_loss))
rating = round(max(0, min(5, rating), 2)) # 평점은 0에서 5 사이로 제한
return bandwidth, delay, loss, rating
# 실시간 모니터링 함수
def monitor_network(devices, clouds, interval=10, duration=10, mode='test'):
print("네트워크 모니터링 시작...")
start_time = time.time()
if mode == 'save':
with open('/mnt/data/network_performance.csv', mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['Device', 'Cloud Server', 'Bandwidth (Mbps)', 'Delay (ms)', 'Packet Loss (%)', 'Rating'])
while time.time() - start_time < duration * 60: # duration 값을 분 단위로 변환
ratings = []
for device in devices:
for cloud in clouds:
bandwidth, delay, loss, rating = measure_performance(device, cloud)
ratings.append((device.name, cloud.name, bandwidth, delay, loss, rating))
print(f"{device.name} -> {cloud.name}: Bandwidth {bandwidth} Mbps, Delay {delay} ms, Packet Loss {loss} %, Rating {rating}")
for row in ratings:
writer.writerow(row)
time.sleep(interval)
print(f"네트워크 모니터링이 {duration}분 후 종료되었습니다.")
else:
while time.time() - start_time < duration * 60: # duration 값을 분 단위로 변환
ratings = []
for device in devices:
for cloud in clouds:
bandwidth, delay, loss, rating = measure_performance(device, cloud)
ratings.append((device.name, cloud.name, bandwidth, delay, loss, rating))
print(f"{device.name} -> {cloud.name}: Bandwidth {bandwidth} Mbps, Delay {delay} ms, Packet Loss {loss} %, Rating {rating}")
time.sleep(interval)
print(f"네트워크 모니터링이 {duration}분 후 종료되었습니다.")
# 네트워크 초기화 및 설정
scale = 'custom' # 'small', 'medium', 'large', 'custom' 중 선택
num_clouds, num_devices, num_switches, cloud_resources = configure_network(scale)
net = Mininet(topo=ScalableTopo(num_clouds, num_devices, num_switches, cloud_resources), controller=OVSController)
net.start()
clouds = [net.get(f'cloud{i+1}') for i in range(num_clouds)]
devices = [net.get(f'device{i+1}') for i in range(num_devices)]
try:
monitor_network(devices, clouds, interval=10, mode = "save", duration = 10)
except KeyboardInterrupt:
print("사용자에 의해 모니터링이 종료되었습니다.")
net.stop()
'GNN' 카테고리의 다른 글
미니넷(Mininet) 소개 및 사용법 (0) | 2024.05.29 |
---|---|
[CODE 리뷰]Dealing with Changes: Resilient Routing via Graph Neural Networks and Multi-Agent Deep Reinforcement Learning (2) | 2023.10.17 |
[Code] NGCF(Neural Graph Collaborative Filtering) (0) | 2023.08.19 |