Skip to content

Instantly share code, notes, and snippets.

@Andygol
Created December 28, 2025 10:57
Show Gist options
  • Select an option

  • Save Andygol/13653fd534cc58f16ac03fe082a0cd69 to your computer and use it in GitHub Desktop.

Select an option

Save Andygol/13653fd534cc58f16ac03fe082a0cd69 to your computer and use it in GitHub Desktop.
Створення декількох VM Multipass зі статичними IP адресами

Створення декількох VM Multipass зі статичними IP адресами

Див докладніше https://blog.andygol.co.ua/uk/2025/12/26/статичні-ip-для-вм-multipass/

Варіант A: Швидке створення з різними IP

# VM 1 - 10.10.0.10
cat > vm1.yaml << 'EOF'
#cloud-config
write_files:
  - path: /etc/netplan/60-custom-network.yaml
    content: |
      network:
        version: 2
        ethernets:
          enp0s2:
            addresses:
              - 10.10.0.10/24
            routes:
              - to: 10.10.0.0/24
                scope: link
    permissions: '0600'
runcmd:
  - netplan apply
hostname: vm1
EOF

# VM 2 - 10.10.0.11
cat > vm2.yaml << 'EOF'
#cloud-config
write_files:
  - path: /etc/netplan/60-custom-network.yaml
    content: |
      network:
        version: 2
        ethernets:
          enp0s2:
            addresses:
              - 10.10.0.11/24
            routes:
              - to: 10.10.0.0/24
    permissions: '0600'
runcmd:
  - netplan apply
hostname: vm2
EOF

# VM 3 - 10.10.0.12
cat > vm3.yaml << 'EOF'
#cloud-config
write_files:
  - path: /etc/netplan/60-custom-network.yaml
    content: |
      network:
        version: 2
        ethernets:
          enp0s2:
            addresses:
              - 10.10.0.12/24
            routes:
              - to: 10.10.0.0/24
    permissions: '0600'
runcmd:
  - netplan apply
hostname: vm3
EOF

# Запустіть всі VM
multipass launch --name vm1 --network name=en0,mode=manual --cloud-init vm1.yaml
multipass launch --name vm2 --network name=en0,mode=manual --cloud-init vm2.yaml
multipass launch --name vm3 --network name=en0,mode=manual --cloud-init vm3.yaml

# Дочекайтесь завершення
sleep 30

# Додайте аліас до bridge101
sudo ifconfig bridge101 10.10.0.1/24 alias

# Перевірте всі VM
multipass list

Варіант B: Скрипт для автоматичного створення

#!/bin/bash
# Створіть файл: create-vms.sh

BASE_IP="10.10.0"
START_NUM=10
COUNT=3

for i in $(seq 0 $((COUNT-1))); do
    VM_NAME="vm$((i+1))"
    VM_IP="$BASE_IP.$((START_NUM+i))"

    cat > ${VM_NAME}.yaml << EOF
#cloud-config
write_files:
  - path: /etc/netplan/60-custom-network.yaml
    content: |
      network:
        version: 2
        ethernets:
          enp0s2:
            addresses:
              - ${VM_IP}/24
            routes:
              - to: ${BASE_IP}.0/24
    permissions: '0600'
runcmd:
  - netplan apply
hostname: ${VM_NAME}
EOF

    echo "Створюю $VM_NAME з IP $VM_IP"
    multipass launch --name $VM_NAME --cloud-init ${VM_NAME}.yaml
done

echo "Чекаю завершення cloud-init..."
sleep 30

TARGET_BRIDGE=$(ifconfig -v | grep -B 20 "member: vmenet" | grep "bridge" | awk -F: '{print $1}' | tail -n 1)

if [ -z "$TARGET_BRIDGE" ]; then
    echo "Помилка: міст не знайдено. Перевірте, чи запущена ВМ."
else
    echo "ВМ знайдена на $TARGET_BRIDGE. Призначаємо $BASE_IP.1..."
    sudo ifconfig $TARGET_BRIDGE $BASE_IP.1/24 alias
fi

echo "Список VM:"
multipass list

Запуск:

chmod +x create-vms.sh
./create-vms.sh

Перевірка зв'язку між VM

# З vm1 до інших
multipass exec -n vm1 -- ping -c 2 10.10.0.11
multipass exec -n vm1 -- ping -c 2 10.10.0.12

# З vm2 до інших
multipass exec -n vm2 -- ping -c 2 10.10.0.10
multipass exec -n vm2 -- ping -c 2 10.10.0.12

# З хоста до всіх
for ip in 10.10.0.10 10.10.0.11 10.10.0.12; do
    echo "Ping $ip:"
    ping -c 2 $ip
done

Видалення статичної IP з окремої VM

Варіант 1: Видалення тільки додаткової IP (залишити VM)

# Видаліть статичну IP з VM
multipass exec -n test-vm -- sudo ip addr del 10.10.0.10/24 dev enp0s2

# Перевірте
multipass exec -n test-vm -- ip addr show enp0s2

# VM залишається з DHCP IP

Варіант 2: Видалення через netplan (постійно)

# Видаліть конфігураційний файл
multipass exec -n test-vm -- sudo rm /etc/netplan/60-custom-network.yaml

# Застосуйте зміни
multipass exec -n test-vm -- sudo netplan apply

Варіант 3: Перезапуск VM (скине тимчасові зміни)

# Якщо IP додана через ip addr add (не через netplan)
multipass restart test-vm

# IP зникне після перезапуску
multipass exec -n test-vm -- ip addr show enp0s2

Повне розбирання інфраструктури

Крок 1: Видаліть всі VM

# Список всіх VM
multipass list

# Зупиніть всі VM
multipass stop --all

# Видаліть конкретні VM
multipass delete test-vm
multipass delete vm1
multipass delete vm2
multipass delete vm3

# Або видаліть всі VM
multipass delete --all

# Остаточно очистіть (purge)
multipass purge

# Перевірте що все видалено
multipass list

Крок 2: Видаліть IP з bridge на хості

# Видаліть alias з bridge100, якщо ви додали його раніше
sudo ifconfig bridge100 -alias 10.10.0.1

# Перевірте що видалено
ifconfig bridge100 | grep "inet "

# Не має бути 10.10.0.1

Крок 3: Очистіть ARP кеш (опціонально)

# Видаліть всі записи для підмережі 10.10.0.0
sudo arp -d -a

# Або конкретні IP
sudo arp -d 10.10.0.10
sudo arp -d 10.10.0.11
sudo arp -d 10.10.0.12

# Перевірте
arp -an | grep 10.10.0
netstat -rn | grep 10.10.0

Крок 4: Видаліть routes (якщо додавали вручну)

# Перевірте routes
netstat -rn | grep 10.10.0

# Видаліть якщо є
sudo route delete 10.10.0.0/24

# Перевірте знову
netstat -rn | grep 10.10.0

Крок 5: Видаліть конфігураційні файли

# Видаліть cloud-init файли
rm -f multipass-static-ip.yaml
rm -f vm1.yaml vm2.yaml vm3.yaml
rm -f create-vms.sh

Крок 6: Перезапустіть Multipass (опціонально)

# Перезапустіть daemon для чистого стану
sudo launchctl unload /Library/LaunchDaemons/com.canonical.multipassd.plist
sudo launchctl load /Library/LaunchDaemons/com.canonical.multipassd.plist

Крок 7: Остаточна перевірка

# Перевірте що все чисто
echo "=== Multipass VM ==="
multipass list

echo "=== Bridge IP ==="
ifconfig bridge100 | grep "inet "

echo "=== Routes ==="
netstat -rn | grep 10.10.0

echo "=== ARP cache ==="
arp -an | grep 10.10.0

echo "=== Launch Daemons ==="
ls -la /Library/LaunchDaemons/ | grep multipass

echo "=== Cloud-init файли ==="
ls -la *.yaml 2>/dev/null || echo "Немає cloud-init файлів"

Очікуваний результат після очистки:

  • Multipass VM: No instances found.
  • Bridge IP: тільки основна IP (не 10.10.0.1)
  • Routes: немає записів з 10.10.0
  • ARP cache: немає записів з 10.10.0
  • Файли: видалені

Інфраструктура повністю розібрана!


Швидкі команди (Cheat Sheet)

Створити інфраструктуру:

# Хост
sudo ifconfig bridge100 10.10.0.1/24 alias

# VM
multipass launch --name test-vm --cloud-init multipass-static-ip.yaml

# Перевірка
ping 10.10.0.10

Розібрати інфраструктуру:

# VM
multipass delete test-vm
multipass purge

# Хост
sudo ifconfig bridge100 -alias 10.10.0.1
sudo arp -d -a

# Перевірка
multipass list
ifconfig bridge100 | grep 10.10.0

Тимчасова IP (без cloud-init):

# Додати
multipass exec -n test-vm -- sudo ip addr add 10.10.0.10/24 dev enp0s1

# Видалити
multipass exec -n test-vm -- sudo ip addr del 10.10.0.10/24 dev enp0s1

Автоматизація: Скрипти створення та розбирання

Скрипт створення (setup.sh)

#!/bin/bash
# Файл: setup.sh

BRIDGE="bridge100"
BRIDGE_IP="10.10.0.1"
SUBNET="10.10.0.0/24"
VM_NAME="test-vm"
VM_IP="10.10.0.10"

echo "=== Налаштування bridge ==="
sudo ifconfig $BRIDGE $BRIDGE_IP/24 alias
ifconfig $BRIDGE | grep "inet "

echo "=== Створення cloud-init ==="
cat > ${VM_NAME}.yaml << EOF
#cloud-config
write_files:
  - path: /etc/netplan/60-custom-network.yaml
    content: |
      network:
        version: 2
        ethernets:
          default:
            dhcp4: true
            addresses:
              - ${VM_IP}/24
            routes:
              - to: default
                via: ${BRIDGE_IP}
                metric: 200
    permissions: '0600'
runcmd:
  - netplan apply
hostname: ${VM_NAME}
EOF

echo "=== Створення VM ==="
multipass launch --name $VM_NAME --cloud-init ${VM_NAME}.yaml

echo "=== Очікування cloud-init ==="
sleep 30
multipass exec -n $VM_NAME -- cloud-init status --wait

echo "=== Перевірка ==="
echo "VM list:"
multipass list

echo "VM IP:"
multipass exec -n $VM_NAME -- ip addr show enp0s1 | grep "inet "

echo "Ping test:"
ping -c 4 $VM_IP

echo "✅ Інфраструктура створена!"

Скрипт розбирання (teardown.sh)

#!/bin/bash
# Файл: teardown.sh

BRIDGE="bridge100"
BRIDGE_IP="10.10.0.1"
VM_NAME="test-vm"

echo "=== Видалення VM ==="
multipass stop $VM_NAME 2>/dev/null
multipass delete $VM_NAME 2>/dev/null
multipass purge

echo "=== Видалення bridge IP ==="
sudo ifconfig $BRIDGE -alias $BRIDGE_IP

echo "=== Очистка ARP ==="
sudo arp -d -a

echo "=== Видалення routes ==="
sudo route delete 10.10.0.0/24 2>/dev/null

echo "=== Видалення конфігів ==="
rm -f ${VM_NAME}.yaml

echo "=== Перевірка ==="
echo "Multipass VM:"
multipass list

echo "Bridge IP:"
ifconfig $BRIDGE | grep "inet " | grep -v "127.0.0.1"

echo "Routes:"
netstat -rn | grep 10.10.0

echo "✅ Інфраструктура розібрана!"

Використання скриптів

# Зробіть виконуваними
chmod +x setup.sh teardown.sh

# Створення
./setup.sh

# Розбирання
./teardown.sh

Troubleshooting розбирання

Проблема: VM не видаляється

# Примусове видалення
multipass stop test-vm --force
multipass delete test-vm --force
multipass purge

# Якщо все ще є проблеми
sudo pkill -9 multipassd
sudo launchctl unload /Library/LaunchDaemons/com.canonical.multipassd.plist
sudo launchctl load /Library/LaunchDaemons/com.canonical.multipassd.plist

Проблема: IP не видаляється з bridge

# Спробуйте знову
sudo ifconfig bridge100 -alias 10.10.0.1

# Якщо не допомагає, перевірте всі aliases
ifconfig bridge100

# Видаліть кожен alias окремо
sudo ifconfig bridge100 -alias [IP]

# В крайньому випадку перезавантажте bridge
sudo ifconfig bridge100 down
sudo ifconfig bridge100 up

Проблема: ARP записи не видаляються

# Примусове видалення всього ARP кешу
sudo arp -d -a

# Перезапустіть мережу (обережно!)
sudo ifconfig bridge100 down
sudo ifconfig bridge100 up

Проблема: Routes залишаються

# Перевірте всі routes
netstat -rn

# Видаліть конкретний route
sudo route delete [IP або subnet]

# Приклад
sudo route delete 10.10.0.10
sudo route delete 10.10.0.0/24

Постійні налаштування (автоматичне створення після перезавантаження)

Якщо хочете, щоб bridge IP створювався автоматично:

# Створіть Launch Daemon
sudo tee /Library/LaunchDaemons/com.local.multipass-bridge.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.local.multipass-bridge</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>-c</string>
        <string>sleep 10 &amp;&amp; /sbin/ifconfig bridge100 10.10.0.1/24 alias</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
</dict>
</plist>
EOF

# Завантажте
sudo launchctl load /Library/LaunchDaemons/com.local.multipass-bridge.plist

# Для видалення
sudo launchctl unload /Library/LaunchDaemons/com.local.multipass-bridge.plist
sudo rm /Library/LaunchDaemons/com.local.multipass-bridge.plist
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment