Wie man Kubernetes auf HyperV ausführt
Disclaimer
Dieses Dokument wird mit einem Repository auf GitHub geliefert, wo Sie die neuesten und besten Konfigurationen finden können. Alle hier erwähnten Teile können sich ändern, daher sollten Sie immer nach der neuesten Version auf Git suchen. Auch wenn diese Übung auf meinem Rechner funktioniert, müssen Sie möglicherweise selbst auf Fehlersuche gehen und herausfinden, wie es bei Ihnen funktioniert. Ich hoffe, dieser Inhalt gibt Ihnen einen guten Überblick über die Einrichtung eines Kube-Clusters auf HyperV von WSL aus mit Hashicorp-Tools.
Der Beitrag wurde von unserem Lead Cloud DevOps Architect Peter Marczis verfasst (Mai 2024)
Einführung
Die heutigen Desktop-PCs sind kleine Kraftpakete und die Preise für Arbeitsspeicher und SSDs sind niedrig. Ich selbst besitze einen Desktop-PC mit praktisch unbegrenzten Ressourcen, verglichen mit dem, an dem ich vor 10 Jahren gearbeitet habe. Ich möchte diese Hardware so effizient wie möglich für mich machen und was könnte eine bessere Aufgabe sein, als einen vollwertigen Kubernetes-Cluster lokal zu betreiben.
Ich bin ein Hardcore-Linuxer, schon seit 20 Jahren, aber ich muss zugeben, dass ich heutzutage meine Stunden vor Windows 11 verbringe. Der Grund dafür ist einfach, dass ich einige Dinge mache, die unter Linux schmerzhaft sind. Mit WSL2 und Visual Studio Code haben wir alle unsere Entwicklungsumgebung, also beschloss ich, es mit HyperV zu versuchen.
Warum gerade WSL? Ich hätte versuchen können, all diese Tools zu installieren und den WSL-Teil loszuwerden, aber dann hätte ich meine gebrüllte Shell wirklich vermisst, und ich wollte sehen, wo Microsoft mit den WSL-Integrationen steht. Spoiler-Alarm, ich bin positiv überrascht, dass sie in die richtige Richtung gegangen sind, auch das ist immer noch ziemlich ruckelig - aber brauchbar.
In diesem Artikel werden wir verschiedene Tools verwenden, um unser Ziel zu erreichen:
- Windows HyperV: ist eine von Microsoft bereitgestellte Virtualisierungsplattform.
- Hasicorp Packer: Werkzeug zur Automatisierung der Erstellung von Maschinen-Images
- Vagrant: Orchestrator, der die Erstellung von Entwicklungsumgebungen auf Virtualisierungsplattformen verwaltet
- Kubernetes: Container-Orchestrationsplattform auf hohem Niveau
Basics
Das Ziel dieser Übung ist es, einen Kube-Cluster zu betreiben, der so produktionsreif wie möglich ist, aber natürlich wird dieses Setup nie in Produktion gehen. So habe ich mit HyperV und Packer von der WSL begonnen. Wenn Sie diese Begriffe noch nie gehört haben, sollten Sie wahrscheinlich aufhören und ein paar Stunden googeln, aber lassen Sie mich versuchen, zusammenzufassen, was hier passiert.
HyperV ist ein Hypervisor, der virtuelle Maschinen betreibt und seit vielen Jahren in der Windows Pro Edition enthalten ist. Es ist nicht perfekt für das, was wir tun wollen, aber es ist, was es ist, und ich bin entschlossen, die bereitgestellten Tools zu verwenden. Ich hatte keine Lust, VirtualBox oder etwas Ähnliches zu installieren. Vergessen Sie nicht, dass Sie HyperV aktivieren müssen, und wenn Sie die Virtualisierungsfunktionen Ihrer CPU im BIOS nicht aktiviert haben, ist es an der Zeit, einen Neustart durchzuführen und dies zu tun.
Packer ist ein Open-Source-Produkt von Hashicorp, mit dem man Basis-Images aus verschiedenen Quellen erstellen kann. In meinem Fall werde ich Ubuntu 22.04.4 LTS alias Jammy verwenden. Die Funktionsweise ist, dass es ein heruntergeladenes ISO-Image nimmt, eine HyperV-Maschine hochfährt, den GRUB-Prompt entführt, Autoinstall einrichtet und die Installation einleitet.
Was ist Autoinstall? Im Laufe der Jahre haben verschiedene Linux-Distributionen unterschiedliche Lösungen entwickelt, um den Installationsprozess des Betriebssystems zu automatisieren. Wir hatten Kickstart, wir hatten Preseeding und so weiter. Ubuntu hat jetzt Autoinstall, und ich wollte das Neue und Glänzende ausprobieren, also habe ich mich für Autoinstall entschieden. Die Konfiguration ist recht einfach, und ich bin im Moment zufrieden damit. Die anfängliche Autoinstall-Konfiguration erhält man, indem man das System manuell installiert. Danach können Sie die Autoinstallationskonfiguration einfach von Ihrem manuell erstellten System abrufen. Dieser Ansatz ist sehr benutzerfreundlich und ermöglicht es Ihnen, die Konfiguration manuell einzustellen, ohne mit YAML- oder JSON-Dateien zu spielen.
#cloud-config
autoinstall:
apt:
disable_components: []
fallback: abort
geoip: true
mirror-selection:
primary:
- country-mirror
- arches: &id001
- amd64
- i386
uri: http://archive.ubuntu.com/ubuntu/
- arches: &id002
- s390x
- arm64
- armhf
- powerpc
- ppc64el
- riscv64
uri: http://ports.ubuntu.com/ubuntu-ports
preserve_sources_list: false
security:
- arches: *id001
uri: http://security.ubuntu.com/ubuntu/
- arches: *id002
uri: http://ports.ubuntu.com/ubuntu-ports
codecs:
install: false
drivers:
install: false
identity:
hostname: ubuntu
password: $y$j9T$sC3tQImc3zsBCjerZViXT0$mrC/i0T5DrPLdAFTE38ART8gAnhUD8OAAwX.9X3.w5.
realname: vagrant
username: vagrant
kernel:
package: linux-generic
keyboard:
layout: us
toggle: null
variant: ''
locale: en_US.UTF-8
network:
ethernets:
eth0:
dhcp4: true
version: 2
oem:
install: auto
source:
id: ubuntu-server-minimal
search_drivers: false
ssh:
allow-pw: false
authorized-keys: [
"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key",
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN1YdxBpNlzxDqfJyw/QKow1F+wvG9hXGoqiysfJOn5Y vagrant insecure public key"
]
install-server: true
storage:
layout:
name: lvm
updates: security
packages:
- linux-azure
- vim
- salt-minion
version: 1
late-commands: [
"echo 'vagrant ALL=(ALL) NOPASSWD:ALL' >> /target/etc/sudoers.d/90-vagrant",
"echo 'UseDNS no' >> /etc/ssh/sshd_config"
]
Vagrant
Nun noch ein paar Dinge zu dieser Konfiguration. Da wir Vagrant verwenden werden (was ich noch nicht erwähnt habe), müssen Sie Ihr Image ein wenig modifizieren. Vagrant ist ein weiteres Hashicorp-Tool, um mehrere VMs lokal zu starten. Sie können es sich als Terraform für Ihre lokalen Entwicklungs-VMs vorstellen. Ja, wir haben VMs benutzt, bevor jeder ein Container-Junkie wurde, und ja, wir benutzen VMs immer noch für dieses Projekt, weil wir einen Kube-Cluster aufbauen wollen.
Die notwendige Konfiguration für Vagrant umfasst also:
- Vagrant-Benutzer, mit dem Passwort vagrant
- Da ein Benutzername und ein Passwort ziemlich unsicher sind, obwohl die ganze Sache doch ziemlich unsicher sein wird, habe ich mich für einen öffentlichen/privaten Schlüssel für SSH entschieden. Das hat natürlich einen Haken, denn wir brauchen einen bekannten privaten Schlüssel. Glücklicherweise kommt Vagrant mit einem öffentlichen privaten Schlüssel, also einem privaten Schlüssel, den wir alle kennen, aber er wird diesen Schlüssel beim ersten Hochfahren ändern. Bitte nicht ausrasten! Der hier verwendete Schlüssel befindet sich im Repository, und das ist beabsichtigt.
- Ich ziehe es vor, „UseDNS no“ lokal zu verwenden, dann geht die Anmeldung viel schneller.
- Wir müssen dem vagrant-Benutzer sudo-Rechte ohne Passwort gewähren.
- Wie Sie später sehen werden, werden wir Salt Stack später verwenden, um unsere Knoten zu konfigurieren.
- Und überraschenderweise brauchen wir etwas namens linux-azure Paket. Dieses Paket enthält die magischen Kernel-Module, die die IP-Konfiguration unseres Rechners an hyperV melden werden. Diese werden von Packer und Vagrant verwendet, um herauszufinden, wo eine Verbindung hergestellt werden soll.
Nun, da wir die Cloud-Konfiguration für die automatische Installation haben, müssen wir nur noch Packer mitteilen, was zu tun ist. Unten finden Sie unsere Packer-Vorlage:
packer {
required_plugins {
hyperv = {
source = "github.com/hashicorp/hyperv"
version = "~> 1"
}
}
}
source "hyperv-iso" "ubuntu" {
# Path to the ISO file
iso_url = "/mnt/c/Users/marcz/Documents/pro/ubuntu-22.04.4-live-server-amd64.iso"
iso_checksum = "sha256:45f873de9f8cb637345d6e66a583762730bbea30277ef7b32c9c3bd6700a32b2"
# Specify the Hyper-V virtual switch name
switch_name = "public_network"
# Hyper-V VM name
vm_name = "PackerBuilder"
# Memory size (in MB)
memory = "4096"
# CPU cores
cpus = "12"
# Size of the virtual hard disk (in GB)
disk_size = "130048"
boot_command = [
"<esc><wait>",
"c<wait>",
"linux /casper/vmlinuz autoinstall 'ds=nocloud;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/'<enter><wait>",
"initrd /casper/initrd<enter><wait>",
"boot<enter>"
]
boot_wait = "5s"
http_directory = "http"
shutdown_command = "echo 'vagrant' | sudo -S shutdown -P now"
ssh_username = "vagrant"
#ssh_password = "vagrant"
ssh_private_key_file = "./ssh-key"
ssh_wait_timeout = "10000s"
}
build {
sources = ["source.hyperv-iso.ubuntu"]
post-processors {
post-processor "shell-local" {
# Add metadata, and pack boxfile, than add it to vagrant
inline = [
"echo '{ \"provider\": \"hyperv\" }' > output-ubuntu/metadata.json",
"cd output-ubuntu",
"tar -cvzf ../ubuntu.box ./*",
"cd -",
"vagrant box add ./ubuntu.box --name ubuntu --force"
]
}
}
}
Lassen Sie uns wie zuvor einige Teile davon besprechen. Wie Sie sehen, müssen Sie das heruntergeladene ISO (oder besser den Hash davon) zusammen mit einigen Parametern für die VM, auf der wir das Image erstellen werden, eingeben.
Ein wichtiger Teil davon ist der boot_command. Mit diesem Boot-Befehl sendet Packer einen ESC-Tastendruck, wartet ein wenig und gibt unsere Zeilen in die GRUB-Befehlszeile ein. Auf diese Weise können wir hier die autoi-nstall-Parameter für den Kernel konfigurieren und den Boot-Prozess starten.
Der
{{ .HTTPIP }}:{{ .HTTPPort }}
Teil wird von Packer dynamisch durch die richtigen Werte ersetzt. Und siehe da, damit sind wir auch schon bei der ersten Misere mit WSL, HyperV und Windows angelangt - der Vernetzung. Standardmäßig macht WSL2 (heute) etwas Seltsames. Sie führt eine VM mit einem NAT-Setup aus, um von der WSL-Ebene aus auf den Rest der Welt zuzugreifen.
Da wir ein fortschrittlicheres Setup benötigen, ist dies für einen Kube-Cluster einfach nicht gut genug. Um unsere Workloads auszuführen, müssen wir WSL so konfigurieren, dass es ein „gespiegeltes“ Netzwerk verwendet. Auf diese Weise werden Ihre Netzwerkkarten für WSL Linux sichtbar, und es erhält (hoffentlich) eine IP-Adresse vom DHCP-Server Ihres lokalen Netzwerks.
Dazu benötigen Sie eine .wslconfig-Datei in Ihrem Home-Verzeichnis mit einem einfachen Inhalt:
[wsl2]
networkingMode = "mirrored"
Sie müssen auch einen neuen Netzwerk-Switch für Packer (und später für Vagrant) in HyperV erstellen, der mit Ihrer Netzwerkkarte verbunden ist.
(Eine Warnung an dieser Stelle: Ich habe das alles auf einem leistungsstarken Desktop-PC mit einer echten Netzwerkkarte gemacht, ich glaube nicht, dass das auf einer WiFi-Karte reibungslos funktioniert).
Ich habe dazu den HyperV-Manager verwendet:
Klicken Sie im „Virtual Switch Manager...“ auf „New virtual network switch“.
Weiter -> Wählen Sie „Extern“, und Sie erhalten ein Bild wie oben abgebildet
Wir haben diesen neuen Switch einfach „public_network“ genannt, wenn Sie einen anderen Namen wählen, müssen Sie den Switch-Namen in der Konfiguration ändern.
Jetzt laufen unsere WSL2 und unser Packer-Rechner alle in unserem echten lokalen Netzwerk, das irgendwo einen DHCP-Server haben muss. Alles in Ordnung, wir bekommen alle IP-Adressen und die neue VM kann sich mit dem winzigen Webdienst von Packer verbinden.
Wenn alles gut gegangen ist, können Sie Packer gleich nach der Installation auf Ihrer WSL in Betrieb nehmen, was ziemlich einfach ist.
Möchten Sie mehr über die Packer Konfiguration erfahren? Dann schauen Sie gerne bei Teil 2 vorbei.