-
Notifications
You must be signed in to change notification settings - Fork 0
1. What's He Building?
For en tid tilbake siden begynte jeg å se litt på postgres-operator - et verktøy for å provisjonere PostgreSQL-clustere på kubernetes. Da blir man fort kjent med konsepter som StatefulSets, Persistent Volumes, og Storage Classes, Services og Endpoints, Nodes, Namespaces og Pods - konsepter som vi ikke ser i det hele tatt når vi graver oss ned i en eller annen kodesnutt som kaster en NullPointerException hver gang det blir sommertid og årstallet er i fibbonaccirekken. Men hva er egentlig Kubernetes (k8s)?
Kort sagt er Kubernetes en greie som kjører koden vår i containere inni en pod som er inni et namespace inni en node inni en vm inni en hypervisor inni en cloud. Det er også gresk(muligens gammelgresk) for kaptein/sjef, som forklarer den maritime estetikken.
Uansett - mens jeg holdt på med postgres-operator ble det ganske raskt klart at jeg ikke helt har oversikten hvordan alle disse virtualiseringsgreiene henger sammen - og jeg spurte meg selv - "hva er det egentlig det her prøver å løse?". Så jeg bestemte meg for å grave meg nesten ned til bunnen - og opp igjen. (1)
Planen er å lage en serie på tre deler om dette:
-
Første del er denne - en tur gjennom qemu-virtualisering, cloud-init, linux-kommandoer, nettverk og tilfeldige krumspring.
-
Andre del blir om libvirt, terraform, og ansible - og nye velmenende (kanskje tilogmed rettede) krumspring, men fremdeles krumspring.
-
Tredje del blir om å replikere omtrent det samme på en skytjeneste, kanskje litt mer planlagt enn de to forrige delene. Det ville ikke overraske meg om det er krumspring her også, men nå er det alvor, så la oss da kalle det digresjoner.
Dette er egentlig ikke en oppskrift, men en øvelse i å sette opp alt fra bunnen av.
Og med alt, så mener jeg kubernetes
, på to noder, med qemu.
Det er ikke så mye av konfigurasjonsdetaljene som blir forklart her - du trenger stort sett ikke studere dette grundig,- men hvis du trenger mer detaljer foreslår jeg bruk av en LLM.
Da vil du bli forklart med teskje enten du vil eller ei. Men husk at en LLM er meget påståelig og kan sende deg ut på en ganske lang og lite fruktbar reise, hvorpå du ender opp omtrent du startet, men litt mer kynisk. Hvis du vil se positivt på det så se på det som karakterbygging. Det kan tenkes jeg vil rante noe om dette på veien.
Jeg håper vi også får til en slags reise gjennom noen abstraksjoner. Tenk Gulliver, men med mer konfigurasjon.
Det er nok egentlig ikke pensum, og jeg er egentlig ikke en lærer. Hvis du helst bare vil surre litt rundt med kubernetes og kontainere, så finnes det mye enklere alternativer. Bruk minikube, kind, podman eller docker . Hvis du liker mentale bilder så se for deg at jeg bare har hakket frem en bitteliten sti gjennom denne jungelen.
Etter denne oppskriften skal vi ha noe slikt som dette kjørende:
Innerst i virtualiseringsteknologier finner du en hypervisor. I likhet med diabetes så kommer den i to typer - type 1 og type 2 (2). Type 1 er et OS laget for virtualisering, Type 2 kjører på et vanlig OS. Jeg har her fokusert på QEMU - sånn omtrent en type 2-hypervisor. (Jeg sier sånn omtrent, fordi vi bruker kvm-støtte som er innebygd i linux-kjernen)
I motsetning til docker/containerd og lxc så emulerer hypervisorer(3)(4) hardware - det vil si at qemu kjører som en egen prosess, med egen prosesshåndtering inni den virtuelle maskinen, mens kontainersystemene kjører det du deployer i kontaineren som isolerte prosesser (og ressurser) på host-maskinen.
Ingen bryr seg egentlig om forskjellen - vi har abstrahert det bort, ikke sant?
Se her hvis du vil gå dypt ned i cgroups/containerd-kaninhullet.
Akkurat i dag kjører jeg dette på en Ryzen 1800x (8 core) med 40GB Ram og noen disker. Det bør være tilstrekkelig til å kjøre en halv dusin virtuelle maskiner.
Før du begynner bør du slå på VT-x eller AM-V i BIOS/UEFI på maskinen. Kommandoen kvm-ok
kan fortelle deg om maskinen din kan kjøre med hardware-akselerasjon (evt sudo dmesg |grep -e kvm -e AMD-Vi
for AMD - hvis det står ting med "enabled" der så er det bra.)
Oppskriftene der ute insisterer også på at du må slå av swap på hosten med
(sudo swapoff -a
), men utviklere følger ikke oppskrifter, så jeg ignorerte denne.
Jeg begynte med å installere en standard ubuntu-server 24.04. Uten docker.
Det klarer du selv uten veiledning. Bare pass på så du ikke sletter og installerer på feil disk når du holder på. Det har aldri skjedd før, og du har ikke lyst til å bli den første.
Nettverksoppsettet ditt finner du med for eksempel netplan status
$ netplan status
Online state: online
DNS Addresses: 127.0.0.53 (stub)
DNS Search: localdomain
● 1: lo ethernet UNKNOWN/UP (unmanaged)
MAC Address: 00:00:00:00:00:00
Addresses: 127.0.0.1/8
::1/128
● 2: eno1 ethernet UP (networkd: eno1)
MAC Address: de:ad:fe:ed:be:ef (Intel Corporation)
Addresses: 10.0.0.34/24 (dynamic, dhcp)
fe80::329c:23ff:fe07:1f14/64 (link)
DNS Addresses: 10.0.0.1
DNS Search: localdomain
Routes: default via 10.0.0.1 from 10.0.0.34 metric 100 (dhcp)
10.0.0.0/24 from 10.0.0.34 metric 100 (link)
10.0.0.1 from 10.0.0.34 metric 100 (dhcp, link)
fe80::/64 metric 256
Hvis nettverksoppsettet ser omtrent slik ut, så har du et bra utgangspunkt.
Nettkortet ditt (her eno1
) og subnettet hosten din er på (10.0.0.0/24
) er det viktige her.
qemu er et sett av emulatorer for ulike maskiner, og vi bruker qemu-system-x86_64.
Den startes enkelt med qemu-system-x86_64 <ti tusen parametere> disk.img
.
Oppgaven nå er å installere Kubernetes på et par VM'er - det vil si at vi setter opp et k8s kontroll-plan, og en worker.
Vi trenger å installere linux-servere på VM'ene også. Jeg har brukt ubuntu, og Ubuntus litt mer rufsete hippie-grandonkel debian, i en evighet, så akkurat denne delen burde gå knirkefritt.
Ubuntu har støtte for cloud-init.
Dette brukes til å autokonfigurere ubuntu-servere (som så kan provisjoneres , som det heter på fint, selv om det ikke er et ord på norsk), ved å legge til noen filer til installasjonen:
user-data
, meta-data
, og network-config
. user-data
er selve konfigurasjonen, meta-data
må du ha uansett, fordi noen har bestemt det, og network-config
trengs fordi vi vil sette statiske IP-adresser på de virtuelle maskinene.
Målet (som vi ikke kommer til å nå her) er å få til et reproduserbart miljø, og at så mye som mulig er deklarativt.
sudo apt install cloud-image-utils whois
Lag disse filene - og plassér dem i ~/qemu/control
meta-data:
instance-id: kubernetes/control1
network-config:
version: 2
ethernets:
enp0s2:
addresses: [10.0.2.100/24]
routes:
- to: default
via: 10.0.2.1
nameservers:
addresses: [10.0.0.1, 8.8.8.8]
user-data:
#cloud-config
hostname: control
fqdn: control.example.com
users:
- default
- name: kubeadmin
groups: sudo, users, admin
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGS+WwHkJNzWzeshuEqF7RASdlV0EMAhXst0DW7ox6mw
lock_passwd: false
passwd: $6$GFa3eTmgdiNxXrar$LjPHerStaarDetMyeFintMenDetErIkkeEtPassordKubeEeBW4sT5DdGjTkkzmHfTQT7EBjE0
ssh_pwauth: true
disable_root: false
package_update: false
package_upgrade: false
package_reboot_if_required: true
runcmd:
- echo '10.0.2.100 {{fqdn}} {{hostname}}' > /etc/cloud/templates/hosts.debian.tmpl
- echo '127.0.0.1 localhost' >> /etc/cloud/templates/hosts.debian.tmpl
- snap install k8s --channel=1.32-classic/stable --classic
- k8s bootstrap --timeout 10m
- sudo k8s status --wait-ready
- snap install kubectx --classic
- mkdir -p /home/kubeadmin/.kube
- chown -R kubeadmin:kubeadmin /home/kubeadmin/.kube
- curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/v0.18.4/cilium-linux-amd64.tar.gz
- tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
- rm cilium-linux-amd64.tar.gz
- cilium install --version 1.17.3 --datapath-mode=tunnel --ipam cluster-pool --cluster-pool-ipv4-cidr 10.0.2.0/24
- su - kubeadmin -c 'echo alias k=\"sudo k8s kubectl\" > ~/.bash_aliases'
final_message: "Kubernetes control plane setup complete. Use 'kubectl get nodes' to verify."
Du trenger forøvrig bare passordinnlogging hvis du skal logge inn på konsollet - men mens du tester cloud-init-delen så er det en grunnleggende god idé å ha den muligheten.
Kommentaren øverst i userdata
#cloud-config
må være der! (Der slapp du 2 timer med feilsøking.)
Her ser du altså user-data-filen - som inneholder kommandoer og konfigurasjon som skal kjøres og settes opp ved første oppstart. Mye av dette ser merkelig ut, men det er et resultat av møysommelig prøving, feiling, og hallusinering av perplexity.io/claude. Uansett virker den (med cilium som CNI), så vi fjerner bare cilium install
-linjen, som er direkte feil , men beholder cilium-cli.
Cloud-init holder selv orden på om den allerede har blitt kjørt, du kan gjenta prosessen med cloud-init clean
og restarte maskinen.
Det er mulig å logge seg inn på vm'ene før cloud-init er ferdig, du kan da se om den er ferdig med cloud-init status
.
Alle versjonsnummer over kan og vil endre seg over tid. Sannsynligheten for at hele denne oppskriften da feiler konvergerer mot 1 over tid.
Du kan sette passordet (altså <kryptert passord>
i fila med mkpasswd
):
mkpasswd -m SHA-512 fisk
$6$c8OlIGZsaW5rISBEdSBzw6UgYXQgZGV0IHZhciBiYXNlNjQh
Så blir passordet fisk
. (Lag ditt eget - jeg modifiserte sha'en, så fisk vil ikke virke)
Du kan/må også kopiere din pubkey fra ~/.ssh/id_ed25519.pub
.(Ikke bruk den jeg har lagt inn!)
(kjør ssh-keygen -t ed25519
for å lage den)
I dette eksempelet installeres ubuntu altså på virtuelle servere, så vi lager et image som inneholder disse filene og så legges dette imaget på som en egen disk under oppstarten av VM'en.
Det finnes andre måter å tilgjengeliggjøre disse filene for ubuntuinstallasjonen - f.eks via en http-server. Lykke til - det er i teorien kjempelett (...) -
men siden det tar en brøkdel av et sekund å lage imaget med cloud-localds
, og flerfoldige timer på å ikke få den http-serveren til å virke - så gjøres det i oppstartskriptet hver gang imaget fyres opp:
(i ~/qemu)
cloud-localds --network-config=control/network-config control/seed-control.img control/user-data control/meta-data
Denne lager seed-control.img som brukes ved oppstart av ...
sudo apt install qemu-system-x86
For at de ulike qemu-vm'ene skal kunne kommunisere med resten av verden og hverandre setter vi opp et eget subnett.
Dessuten trenger vi på host-maskinen et tap-interface (et fake nettverkskort) for hver vm. Og en bridge, og iptables-oppsett:
Her må du finne din variant av eno1
og subnettoppsett. (Og nameservers, hvis du har din egen)
/etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
eno1:
addresses:
- 10.0.0.34/24
routes:
- to: default
via: 10.0.0.1
nameservers:
addresses: [1.1.1.1,8.8.8.8]
bridges:
br0:
addresses:
- 10.0.2.1/24
(Du kan fjerne /etc/netplan/50-cloud-init.yml, og sette sudo chmod 600 /etc/netplan/01-netcfg.yaml
, hvis du vil)
Du trenger tap-interfaces: /etc/systemd/system/tap-interfaces.service
[Unit]
Description=Create persistent TAP interfaces
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/ip tuntap add dev tap0 mode tap user <bruker>
ExecStart=/usr/bin/ip tuntap add dev tap1 mode tap user <bruker>
ExecStart=/usr/bin/ip tuntap add dev tap2 mode tap user <bruker>
ExecStart=/usr/bin/ip link set tap0 up
ExecStart=/usr/bin/ip link set tap1 up
ExecStart=/usr/bin/ip link set tap2 up
# Add to bridge (retry until br0 exists)
ExecStart=/bin/sh -c 'until /usr/bin/ip link set tap0 master br0; do sleep 1; done'
ExecStart=/bin/sh -c 'until /usr/bin/ip link set tap1 master br0; do sleep 1; done'
ExecStart=/bin/sh -c 'until /usr/bin/ip link set tap2 master br0; do sleep 1; done'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Bytt ut bruker med ditt favorittbrukernavn. (Jeg liker forøvrig ikke de ExecStart-kommandoene med until
- hvis br0
av en eller
annen grunn ikke skulle være der ved oppstart så vil vel maskinen henge før du får et konsoll å leke i.)
Kjør (som root, eller skriv sudo
foran kommandoene)
netplan apply && systemctl daemon-reload && systemctl start tap-interfaces.service
brctl show
(fra bridge-utils
) kan vise deg om bridge-oppsettet funker:
Da skal netplan status --all
vise noe sånt som dette:
netplan status --all
Online state: online
DNS Addresses: 127.0.0.53 (stub)
DNS Search: .
● 2: eno1 ethernet UP (networkd: eno1)
MAC Address: ma:cc:ad:dr:es:ee (Intel Corporation)
Addresses: 10.0.0.34/24
fe80::329c:23ff:fe07:1f14/64 (link)
DNS Addresses: 8.8.8.8
Routes: default via 10.0.0.1 (static)
10.0.0.0/24 from 10.0.0.34 (link)
fe80::/64 metric 256
● 3: tap0 tunnel/tun DOWN/UP (unmanaged)
MAC Address: 76:19:6c:f0:d2:b6
Addresses: fe80::7419:6cff:fef0:d2b6/64 (link)
Routes: fe80::/64 metric 256
Bridge: br0
● 4: tap1 tunnel/tun DOWN/UP (unmanaged)
MAC Address: 5e:82:18:ba:e8:0b
Bridge: br0
● 6: br0 bridge DOWN/UP (networkd: br0)
MAC Address: 06:eb:36:e5:67:f9
Addresses: 10.0.2.1/24
fe80::4eb:36ff:fee5:67f9/64 (link)
Routes: 10.0.2.0/24 from 10.0.2.1 (link)
fe80::/64 metric 256
Interfaces: tap0
tap1
Ok, da er vi klar til å fyre opp en virtuell maskin. Dette var jo nesten like enkelt som docker run
!
Lag et oppstartskript (Jeg legger det i ~/qemu/qcontrol.sh
):
#!/bin/bash
cloud-localds --network-config=control/network-config control/seed-control.img control/user-data control/meta-data
# uncomment for a fresh restart
cp noble.img noble-control.img
qemu-system-x86_64 \
-display none \
-nographic \
-netdev tap,id=n1,ifname=tap0,script=no,downscript=no \
-device virtio-net-pci,netdev=n1,mac=52:54:00:12:34:56 \
-cpu host,migratable=off \
-machine type=q35,accel=kvm \
-smp 8,sockets=8 \
-m 12G -hda noble-control.img -serial mon:stdio \
-drive file=control/seed-control.img,format=raw
Hvis du har mindre minne og færre kjerner kan du endre -m og -smp-parameterene tilsvarende. Legg merke til ifname=tap0 og mac-addressen - disse må endres for hver node. I skriptet over blir noble.img kopiert over disken til control hver gang.
Du må være medlem av kvm-gruppen:
sudo usermod -a -G kvm brukernavn
newgrp kvm
(logg ut og inn igjen etterpå, eller bruk newgrp
, som nesten ingen nevner finnes):
Jeg skrev tidligere at qemu startes med et image - over er dette "noble-control.img", som blir kopiert fra "noble.img" (gjenbruk kommer senere) Dette er en QCow2-fil som qemu kan lese som inneholder et serverimage som fyrer opp en installasjon ved oppstart.
Du trenger med andre ord et cloud-image (altså et QCow2-image, men med større markedsføringsbudsjett) for Ubuntu 24.04(Noble) :
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img -O ~/qemu/noble.img
# systemdisken er usaklig liten, så vi øker den til 30G
qemu-img resize ~/qemu/noble.img 30G
Hvis du ikke øker disken så går du tom for disk rett etter at du tror at alt virker. Det er også mulig å bruke noe qcow2-overlay-greier her for å spare diskplass, som jeg kun skal sette meg inn i når jeg skal begynne å konkurrere med Google om å ha det største datasenteret i Telemark.
Hvis du starter qemu nå med kommandoen over, så er det fremdeles ikke noe eksternt nett her. Det vil si, VM'ene kan nå hosten (10.0.0.34) og sitt eget subnett (10.0.2.0/24), men ikke noe mer.
Husker du jeg nevnte iptables
? Her kommer iptables
- men først må du slå på IP-forwarding, som sannsynligvis er slått av på hosten:
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
Lagre dette i fil
(eller noe)
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*filter
:INPUT ACCEPT [28251:2387673]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [15649:2006458]
-A FORWARD -i br0 -o eno1 -j ACCEPT
-A FORWARD -i eno1 -o br0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i br0 -o br0 -j ACCEPT
-A FORWARD -i br0 -o eno1 -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i br0 -o eno1 -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i eno1 -o br0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i br0 -o br0 -j ACCEPT
COMMIT
*nat
:PREROUTING ACCEPT [721:242745]
:INPUT ACCEPT [24:2790]
:OUTPUT ACCEPT [12:908]
:POSTROUTING ACCEPT [167:10396]
-A POSTROUTING -s 10.0.2.0/24 -o eno1 -j MASQUERADE
COMMIT
# Completed on Tue Apr 29 11:41:14 2025
Kjør inn med cat fil | sudo iptables-restore
. Husk å skifte til rett interface (eno1
).
Hvis du allerede har installert docker eller noe andre fancy greier på maskinen du gjør dette på så forsvinner ip-tables-konfigurasjonen som den applikasjonen trenger. Du har blitt advart. Visstnok har
iptables
blitt erstattet av nftables ognft
, men det er bare ti år siden nå - og ser mer verbost ut, så jeg velger å ignorere det for denne gang.
Hvis du vil slippe å gjøre dette hele tiden så kan oppsettet lagres med netfilter-persistent save
,
men foreløpig er det greit å ikke gjøre noe med dette - nettverksoppsettet her er midlertidig uansett.
Dette setter opp forwarding fra tap
-interfacene via br0
(bridge-interfacet) til eno1
(fysisk interface på host),
masquerade av 10.0.2.0/24 (Som betyr at alt inni subnettet later som de er 10.0.0.34),
og iptables-oppsettet forteller linuxkjernen hva som skal til for å holde orden på TCP-koblingene mellom subnettene.
Send din bestevenn-AI iptables-fila over, den kan faktisk forklare det i detalj.
(Kort sagt: Vi har laget den lille doble pilen som det står br0
ved på figuren)
Nå skal altså alt være klart for å fyre opp kontrollplanet (k8s-control):
cd ~/qemu && sh qcontrol.sh
Etter en ... god stund, er installasjonen klar. I mellomtiden kan du jo fortsette under med workernoden (i en ny terminal,selvsagt) og hoppe tilbake hit etterpå.
Da spytter den ut cloud-init: Kubernetes control plane setup complete. Use 'kubectl get nodes' to verify.
bruk
Ctrl-A x
for å avslutte qemu. Og når du har noe som virker så er det sikkert lurt å kommentere bort dencp noble.img
-linja i oppstart-scriptet. Hvis ting feiler, så kan du se på innholdet med qemu-nbd
Da kan du logge inn med kubeadmin
og passordet du lagde.
og teste med
k get nodes
(k er alias til sudo k8s kubectl
, som er litt tungt å skrive tusen ganger om dagen)
NAME STATUS ROLES AGE VERSION
k8s-control-01 Ready control-plane,worker 2m45s v1.32.3`
Hurra, du har allerede et kubernetes-cluster med én node!
(Dette er nesten det samme du får med kommandoen minikube start
, så nå kan du angre på at du ikke brukte det istedet.)
Bruk ssh for å komme inn på vm'en, qemu-konsollet vil sannsynligvis herje med din ellers positive innstilling. Eller enda bedre - ta en titt på mosh. Da kan du sette opp clusteret selv om du venter på buss for tog i en tunnel mellom Drammen og Oslo. Konsollene kan med fordel startes opp i egne tmux-vinduer
Siden vi ikke finner opp en mye mer krøkkete og dårligere versjon av minikube på nytt(8), så trenger vi en dedikert worker-node i tillegg, slik at vi har to k8s-noder kjørende:
#!/bin/bash
cloud-localds --network-config=worker/network-config worker/seed-worker.img worker/user-data worker/meta-data
# uncomment for a fresh restart, or comment if not
cp noble.img noble-worker.img
qemu-system-x86_64 \
-nographic \
-netdev tap,id=n1,ifname=tap1,script=no,downscript=no\
-device virtio-net-pci,netdev=n1,mac=52:54:00:12:34:57 \
-machine accel=kvm:tcg \
-smp 8,sockets=8 -m 8192 -hda noble-worker.img -serial mon:stdio \
-drive file=worker/seed-worker.img,format=raw
version: 2
ethernets:
ens3:
addresses: [10.0.2.200/24]
routes:
- to: default
via: 10.0.2.1
nameservers:
addresses: [10.0.0.1, 8.8.8.8]
(Jeg vet egentlig ikke hvorfor nettverkskortet heter ens3 her og enp0s2 på control, men det får vi sikkert problemer med en eller annen gang)
instance-id: kubernetes/worker1
#cloud-config
hostname: k8s-worker-01
fqdn: k8s-worker-01.example.com
manage_etc_hosts: true
users:
- default
- name: kubeadmin
groups: sudo, users, admin
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- ssh-ed25519 <key>
lock_passwd: false
passwd: sha-512-pwd
ssh_pwauth: True
package_update: false
package_upgrade: false
package_reboot_if_required: true
ssh_pwauth: true
disable_root: false
write_files:
- path: /home/kubeadmin/custom-containerd-config.yaml
content: |
containerd-base-dir: /var/snap/k8s/common/containerd
permissions: '0644'
runcmd:
- snap install k8s --channel=1.32-classic/stable --classic
- snap start k8s.containerd
- snap start k8s.kubelet
- snap start k8s.kube-proxy
- snap start k8s.k8s-apiserver-proxy
# Enable services to start on boot
- snap start --enable k8s.containerd
- snap start --enable k8s.kubelet
- snap start --enable k8s.kube-proxy
- snap start --enable k8s.k8s-apiserver-proxy
final_message: "Kubernetes worker node setup complete."
Det er faktisk mulig at de start/enable-kommandoene ikke er nødvendige5. Claude ville ha dem der. Finn ut selv da vel! user-data er ganske sensitiv på hva du skriver. Hvis noe er feil får du en feilmelding som ser omtrent slik ut:
schema.py[WARNING]: cloud-config failed schema validation! You may run 'su
(Som vanlig trunkeres den viktige biten - men den sier "sudo cloud-init schema --system" to check the details.
Det er også forholdsvis ubrukelig, for du får ikke logget inn uten at user-data virker og legger inn brukere, men du kan sjekke fila lokalt
med cloud-init schema -c worker/user-data
. Det kunne spart meg for mange timer hvis jeg hadde visst dette for noen dager siden!
start ./qworker.sh (i egen ny terminal) Mens du har tastet inn (eller copypastet) dette, så er kontroll-planet ditt kanskje operativt.
sudo k8s kubectl get nodes # se om ting er oppe og går
sudo k8s get-join-token k8s-worker-01 --worker
Kopier tokenet du får. (Du kan sjekke det ut på https://jwt.io - ip-adressen til k8s-control skal ligge inni der et eller annet sted)
sudo k8s join-cluster <token> --file custom-containerd-config.yaml
Husk å få med hele greia - terminaler/tmux og konsoller kan trunkere vekk biter av tokenet.
ssh kubeadmin@10.0.2.100 sudo k8s get-join-token k8s-worker-01 --worker > token
scp kubeadmin@10.0.2.100:token kubeadmin@10.0.2.200:/tmp/token`
ssh kubeadmin@10.0.2.200 sudo k8s join-cluster $(cat /tmp/token) --file custom-containerd-config.yaml
Hurra? Neida.
Siden forrige gang jeg gikk gjennom dette så har det tydeligvis skjedd ting: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2101914 får kube-proxy til å hikke:
Apr 29 13:10:30 k8s-control-01 k8s.kube-proxy[2421]: E0429 13:10:30.309164 2421 proxier.go:1564] "Failed to execute iptables-restore" err=<
Apr 29 13:10:30 k8s-control-01 k8s.kube-proxy[2421]: exit status 2: ip6tables-restore v1.8.6 (legacy): unknown option "--xor-mark"
Flott. Dette skyldes visst en oppdatering(eller regresjon, avhengig av hvem du spør) av linuxkjernen i ubuntu 24.04, og nå begynner jeg å bli litt rastløs. Hva gjør '--xor-mark'?? Vil ikke vite det.
Jeg spør min lokale svanemerkede AI om hjelp til å pinne kjernen til en versjon som virker, siden jeg tilfeldigvis tror at det er det de kaller det i debian-land:
Dette legges til i cloud-init for både worker og control under runcmd
:
# Install the desired kernel version
- apt-get update
- apt-get install -y linux-image-6.8.0-55-generic linux-headers-6.8.0-55-generic
# Set the kernel as default in GRUB (using exact menu entry name)
- |
sed -i 's|^GRUB_DEFAULT=.*|GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.8.0-55-generic"|' /etc/default/grub
update-grub
# Pin the kernel version to block upgrades
- |
echo "Package: linux-image-6.8.0-55-generic linux-headers-6.8.0-55-generic" > /etc/apt/preferences.d/99-kernel-pin
echo "Pin: version 6.8.0-55*" >> /etc/apt/preferences.d/99-kernel-pin
echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/99-kernel-pin
Siden vi henter ned oppdaterte versjoner (current
) av noble-imaget, så kan dette løse seg når som helst. Eller bli verre.
Det ser for meg ut som en helt fjollete måte å provisjonere maskiner på, laget av en AI som har lest altfor mye regex i sine formative år
(altså under treningen av modellen), men dette problemet overlater vi til de som arver denne riggen. Jeg lurer litt på om ikke write_files
kunne blitt brukt her også, men jeg gidder ikke sjekke det. Dessuten mistenker jeg at modellen ikke vet at apt-mark hold
(for å pinne pakker til en bestemt versjon) er en greie.
Prøv igjen - du må reboote en gang etter cloud-init - kjør join-greiene og (trompetfanfare): (med sudo k8s kubectl get nodes
på k8s-control)
Achievement unlocked $k get nodes NAME STATUS ROLES AGE VERSION k8s-control-01 Ready control-plane,worker 13m v1.32.3 k8s-worker-01 Ready worker 5m41s v1.32.3
Merk at dette sannsynligvis vil endre seg med en ny versjon av kubernetes og/eller linux-kjernen, sånn at alt over slutter å virke igjen, eller blir unødvendig.
- k8s-worker-01 har /home/kubeadmin,men den er eid av root.
- k8s-control-01 kan med fordel få en .kube/config. (Manuelt
sudo cp /etc/kubernetes/admin.conf .kube/config && sudo chown kubeadmin .kube/config
) - så funkercilium status
- Egentlig bør CNI'en visstnok kjøres etter at alle nodene er oppe, men det ser nå ut til å fungere uansett.
(Sjekk ting med cilium connectivity test|perf
)
Etter mitt syn er det en del problemer med denne riggen:
- Det er for mye manuell konfigurasjon (netplan, tap-interfaces, systemctl-greier osv.) her. Det blir litt for mye strikk og binders (7). Det beste er å ignorere alt dette og la en voksen håndtere det - vi må rett og slett abstrahere bort alt tjafset.
- Ingenting av dette er repeterbart. Alt bør kunne repeteres.
- En del av hackene over er merkelige. Cilium manuell installasjon? Starte/enable alle k8s komponentene på workeren? containerd-greier? Vet ikke helt hvorfor det måtte til her, men jeg har en mistanke. (Se under)
- cloud-init-opplegget her gjør altfor mye. Det blir mer oversiktlig hvis vi splitter opp konfigurasjonen i fornuftige biter, men det er iallfall omtrent det eneste som kan gjenbrukes av dette.
- Språkmodeller / Claude er nyttige til noen ting - "formatter denne cloudinit-fila" , "hva er feil med nettverksoppsettet her:" osv. Men
vibe devopsing
er bortimot umulig. Det absolutt største problemet i denne øvelsen var å få Claude til å forstå og huske at jeg installerer Canonical-versjonen av kubernetes. I standardinstallasjonen må man eksplisitt spesifisere containerd-socketen og installere en CNI, noe Claude blander inn i løsningsforslagene.
Hva kan dette brukes til?
Nesten ingenting. Dette er en introduksjon til noen underliggende teknologier. En øvelse, ikke sant? Skal du ha noe seriøst brukbart (uten k8s), så kan du se på Robin sin post. Hadde dette vært en forskingsartikkel så hadde det stått her: "Further research is needed" (FRIN).
Derimot - hvis du har lest gjennom dette dokumentet helt hit så har du kanskje en idé om hva neste abstraksjonlag prøver å løse. Dette laget heter libvirt, og med libvirt kan vi lage et oppsett som faktisk kan være brukbart for noe.
I neste del går vi altså igjennom libvirt
, og introduserer terraform
, slik at vi kan skjule den underliggende
kompleksiteten med ny og bedre kompleksitet, samt ansible
, så vi kan automatisere installasjonen av terraform
, og andre ting for å forenkle installasjonen av ansible
(Sånn går no dagan).
Kanskje vi til og med får stappet noe inn i k8s-clusteret vi setter opp? Jeg mistenker nå at postgres-operator vil bli fraværende en stund til.
Imidlertid håper jeg dette har vært et lite et krasjkurs i hands-on linux-konfigurasjon, cloud-init, qemu og nettverksoppsett.
Kartet er ikke terrenget
Litt av kartet finner du her:
-
kommando --parameter $(en annen kommando som produserer tekst)
er mer nyttig enn man skulle trodd. - Jeg installerer alltid
zsh
+z
oh-my-zsh
,mosh
,tmux
og z-jump-around på maskiner. (Og emacs, men det er for spesielt interesserte) - Selv om jeg liker
emacs
, så kan man bli kanske effektiv påvim
med noen få års trening. - Ta en titt på kommandoene sysctl, systemctl, ss, ip, netplan, lvm-verktøyene (de heter alle noe med lv*), lsblk, blkid, iptables, nft. De er alle nyttige, og godt dokumentert. En liten tur innom journalctl for feilsøking er også nyttig.
- htop, btop, atop , glance kan gi deg en mer fancy versjon av
top
. Eller kjør hollywood hvis du vil ha noe pent å se på isteden. - Med litt bruk av
tcpdump
+wireshark
(elleriptraf-ng
) i tillegg så kan du virkelig få Mr.Robot-følelsen (Nyttig for å sjekke om det kommer trafikk på f.eksbr0
).
Kanskje vi tilogmed får sett noe på postgres-operator etterhvert...↩
- og også type 1.5 (Som tilsvarer KVM + QEMU, såvidt jeg har forstått). Legg merke til at konseptene ble introdusert i 1973. ↩
Jeg tar med den manuelle cilium-installasjonen (Cilium er nettverkssystemet(CNI) som brukes her i kubernetes) (inklusive ugyldige parametere), fordi en LLM mente dette var absolutt nødvendig da jeg kjørte det første gang. Andre gangen var det fullstendig unødvendig. Problemet er nok at den vanlige installasjonsveiledningen til kubernetes må man installere CNI'en manuelt, mens i Canonical-versjonen kommer den ferdig i snap-pakken. ↩
Det finnes ikke noe norsk ord, men "vaktmesterkone" kan kanskje passe? ↩
Jeg er faktisk ikke sikker lenger på om den custom-containerd-config.yaml-fila er nødvendig heller, i neste del av dette så fungerte det uten, så jeg anbefaler å teste det ut selv. ↩
Jeg angrer nå veldig på at jeg begynte med fotnoter, siden gh markdown som vi bruker på nettsiden vår ikke støtter dem, og alt må fikses manuelt, og det har blitt rot i nummereringen alt ↩
Jeg tilbrakte en del av 90- og 00-tallet med en stor eske med strikk og binders i bråkete maskinrom. Da provisjonerte vi maskiner med et heksebrygg laget av ssh
, perl
og bash
. Og biler sa ikke bing og bong, men brum. Det var tider det! ↩
Vi gjør jo egentlig det da: https://minikube.sigs.k8s.io/docs/tutorials/multi_node/ ↩