VMI Network Filter

Injects iptables-based network filtering into a KubeVirt Virtual Machine Instance (VMI) by applying INPUT and OUTPUT rules inside the virt-launcher network namespace via nsenter. Supports port and protocol-specific filtering so you can selectively block DNS, SSH, HTTP, or any other traffic without cutting all connectivity. The tap interface (tap0) is targeted directly so only the specific VMI is isolated, leaving OVN's BFD heartbeats and other node workloads unaffected.

How to Run VMI Network Filter Scenarios

Choose your preferred method to run VMI network filter scenarios:

Example scenario file: virt_network.yaml

Configuration

- id: vmi_network_filter
  image: "quay.io/krkn-chaos/krkn-network-chaos:latest"
  wait_duration: 300
  test_duration: 120
  label_selector: ""
  service_account: ""
  taints: []
  namespace: "my-namespace"
  instance_count: 1
  execution: serial
  target: ".*"
  interfaces: []
  ingress: true
  egress: true

For the common module settings please refer to the documentation.

  • target: regex to match VMI names within the namespace (e.g. "<vmi-name-prefix>-.*" or ".*" for all)
  • namespace: namespace containing the target VMIs (required; also supports regex to match multiple namespaces)
  • interfaces: list of tap interface names to target. Leave empty to auto-detect the tap device in the virt-launcher network namespace
  • ingress: apply iptables DROP rules to incoming traffic
  • egress: apply iptables DROP rules to outgoing traffic
  • ports: list of ports to block (omit or leave empty to block all ports)
  • protocols: list of IP protocols to filter — tcp, udp, or both (defaults to ["tcp", "udp"])

Catastrophic Configurations

Full network isolation (most catastrophic):

  ingress: true
  egress: true
  # no ports or protocols — blocks all TCP and UDP

Complete network cut to the VMI.

DNS blackout (cascading failures):

  ingress: true
  egress: true
  protocols:
    - tcp
    - udp
  ports:
    - 53

Blocking DNS (port 53) causes every service inside the VM that resolves hostnames to fail with timeouts. Cascading failures across the application stack without a hard cut — often the most realistic chaos scenario.

Management plane loss:

  ingress: true
  egress: true
  protocols:
    - tcp
  ports:
    - 22
    - 443
    - 6443

Blocks SSH, HTTPS, and the Kubernetes API server. The VM stays running but is unreachable for management and API calls.

Application layer only:

  ingress: true
  egress: true
  protocols:
    - tcp
  ports:
    - 80
    - 443
    - 8080
    - 8443

Kills HTTP/HTTPS traffic only — tests application resilience without taking the entire VM offline.

Usage

To enable VMI network filter scenarios edit the kraken config file, go to the section kraken -> chaos_scenarios of the yaml structure and add a new element to the list named network_chaos_ng_scenarios then add the desired scenario pointing to the scenario yaml file.

kraken:
    ...
    chaos_scenarios:
        - network_chaos_ng_scenarios:
            - scenarios/openshift/virt_network.yaml

Run

python run_kraken.py --config config/config.yaml

Run

$ podman run --name=<container_name> --net=host --pull=always --env-host=true -v <path-to-kube-config>:/home/krkn/.kube/config:Z -d containers.krkn-chaos.dev/krkn-chaos/krkn-hub:vmi-network-filter
$ podman logs -f <container_name or container_id> # Streams Kraken logs
$ podman inspect <container-name or container-id> --format "{{.State.ExitCode}}" # Outputs exit code which can considered as pass/fail for the scenario
$ docker run $(./get_docker_params.sh) --name=<container_name> --net=host --pull=always -v <path-to-kube-config>:/home/krkn/.kube/config:Z -d containers.krkn-chaos.dev/krkn-chaos/krkn-hub:vmi-network-filter
OR
$ docker run -e <VARIABLE>=<value> --net=host --pull=always -v <path-to-kube-config>:/home/krkn/.kube/config:Z -d containers.krkn-chaos.dev/krkn-chaos/krkn-hub:vmi-network-filter
$ docker logs -f <container_name or container_id> # Streams Kraken logs
$ docker inspect <container-name or container-id> --format "{{.State.ExitCode}}" # Outputs exit code which can considered as pass/fail for the scenario

TIP: Because the container runs with a non-root user, ensure the kube config is globally readable before mounting it in the container. You can achieve this with the following commands:

kubectl config view --flatten > ~/kubeconfig && chmod 444 ~/kubeconfig && docker run $(./get_docker_params.sh) --name=<container_name> --net=host --pull=always -v ~/kubeconfig:/home/krkn/.kube/config:Z -d containers.krkn-chaos.dev/krkn-chaos/krkn-hub:vmi-network-filter

Supported parameters

The following environment variables can be set on the host running the container to tweak the scenario/faults being injected:

ex.) export <parameter_name>=<value>

See list of variables that apply to all scenarios here that can be used/set in addition to these scenario specific variables

ParameterDescriptionTypeDefault
TOTAL_CHAOS_DURATIONChaos duration in secondsnumber60
VMI_NAMERegex to match VMI names (e.g. virt-server-.* or .* for all)string""
LABEL_SELECTORLabel selector to filter VMIs (e.g. app=myapp)string""
NAMESPACENamespace containing the target VMIsstringdefault
INSTANCE_COUNTMaximum number of VMIs to targetnumber1
EXECUTIONExecution mode: serial or parallelenumparallel
INGRESSApply DROP rules to incoming trafficbooleanfalse
EGRESSApply DROP rules to outgoing trafficbooleanfalse
INTERFACESComma-separated tap interface names (empty to auto-detect)string""
PORTSComma-separated port numbers to block (empty = all ports)string""
SCENARIO_TYPEPlugin key krkn dispatches the scenario on. Fixed by the container image, not a knob to change.-network_chaos_ng_scenarios
SCENARIO_FILEPath to the scenario file baked into the container image. Fixed by the image, not a knob to change.-scenarios/kube/vmi-network-filter.yml
IMAGENetwork chaos injection workload imagestringquay.io/krkn-chaos/krkn-hub-multiarch:workload-krkn-network-...
PROTOCOLSComma-separated protocols to filter: tcp, udp, or bothstringtcp
TAINTSList of taints for which tolerations are created (e.g. ["node-role.kubernetes.io/master:NoSchedule"])string""
SERVICE_ACCOUNTOptional service account for the scenario workloadstring""

NOTE In case of using custom metrics profile or alerts profile when CAPTURE_METRICS or ENABLE_ALERTS is enabled, mount the metrics profile from the host on which the container is run using podman/docker under /home/krkn/kraken/config/metrics-aggregated.yaml and /home/krkn/kraken/config/alerts. For example:

$ podman run --name=<container_name> --net=host --pull=always --env-host=true -v <path-to-custom-metrics-profile>:/home/krkn/kraken/config/metrics-aggregated.yaml -v <path-to-custom-alerts-profile>:/home/krkn/kraken/config/alerts -v <path-to-kube-config>:/home/krkn/.kube/config:Z -d containers.krkn-chaos.dev/krkn-chaos/krkn-hub:vmi-network-filter
krknctl run vmi-network-filter [--<parameter> <value>]

Can also set any global variable listed here

VMI Network Filter Parameters

ParameterDescriptionTypeRequiredDefaultPossible Values
--chaos-durationSet chaos duration (in sec) as desirednumberNo60
--vmi-nameThe VirtualMachineInstance name to target (if label selector not specified)stringNo""
--label-selectorVMI label selector used to target one or more VMIs by labelstringNo""
--namespaceNamespace where the target VMI is runningstringNodefault
--instance-countNumber of instances to target if more than one is selected by the LABEL_SELECTORnumberNo1
--executionWhen multiple VMIs are selected the execution on all of them can be performed in parallel or serialenumNoparallelparallel/serial
--ingressIncoming network traffic will be filteredbooleanYes-
--egressOutgoing network traffic will be filteredbooleanYes-
--interfacesNetwork interfaces to filter traffic on (if more than one separated by comma eg. eth0,eth1,eth2)stringNo""
--portsNetwork ports to filter traffic on (if more than one separated by comma eg. 8080,8081,8082)stringYes-
--protocolsThe network protocols that will be filtered (tcp, udp or both of them comma separated e.g. tcp,udp)stringNotcp
--imageThe network chaos injection workload container imagestringNoquay.io/krkn-chaos/krkn-hub-multiarch:workload-krkn-network-...
--taintsComma-separated taints for which tolerations are created, e.g. node-role.kubernetes.io/master:NoSchedulestringNo""
--service-accountThe service account associated with the VMI Network Filter workloadstringNo""

Parameter Format Details

VMI Selection:

  • --namespace: required; supports regex to match multiple namespaces (e.g. virt-density-.*)
  • --target: regex matched against VMI names (e.g. <vmi-name-prefix>-.* targets all VMIs whose name starts with that prefix)
  • Use --instance-count to limit how many matching VMIs are targeted

Port and Protocol Format:

  • --ports: comma-separated integers, no spaces (e.g. 53 or 22,443,6443). Omit to block all ports
  • --protocols: tcp, udp, or tcp,udp. Defaults to both

Interface Detection:

  • Leave --interfaces empty to let the scenario auto-detect the tap device inside the virt-launcher network namespace
  • Specify explicitly (e.g. tap0) only if auto-detection fails

Example Commands

DNS blackout (most impactful cascading failure):

krknctl run vmi-network-filter \
  --namespace <namespace> \
  --target ".*" \
  --ports 53 \
  --protocols tcp,udp \
  --ingress true \
  --egress true \
  --chaos-duration 120

Full network isolation:

krknctl run vmi-network-filter \
  --namespace <namespace> \
  --target "<vmi-name>" \
  --ingress true \
  --egress true \
  --chaos-duration 60

Management plane loss (SSH + API):

krknctl run vmi-network-filter \
  --namespace <namespace> \
  --target "<vmi-name-prefix>-.*" \
  --instance-count 2 \
  --ports 22,443,6443 \
  --protocols tcp \
  --ingress true \
  --egress true \
  --chaos-duration 300

Application layer only (HTTP/HTTPS):

krknctl run vmi-network-filter \
  --namespace <namespace> \
  --target ".*" \
  --execution parallel \
  --ports 80,443,8080,8443 \
  --protocols tcp \
  --ingress true \
  --egress true \
  --chaos-duration 180