Server Installation/UML: Unterschied zwischen den Versionen
Lars (Diskussion | Beiträge) (von "jun" übertragen) |
Lars (Diskussion | Beiträge) (Skript besser formatiert) |
||
Zeile 49: | Zeile 49: | ||
Auf [[Server/jun]] verwenden wir folgendes Skript: | Auf [[Server/jun]] verwenden wir folgendes Skript: | ||
− | |||
− | |||
− | set -eu | + | #!/bin/sh |
− | + | ||
− | BASE_DIR=~/uml | + | set -eu |
− | + | ||
− | # Wir wollen keine absoluten Links in den cow-Dateien - also lieber ins Verzeichnis | + | BASE_DIR=~/uml |
− | # wechseln und dann mit relativen Pfaden arbeiten. | + | |
− | cd "$BASE_DIR" | + | # Wir wollen keine absoluten Links in den cow-Dateien - also lieber ins Verzeichnis |
− | + | # wechseln und dann mit relativen Pfaden arbeiten. | |
− | + | cd "$BASE_DIR" | |
− | SCREEN_NAME=uml_console | + | |
− | UML_BIN="./openwrt-0.5.3-unstable-1728-uml-vmlinux" | + | |
− | UML_BASE_IMAGE="openwrt-0.5.3-unstable-1728-uml-ext4.img" | + | SCREEN_NAME=uml_console |
− | UML_IMAGE_DIR="hosts" | + | UML_BIN="./openwrt-0.5.3-unstable-1728-uml-vmlinux" |
− | UML_RUN_DIR="run" | + | UML_BASE_IMAGE="openwrt-0.5.3-unstable-1728-uml-ext4.img" |
− | UML_MEMORY=32M | + | UML_IMAGE_DIR="hosts" |
− | UML_DEFAULT_ARGS="uml_dir=$UML_RUN_DIR ssl=pty mem=$UML_MEMORY" | + | UML_RUN_DIR="run" |
− | + | UML_MEMORY=32M | |
− | + | UML_DEFAULT_ARGS="uml_dir=$UML_RUN_DIR ssl=pty mem=$UML_MEMORY" | |
− | send_screen_command() { | + | |
+ | |||
+ | send_screen_command() { | ||
screen -S "$SCREEN_NAME" -X "$@" | screen -S "$SCREEN_NAME" -X "$@" | ||
− | } | + | } |
− | + | ||
− | + | ||
− | run_screen_if_not_running() { | + | run_screen_if_not_running() { |
screen -ls "$SCREEN_NAME" >/dev/null || screen -S "$SCREEN_NAME" -d -m | screen -ls "$SCREEN_NAME" >/dev/null || screen -S "$SCREEN_NAME" -d -m | ||
− | } | + | } |
− | + | ||
− | + | ||
− | poweroff_host() { | + | poweroff_host() { |
local name="$1" | local name="$1" | ||
local pidfile="$UML_RUN_DIR/$name/pid" | local pidfile="$UML_RUN_DIR/$name/pid" | ||
[ -e "$pidfile" ] || return | [ -e "$pidfile" ] || return | ||
kill "$(cat "$pidfile")" | kill "$(cat "$pidfile")" | ||
− | } | + | } |
− | + | ||
− | + | ||
− | clear_host_cow() { | + | clear_host_cow() { |
local name="$1" | local name="$1" | ||
rm -f "$UML_IMAGE_DIR/${name}.cow" | rm -f "$UML_IMAGE_DIR/${name}.cow" | ||
− | } | + | } |
− | + | ||
− | configure_host_in_current_window() { | + | configure_host_in_current_window() { |
local name="$1" | local name="$1" | ||
# TODO: leider funktioniert "select" nicht - also muss das Zielfenster aktuell aktiv sein :( | # TODO: leider funktioniert "select" nicht - also muss das Zielfenster aktuell aktiv sein :( | ||
Zeile 102: | Zeile 102: | ||
send_screen_command stuff "$line\n" | send_screen_command stuff "$line\n" | ||
done <<-EOF | done <<-EOF | ||
− | + | ||
uci set "system.@system[0].hostname=$name" | uci set "system.@system[0].hostname=$name" | ||
uci set "network.lan.ifname=none" | uci set "network.lan.ifname=none" | ||
Zeile 113: | Zeile 113: | ||
uci commit | uci commit | ||
reload_config | reload_config | ||
− | EOF | + | EOF |
− | } | + | } |
− | + | ||
− | + | ||
− | run_host() { | + | run_host() { |
local name="$1" | local name="$1" | ||
local host_image="$UML_IMAGE_DIR/${name}.cow" | local host_image="$UML_IMAGE_DIR/${name}.cow" | ||
Zeile 137: | Zeile 137: | ||
configure_host_in_current_window "$name" | configure_host_in_current_window "$name" | ||
} | } | ||
− | } | + | } |
− | + | ||
− | + | ||
− | case "${1:-help}" in | + | case "${1:-help}" in |
start) | start) | ||
run_screen_if_not_running | run_screen_if_not_running | ||
Zeile 176: | Zeile 176: | ||
exit 1 | exit 1 | ||
;; | ;; | ||
− | esac | + | esac |
− | + | ||
Pfade sind natürlich anzupassen. | Pfade sind natürlich anzupassen. |
Version vom 8. Januar 2016, 21:22 Uhr
Überblick
user-mode-linux ermöglicht die Virtualisierung eines Systems im Userspace eines Hosts. Abgesehen von der Netzwerkkonfiguration genügen somit einfache Nutzerrechte, um diese Virtualisierung zu verwenden und zu verwalten.
Als Vorraussetzung ist ein für die Ziel-Plattform "UML" kompilierter Linux-Kernel erforderlich. Dieser kompilierte Kernel ist im Unterschied zu einem üblichen Linux-Kernel ein ausführbares Programm. Zusätzlich zum UML-Kernel wird ein root-Dateisystem benötigt. Es wird üblicherweise in Form eines Images als Paramter bei der Ausführung mitgegeben.
Da ein UML-Kernel nur auf einer bestimmten Plattform lauffähig ist (der des Build-Hosts), verteilt openwrt keine UML-Kernel. Somit sind diese selbst zu kompilieren. Alternativ liefert beispielsweise auch Debian ein user-mode-linux-Paket aus. Für die Verwendung von openwrt-Images muss anschließend lediglich das im Debian-Paket enthaltene /lib/modules/-Verzeichnis auf das Image kopiert werden.
Ersteinrichtung
Pakete installieren:
apt-get install dnsmasq vde2
dnsmasq-Konfiguration (/etc/dnsmasq.d/custom.conf):
interface=lo interface=virt-uplink dhcp-range=172.16.10.10,172.16.10.50,12h server=/on/192.168.10.2 server=172.23.12.1 # die virtuellen Clients sollen bei uns die DNS-Anfragen aufloesen dhcp-option=6, 172.16.10.1
Virtuelle Interfaces konfigurieren (/etc/network/interfaces):
auto virt-uplink iface virt-uplink inet static address 172.16.10.1 netmask 255.255.255.0 vde2-switch -t virt-uplink auto virt-mesh1 iface virt-mesh1 inet manual vde2-switch -t virt-mesh1 auto virt-mesh2 iface virt-mesh2 inet manual vde2-switch -t virt-mesh2 auto virt-mesh3 iface virt-mesh3 inet manual vde2-switch -t virt-mesh3
Nutzer einrichten:
adduser --disabled-password uml-virt adduser uml-virt vde2-net
Verwaltung
Nun fehlt noch ein Skript für den Start der Hosts bzw. für die Definition der Vernetzung.
Die interessanteste Zeile in diesem Skript ist der Aufruf des UML-Kernels:
./uml_vmlinuz uml_dir=run ssl=pty mem=32M ubd0=host_foo.cow:openwrt-uml-ext4.img umid=host_foo eth0=daemon,,,/var/run/vde2/virt-uplink.ctl/ctl
Auf Server/jun verwenden wir folgendes Skript:
#!/bin/sh set -eu BASE_DIR=~/uml # Wir wollen keine absoluten Links in den cow-Dateien - also lieber ins Verzeichnis # wechseln und dann mit relativen Pfaden arbeiten. cd "$BASE_DIR" SCREEN_NAME=uml_console UML_BIN="./openwrt-0.5.3-unstable-1728-uml-vmlinux" UML_BASE_IMAGE="openwrt-0.5.3-unstable-1728-uml-ext4.img" UML_IMAGE_DIR="hosts" UML_RUN_DIR="run" UML_MEMORY=32M UML_DEFAULT_ARGS="uml_dir=$UML_RUN_DIR ssl=pty mem=$UML_MEMORY" send_screen_command() { screen -S "$SCREEN_NAME" -X "$@" } run_screen_if_not_running() { screen -ls "$SCREEN_NAME" >/dev/null || screen -S "$SCREEN_NAME" -d -m } poweroff_host() { local name="$1" local pidfile="$UML_RUN_DIR/$name/pid" [ -e "$pidfile" ] || return kill "$(cat "$pidfile")" } clear_host_cow() { local name="$1" rm -f "$UML_IMAGE_DIR/${name}.cow" } configure_host_in_current_window() { local name="$1" # TODO: leider funktioniert "select" nicht - also muss das Zielfenster aktuell aktiv sein :( #send_screen_command select "$name" # oeffne die Konsole send_screen_command stuff "\n" while read line; do send_screen_command stuff "$line\n" done <<-EOF uci set "system.@system[0].hostname=$name" uci set "network.lan.ifname=none" uci delete -q "network.wan" uci set "network.wan=interface" uci set "network.wan.ifname=eth0" uci set "network.wan.proto=dhcp" uci set "network.wan.hostname=$name" uci set "firewall.@zone[1].input=ACCEPT" uci commit reload_config EOF } run_host() { local name="$1" local host_image="$UML_IMAGE_DIR/${name}.cow" local run_post_configure=0 shift local args="$UML_DEFAULT_ARGS ubd0=$host_image:$UML_BASE_IMAGE umid=$name" local netname local netindex=0 for netname in "$@"; do args="$args eth${netindex}=daemon,,,/var/run/vde2/${netname}.ctl/ctl" netindex=$((netindex+1)) done # ist eine Nachkonfiguration noetig? [ -e "$host_image" ] || run_post_configure=1 send_screen_command screen -t "$name" "$UML_BIN" $args [ "$run_post_configure" = "0" ] || { # warte auf Ende des Boot-Vorgangs sleep 10 configure_host_in_current_window "$name" } } case "${1:-help}" in start) run_screen_if_not_running run_host "host1" "virt-uplink" "virt-mesh1" run_host "host2" "virt-uplink" "virt-mesh1" "virt-mesh2" run_host "host3" "virt-uplink" "virt-mesh2" "virt-mesh3" run_host "host4" "virt-uplink" "virt-mesh3" ;; stop) poweroff_host "host1" poweroff_host "host2" poweroff_host "host3" poweroff_host "host4" send_screen_command quit ;; restart) "$0" stop "$0" start ;; connect) screen -x "$SCREEN_NAME" ;; clear-cow) clear_host_cow "host1" clear_host_cow "host2" clear_host_cow "host3" clear_host_cow "host4" ;; --help|help) echo "Syntax: $(basename "$0") SESSION { start | stop | restart | connect | clear-cow | help }" echo ;; *) "$0" help >&2 exit 1 ;; esac
Pfade sind natürlich anzupassen.