Uživatelské nástroje

Nástroje pro tento web


navody:vps:kvm

Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revizePředchozí verze
Následující verze
Předchozí verze
navody:vps:kvm [2023/10/20 11:03] rene.lanavody:vps:kvm [2026/08/17 11:09] (aktuální) – Napojení na revizi zdroje a testy virtualizace aither
Řádek 1: Řádek 1:
 <page>manuals:vps:kvm</page> <page>manuals:vps:kvm</page>
-====== Používání KVM na vpsFree.cz  ====== 
-VPS jsou [[informace:vpsadminos|linuxové kontejnery]], tzn. na nodu běží jeden kernel, který je sdílený 
-mezi všemi VPS. Pokud z nějakého důvodu potřebuješ vlastní kernel, nebo chceš provozovat jiný operační 
-systém, můžeš si ve VPS spouštět vlastní plnohodnotné virtuály pomocí QEMU/KVM. 
  
-===== Konfigurace ===== +<kb-managed 
-Nejprve je potřeba ve vpsAdminu v detailu VPS zapnout následující vlastnosti:+  source="contract/pages/navody-vps-kvm.txt" 
 +  test="kb/kvm#*" 
 +/>
  
-  * TUN/TAP - povolí vytváření virtuálních interface, které jsou pak bridgovány, +====== KVM a libvirt uvnitř VPS ======
-  * KVM – povolí použití KVM (pro HW podporu virtualizace).+
  
-Na vpsFree není jiná možnost než mít disky pro KVM virtuály v souborech (images). Doporučujeme k tomu vytvořit nový (sub)dataset, **vypnout v něm kompresi** a nastavit velikost bloku (Record size) na 65536 B. Vypnutí komprese je velmi důležité, jinak vám bude image bobtnat a bobtnat, přes deklarovanou velikost image, dokud nenarazí na kvótu datasetu! Pro optimální výkon vytvářejte „raw“ image.+===== Instalace libvirt =====
  
-===== libvirt ===== +vpsAdminOS provozuje VPS v kontejnerech, nikoli ve virtuálních strojích. KVM 
-Virtuály můžeš spravovat pomocí [[https://libvirt.org|libvirt]] ve VPS +uvnitř VPS proto není vnořená virtualizace: virtuální stroje používají 
-ipojit se k němu přes [[https://virt-manager.org|virt-manager]].+hardwarovou virtualizaci fyzického nodu ímo. 
 +Tento návod používá aktuální šablonu **Debian (latest)**, libvirt a systémové 
 +spojení ''qemu:///system''.
  
-===== Mount dataset export z NAS serveru pro QEMU/KVM ===== +<vpsadmin-nav id="vps.features.open"> 
-Pokud chceš používat v QEMU/KVM připojený dataset export z NAS serveru, například pro mount ISO obrazu CD pro boot systému a dostaneš toto hlášení "//Failed to lock byte 100: No locks available//", musí být daný export namountován do hostitelského systému s příznakem "nolock".+Pro virtualizaci je potřeba funkce **KVM**. **TUN/TAP** je potřeba pro síťová 
 +rozhraní virtuálních strojů typu TAP. Obě funkce jsou u nových VPS zapnuté ve 
 +výchozím nastavení v sekci **Funkce** v detailu VPS ve vpsAdminu. 
 +</vpsadmin-nav>
  
-Například pokud používáš pro mount do systému fstab:+{{:cs:screenshots:vpsadmin:vps-details:feature-settings.png?direct|Výchozí funkce VPS}}
  
-  562.586.65.25:/nas/4562 /mnt/export4562 nfs vers=3,nofail 0 0+Nainstaluj QEMUlibvirt a ''virt-install'' z Debianu:
  
-Nově použiješ mount příkaz takto:+<code bash> 
 +#!/usr/bin/env bash 
 +set -euo pipefail
  
-  562.586.65.25:/nas/4562 /mnt/export4562 nfs vers=3,nofail,nolock 0 0+apt-get update 
 +apt-get install --yes \ 
 +  iptables \ 
 +  libvirt-clients \ 
 +  libvirt-daemon-system \ 
 +  qemu-system-x86 \ 
 +  qemu-utils \ 
 +  virtinst
  
-(**//562.586.65.25//** Adresa tvého NFS serveru; **//4562//** > číslo tvého datasetu na NFS serveru)+virsh --connect qemu:///system version 
 +</code>
  
-===== KVM na Alpine Linuxu  =====+Používej systémové spojení ''qemu:///system''. Pro vzdálenou správu použij 
 +libvirt přes SSH, například ''qemu+ssh://root@HOST/system'', a chraň SSH 
 +klíčem. Nezveřejňuj nešifrovaný libvirt TCP socket do internetu.
  
-Připravu hypervizoru lze provést automatizovaně pomocí [[http://docs.ansible.com/ansible/latest/index.html|Ansible]].+===== Diskové obrazy a ZFS =====
  
-[[https://gist.github.com/HalisCz/192955c64c255ee15cc647f6efabd020|Na GitHubu]] jsou dle níže uvedeného návodu automatizovány zatím tyto sekce: +Pro obrazy disků použij samostatný [[navody:vps:datasety|subdataset]]. Jeho ZFS 
-  * [[navody:vps:kvm#instalace_balicku_a_konfigurace_hypervizoru|Instalace balíčků a konfigurace hypervizoru]] - tag ''instalace'' +vlastnosti pak můžeš změnit bez zásahu do kořenového datasetu VPS. Úložiště 
-  * [[navody:vps:kvm#nastaveni_iptables|Nastavení iptables]] - tag ''nastaveni-iptables''+připrav takto:
  
-==== Instalace balíčků konfigurace hypervizoru ====+  * <vpsadmin-nav id="datasets.edit.open">V detailu VPS u kořenového datasetu použij akci **Upravit** a zmenši jeho referenční kvótu o prostor určený pro obrazy.</vpsadmin-nav> 
 +  * <vpsadmin-nav id="datasets.create.open">Pomocí **Vytvořit dataset** vytvoř subdataset ''vm-images'' s uvolněnou kapacitou.</vpsadmin-nav> 
 +  * <vpsadmin-nav id="datasets.mount.open">U datasetu ''vm-images'' použij **Mount** připoj jej do VPS jako ''/srv/libvirt/images''.</vpsadmin-nav>
  
-Nainstalujte potřebné balíčky (ip6tables je volitelný):+Například z běžné kapacity 120 GiB můžeš ponechat 20 GiB kořenovému datasetu 
 +a 100 GiB přidělit datasetu ''vm-images''. Prvnímu disku virtuálního stroje pak 
 +můžeš přidělit například 80 GiB a ponechat 20 GiB volných pro jeho růst a 
 +snapshoty.
  
-<code shell> +Subdataset se [[navody:vps:zalohy|snapshotuje]] odděleně od kořenového datasetu 
-apk update +VPS.
-apk add qemu-system-x86_64 qemu-openrc qemu-img bridge iptables ip6tables +
-</code>+
  
-Nastavte potřebná práva pro přístup ke KVM a TUN (do skupin //kvm// a //netdev// by měl patřit uživatel //qemu//, pod kterým bude běžet vytvořený virtuál):+{{:cs:screenshots:vpsadmin:vps-details:datasets.png?direct|Datasety VPS}}
  
-<code shell+Připojený adresář přidej do libvirt jako trvalý storage pool: 
-chown :kvm /dev/kvm + 
-chmod g+rw /dev/kvm +<code bash
-chown :netdev /dev/net/tun +#!/usr/bin/env bash 
-chmod g+rw /dev/net/tun+set -euo pipefail 
 + 
 +virsh --connect qemu:///system pool-define-as \ 
 +  vm-images dir --target /srv/libvirt/images 
 +virsh --connect qemu:///system pool-start vm-images 
 +virsh --connect qemu:///system pool-autostart vm-images 
 +virsh --connect qemu:///system pool-info vm-images
 </code> </code>
  
-Nakonfigurujte bridge pro Qemu/KVM virtuály; vytvořte soubor ///etc/network/interfaces.tail// (IP adresu si samozřejmě můžete zvolit libovolnou privátního rozsahu):+Disky pak vytvářej prostřednictvím libvirt, ''virt-install'' nebo 
 +''virt-manager'' v poolu ''vm-images''
 + 
 +ZFS vlastnosti subdatasetu ponech na výchozích hodnotách, dokud měření 
 +neukáže důvod ke změně. Komprese je ve výchozím nastavení zapnutá. Výchozí 
 +''recordsize=128K'' určuje maximální velikost záznamu souboruZFS podle potřeby 
 +používá i menší záznamy. Změna ''recordsize'' se projeví pouze u nově 
 +vytvořených souborů. 
 + 
 +Pro obrazy na ZFS je vhodnou výchozí volbou formát ''raw'', protože nepřidává 
 +další copy-on-write vrstvu. ''qcow2'' použij, pokud potřebuješ jeho backing 
 +files, interní snapshoty nebo jiné funkce obrazového formátu. 
 + 
 +Podrobnosti k ladění podle zátěže popisuje [[https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Workload%20Tuning.html|OpenZFS Workload Tuning]], formáty obrazů pak [[https://www.qemu.org/docs/master/system/images|dokumentace QEMU]]. 
 + 
 +===== Síť virtuálních strojů ===== 
 + 
 +Síťové rozhraní VPS je k nodu připojené směrovaným spojem na třetí vrstvě. 
 +Nepřidávej proto rozhraní VPS do bridge spravovaného libvirt. Pro připojení 
 +virtuálních strojů k síti jsou vhodná dvě zapojení: 
 + 
 +^ Zapojení ^ Adresy v doméně ^ Výhody ^ Nevýhody ^ 
 +| NAT v libvirt | Privátní IPv4 a privátní ULA IPv6 | Funguje s běžnými adresami VPS, snadno obslouží více domén. | Příchozí služby potřebují přesměrování portů a provoz prochází NAT44 i NAT66. | 
 +| Směrované veřejné adresy | Veřejná IPv4 ''/32'' a adresy ze samostatné IPv6 ''/64'' | Doména je dostupná přímo, bez NAT a bez překladu portů. | Vyžaduje privátní IPv4 na VPS, další směrovanou IPv6 síť a pečlivě nastavený firewall. | 
 + 
 +NAT je obvykle jednodušší pro jednu nebo několik domén s malým počtem 
 +zveřejněných služeb. Směrované adresy použij, když má mít doména vlastní 
 +veřejné adresy, všechny porty nebo protokoly, které se přes port forwarding 
 +obsluhují špatně. Pro čistě vnitřní komunikaci mezi doménami můžeš přidat další 
 +izolovanou síť libvirt; přístup ven nadále řeší jedno uvedených zapojení. 
 + 
 +==== Veřejné adresy na VPS a dvouprotokolový NAT ==== 
 + 
 +Veřejná IPv4 ''/32'' i IPv6 ''/64'' zůstanou na VPS. Doména dostane 
 +''192.168.124.10/24'' a ''fd5f:6d2e:9c4a:124::10/64'' ze sítě 
 +''dualstack-nat''. Libvirt překládá odchozí IPv4 pomocí NAT44 a IPv6 pomocí 
 +NAT66. Výchozí síť ''default'' v běžné instalaci libvirt obvykle obsahuje jen 
 +IPv4 a používá ''192.168.122.0/24'', proto zde definujeme vlastní 
 +dvouprotokolovou síť s odlišnou IPv4 podsítí. NAT66 se v XML zapíná pomocí 
 +''<nat ipv6='yes'/>''; podrobnosti jsou v 
 +[[https://libvirt.org/formatnetwork.html|dokumentaci formátu sítí libvirt]]. 
 + 
 +ULA ''fd5f:6d2e:9c4a::/48'' je příklad pro samostatnou instalaci. Pokud budeš 
 +více privátních sítí později propojovat pomocí VPN nebo směrování, vytvoř pro 
 +každou z nich vlastní náhodný ULA ''/48'' a změň ''HOST_IPV6''
 +''GUEST_IPV6'' na adresy ze stejné ''/64''
 + 
 +Podstatnou část definice sítě tvoří následující XML:
  
-<code shell+<code xml
-auto br0 +<network> 
-iface br0 inet static +  <name>dualstack-nat</name> 
-     pre-up brctl addbr br0 +  <forward mode='nat'> 
-     address 172.17.1.1 +    <nat ipv6='yes'/> 
-     netmask 255.255.255.0 +  </forward> 
-     post-down brctl delbr br0+  <bridge name='virbr-nat'/> 
 +  <ip address='192.168.124.1' prefix='24'/> 
 +  <ip family='ipv6' address='fd5f:6d2e:9c4a:124::1' prefix='64'/> 
 +</network>
 </code> </code>
  
-Jelikož OpenVZ poněkud neohrabaně episuje soubor ///etc/network/interfaces// (proto také konfiguraci bridge přidáváme do //interfaces.tail//, tak nejjistější je v tuto chvíli kontejner restartovat. :/+Vytvořenou doménu ipoj k ''dualstack-nat'', například volbou 
 +''--network network=dualstack-nat,model=virtio'' ve ''virt-install''V doméně 
 +nastav stabilní adresy a brány:
  
-Povolte uživateli ve skupině //qemu// spravovat vytvořený bridge:+<code conf> 
 +auto ens3 
 +iface ens3 inet static 
 +    address 192.168.124.10/24 
 +    gateway 192.168.124.1
  
-<code shell> +iface ens3 inet6 static 
-echo "allow br0" > /etc/qemu/bridge.conf +    address fd5f:6d2e:9c4a:124::10/64 
-chown root:qemu /etc/qemu/bridge.conf +    gateway fd5f:6d2e:9c4a:124::1
-chmod 0640 /etc/qemu/bridge.conf+
 </code> </code>
  
-Nastavte IP maškarádu pro přístup Qemu/KVM virtuálů ven do veřejného Internetu.+Přesměrování portu se skládá z DNAT na adresu domény a povolení odpovídajícího 
 +forwarduPro web na IPv4 jsou podstatou například tyto dva příkazy:
  
-Pokud už máte nakonfigurované iptables, tak jen přidejte pravidlo:+<code bash> 
 +iptables -t nat -I PREROUTING 1 -tcp -d VPS_IPV4 --dport 80 \ 
 +  -j DNAT --to-destination 192.168.124.10:80 
 +iptables -t filter -I FORWARD 1 -p tcp -d 192.168.124.10 --dport 80 \ 
 +  -j ACCEPT 
 +</code>
  
-<code> +Stejná pravidla je potřeba vytvořit i pomocí ''ip6tables'' pro IPv6. Ručně 
-iptables -t nat -A POSTROUTING -s 172.17.1.0/24 ! -o br0 -j MASQUERADE+zadaná pravidla však libvirt při změnách sítě nezachová. Následující úplný 
 +skript proto vytvoří síť, soubor s přesměrováním a hook, který pravidla obnoví 
 +při spuštění nebo znovupřipojení sítě. Ve výchozím nastavení zveřejní web na 
 +portu 80 a SSH domény na portu 2222 pro IPv4 i IPv6. 
 + 
 +Ulož jej například jako ''/root/configure-nat-port-forwards.sh'' a spusť 
 +s jednou veřejnou IPv4 a jednou adresou z IPv6 ''/64'' nakonfigurovanou na VPS: 
 + 
 +<code bash> 
 +PUBLIC_IPV4=VPS_IPV4 PUBLIC_IPV6=VPS_IPV6 \ 
 +  /root/configure-nat-port-forwards.sh
 </code> </code>
  
-V opačném ípadě můžete postupovat např. podle odstavce [[#nastaveni_iptables|Nastavení iptables]].+Skript se spouští i prvním vytvoření sítě a znovu při změně jeho vstupních 
 +hodnot, ne po každém restartu VPSSíť má zapnutý autostart a pravidla při jejím 
 +spuštění načte hook.
  
 +<code bash>
 +#!/usr/bin/env bash
 +set -euo pipefail
  
-==== Vytvoření spuštění virtuálu ====+: "${PUBLIC_IPV4:?set PUBLIC_IPV4 to the VPS public IPv4 address}" 
 +: "${PUBLIC_IPV6:?set PUBLIC_IPV6 to public IPv6 address of the VPS}"
  
-V tomto návodu předpokládám použití [[https://github.com/jirutka/qemu-openrc|qemu-openrc]] – OpenRC init skript pro startování Qemu/KVM. Na Alpine samozřejmě můžete používat i libvirt, ale opravdu chcete a potřebujete jeho neohrabané XML konfiguráky a/nebo klikátka nad ním…? ;) Qemu-openrc je výrazně jednodušší a transparentnější řešení. Každý virtuál je reprezentovaný init skriptem, stejně jako ostatní programy, můžete deklarativně nastavovat závislosti mezi virtuály atd.+guest_ipv4=${GUEST_IPV4:-192.168.124.10} 
 +guest_ipv6=${GUEST_IPV6:-fd5f:6d2e:9c4a:124::10} 
 +host_ipv4=${HOST_IPV4:-192.168.124.1} 
 +host_ipv6=${HOST_IPV6:-fd5f:6d2e:9c4a:124::1} 
 +connection=qemu:///system 
 +network=dualstack-nat 
 +hook=/etc/libvirt/hooks/network.d/50-port-forwards 
 +config=/etc/libvirt/port-forwards.conf 
 +xml=$(mktemp) 
 +trap 'rm -f "$xml"' EXIT
  
-Vytvoření nového virtálu spočívá pouze v přípravě image disku, vytvoření symlinku pro init skript a úpravě jednoduchého konfiguračního skriptuNechť se nový virtuál jmenuje třeba „myvirt.+network_uuid=$(virsh --connect "$connection" net-uuid "$network" 2>/dev/null || :) 
 +uuid_element= 
 +if [[ -n $network_uuid ]]; then 
 +  uuid_element="  <uuid>$network_uuid</uuid>" 
 +fi 
 +cat >"$xml" <<EOF 
 +<network> 
 +  <name>$network</name> 
 +$uuid_element 
 +  <forward mode='nat'> 
 +    <nat ipv6='yes'/> 
 +  </forward> 
 +  <bridge name='virbr-nat' stp='on' delay='0'/> 
 +  <ip address='$host_ipv4' prefix='24'> 
 +    <dhcp> 
 +      <range start='192.168.124.100' end='192.168.124.254'/> 
 +    </dhcp> 
 +  </ip> 
 +  <ip family='ipv6' address='$host_ipv6' prefix='64'/> 
 +</network> 
 +EOF
  
-Připravte raw image pro myvirt o potřebné velikosti:+if virsh --connect "$connection" net-list --name \ 
 +  | grep -Fx "$network" >/dev/null; then 
 +  printf '%s is active. Shut down its attached domains, run ' "$network" >&
 +  printf 'virsh net-destroy %s, then rerun this script.\n' "$network" >&
 +  exit 1 
 +fi
  
-<code shell> +install -d -m 0755 /etc/libvirt/hooks/network.d 
-mkdir -p /var/lib/qemu/myvirt+install --m 0755 /etc/libvirt 
-qemu-img create -f raw /var/lib/qemu/myvirt/disk0.raw 5G +cat >"$hook" <<'HOOK' 
-chown qemu:qemu /var/lib/qemu/myvirt/disk0.raw +#!/usr/bin/env bash 
-chmod 0600 /var/lib/qemu/myvirt/disk0.raw +set -euo pipefail 
-</code>+ 
 +PATH=/usr/sbin:/usr/bin:/sbin:/bin 
 +network=${1-} 
 +action=${2-} 
 +config=/etc/libvirt/port-forwards.conf 
 +nat_chain=VPSFREE_KVM_DNAT 
 +filter_chain=VPSFREE_KVM_FWD 
 + 
 +[[ $network == dualstack-nat ]] || exit 0 
 +exec 9>/run/lock/vpsfree-kvm-port-forwards.lock 
 +flock 9 
 + 
 +delete_jumps() { 
 +  local tool 
 +  for tool in iptables ip6tables; do 
 +    while "$tool" -w -t nat -C PREROUTING -j "$nat_chain" 2>/dev/null; do 
 +      "$tool" -w -t nat -D PREROUTING -j "$nat_chain" 
 +    done 
 +    while "$tool" -w -t filter -C FORWARD -j "$filter_chain" 2>/dev/null; do 
 +      "$tool" -w -t filter -D FORWARD -j "$filter_chain" 
 +    done 
 +  done 
 +
 + 
 +delete_chains() { 
 +  local tool 
 +  for tool in iptables ip6tables; do 
 +    if "$tool" -w -t nat -S "$nat_chain" >/dev/null 2>&1; then 
 +      "$tool" -w -t nat -F "$nat_chain" 
 +      "$tool" -w -t nat -X "$nat_chain" 
 +    fi 
 +    if "$tool" -w -t filter -S "$filter_chain" >/dev/null 2>&1; then 
 +      "$tool" -w -t filter -F "$filter_chain" 
 +      "$tool" -w -t filter -X "$filter_chain" 
 +    fi 
 +  done 
 +
 + 
 +cleanup() { 
 +  delete_jumps 
 +  delete_chains 
 +
 + 
 +valid_ip_address() { 
 +  local family=$1 address=$2 
 + 
 +  perl -MSocket=AF_INET,AF_INET6,inet_pton -e ' 
 +    my ($family, $address) = @ARGV; 
 +    my $af = $family eq "ipv4" ? AF_INET : AF_INET6; 
 +    exit(defined(inet_pton($af, $address)) ? 0 : 1); 
 +  ' "$family" "$address" 
 +
 + 
 +if [[ $action == stopped ]]; then 
 +  cleanup 
 +  exit 0 
 +fi 
 +[[ $action == started || $action == reconnect ]] || exit 0 
 + 
 +entries=() 
 +while read -r family protocol public_ip public_port guest_ip guest_port extra \ 
 +    || [[ -n ${family:-} ]]; do 
 +  [[ -n ${family:-} && $family != \#* ]] || continue 
 +  [[ $family == ipv4 || $family == ipv6 ]] || { 
 +    printf 'Invalid address family in %s: %s\n' "$config" "$family" >&
 +    exit 1 
 +  } 
 +  [[ $protocol == tcp || $protocol == udp ]] || { 
 +    printf 'Invalid protocol in %s: %s\n' "$config" "$protocol" >&
 +    exit 1 
 +  } 
 +  for address in "$public_ip" "$guest_ip"; do 
 +    valid_ip_address "$family" "$address" || { 
 +      printf 'Invalid %s address in %s: %s\n' \ 
 +        "$family" "$config" "$address" >&
 +      exit 1 
 +    } 
 +  done 
 +  [[ $public_port =~ ^[0-9]{1,5}$ && $guest_port =~ ^[0-9]{1,5}$ ]] || { 
 +    printf 'Invalid port in %s\n' "$config" >&
 +    exit 1 
 +  } 
 +  public_port=$((10#$public_port)) 
 +  guest_port=$((10#$guest_port)) 
 +  ((public_port >= 1 && public_port <= 65535)) || exit 1 
 +  ((guest_port >= 1 && guest_port <= 65535)) || exit 1 
 +  [[ -z ${extra:-} ]] || { 
 +    printf 'Too many fields in %s\n' "$config" >&
 +    exit 1 
 +  } 
 +  entries+=("$family|$protocol|$public_ip|$public_port|$guest_ip|$guest_port"
 +done <"$config" 
 + 
 +cleanup 
 +for tool in iptables ip6tables; do 
 +  "$tool" -w -t nat -N "$nat_chain" 
 +  "$tool" -w -t filter -N "$filter_chain" 
 +done 
 +for entry in "${entries[@]}"; do 
 +  IFS='|' read -r family protocol public_ip public_port guest_ip guest_port \ 
 +    <<<"$entry" 
 +  tool=iptables 
 +  destination="$guest_ip:$guest_port" 
 +  if [[ $family == ipv6 ]]; then 
 +    tool=ip6tables 
 +    destination="[$guest_ip]:$guest_port" 
 +  fi 
 +  "$tool" -w -t nat -A "$nat_chain" -p "$protocol" -d "$public_ip"
 +    --dport "$public_port" -j DNAT --to-destination "$destination" 
 +  "$tool" -w -t filter -A "$filter_chain" -p "$protocol" -d "$guest_ip"
 +    --dport "$guest_port" -j ACCEPT 
 +done 
 +for tool in iptables ip6tables; do 
 +  "$tool" -w -t nat -I PREROUTING 1 -j "$nat_chain" 
 +  "$tool" -w -t filter -I FORWARD 1 -j "$filter_chain" 
 +done 
 +HOOK 
 +chmod 0755 "$hook"
  
-Zkopírujte výchozí konfigurák /etc/conf.d/qemu do /etc/conf.d/qemu.myvirt a upravte dle potřeby:+cat >"$config" <<EOF 
 +# RODINA PROTOKOL VEŘEJNÁ_IP VEŘEJNÝ_PORT IP_DOMÉNY PORT_DOMÉNY 
 +ipv4 tcp $PUBLIC_IPV4 80 $guest_ipv4 80 
 +ipv4 tcp $PUBLIC_IPV4 2222 $guest_ipv4 22 
 +ipv6 tcp $PUBLIC_IPV6 80 $guest_ipv6 80 
 +ipv6 tcp $PUBLIC_IPV6 2222 $guest_ipv6 22 
 +EOF
  
-<code shell> +virsh --connect "$connection" net-define "$xml" 
-cd /etc/conf.d +virsh --connect "$connection" net-autostart "$network" 
-cp qemu qemu.myvirt +systemctl restart libvirtd.service 
-vi qemu.myvirt  # read comments and edit+if ! virsh --connect "$connection" net-list --name \ 
 +  | grep -Fx "$network" >/dev/null; then 
 +  virsh --connect "$connection" net-start "$network" 
 +fi 
 +"$hook" "$network" started begin - 
 +virsh --connect "$connection" net-dumpxml "$network"
 </code> </code>
  
-Zejména tedy idejte ipravený image:+Další port idáš do ''/etc/libvirt/port-forwards.conf'' ve tvaru 
 +''RODINA PROTOKOL VEŘEJNÁ_IP VEŘEJNÝ_PORT IP_DOMÉNY PORT_DOMÉNY''. Například 
 +HTTPS dostupné na portu 8443 idáš pro oba protokoly takto:
  
-<code shell+<code conf
-disk1_file="/var/lib/qemu/myvirt/disk0.raw" +ipv4 tcp VPS_IPV4 8443 192.168.124.10 443 
-disk1_format="raw"+ipv6 tcp VPS_IPV6 8443 fd5f:6d2e:9c4a:124::10 443
 </code> </code>
  
-A zřejmě také instalační CD které distribuce, které jste si předem stáhli:+Podporované protokoly jsou ''tcp'' a ''udp''. Řádek s neplatnou syntaxí se 
 +odmítne dříve, než se změní aktivní pravidla. Po změně souboru pravidla načti:
  
-<code shell+<code bash
-cdrom0_file="/var/lib/qemu/alpine-virt-3.4.1-x86_64.iso"+/etc/libvirt/hooks/network.d/50-port-forwards   dualstack-nat started begin -
 </code> </code>
  
-Vytvořte symlink pro init skript a spusťte myvirt:+Port 2222 byl zvolen proto, aby SSH domény nekolidovalo s SSH samotné VPS. 
 +Pravidla firewallu VPS dále omez podle toho, kdo má mít ke službám přístup.
  
-<code shell> +==== Privátní IPv4 na VPS a veřejné adresy v doméně ====
-cd /etc/init.d +
-ln -s qemu qemu.myvirt+
  
-rc-service qemu.myvirt start +V tomto zapojení má VPS privátní IPv4 ''/32'' a svou běžnou veřejnou IPv6 
-</code>+''/64''Doména dostane veřejnou IPv4 ''/32'' a adresu ze samostatné IPv6 
 +''/64'', která je směrovaná přes adresu VPS z její první ''/64''. Privátní IPv4 
 +VPS funguje ve vnitřní síti vpsFree.cz a na internet odchází přes NAT na našich 
 +routerech; veřejné adresy domény se v libvirt nepřekládají.
  
-<note important> +Pro IPv4 nejprve požádej podporu o idělení privátní IPv4 ''/32'' k VPS.
-Pokud máte problémy s tím, ži větším provozu na síťové kartě spadne ve virtuálu sít, zkuste použít driver e1000 místo výchozího virtio-net-pci:+
  
-<code shell>net0_device="e1000"</code>+<vpsadmin-nav id="networking.routable-addresses.open"
 +V části **Síť → Routované adresy** pak vyber veřejnou ''/32'' v poli 
 +**Adresa**, privátní adresu VPS v poli **Přes** a cílové rozhraní VPS. Veřejná 
 +adresa se tím nenastaví na žádném rozhraní uvnitř VPS; vpsAdminOS ji k VPS 
 +směruje přes privátní adresu. 
 +</vpsadmin-nav>
  
-stabilitu je možno otestovat iperf-em, na testovanem stroji:+<vpsadmin-nav id="networking.routable-addresses.open"> 
 +Pro IPv6 použij další ''/64''kterou máš v části **Síť → Routované adresy** 
 +k dispozici, a nastav její směrování přes adresu z běžné ''/64'' VPS. Pokud už 
 +máš směrovanou větší síť, například ''/48'', vyber z ní pro doménu 
 +samostatnou ''/64''. První adresu této druhé ''/64'' použijeme jako bránu na 
 +bridge libvirt; například pro ''ROUTED_IPV6_PREFIX::/64'' to bude 
 +''ROUTED_IPV6_PREFIX::1''
 +</vpsadmin-nav>
  
-<code shell>iperf -s</code>+Tok IPv4 paketů používá malou tranzitní síť pouze mezi VPS a doménou:
  
-na hostiteli pak: +<code> 
-<code shell+internet → veřejná /32 → VPS → 192.168.123.1/30 
-iperf -c 172.17.1.X -P 20+                                  ↓ 
 +                            192.168.123.2/30 → veřejná /32 v doméně
 </code> </code>
-</note> 
  
-==== Nastavení iptables ====+V XML libvirt je veřejná IPv4 samostatná trasa přes tranzitní adresu domény. 
 +Směrovaná IPv6 ''/64'' je naproti tomu přímo na bridge:
  
-Pokud nepoužíváte žádný nástroj pro generování iptables pravidel (jako např. [[https://github.com/MaxKellermann/ferm|ferm]]), doporučuji vyjít z [[https://gist.github.com/jirutka/3742890|připravené šablony pravidel]]. Tyto jsou přímo ve formátu iptables, který je možný načíst pomocí iptables-restore.+<code xml> 
 +<network> 
 +  <name>public-routed</name> 
 +  <forward mode='open'/
 +  <bridge name='virbr-public'/> 
 +  <ip address='192.168.123.1' prefix='30'/
 +  <ip family='ipv6' address='ROUTED_IPV6_PREFIX::1' prefix='64'/
 +  <route family='ipv4' address='PUBLIC_IPV4' prefix='32' 
 +         gateway='192.168.123.2'/
 +</network> 
 +</code>
  
-Stáhněte upravenou šablonu pravidel s přidanou maškarádou pro náš bridge do /etc/iptables:+Na VPS musí být povolené směrování obou protokolů:
  
-<code shell+<code bash
-rmdir /etc/iptables +sysctl -w net.ipv4.ip_forward=1 
-wget -O /etc/iptables https://gist.githubusercontent.com/jirutka/3742890/raw/c9f6bdbfcf597578e562c92ea1e256a9ebcf3a2c/rules-both.iptables+sysctl -w net.ipv6.conf.all.forwarding=1
 </code> </code>
  
-Upravte konfigurák /etc/conf.d/iptables (IPv4): +Následující skript vytvoří tuto síť a uloží forwarding do 
- +''/etc/sysctl.d/90-libvirt-routing.conf''. Ulož jej například jako 
-<code shell> +''/root/configure-routed-network.sh'' a spusť jej s routovanou IPv4 a první 
-/etc/conf.d/iptables+adresou routované IPv6 ''/64'':
  
-IPTABLES_SAVE="/etc/iptables" +<code bash> 
-#SAVE_RESTORE_OPTIONS="-c" +PUBLIC_IPV4=PUBLIC_IPV4 \ 
-SAVE_ON_STOP="no" +IPV6_GATEWAY=ROUTED_IPV6_PREFIX::1 \ 
-IPFORWARD="yes"+  /root/configure-routed-network.sh
 </code> </code>
  
-a /etc/conf.d/ip6tables (IPv6):+Stejně jako u NAT se skript spouští při vytvoření sítě nebo změně adres. 
 +Autostart sítě nastavení v ''/etc/sysctl.d'' se postarají o restarty VPS.
  
-<code shell+<code bash
-# /etc/conf.d/ip6tables+#!/usr/bin/env bash 
 +set -euo pipefail
  
-IP6TABLES_SAVE="/etc/iptables+: "${PUBLIC_IPV4:?set PUBLIC_IPV4 to the routed public IPv4 address}" 
-SAVE_RESTORE_OPTIONS="-T filter+"${IPV6_GATEWAY:?set IPV6_GATEWAY to the first address of the routed IPv6 /64}" 
-SAVE_ON_STOP="no+ 
-IPFORWARD="yes"+host_transit_ipv4=${HOST_TRANSIT_IPV4:-192.168.123.1} 
 +guest_transit_ipv4=${GUEST_TRANSIT_IPV4:-192.168.123.2} 
 +connection=qemu:///system 
 +network=public-routed 
 +forwarding_config=/etc/sysctl.d/90-libvirt-routing.conf 
 +xml=$(mktemp) 
 +trap 'rm -f "$xml"' EXIT 
 + 
 +export LC_ALL=
 +network_uuid=$(virsh --connect "$connection" net-uuid "$network" 2>/dev/null || :) 
 +uuid_element= 
 +if [[ -n $network_uuid ]]; then 
 +  uuid_element="  <uuid>$network_uuid</uuid>
 +fi 
 +cat >"$xml" <<EOF 
 +<network> 
 +  <name>$network</name> 
 +$uuid_element 
 +  <forward mode='open'/> 
 +  <bridge name='virbr-public' stp='on' delay='0'/> 
 +  <ip address='$host_transit_ipv4' prefix='30'/> 
 +  <ip family='ipv6' address='$IPV6_GATEWAY' prefix='64'/> 
 +  <route family='ipv4' address='$PUBLIC_IPV4' prefix='32' 
 +         gateway='$guest_transit_ipv4'/> 
 +</network> 
 +EOF 
 + 
 +if virsh --connect "$connection" net-list --name \ 
 +  | grep -Fx "$network" >/dev/null; then 
 +  printf '%s is active. Shut down its attached domains, run ' "$network" >&
 +  printf 'virsh net-destroy %s, then rerun this script.\n' "$network" >&
 +  exit 1 
 +fi 
 + 
 +install -d -m 0755 "$(dirname "$forwarding_config")" 
 +cat >"$forwarding_config" <<'EOF' 
 +net.ipv4.ip_forward = 1 
 +net.ipv6.conf.all.forwarding = 1 
 +EOF 
 +sysctl --quiet --load "$forwarding_config" 
 + 
 +virsh --connect "$connection" net-define "$xml" 
 +virsh --connect "$connection" net-autostart "$network" 
 +virsh --connect "$connection" net-start "$network" 
 +virsh --connect "$connection" net-dumpxml "$network"
 </code> </code>
  
-Spusťte iptables a ip6tables a idejte je do runlevel boot:+Pokud je síť již aktivní, skript ji nezmění. Vypni ipojené domény, zastav 
 +síť příkazem ''virsh net-destroy public-routed'', skript spusť znovu a domény 
 +opět zapni. Skript zachová UUID existující sítě.
  
-<code shell+Doménu připoj k ''public-routed''. V Debianu v doméně pak například ulož 
-rc-service iptables start +následující konfiguraci do ''/etc/network/interfaces.d/public-routed''; 
-rc-service ip6tables start +''ens3'', ''PUBLIC_IPV4'', ''GUEST_IPV6'' a ''IPV6_GATEWAY'' nahraď 
-rc-update add iptables boot +skutečnými hodnotami: 
-rc-update add ip6tables boot+ 
 +<code conf
 +auto ens3 
 +iface ens3 inet static 
 +    address 192.168.123.2/30 
 +    up ip address add PUBLIC_IPV4/32 dev ens3 
 +    up ip route replace default via 192.168.123.1 src PUBLIC_IPV4 
 +    down ip address del PUBLIC_IPV4/32 dev ens3 
 + 
 +iface ens3 inet6 static 
 +    address GUEST_IPV6/64 
 +    gateway IPV6_GATEWAY
 </code> </code>
  
 +''forward mode='open''' nechává filtrování forwardovaného provozu na firewallu
 +VPS. Povol jen provoz, který má být doméně dostupný, a nezapomeň na pravidla
 +pro IPv4 i IPv6. Veřejná IPv4 je nakonfigurovaná pouze v doméně. IPv6 brána a
 +adresy domén jsou z druhé, směrované ''/64''; na vnějším rozhraní VPS zůstává
 +jen adresa z její běžné ''/64''. Ani jeden protokol v tomto zapojení nepoužívá
 +NAT.
 +
 +===== Instalační ISO na NFS =====
 +
 +Instalační ISO je bezpečnější nejprve zkopírovat na lokální dataset. U staršího
 +NFSv3 exportu bez funkčního síťového zamykání může QEMU při čekání na zámek
 +uvíznout nebo skončit chybou jako ''Failed to lock byte 100'' či
 +''Failed to get ... lock''.
 +
 +Pouze pro jednoho klienta a pouze pro instalační ISO připojené pro čtení lze
 +použít ''nolock'':
 +
 +<code bash>
 +#!/usr/bin/env bash
 +set -euo pipefail
 +
 +: "${NFS_SERVER:?set NFS_SERVER to the NAS server address}"
 +: "${NFS_EXPORT:?set NFS_EXPORT to the exported dataset path}"
 +
 +mountpoint=${ISO_MOUNTPOINT:-/mnt/installer-iso}
 +install -d -m 0755 "$mountpoint"
 +mount -t nfs -o ro,vers=3,nolock \
 +  "${NFS_SERVER}:${NFS_EXPORT}" "$mountpoint"
 +
 +findmnt --noheadings --output FSTYPE,OPTIONS --target "$mountpoint"
 +</code>
  
-===== Kontakty =====+''nolock'' vypíná síťové zamykání NLM a ostatní klienti pak nevidí lokální 
 +zámky. Nikdy jej nepoužívej pro zapisovatelný nebo sdílený disk virtuálního 
 +stroje. U NFSv4 je zamykání součástí protokolu a tato volba není řešením. Viz 
 +[[https://man7.org/linux/man-pages/man5/nfs.5.html|nfs(5)]].
  
-<maintainers> 
-jirutka (Alpine Linux) 
-</maintainers> 
navody/vps/kvm.1697799832.txt.gz · Poslední úprava: autor: rene.la