Podman, KVM og containere: en praktisk guide til sikker virtualisering

Sidste ændring: 9 marts 2026
Forfatter: TecnoDigital
  • Containere deler kernen med værten, så deres isolation afhænger af navnerum, cgroups og systemhærdning.
  • Podman giver ekstra sikkerhed sammenlignet med klassisk Docker ved at undgå en central root-daemon og muliggøre rootless execution.
  • Bro-, værts- og rodløse netværk (slirp4netns, paste) i Podman giver dig mulighed for at justere balancen mellem konnektivitet og isolation.
  • Kombinationen af ​​KVM, containere og bedste praksis (rootless, MAC, seccomp, billedscanning) giver en robust platform til produktion.

Podman KVM sikker virtualisering

Når man begynder at opsætte et seriøst containermiljø på Linux, opstår det samme spørgsmål straks: i hvilken grad er det sikkert udelukkende at stole på containere, og hvornår er det tilrådeligt at opgradere til KVM eller mikro-VM'er? I virksomhedsmiljøer, hvor Docker, Podman, LXC, virtuelle KVM-maskiner og forskellige hypervisorer blandes sammen, er en solid forståelse af isolationsmodellen nøglen til at undgå fejl.

Derudover er ret komplekse scenarier ikke ualmindelige, såsom at forsøge at bruge Docker Desktop eller Podman i en virtuel maskine i VirtualBox eller KVM , hvor flere niveauer af virtualisering (indlejret eller ej) kommer i spil, og det er nemt at støde på fejl som "KVM er ikke aktiveret på værten." Lad os organisere alle disse dele - containere, VM'er, Podman, KVM, netværk og sikkerhed - og se, hvordan man kombinerer dem for at opnå virkelig sikker og praktisk virtualisering.

Klassisk virtualisering med KVM og virtuelle maskiner

Fundamentet for hele denne opsætning er fortsat den komplette virtualisering af operativsystemer ved hjælp af hypervisorer som KVM, Xen eller ESXi . Her kører den fysiske hardware en hypervisor, der er ansvarlig for at "opdele" maskinen i flere uafhængige virtuelle maskiner.

I denne model starter hver virtuel maskine sin egen kerne og gæsteoperativsystem , helt adskilt fra værten. Hypervisoren (for eksempel KVM, integreret i Linux-kernen) fungerer som en gatekeeper mellem hardwaren og de virtuelle maskiner og er ansvarlig for den stærke isolation mellem dem.

Vi taler generelt om to typer hypervisorer: Type 1 eller bare metal hypervisorer, der kører direkte på hardwaren, og Type 2 hypervisorer, der hostes oven på et eksisterende operativsystem. VirtualBox eller VMware Workstation ville være Type 2 , mens en KVM, der administreres af libvirt på en Linux-server, er tættere på et Type 1-scenarie, selvom den deler plads med selve værten.

Den største fordel ved denne tilgang er, at hver VM har sin egen komplette stak: kerne, brugerplads, tjenester, netværk og lager . Dette giver stor fleksibilitet og muligheden for at køre forskellige operativsystemer og kerneversioner på den samme fysiske maskine.

For at administrere disse virtualiserede platforme i GNU/Linux bruges libvirt næsten altid som et orkestrerings-API , oven i hvilket grafiske og kommandolinjeværktøjer understøttes, eller større projekter som OpenStack, der bygger komplette clouds ved at kombinere VM'er, bare metal og containere.

Hardwarekrav og almindelige problemer med KVM

Før du kører KVM eller bruger løsninger, der afhænger af det (f.eks. nogle Docker Desktop- eller micro-VM-konfigurationer), skal du sørge for, at processoren understøtter hardwarevirtualisering (VT-x på Intel eller SVM/AMD-V på AMD), og at det er aktiveret i BIOS/UEFI.

I Linux har vi en hurtig kontrol: Hvis kommandoen `grep -E 'svm|vmx' /proc/cpuinfo` ikke returnerer noget, eller hvis indstillingen stadig er deaktiveret i firmwaren, vil KVM ikke fungere. Desuden, i scenarier, hvor vi kører VM'er inde i en anden VM (indlejret virtualisering), skal topniveau-hypervisoren eksplicit eksponere disse udvidelser for gæsten.

Når noget går galt, vises typiske meddelelser, såsom den berygtede Docker Desktop-popup i RHEL 9 i VirtualBox: "KVM er ikke aktiveret på værten ." Problemet her ligger ikke direkte i Docker eller RHEL, men snarere i, at VirtualBox VM'en ikke modtager de nødvendige virtualiseringsudvidelser til at køre KVM i den.

Kommandoer som `modprobe kvm` eller `modprobe kvm_amd / kvm_intel` burde indlæse kernemodulerne uden fejlmeddelelser. Hvis `dmesg` ikke viser noget relevant, eller `lsmod | grep kvm` kun viser en ren `kvm` og `irqbypass`, og de CPU-specifikke moduler mangler, er det meget sandsynligt, at hardwarevirtualisering ikke eksponeres for gæstesystemet eller er deaktiveret i firmwaren.

I disse scenarier, selvom alle mulige funktioner er aktiveret i gæstekonfigurationen, vil KVM simpelthen ikke fungere, hvis VirtualBox ikke tilbyder indlejret virtualisering, eller hvis den er forkert konfigureret . Løsningen involverer at gennemgå værtshypervisorens konfiguration (VirtualBox, VMware osv.) og aktivere indlejret virtualisering, hvis det er muligt.

Containere: Let virtualisering på operativsystemniveau

I modsætning til traditionelle VM'er tilbyder containere en anden tilgang: de emulerer ikke al hardware, men genbruger i stedet værtskernen og isolerer processer og ressourcer ved hjælp af Linux-kernefunktioner.

En container er i bund og grund et sæt processer indkapslet ved hjælp af navnerum og cgroups . Inden for dette "miljø" tror applikationen, at den kører på sin egen maskine med sit eget filsystem, netværksgrænseflader og PID'er, men i virkeligheden deler den kernen med værten.

Containere tilbyder næsten native ydeevne, fordi der ikke er nogen anden kerne involveret og ingen fuld hardwareemulering . Overhead er minimal: lige nok til at montere navnerum, begrænse ressourcer med cgroups og håndhæve sikkerhedspolitikker (seccomp, AppArmor, SELinux osv.).

Dette design har dog en betydelig konsekvens: alle arbejdsbelastninger deler den samme fysiske kerne . En alvorlig sårbarhed i den kerne kan pludselig blive en potentiel undslipsvektor for alle containere, der kører på den node.

Derfor siges det ofte, at containerisolering ikke er "absolut" som en virtuel maskines . Hvis nogen formår at udnytte en kritisk kernefejl, ophører navnerum med at være en effektiv barriere, og grænserne mellem containere og værter kan brydes.

Navnerum og c-grupper: fundamentet for containerisolering

I Linux er containerisolering bygget på to hovedsøjler: navnerum til at adskille systemvisninger og cgroups til at begrænse og tage højde for ressourcer.

  PC-blæserkonfiguration: En komplet guide til kurver og luftstrøm

Navnerum isolerer ting som PID'er, netværk, monteringspunkter, IPC, værtsnavn (UTS) og brugere . På denne måde "ser" en proces kun processerne, netværksgrænsefladerne, filsystemet og værtsnavnet for sit eget navnerum, hvilket giver den følelsen af ​​at være på et andet system.

For deres vedkommende giver cgroups dig mulighed for at angive, hvor meget CPU, hukommelse, disk-I/O, antal processer osv. en container kan forbruge . Dette forhindrer ukontrolleret belastning i at overbelaste hele værten, hvilket er vigtigt, når man deler noder mellem teams eller projekter.

Det er dog afgørende at forstå, at navnerum og cgroups alene ikke er et komplet sikkerhedssystem . De forhindrer ikke udnyttelse af kernesårbarheder, filtrerer ikke systemkald eller administrerer detaljerede adgangspolitikker. De er fundamentet, men de skal styrkes.

Den fornuftige måde at hærde miljøet på er at kombinere syscall-filtre med seccomp, MAC-politikker (AppArmor eller SELinux) og en drastisk reduktion af procesfunktioner, ideelt set sammen med brugernavnerum og rootless mode for at minimere skade, hvis nogen formår at undslippe containeren.

Sikkerhedstrusler på containerplatforme

I en rigtig containerplatform er angrebsfladen spredt over flere lag: kernen og runtime (runc, containerd, CRI-O), image-forsyningskæden, container-/orkestratorkonfigurationen og den underliggende infrastruktur (cloud, storage, IAM, netværk).

Almindelige angrebsvektorer omfatter softwaresårbarheder i kernen eller containerens runtime, brug af usikre eller ikke-vedligeholdte billeder, konfigurationsfejl i Kubernetes eller Docker (privilegerede containere, farlige værtmonteringer, overdrevent åbne netværkstilstande) og sikkerhedsfejl i registre eller CI/CD-pipelines.

I mange hændelser i den virkelige verden er der ikke én enkelt "magisk fejl", men snarere en kombination af kendt sårbarhed plus slap konfiguration : containere, der kører som root, brug af --privileged-flaget, montering af værtsfilsystemet i containeren og fravær af seccomp eller MAC.

Oven i alt dette er problemet med forsyningskæden: Offentlige basebilleder indeholder ofte CVE'er, forældede pakker og dårligt kontrollerede afhængigheder . Det er relativt nemt for malware at slippe igennem eller for et kompromitteret bibliotek at forblive inaktivt, indtil betingelserne er rette for, at det kan køre.

Derfor er det i produktion ikke valgfrit: du skal scanne images for sårbarheder med værktøjer som Trivy, Clair eller Grype , kontrollere hvilke registre der bruges (Harbor, Quay, GHCR med politikker) og signere/verificere images, før du implementerer dem i en klynge.

Docker vs. Podman: Indvirkning på trusselsmodellen

Inden for applikationscontainernes verden dækker Docker og Podman lignende funktioner, men deres arkitektur adskiller sig betydeligt, og det ændrer den sikkerhedsmodel, vi arbejder med på en vært.

Docker er i sin klassiske rootful-tilstand afhængig af en central daemon (dockerd), der kører som root . CLI'en kommunikerer med denne daemon via /var/run/docker.sock eller via TCP, og det er denne privilegerede proces, der opretter og ødelægger containere, administrerer billeder, netværk og volumener og interagerer med registre.

Det betyder, at alle med adgang til Docker-socket'en praktisk talt har root-adgang til værten , fordi de kan starte privilegerede containere, montere vilkårlige filsystemer og ændre kritisk konfiguration. Daemonen bliver effektivt et enkelt fejlpunkt.

Podman blev derimod født med ideen om at være en dæmonfri containermotor, der er så "native" til Linux som muligt . Der er ingen permanent central proces; containere styres af brugeren eller af systemd, og integration med sidstnævnte gør det muligt at styre containere via serviceenheder.

Denne tilgang stemmer bedre overens med Unix-modellen om, at "hver proces tilhører den bruger, der starter den", og undgår at være afhængig af en daemon med høje rettigheder . Derudover tilbyder Podman kompatibilitet med Docker-kommandoer, hvilket forenkler migrering (du kan endda bruge alias `docker=podman` i miljøer, hvor du ikke ønsker at installere Docker CE).

Rodløs tilstand og brugernavnerum

Et af de største praktiske fremskridt i at reducere virkningen af ​​en potentiel container-escape er rootless mode kombineret med brugernavnerum . Spørgsmålet, som dette sigter mod at besvare, er: "Hvad sker der, hvis containeren escaper?"

Brugernavneområder giver dig mulighed for at omkorte containerens UID 0 til et ikke-privilegeret UID på værten . Med andre ord, inde i containeren tror applikationen, at den er root, men fra værtens perspektiv er den proces faktisk en almindelig bruger med et tildelt subuid/subgid-område.

På denne måde, selvom en angriber får root-rettigheder inde i containeren og formår at kæde en kernel- eller runtime-exploit sammen, gør de det som en ikke-privilegeret bruger, når de vender tilbage til værten . De kan ikke overskrive root-binære filer, montere følsomme filsystemer eller manipulere enheder, hvor de mangler de nødvendige rettigheder.

Podman blev designet fra starten med denne model i tankerne: rodløs containerisering som standard når det er muligt , brug af SELinux/AppArmor og cgroups selv uden root, og en stærk vægt på at minimere strukturelle privilegier.

Docker tilbyder nu også en ægte rootless-tilstand , hvor dockerd og containere befinder sig inden for et brugernavneområde, i modsætning til den ældre userns-remap, hvor dæmonen forblev root. Fra et sikkerhedsmæssigt synspunkt forhindrer dette en udnyttelse mod dockerd i at give automatisk root-adgang til værten.

Containernetværk med Podman: bridge-, host-, macvlan- og rootless-grænseflader

Et andet vigtigt element for sikkerhed og praktisk drift er containernetværkslaget . Podman tilbyder forskellige mekanismer til at levere forbindelse, med særlig vægt på rodløse scenarier.

  Native M.2-port vs. PCIe-adapter: hvilken er den rigtige for dig?

Podman 4 introducerede netavark, en netværksdriver, der følger CNI-modellen for at forsyne containere med IP-adresser på bro-netværk, macvlans osv. Med netavark opretter rootful-containere typisk som standard forbindelse til et netværk kaldet "podman", der er tilknyttet en Linux-bro (podman0) på værten med adresseringen 10.88.0.0/16.

Dette standardbro-netværk leverer grundlæggende internetforbindelse via SNAT-regler og giver dig mulighed for at eksponere containerporte til værten ved hjælp af `-po --publish`, som genererer DNAT-regler i iptables/nftables. For Docker-kompatibilitet kører dette netværk ikke en intern DNS-server.

Vi kan også oprette brugerdefinerede bronetværk , som isolerer grupper af containere fra hinanden og leverer intern DNS. Dette gør det muligt for containere at identificere hinanden ved navn inden for deres private netværk, gør det nemmere at adskille tjenester, der ikke burde kunne se hinanden, og giver mere kontrol over MTU, firewalls og andre funktioner.

I mere avancerede miljøer er det muligt at bruge macvlan- eller ipvlan-netværk til at forbinde containere direkte til værtens fysiske netværk. Macvlan tillader containere at kommunikere med hinanden, mens ipvlan har tendens til at isolere dem mere; disse er nyttige muligheder i implementeringer, hvor hver container skal ses som en reel vært af resten af ​​netværket.

Rodløse netværk: slirp4netns og pasta

Når brugeren ikke er root, bliver tingene komplicerede: en bruger uden privilegier kan ikke frit ændre det globale netværksnavneområde eller oprette vilkårlige grænseflader, så Podman er nødt til at ty til brugerrumsløsninger for at skabe forbindelse.

Det er her, slirp4netns kommer ind i billedet , den klassiske mekanisme, der bruges af Podman rootless . Dette projekt opretter et isoleret netværksmiljø i containeren og bruger kernens slirp-modul til at udføre adresseoversættelse (NAT) og give containeren adgang til internettet via værtens netværk.

I praksis opretter slirp4netns en TAP-grænseflade i containerens netværksnavneområde (for eksempel tap0 med IP 10.0.2.100 og gateway 10.0.2.2) og ruter trafik via en TCP/IP-stak implementeret i brugerområdet. Det er funktionelt, men tilføjer noget overhead og visse begrænsninger.

En af disse begrænsninger er, at ikke-privilegerede brugere ikke kan bruge porte under 1024. Sysctl-parameteren net.ipv4.ip_unprivileged_port_start markerer, hvilken port de betragtes som "ikke-privilegerede" fra (som standard 1024), selvom dette kan justeres omhyggeligt, hvis sikkerhedsmodellen tillader det.

I Podman 5 er slirp4netns erstattet af pasta som standard rodløs mekanisme . Pasta fungerer også udelukkende i brugerområdet, men takket være tap-grænsefladen og zero-copy-teknikkerne opnår den næsten native netværksydelse, hvilket reducerer påvirkningen på latenstid og gennemløb sammenlignet med slirp4netns.

Bro og vært netværk i rootless containere

Selv når vi arbejder i ikke-root-tilstand, kan vi forbinde rootless-containere til standard "podman"-bronetværket ved hjælp af `--network=podman`. Dette udnytter netavarks muligheder og knytter porte til værten med `-p`, ligesom i rootful-tilstand.

Det er også muligt at oprette brugerdefinerede bronetværk i rodløse miljøer . I dette tilfælde oprettes broerne og tilhørende enheder ikke i værtens globale netværksnavnerum, men i brugerens navnerum, så disse grænseflader vil ikke være synlige fra værten med en simpel `sudo ip a`-kommando.

For at inspicere disse rodløse broer tilbyder Podman kommandoen `podman unshare --rootless-netns` , som åbner en shell i brugerens netværksnavnerum. Derfra kan de interne broer observeres, og direkte forbindelse til containerne kan verificeres.

Denne isolation har en mærkelig effekt: Der er muligvis ikke direkte forbindelse fra værten til IP'erne for disse rodløse containere.men det virker med porte, der er knyttet til værtens egen IP-adresse, som fungerer som indgangspunkt til tjenesten.
Til kommunikation mellem containere tillader den DNS-server, der er integreret i det brugerdefinerede bronetværk, at de taler ved navn, hvilket i høj grad forenkler konfigurationen af ​​distribuerede applikationer.

I den anden ende er værtsnetværket (--network=host) , hvor containeren deler netværksstakken med værten uden sin egen IP-adresse. I denne tilstand, hvis en rootless container starter en server på port 8080/tcp, vil tjenesten være direkte tilgængelig på værtens port 8080, hvilket sparer portmapping, men reducerer isolation.

Podman Desktop, billeddannelsesværktøjer og lokal orkestrering

For dem, der foretrækker noget mere visuelt, tilbyder Podman Desktop et grafisk miljø til administration af containere, pods, billeder og netværkskonfigurationer på udviklingsmaskiner. Det fungerer som et direkte alternativ til Docker Desktop, men er afhængig af den dæmonløse motor.

Billeder hentes ved hjælp af `podman pull`, som downloader fra de registre, der er defineret i `/etc/containers/registries.conf` . Hvis billedet er angivet uden et registreringsnavn, forsøger Podman at finde det i den konfigurerede registreringsrækkefølge ved at bruge `latest`-tagget som standard.

Ud over Podman CLI kan vi bruge skopeo som et dedikeret værktøj til at administrere, inspicere og kopiere billeder mellem registre og lokale arkiver. Kommandoer som kopiér, slet og synkroniser giver os mulighed for at automatisere synkronisering mellem arkiver, markere billeder til garbage collection og flytte artefakter mellem miljøer.

Når imaget er downloadet, giver `podman run` dig mulighed for at starte containere ved at angive transport og sti (som standard Docker-transport og søgning i den konfigurerede registreringsdatabase). De sædvanlige indstillinger (-d, -p, --name, --pod osv.) dækker både laboratoriescenarier og mere seriøse implementeringer.

Daglig administration udføres med `podman ps` til at liste containere, `podman stop/start` til at stoppe eller starte eksisterende instanser og `podman rm` til at fjerne stoppede containere . Hvis en container er blevet ændret, og vi ønsker at konvertere den til et nyt image, gemmer `podman commit` disse ændringer under et nyt navn.

  Crontab Linux: Introduktion til opgaveplanlægning

Pods og avancerede udførelsesmodeller med Podman

Inspireret af Kubernetes giver Podman dig mulighed for at gruppere containere i pods, der deler den samme netværksstak og bestemte ressourcer . Det er et perfekt mønster til ting som en database og dens klient, eller flere mikrotjenester, der skal kommunikere med lav latenstid.

Kommandoen `podman pod create` opretter en ny pod og returnerer dens ID, men som standard forbliver pod'en stoppet, indtil en tilknyttet container startes, eller den eksplicit startes med `podman pod start`.

For at se hvilke pods der er på systemet, skal du bruge `podman pod ls` , som også viser den INFRA-container, der er tilknyttet hver enkelt. Denne særlige container holder netværket og andre delte ressourcer i pod'en kørende, så antallet af containere aldrig er nul.

Podman tilbyder specifikke kommandoer til at starte, stoppe eller genstarte hele pods (podman pod start/stop/restart) , men vi kan også kun reagere på en specifik container i pod'en uden at ændre resten, hvilket opretholder procesisolation på applikationsniveau.

For at tilføje flere containere til en eksisterende pod skal du bruge `podman run --pod POD_NAME` , der følger samme syntaks som for individuelle containere. Du kan ikke fjerne en container fra en pod uden at ødelægge den, da pod-medlemskab er knyttet til dens livscyklus.

Overvågning udføres med podman ps –pod eller specifikke kommandoer til at overvåge processerne i alle containere i alle pods , hvilket hurtigt identificerer, hvad der tilhører hvilken gruppe, og hvordan tjenesterne er distribueret.

Containere, LXC og applikationsvirtualisering

Selvom Docker og Podman dominerer samtalen, er de ikke de eneste containeriseringsmuligheder i GNU/Linux . Løsninger som LXC/LXD, systemd-nspawn og Kata Containers adresserer problemet fra lidt forskellige vinkler.

LXC leverer meget lette systemcontainere med deres eget værtsnavn, IP-adresse, filsystem og komplette init-system . Kombineret med LXD, der fungerer som en hypervisor for containere og VM'er, leverer det en oplevelse, der minder meget om at have flere lette maskiner med næsten bare-metal-ydeevne.

Mens Docker/Podman fokuserer på OCI-kompatible applikationscontainere , skinner LXC, når der er behov for persistente miljøer med flere tjenester og processer, og opfører sig som en VM, men med mindre overhead og en meget naturlig integration med Linux-kernen.

Fra et ydeevnesynspunkt kan LXC køre dataintensive virksomhedsapplikationer stort set uden ulemper , hvilket gør det til et effektivt valg til latenstidsfølsomme arbejdsbelastninger, der ikke kræver den stærke isolation fra en traditionel VM.

Sideløbende med dette har teknologier rettet mod mikro-VM'er og forbedret isolering også vundet frem, såsom Kata Containers , der starter hver pod i en lille virtuel maskine med sin egen kerne, eller gVisor, der indsætter en "kernel sandbox" skrevet i Go mellem applikationen og Linux. Begge reducerer afhængigheden af ​​den delte kerne og bevæger sig tættere på sikkerhedsmodellen for VM'er, samtidig med at containernes brugervenlighed opretholdes.

Bedste fremgangsmåder til hærdning af Docker og Podman

Med alt ovenstående er den rimelige tilgang til en robust containerplatform at arbejde i lag: segmentering med navnerum/cgroups, filtreringspolitikker med seccomp og MAC og strukturel privilegiebegrænsning via rootless mode.

I praksis er det tilrådeligt at anvende standardpraksisen med at køre containere i ikke-root-tilstand, når det er muligt , især i miljøer med flere lejere eller i delte clouds. Podman muliggør dette som standard, og Docker rootless dækker den samme filosofi, når kompatibilitet er påkrævet.

Værtskernen skal holdes opdateret med sikkerhedsrettelser . Sårbarheder som Dirty COW, Dirty Pipe og andre adresseres med opdateringer, der skal implementeres relativt hurtigt, hvis vi ikke vil lade døren stå åben for containerudbrud.

En anden yderst effektiv foranstaltning er at bruge uforanderlige, containerorienterede distributioner, såsom openSUSE MicroOS eller Flatcar Linux . Deres skrivebeskyttede root- og atomiske opdateringssystem reducerer angrebsfladen betydeligt og letter rollbacks, hvis noget går galt efter en patch.

Angående konfiguration: ingen privilegerede containere i produktion undtagen i ekstremt kontrollerede tilfælde , kør ikke applikationer som root inde i containeren, brug skrivebeskyttede filsystemer når det er muligt, og begræns mulighederne til et absolut minimum. SELinux/AppArmor- og seccomp-profiler, der er skræddersyet til applikationens faktiske kald, er praktisk talt obligatoriske.

Endelig må vi ikke glemme runtime-overvågningsaspektet . Værktøjer som Falco, Sysdig Secure eller Aqua hjælper med at opdage anomalier, escape-forsøg (såsom usædvanlig adgang til /proc eller /sys), atypisk netværkstrafik eller mistænkelige kommandoer, hvilket giver tid til at reagere, før angrebet tager fat.

Ved at kombinere klassisk virtualisering med KVM, containere administreret af Podman (helst i rootless-tilstand), velsegmenterede netværk og gode hærdningspraksisser kan der opbygges en yderst fleksibel og ret sikker virtualiseringsplatform. Forståelse for, at den delte kerne er det mest kritiske punkt, afhængighed af VM'er eller mikro-VM'er, når risiko eller overholdelse af lovgivning kræver det, og omhyggelig styring af imageforsyningskæden gør forskellen mellem et laboratoriemiljø og en produktionsklar infrastruktur.

Typer af servervirtualisering
Relateret artikel:
Typer af servervirtualisering