RouterOS handleiding

Container

Deze sectie behandelt de ondersteuning voor containers in RouterOS, waaronder containerconfiguratie, virtuele Ethernet-interfaces, opslag en toepassingsvoorbeelden. Gebruik deze om ondersteunde containerdiensten op RouterOS-apparaten te draaien.

Vereiste pakketten: container

Een container is MikroTik's implementatie van Linux-containers, waarmee gebruikers gecontaineriseerde omgevingen binnen RouterOS kunnen draaien. De containerfunctie werkt in de nieuwste MikroTik RouterOS v7.x-versie. Containers zijn compatibel met images van Docker Hub, GCR, Quay of andere aanbieders, evenals met images die op andere apparaten zijn gebouwd, met dezelfde formaten die door deze aanbieders worden ondersteund. Hoewel RouterOS een andere syntaxis gebruikt dan Docker, biedt het toch vergelijkbare functionaliteit.

Disclaimer

Gevaar U hebt fysieke toegang tot uw RouterOS-apparaat nodig om ondersteuning voor de containerfunctie in te schakelen; deze is standaard uitgeschakeld;

  • zodra de containerfunctie is ingeschakeld, kunnen containers op afstand worden toegevoegd/geconfigureerd/gestart/gestopt/verwijderd!
  • als uw RouterOS-apparaat gecompromitteerd is, kunnen containers worden gebruikt om eenvoudig kwaadaardige software te installeren op uw RouterOS-apparaat en via het netwerk;
  • je RouterOS-apparaat is net zo veilig als alles wat je in een container draait;
  • als u een container draait, is er geen enkele garantie op het gebied van beveiliging;
  • het draaien van een container image van derden op uw RouterOS-apparaat kan een beveiligingsgat, aanvalsvector of aanvalsoppervlak openen;
  • een expert met kennis van het bouwen van exploits zal in staat zijn om te jailbreaken/te escaleren naar root;

Beveiligingsrisico's

  • Wanneer een beveiligingsexpert zijn exploitonderzoek publiceert, kan iedereen zo'n exploit toepassen.
  • Iemand kan een container image bouwen dat de exploit kan gebruiken EN een Linux root shell biedt.
  • Door een root-shell te gebruiken kan iemand een permanente achterdeur/kwetsbaarheid in uw RouterOS-systeem achterlaten, zelfs nadat de container-image is verwijderd en de containerfunctie is uitgeschakeld.
  • Als er een kwetsbaarheid in de primaire of secundaire RouterBOOT (of de pre-loader van de fabrikant) wordt geïnjecteerd, kan zelfs Netinstall dit mogelijk niet herstellen.

Requirements

Het container-pakket is compatibel met de architecturen arm, arm64 en x86. Het gebruik van de remote-image-functionaliteit (vergelijkbaar met docker pull) vereist veel vrije ruimte in het hoofdgeheugen; boards met 16 MB SPI-flash kunnen vooraf gebouwde images op USB of andere schijfmedia gebruiken.

Danger

  • Een externe schijf die ten minste 100MB/s sequentiële lees-/schrijfsnelheid en 10K random iops ondersteunt, wordt aanbevolen. Bij gebruik van tragere schijven kunnen de extractietijden van containers langer worden.
  • Het Container-pakket moet zijn geïnstalleerd
  • Voor apparaten met een EN7562CT-CPU zoals de hEX Refresh worden alleen arm32v5-containerimages ondersteund, wat betekent dat er een beperkt aantal containers kan worden uitgevoerd.

Submenu: /container

Properties

Property Description
restart-interval (string; Default: ) Geef een interval op waarna de Container opnieuw wordt gestart bij een storing van de Container. Voorbeeld: 10s
cmd (string; Default: ) Het belangrijkste doel van een CMD is om standaardwaarden te bieden voor een uitvoerende container. Deze standaardwaarden kunnen een executable bevatten, of ze kunnen de executable weglaten, in welk geval u ook een ENTRYPOINT instructie moet opgeven.
comment (string; Standaard: ) Korte beschrijving
dns (string; Default: ) Als de container een andere DNS nodig heeft, kan dat hier worden geconfigureerd
domain-name (string; Default: ) Stelt de domeinnaam van de container in
entrypoint (string; Default: ) Met een ENTRYPOINT kunt u een uitvoerbaar bestand opgeven dat wordt uitgevoerd bij het starten van de container. Voorbeeld: /bin/sh
envlist (string; Default: ) Lijst met omgevingsvariabelen (geconfigureerd onder /container/envs ) die met de container gebruikt moeten worden
file (string; Default: ) Een container-tarball *tar.gz als de container vanuit een bestand wordt geïmporteerd
hostname (string; Default: ) Het toewijzen van een hostnaam aan een container helpt om de container eenvoudiger te identificeren en te beheren
interface (string; Standaard: ) veth-interface die met de container gebruikt moet worden
logging (string; Standaard: ) indien ingesteld op yes, wordt alle uitvoer die door de container wordt gegenereerd in het RouterOS-log getoond
start-on-boot (string; Default: ) indien ingesteld op yes, wordt de container automatisch gestart bij het opstarten van het apparaat.
mountlists (string; Standaard: ) mounts uit het submenu /container/mounts/ die met deze container worden gebruikt
mount (string; Standaard: ) geef een directory op die als mount gebruikt moet worden
remote-image (string; Standaard: ) de naam van de container image die geïnstalleerd moet worden als er een externe registry wordt gebruikt (geconfigureerd onder /container/config/set registry-url=...)
root-dir (string; Default: ) wordt gebruikt om de container store buiten het hoofdgeheugen op te slaan
stop-signal (string; Default: 15) bepaalt welk Linux-signaal wordt verzonden om de container te beëindigen als deze na 10 seconden nog draait. Verschillende signalen kunnen een nette afsluiting of onmiddellijke beëindiging mogelijk maken, of applicatiespecifieke acties activeren
workdir (string; Default: ) de working directory voor het cmd-entrypoint
devices (string; Default: ) geeft een fysiek apparaat door aan de container
cpu-list (string; Default: ) geeft aan op welke CPU-cores de container mag draaien
user (string; Standaard: ) stelt de gebruiker en groep in waarmee het containerproces vóór de uitvoering wordt gedraaid.
memory-high (int; Standaard: ) "Zachte" RAM-gebruikslimiet in bytes voor een specifieke container. Als het gebruik boven de bovengrens uitkomt, worden de processen afgeknepen en onder reclaim-druk gezet.
memory-max (int; Standaard: ) Maximale limiet voor RAM-gebruik in bytes per container (het containerproces wordt beëindigd als de waarde van memory-max kleiner is dan de memory-current van de container). Vanaf 7.23 kan deze parameter niet lager dan 1MB worden ingesteld, om te voorkomen dat de container te vroeg in het opstartproces wordt beëindigd
swap-max (int; Standaard: ) Maximale hoeveelheid swapruimte (in bytes) die de container mag gebruiken. Vereist dat swap is ingeschakeld op het apparaat (zie Swap space).
stop-time (string; Default: ) Tijdslimiet waarbinnen de container netjes moet stoppen voordat het stop-signal wordt verzonden.
tmpfs (string; Default: ) Tijdelijke mountpunten van het bestandssysteem voor de container. Formaat: size@dir, bijvoorbeeld 64M@/tmp.
layer-dir (string; Standaard: ) Directory voor het opslaan van container-imagelagen, gebruikt voor gedeelde laagopslag tussen containers.
shm-size (int; Default: ) Grootte van het gedeelde geheugenbestandssysteem /dev/shm in bytes voor de container.
default-dns (string; Default: ) Standaard DNS-servers overgenomen uit de systeemconfiguratie /ip/dns.
hosts (string; Default: ) Aangepaste toewijzingen van hostnaam naar IP-adres voor de container. Formaat: host=ip.
restart-policy (string; Default: ) Definieert het herstartbeleid voor de container: no (nooit herstarten), on-failure (alleen herstarten bij een exitcode die niet nul is) of always (altijd herstarten).
restart-max-count (int; Default: ) Maximaal aantal herstartpogingen dat is toegestaan binnen het tijdvenster restart-interval.
stop-on-unhealthy (string; Default: ) Als dit op yes is ingesteld, wordt de container automatisch gestopt wanneer de healthcheck-status unhealthy wordt.

Waarschuwing Standaard gebruikt de container dezelfde DNS als geconfigureerd in het submenu /ip/dns. Als hier geen DNS is geconfigureerd en de parameter dns van de container niet is opgegeven, zal de container niet starten!

Menuspecifieke commando's

Property Description
update Werkt de container image bij. Haalt deze automatisch op uit de container repository en pakt hem uit, waarbij de originele image wordt vervangen.
kill Beëindigt de opgegeven draaiende container.
restart Herstart de opgegeven draaiende container.
repull Haalt/pakt de container image opnieuw uit.
shell Opent de containershell van een draaiende container.
run Start de container en gaat naar de shell ervan. Handig als de container afsluit na het draaien.

Containerconfiguratie

Submenu: /container/config

Property Description
registry-url externe registry-url waarvandaan de container wordt gedownload (standaard: https://lscr.io/)
tmpdir Directory voor het uitpakken van containers
layer-dir Directory voor het opslaan van container-imagelagen, gebruikt voor gedeelde laagopslag tussen containers
memory-high Globale "soft" RAM-gebruikslimiet in bytes voor een specifieke container. Als het gebruik boven de bovengrens komt, worden de processen afgeknepen en onder reclaim-druk gezet.
memory-max Globale maximale RAM-gebruikslimiet in bytes per container (het containerproces wordt beëindigd als de memory-max waarde kleiner is dan de container memory-current). Vanaf 7.23 kan deze parameter niet lager dan 1MB worden ingesteld, om te voorkomen dat de container te vroeg in het opstartproces wordt beëindigd
swap-max (int; Standaard: ) Globale standaardwaarde voor de maximale hoeveelheid swapruimte (in bytes) per container. Individuele containers kunnen dit overschrijven met hun eigen swap-max instelling. Vereist dat swap op het apparaat is ingeschakeld (zie Swap space).
username Geeft de gebruikersnaam voor authenticatie aan (vanaf ROS 7.8)
password gevoelig Geeft het wachtwoord voor authenticatie aan (vanaf ROS 7.8)

Alleen-lezen eigenschappen

Property Description
assumed-registry-url Automatisch gedetecteerde registry-URL.
memory-current Huidig totaal geheugengebruik van alle containers in bytes.

Examples

Pi-hole draaien

Prerequisites

  1. RouterOS-apparaat met RouterOS v7.4beta of nieuwer en een geïnstalleerd Container-pakket - Hoe u pakketten installeert
  2. Fysieke toegang tot een apparaat om de containermodus in te schakelen - dit wordt hieronder toegelicht
  3. Aangesloten HDD, SSD of USB-station voor opslag - geformatteerd met een bestandssysteem dat door RouterOS wordt ondersteund - Schijven formatteren/beheren

Stappen om Pi-hole uit te voeren

  1. Schakel de Container-modus in en volg de instructies die het commando geeft (lees meer over Device-mode. U moet de device-mode bevestigen met een druk op de resetknop, of met een koude herstart (als u Containers op x86 gebruikt):

    /system/device-mode/update container=yes 
    

    :::danger Device-mode beperkt standaard het gebruik van containers; zorg ervoor dat uw apparaat volledig beveiligd is voordat u toegang tot de container-modus verleent. :::

  2. Maak een nieuwe veth-interface aan en wijs een IP-adres toe uit een reeks die uniek is in uw netwerk:

    /interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1
    

    :::info De volgende configuratie komt overeen met de netwerkmodus "bridge" in andere Container-engines zoals Docker. Het is ook mogelijk om een configuratie te maken die overeenkomt met "host".

    Belangrijk: Eén veth-interface kan voor meerdere Containers worden gebruikt. U kunt meerdere veth-interfaces aanmaken om geïsoleerde netwerken voor verschillende Containers te maken. :::

  3. Maak een nieuwe bridge aan die voor uw Containers gebruikt gaat worden en wijs hetzelfde IP-adres toe dat als gateway voor de veth-interface is gebruikt:

    /interface/bridge/add name=containers
    /ip/address/add address=172.17.0.1/24 interface=containers
    
  4. Voeg de veth-interface toe aan je zojuist aangemaakte bridge:

    /interface/bridge/port/add bridge=containers interface=veth1
    
  5. Maak een NAT aan voor uitgaand verkeer:

    /ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24
    
  6. Maak omgevingsvariabelen aan voor de Container:

    /container/envs/add list=ENV_PIHOLE key=TZ value="Europe/Riga"
    /container/envs/add list=ENV_PIHOLE key=FTLCONF_webserver_api_password value="mysecurepassword"
    /container/envs/add list=ENV_PIHOLE key=DNSMASQ_USER value="root"
    
  7. Maak gemounte volumes aan voor de Container:

    /container/mounts/add list=MOUNT_PIHOLE_PIHOLE src=disk1/volumes/pihole/pihole dst=/etc/pihole
    /container/mounts/add list=MOUNT_PIHOLE_DNSMASQD src=disk1/volumes/pihole/dnsmasq.d dst=/etc/dnsmasq.d
    

    :::warning src= verwijst naar een locatie in RouterOS (dit kan ook src=disk1/etc_pihole zijn als u bijvoorbeeld besluit configuratiebestanden op externe USB-media te plaatsen), dst= verwijst naar de gedefinieerde locatie (raadpleeg de handleiding/wiki/github van de container voor informatie over waar dit naartoe moet wijzen). Als de src directory bij het eerste gebruik niet bestaat, wordt deze gevuld met wat de container op de dst locatie heeft. :::

    :::warning Het wordt sterk aanbevolen om Container-volumes op een aan uw RouterOS-apparaat gekoppelde schijf te plaatsen. Vermijd het plaatsen van Container-volumes op de ingebouwde opslag. :::

  8. Configureer het gebruik van een specifieke Container-repository, bijvoorbeeld om Docker.io te gebruiken:

    /container/config/set registry-url=https://registry-1.docker.io tmpdir=disk1/tmp
    
  9. Voeg een Container toe:

    /container/add remote-image=pihole/pihole interface=veth1 root-dir=disk1/images/pihole mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole
    

    :::tip Als je de uitvoer van de container in /log/print wilt zien, voeg dan logging=yes toe bij het aanmaken van een Container; root-dir moet naar een externe schijf verwijzen. Het gebruik van interne opslag voor Containers wordt afgeraden.

    Belangrijk: Er zijn meerdere manieren om een Container-image te verkrijgen; bekijk de sectie Adding a Container image als je een alternatieve manier nodig hebt om een Container-image toe te voegen.

    Belangrijk: Bij het toevoegen van een Container wordt het downloaden of uitpakken gestart; de Container zelf wordt na het toevoegen niet gestart. Je moet hem na het downloaden/uitpakken de eerste keer handmatig starten. :::

  10. Controleer de status van uw Container en wacht tot het downloaden/uitpakken is voltooid en status=stopped is:

    /container/print
    
  11. Start de container:

    /container/start pihole
    
  12. Maak een port forwarding aan voor uw Container:

    /ip/firewall/nat
    add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=80 protocol=tcp to-addresses=172.17.0.2 to-ports=80
    
  13. Je zou toegang moeten hebben tot het Pi-hole-webpaneel door in je webbrowser naar http://192.168.88.1/admin/ te navigeren.

  14. Om Pi-hole op uw apparaten te gaan gebruiken, wijzigt u hun DNS-configuratie zodat 192.168.88.1 als DNS-server wordt gebruikt.

Een Container image toevoegen

Er zijn meerdere manieren om een Container image draaiend te krijgen op uw RouterOS-apparaat. Bekijk de onderstaande voorbeelden.

Optie A: Haal een image op uit een externe library

Stel registry-url in (voor het downloaden van containers uit de Docker registry) en stel de extract directory (tmpdir) in op het aangesloten USB-medium:

/container/config/set registry-url=https://registry-1.docker.io tmpdir=disk1/tmp

een image ophalen:

/container/add remote-image=pihole/pihole interface=veth1 root-dir=disk1/images/pihole mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole

De image wordt automatisch opgehaald en uitgepakt naar root-dir. De status kan gecontroleerd worden met

/container/print

Optie B: Importeer een image vanaf de pc

Je kunt je pc met Docker of Podman gebruiken om de vereiste container image te downloaden en op te slaan in een archief. We raden Podman aan, omdat het met Podman eenvoudiger is om containers voor specifieke architecturen te bouwen en te downloaden.

  1. Download het benodigde image op basis van de architectuur van uw RouterOS-apparaat.

    #For ARM64
    podman pull --arch=arm64 docker.io/pihole/pihole
    
    #For ARM
    podman pull --arch=arm docker.io/pihole/pihole
    
    #For AMD64
    podman pull --arch=amd64 docker.io/pihole/pihole
    
  2. Sla de container-image op in een archief.

    podman save pihole > pihole.tar
    
  3. Upload het archief naar uw RouterOS-apparaat, bijvoorbeeld:

    rsync -av pihole.tar admin@192.168.88.1:/data/disk1/
    

    :::tip U kunt ook Winbox gebruiken om bestanden te uploaden! :::

  4. Maak een container aan op uw RouterOS-apparaat met het geüploade archiefbestand van de container-image.

    /container/add file=disk1/pihole.tar interface=veth1 root-dir=disk1/pihole mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole
    

Optie C: Bouw een image op de pc

Je kunt je eigen Containers bouwen en ze op je RouterOS-apparaat gebruiken. Hoewel je Containers met Docker kunt bouwen, raden we Podman aan, omdat het met Podman eenvoudiger is om Containers voor een specifieke architectuur te bouwen.

  1. Haal de bronbestanden op voor de Container-image die u nodig heeft, bijvoorbeeld met git.

    git clone https://github.com/pi-hole/docker-pi-hole.git
    cd docker-pi-hole
    
  2. Bouw de Container-image door het Dockerfile of Containerfile en de doelarchitectuur op te geven.

    #For ARM64
    podman build --platform linux/arm64 --tag pihole -f ./src/Dockerfile
    
    #For ARM
    podman build --platform linux/arm --tag pihole -f ./src/Dockerfile
    
    #For AMD64
    podman build --platform linux/amd64 --tag pihole -f ./src/Dockerfile
    
  3. Sla de container-image op in een archief.

    podman save pihole > pihole.tar
    
  4. Upload het archief naar uw RouterOS-apparaat, bijvoorbeeld.

    rsync -av pihole.tar admin@192.168.88.1:/data/disk1/
    

    :::tip U kunt ook Winbox gebruiken om bestanden te uploaden! :::

  5. Maak een container aan op uw RouterOS-apparaat met het geüploade archiefbestand van de container-image.

    /container/add file=disk1/pihole.tar interface=veth1 root-dir=disk1/pihole mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole
    
Alternatief: Docker gebruiken om Container-images te bouwen

Om Dockerfile te gebruiken en uw eigen docker-pakket te maken, moet docker geïnstalleerd zijn, evenals buildx of een andere buildertoolkit.

Controleer na de installatie of er extra architecturen beschikbaar zijn:

docker buildx ls

zou het volgende moeten teruggeven:

NAME/NODE DRIVER/ENDPOINT STATUS  PLATFORMS
default * docker
  default default         running linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

Zo niet, installeer dan extra architecturen:

docker run --privileged --rm tonistiigi/binfmt --install all

Haal uw project op of maak het aan met een Dockerfile erbij, bouw het en extraheer de image (pas --platform aan indien nodig):

git clone https://github.com/pi-hole/docker-pi-hole.git
cd docker-pi-hole
docker buildx build  --no-cache --platform arm64 --output=type=docker -t pihole .
docker save pihole > pihole.tar

Upload pihole.tar naar uw RouterOS-apparaat.

Images en objecten op het Linux-systeem kunnen worden pruned

Maak een container vanuit het tar-image

/container/add file=pihole.tar interface=veth1 mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD envlist=ENV_PIHOLE name=pihole

Netwerkvoorbeelden

Bridge met NAT

In deze netwerkopstelling gebruiken alle Containers dezelfde veth-interface en communiceren ze met elkaar zonder enige firewallbeperkingen, maar u moet poorten doorsturen om toegang tot een poort van een Container toe te staan.

Een databasecontainer moet bijvoorbeeld communiceren met een webapplicatiecontainer; de webapplicatie heeft nodig dat poort 80 naar buiten toe wordt blootgesteld, maar de databasecontainer hoeft geen enkele poort naar buiten toe bloot te stellen.

  • De netwerkconfiguratie:

    /interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1
    /interface/bridge/add name=containers
    /ip/address/add address=172.17.0.1/24 interface=containers
    /interface/bridge/port/add bridge=containers interface=veth1
    /ip/firewall/nat
    add chain=srcnat action=masquerade src-address=172.17.0.0/24
    add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=80 protocol=tcp to-addresses=172.17.0.2 to-ports=80
    
  • De configuratie van de databasecontainer:

    /container/envs/add list=ENV_POSTGRES key=POSTGRES_DB value="webapp"
    /container/envs/add list=ENV_POSTGRES key=POSTGRES_PASSWORD value="<changeme>"
    /container/envs/add list=ENV_POSTGRES key=POSTGRES_USER value="webapp"
    /container/envs/add list=ENV_POSTGRES key=PGDATA value="/var/lib/postgresql/data/pgdata"
    /container/envs/add list=ENV_POSTGRES key=POSTGRES_INITDB_ARGS value="--encoding='UTF8' --lc-collate='C' --lc-ctype='C'"
    /container/mounts/add list=MOUNT_POSTGRES src=disk1/volumes/postgres/data dst=/var/lib/postgresql/data
    /container/add remote-image=postgres:15 interface=veth1 root-dir=disk1/images/postgres mountlists=MOUNT_POSTGRES envlist=ENV_POSTGRES name=postgres start-on-boot=yes logging=yes
    
  • De configuratie van de webapp-container:

    /container/add remote-image=dpage/pgadmin4 interface=veth1 root-dir=disk1/images/pgadmin name=pgadmin start-on-boot=yes logging=yes
    

In dit voorbeeld is poort 80 van pgadmin voor iedereen toegankelijk, maar poort 5432 van postgres niet; die is alleen bereikbaar via pgadmin als 127.0.0.1 of via het RouterOS-apparaat waarop de Container draait als 172.17.0.2.

Geïsoleerde containers

In deze netwerkopstelling hebt u meerdere Containers en wilt u ervoor zorgen dat sommige daarvan zonder firewallbeperkingen kunnen communiceren, terwijl andere geïsoleerd moeten zijn van andere Containers. U wilt bijvoorbeeld twee database-Containers maken en die isoleren.

  • De netwerkconfiguratie.

    /interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1
    /interface/veth/add name=veth2 address=172.18.0.2/24 gateway=172.18.0.1
    /interface/bridge/add name=containers1
    /interface/bridge/add name=containers2
    /ip/address/add address=172.17.0.1/24 interface=containers1
    /ip/address/add address=172.18.0.1/24 interface=containers2
    /interface/bridge/port/add bridge=containers1 interface=veth1
    /interface/bridge/port/add bridge=containers2 interface=veth2
    /ip/firewall/nat
    add chain=srcnat action=masquerade src-address=172.17.0.0/24
    add chain=srcnat action=masquerade src-address=172.18.0.0/24
    add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=81 protocol=tcp to-addresses=172.17.0.2 to-ports=80
    add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=82 protocol=tcp to-addresses=172.18.0.2 to-ports=80
    
  • De configuraties van de eerste en tweede databasecontainer.

    /container/envs/add list=ENV_POSTGRES1 key=POSTGRES_DB value="webapp1"
    /container/envs/add list=ENV_POSTGRES1 key=POSTGRES_PASSWORD value="<changeme>"
    /container/envs/add list=ENV_POSTGRES1 key=POSTGRES_USER value="webapp1"
    /container/envs/add list=ENV_POSTGRES1 key=PGDATA value="/var/lib/postgresql/data/pgdata"
    /container/envs/add list=ENV_POSTGRES1 key=POSTGRES_INITDB_ARGS value="--encoding='UTF8' --lc-collate='C' --lc-ctype='C'"
    /container/mounts/add list=MOUNT_POSTGRES1 src=disk1/volumes/postgres1/data dst=/var/lib/postgresql/data
    /container/add remote-image=postgres:15 interface=veth1 root-dir=disk1/images/postgres1 mountlists=MOUNT_POSTGRES1 envlist=ENV_POSTGRES1 name=postgres1 start-on-boot=yes logging=yes
    
    /container/envs/add list=ENV_POSTGRES2 key=POSTGRES_DB value="webapp2"
    /container/envs/add list=ENV_POSTGRES2 key=POSTGRES_PASSWORD value="<changeme>"
    /container/envs/add list=ENV_POSTGRES2 key=POSTGRES_USER value="webapp2"
    /container/envs/add list=ENV_POSTGRES2 key=PGDATA value="/var/lib/postgresql/data/pgdata"
    /container/envs/add list=ENV_POSTGRES2 key=POSTGRES_INITDB_ARGS value="--encoding='UTF8' --lc-collate='C' --lc-ctype='C'"
    /container/mounts/add list=MOUNT_POSTGRES2 src=disk1/volumes/postgres2/data dst=/var/lib/postgresql/data
    /container/add remote-image=postgres:15 interface=veth2 root-dir=disk1/images/postgres2 mountlists=MOUNT_POSTGRES2 envlist=ENV_POSTGRES2 name=postgres2 start-on-boot=yes logging=yes
    
  • De configuraties van de eerste en tweede webapp-container.

    /container/add remote-image=dpage/pgadmin4 interface=veth1 root-dir=disk1/images/pgadmin1 name=pgadmin1 start-on-boot=yes logging=yes
    
    /container/add remote-image=dpage/pgadmin4 interface=veth2 root-dir=disk1/images/pgadmin2 name=pgadmin2 start-on-boot=yes logging=yes
    

In dit voorbeeld kan pgadmin1 wel postgres1 bereiken, maar niet postgres2. Op dezelfde manier kan pgadmin2 wel postgres2 bereiken, maar niet postgres1.

Container in een Layer2-netwerk

In deze netwerkopstelling is uw Container rechtstreeks gekoppeld aan een Layer2-netwerk met andere fysieke netwerkapparaten. Deze netwerkopstelling komt overeen met de netwerkmodus "host" op andere Container-engines zoals Docker.

Gevaar In deze netwerkopzet zijn alle poorten van uw container blootgesteld. Dit wordt als onveilig beschouwd, maar het verbetert de netwerkprestaties van de container wel enigszins.

  • De netwerkconfiguratie.

    /interface/veth/add name=veth1 address=192.168.88.2/24 gateway=192.168.88.1
    /interface/bridge/port/add bridge=bridge interface=veth1
    
  • Als op uw RouterOS-apparaat services op dezelfde poort draaien, moet u deze uitschakelen.

    /ip/service/disable [find where name=www]
    
  • De webapp-configuratie.

    /container/add remote-image=dpage/pgadmin4 interface=veth1 root-dir=disk1/images/pgadmin name=pgadmin start-on-boot=yes logging=yes
    

In dit voorbeeld heeft de Container pgadmin geen port forwarding nodig, maar zijn alle andere poorten die de Container gebruikt nu toegankelijk voor anderen op hetzelfde Layer2-netwerk. Dit type opstelling zou alleen moeten worden gebruikt wanneer uw toepassing vereist dat de Container een IP-adres in hetzelfde Layer2-netwerk heeft, zoals toepassingen die broadcastverkeer gebruiken voor service discovery (in de meeste gevallen kunnen dergelijke vereisten alsnog worden omzeild door NAT te gebruiken).

IPv4 en IPv6 voor Container

In deze netwerkopstelling kan uw Container communiceren via IPv4 en IPv6. De oplossing is gebaseerd op de netwerkopstelling Bridge with NAT.

  • De netwerkconfiguratie.

    /ip/address
    add address=172.17.0.1/24 interface=containers
    /ip/firewall/nat
    add action=masquerade chain=srcnat src-address=172.17.0.0/24
    add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=80 protocol=tcp to-addresses=172.17.0.2 to-ports=80
    /ipv6/address
    add address=fd8d:5ad2:24:2::1 interface=containers
    /ipv6/firewall/nat
    add action=masquerade chain=srcnat src-address=fd8d:5ad2:24:2::/64
    add action=dst-nat chain=dstnat dst-address=fd8d:5ad2:24:2::1 dst-port=80 protocol=tcp to-addresses=fd8d:5ad2:24:2::2 to-ports=80
    /interface/veth
    add address=172.17.0.2/24,fd8d:5ad2:24:2::2/64 gateway=172.17.0.1 gateway6=fd8d:5ad2:24:2::1 name=veth1
    /interface/bridge/port/add bridge=containers interface=veth1
    
  • De configuratie van de webapp-container.

    /container/add remote-image=nginx interface=veth1 root-dir=disk1/images/nginx name=nginx start-on-boot=yes logging=yes
    

Healthcheck

Vanaf RouterOS 7.23 is ondersteuning voor healthcheck in RouterOS geïmplementeerd. Healthcheck is een mechanisme dat helpt te controleren of de applicatie in de container correct draait.

Healthchecks zijn gebaseerd op standaard exitcodes. Het commando dat voor de healthcheck wordt gebruikt, moet 0 teruggeven wanneer de applicatie gezond is en een exitcode ongelijk aan nul wanneer deze ongezond is.

In de meeste gevallen is bij containers die een webinterface draaien een eenvoudig HTTP GET-verzoek naar localhost voldoende om te controleren of de applicatie correct reageert.

Property Description
healthcheck-cmd (string; Default:) commando dat wordt gebruikt voor de healthcheck
healthcheck-interval (time; Default: 00:00:30) tijdsinterval in het formaat HH:MM:SS
healthcheck-retries (int; Default: 3) bij een mislukte controle - het aantal nieuwe pogingen voordat de containerapplicatie als ongezond wordt beschouwd
healthcheck-start-interval (time; Default: 00:00:05) tijd tussen healthchecks in de startperiode
healthcheck-start-period (time; Default: 00:00:00) geeft de container tijd om te starten. eventuele fouten binnen de startperiode worden niet bij de retries-teller opgeteld
healthcheck-status (string) huidige gezondheidsstatus van de container. toont de huidige status van de applicatie binnen de container en de uitvoer van de probe
healthcheck-timeout (time; Default: 00:00:30) als het healthcheck-probing langer duurt dan de opgegeven periode, telt de controle als mislukt

Healthcheck-voorbeeld

Voor dit voorbeeld zetten we een HomeAssistant-container op en configureren we er een eenvoudige healthcheck op.

Raadpleeg voor een handleiding over het opzetten van een HomeAssistant-container onze HomeAssistant setup guide

Om de E-mail-tool in te stellen. Raadpleeg onze E-mail-documentatiepagina

  1. Controleer de naam van uw container

    [admin@ROSE] > container print 
    Flags: S - STOPPED, R - RUNNING
    Columns: NAME, ROOT-DIR, INTERFACE, MEMORY-CURRENT, CPU-USAGE, CONTAINER-SIZE, DATA-SIZE, TAG
    #   NAME                ROOT-DIR                                        INTERFACE                MEMORY-CURRENT  CPU-USAGE  CONTAINER-SIZE  DATA-SIZE  TAG                                                                   
    1 S home-assistant  /nvme1/apps/home-assistant/home-assistant_root  veth-home-assistant                          0  2201.9MiB       471.9KiB   docker.io/homeassistant/home-assistant:latest
    
  2. Nadat een container is aangemaakt, kunnen we er healthcheck op inschakelen door het healthcheck-commando in te stellen. Voor deze specifieke container. We kunnen ook de healthcheck-interval verhogen en een start-period opgeven, aangezien HomeAssistant een zware container is en op sommige apparaten trager kan starten.

    /container/set home-assistant healthcheck-cmd="curl -f http://localhost:8123" healthcheck-interval="00:01:00" healthcheck-start-period="00:02:00"
    

    Als dit lukt en de container start, zou je de container met de status "Healthy" moeten zien draaien. Daarnaast wordt het veld healthcheck-status gevuld met de huidige status van de container en met de uitvoer van het curl-commando.

    [admin@ROSE] > container print proplist=name,healthcheck-status
    Flags: S - STOPPED, R - RUNNING, H - HEALTHY
    Columns: NAME, HEALTHCHECK-STATUS
    #   NAME                HEALTHCHECK-STATUS                                                                           
    
     H home-assistant  good, output:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                                              Dload  Upload   Total   Spent    Left  Speed     
    

Als extra stap kunt u een script maken dat de status van de container opvraagt en een notificatie naar uw e-mail stuurt als de healthcheck mislukt, en een scheduler toevoegen om het script regelmatig uit te voeren.

  1. Maak het script aan:

    /system script
    add name=unhealthy-container-alert source="
    :global lastState\
        \n:local currentState \"\"\
        \n:local msg \"\"\
        \n:foreach i in=[/container find where unhealthy] do={\
        \n:local name [/container get \$i name]\
        \n:set currentState (\$currentState . \$name . \";\")\
        \n}\
        \n:if ([:len \$currentState] = 0) do={\
        \n:set lastState \"\"\
        \n} else={\
        \n:if (\$currentState != \$lastState) do={\
        \n:set lastState \$currentState\
        \n:foreach i in=[/container find where unhealthy] do={\
        \n:local name [/container get \$i name]\
        \n:set msg (\$msg . \$name . \" is UNHEALTHY\\n\")\
        \n}\
        \n/tool e-mail send to=\"admin@example.com\" subject=\"Unhealthy container(s)\" body=\$msg\
        \n}\
        \n}"
    

    :::warning Vergeet niet om admin@example.com te vervangen door uw eigen e-mailadres. :::

  2. Maak de scheduler aan:

    /system scheduler
    add interval=2m name=container-healthcheck-alert on-event="/system/script/run unhealthy-container-alert"
    

Memory

Er zijn drie parameters die het geheugengedrag van containers bepalen: memory-max, memory-high en swap-max. Elk kan per container of globaal worden geconfigureerd in /container/config. De globale waarden fungeren als standaardwaarden; als zowel een limiet per container als een globale limiet is ingesteld, geldt de laagste waarde (dit werkt in beide richtingen).

memory-max

Stelt de harde bovengrens in voor het RAM-gebruik van de container (in bytes). Als een container deze limiet overschrijdt, wordt deze beëindigd. Wanneer dit op beide niveaus is ingesteld, bijvoorbeeld de limiet per container is 500MB en de globale limiet is 300MB, dan geldt de limiet van 300MB. Als swap is ingeschakeld, kan de container proberen het overtollige geheugen weg te swappen in plaats van beëindigd te worden.

memory-high

Stelt een zachte bovengrens in voor het RAM-gebruik van de container (in bytes). Wanneer de limiet wordt bereikt, worden de containerprocessen afgeremd en onder zware geheugenterugwinningsdruk gezet - het systeem probeert geheugen vrij te maken (inclusief swappen). In tegenstelling tot memory-max wordt de container nooit beëindigd wegens overschrijding van deze limiet.

swap-max

Definieert de maximale hoeveelheid swapruimte (in bytes) die een container mag gebruiken. Werkt samen met memory-max - zodra een container zijn limiet van memory-max bereikt, wordt het overtollige geheugen weggeschreven naar swap tot aan de limiet van swap-max. Als een container bijvoorbeeld een memory-max van 600MB heeft en een proces probeert 800MB te gebruiken, wordt de resterende 200MB naar swap geschreven. Swap moet op het apparaat ingeschakeld zijn (zie Swap space).

Tips en trucs

  • Containers gebruiken veel schijfruimte. Via USB/SATA of NVMe aangesloten media worden sterk aanbevolen. Voor apparaten met USB-poorten kunnen USB-naar-SATA-adapters met 2,5"-schijven worden gebruikt, voor extra opslag en snellere bestandsbewerkingen.

  • Gebruik de start-on-boot-optie om containers te starten na een herstart van de router (vanaf 7.6beta6):

    /container/print
      0 name="2e679415-2edd-4300-8fab-a779ec267058" tag="test_arm64:latest" os="linux" arch="arm" interface=veth2 
        root-dir=disk1/alpine mountlists="" dns="" logging=yes start-on-boot=yes status=running 
    
    /container/set 0 start-on-boot=yes
    
  • Het is mogelijk om toegang te krijgen tot de shell van een draaiende container:

    /container/shell 0
    
  • Het is mogelijk om de container-timeout in seconden in te stellen, anders blijft deze onbeperkt open:

    /container/shell 0 timeout=120
    
  • Schakel logging in om output van de container te krijgen:

    /container/set 0 logging=yes
    
  • Sommige containers hebben extra rechten nodig om goed te kunnen werken:

    /container/set 0 user=0:0
    
  • Je kunt commando's binnen een Container uitvoeren met een specifieke gebruiker en zonder /bin/sh aan te roepen:

    /container/shell nextcloud user=www-data cmd="php /var/www/html/cron.php" no-sh
    
  • Vanaf versie 7.11beta5 kunnen meerdere adressen en ipv6-adressen worden toegevoegd:

    /interface/veth/add address=172.17.0.3/16,fd8d:5ad2:24:2::2/64 gateway=172.17.0.1 gateway6=fd8d:5ad2:24:2::1
    
  • Actief draaiende /dev/-nodes naar de container:

    /dev/full	/dev/null	/dev/random		/dev/tty	/dev/urandom	/dev/zero	/dev/console	/dev/net/tun	/dev/kvm	/dev/fuse
    
  • Met de parameter Devices is het mogelijk de seriële terminal beschikbaar te maken voor de container.

/container/set your-container devices=serial0:""

Info Om de container de seriële consolepoort te laten gebruiken, moet u eerst de seriële console vrijmaken die door RouterOS wordt gebruikt onder /system/console

Bron

Zoek je hoe de configurator zelf werkt? Handleiding bij de configurator

Bijgewerkt op 2026-08-22.