Skip to main content

Minimize Admission Of Containers Sharing The Host Network

More Info:​

Sharing the host network namespace exposes node network interfaces and bypasses network policies. Enforce policies that restrict admission of hostNetwork containers.

Risk Level​

High

Address​

Security

Compliance Standards​

  • CIS OKE

Triage and Remediation​

Remediation​

Manual Steps
  1. Identify all pods using hostNetwork across the cluster

    • Run on: any machine with kubectl access
    • Command:
      kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostNetwork==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
    • Review: Determine which are platform/infra components (e.g., CNI, DNS, ingress) vs. user workloads; list user workloads that use hostNetwork.
  2. Review existing admission controls / policies per namespace

    • Run on: any machine with kubectl access
    • Commands:
      kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io -o wide
      kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io -o wide
      kubectl get limitranges,resourcequotas,networkpolicies,configmaps -A
    • Review: For each user-workload namespace, check if there is any admission controller (e.g., OPA Gatekeeper, Kyverno, custom webhooks) or policy that explicitly restricts spec.hostNetwork: true. Note which namespaces lack such protection.
  3. Determine business/operational need for each hostNetwork pod

    • For each user-workload pod from step 1, review deployment manifests and owners:
      kubectl get pod -n <NAMESPACE> <POD_NAME> -o yaml
    • Decide with application owners whether hostNetwork is truly necessary (e.g., low-latency network access, node-local ports). Document which workloads can drop hostNetwork and which must retain it.
  4. Plan and apply namespace-level admission policies to restrict hostNetwork

    • Choose or confirm your admission mechanism (e.g., Kyverno, OPA Gatekeeper, custom webhook).
    • For each user-workload namespace that should disallow hostNetwork, create/update a policy that:
      • Denies new pods (and controllers: Deployments, DaemonSets, etc.) with spec.hostNetwork: true, except for explicitly allowed labels/namespaces.
    • Apply policy manifests from any machine with kubectl access:
      kubectl apply -f <POLICY_MANIFEST>.yaml
    • Ensure policies are scoped per-namespace as required by your governance.
  5. Refactor or reconfigure existing workloads to stop using hostNetwork where possible

    • For each pod that does not strictly require hostNetwork:
      • Update the workload manifest (Deployment/StatefulSet/DaemonSet/etc.) to remove or set hostNetwork: false.
    • Apply the updated manifest from any machine with kubectl access:
      kubectl apply -f <UPDATED_WORKLOAD>.yaml
    • Coordinate with application teams and schedule changes to avoid disruption; be aware that networking behavior (ports, policies, source IPs) will change.
  6. Verify effectiveness of policies and remaining hostNetwork usage

    • Confirm that new hostNetwork pods are blocked in protected namespaces (expect admission denial):
      kubectl run test-hostnet --image=busybox --restart=Never \
      --overrides='{"apiVersion":"v1","kind":"Pod","spec":{"hostNetwork":true,"containers":[{"name":"c","image":"busybox","command":["sleep","3600"]}]}}' \
      -n <PROTECTED_NAMESPACE>
    • Re-run the audit query to ensure only justified workloads use hostNetwork:
      kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostNetwork==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
    • Confirm that any remaining hostNetwork pods are documented, approved exceptions and that corresponding namespaces still have admission policies in place.
Using kubectl

Using kubectl​

1. List pods that request hostNetwork​

Run on: any machine with kubectl access.

kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,HOSTNETWORK:.spec.hostNetwork' \
--no-headers | grep -E 'true$' || echo "No pods with hostNetwork=true found"

Problem indication: Any line returned (namespace/name with HOSTNETWORK = true) is using the host network and must be reviewed for necessity and risk.

To see details for a specific pod:

kubectl get pod <pod-name> -n <namespace> -o yaml

Review .spec.hostNetwork: true and the pod’s purpose.


2. Discover whether pod security controls exist​

a. Pod Security admission labels on namespaces (if using built-in PSA)

kubectl get ns --show-labels

Problem indication: Namespaces with user workloads that lack any pod-security.kubernetes.io/* labels, or are labeled with an overly-permissive level (e.g., privileged) likely do not restrict hostNetwork.

Check a specific namespace:

kubectl get ns <namespace> -o yaml

Inspect metadata.labels for pod-security.kubernetes.io/enforce (or audit/warn). Levels restricted/baseline are stricter; privileged means essentially unrestricted.


b. PodSecurityPolicy (legacy clusters only)

Check if PSP is enabled and list existing policies:

kubectl get psp

If PSPs exist, inspect them:

kubectl get psp <psp-name> -o yaml

Problem indication: Policies that apply to user workloads (via RBAC bindings) and allow hostNetwork: true without clear justification or scoping. In a PSP YAML, look at:

spec:
hostNetwork: true

This indicates the policy permits host networking.


c. Admission webhooks / OPA / Gatekeeper / Kyverno (if used)

List all Mutating/ValidatingWebhookConfigurations:

kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io
kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io

Inspect each security-related webhook:

kubectl get validatingwebhookconfiguration <name> -o yaml
kubectl get mutatingwebhookconfiguration <name> -o yaml

Problem indication: No webhook configurations that reference policies about spec.hostNetwork, or policy engines (OPA Gatekeeper, Kyverno, etc.) installed without any constraints/policies targeting hostNetwork. You will need to review the webhook/policy definitions themselves (in the policy engine’s CRDs) to determine whether hostNetwork is restricted.


3. Verify after policy decisions​

After you adjust policies (outside the scope of kubectl alone), re-run:

kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,HOSTNETWORK:.spec.hostNetwork' \
--no-headers | grep -E 'true$' || echo "No pods with hostNetwork=true found"

If any HOSTNETWORK=true pods remain, they should be explicitly approved exceptions; otherwise, they indicate a remaining policy gap.

Automation
#!/usr/bin/env bash
set -euo pipefail

# This script must run on any machine with kubectl access and correct kubeconfig.
# It reports all Pods and workload templates that request hostNetwork=true.

echo "=== Pods currently using hostNetwork ==="
kubectl get pods -A -o json \
| jq -r '
.items[]
| select(.spec.hostNetwork == true)
| [
.metadata.namespace,
.metadata.name,
(.metadata.ownerReferences[0].kind // "Pod"),
(.metadata.ownerReferences[0].name // "-"),
(.spec.serviceAccountName // "default")
]
| @tsv' \
| awk 'BEGIN{OFS="\t"; print "NAMESPACE","POD","OWNER_KIND","OWNER_NAME","SERVICE_ACCOUNT"}1'

echo
echo "=== Workload templates allowing hostNetwork (may create hostNetwork pods in future) ==="
# Deployments
kubectl get deploy -A -o json \
| jq -r '
.items[]
| select(.spec.template.spec.hostNetwork == true)
| ["Deployment",
.metadata.namespace,
.metadata.name,
(.spec.template.spec.serviceAccountName // "default")
]
| @tsv' \
| awk 'BEGIN{OFS="\t"; print "KIND","NAMESPACE","NAME","SERVICE_ACCOUNT"}1'

# DaemonSets
kubectl get ds -A -o json \
| jq -r '
.items[]
| select(.spec.template.spec.hostNetwork == true)
| ["DaemonSet",
.metadata.namespace,
.metadata.name,
(.spec.template.spec.serviceAccountName // "default")
]
| @tsv' \
| awk 'BEGIN{OFS="\t"; print "KIND","NAMESPACE","NAME","SERVICE_ACCOUNT"}1'

# StatefulSets
kubectl get sts -A -o json \
| jq -r '
.items[]
| select(.spec.template.spec.hostNetwork == true)
| ["StatefulSet",
.metadata.namespace,
.metadata.name,
(.spec.template.spec.serviceAccountName // "default")
]
| @tsv' \
| awk 'BEGIN{OFS="\t"; print "KIND","NAMESPACE","NAME","SERVICE_ACCOUNT"}1'

echo
echo "=== Namespaces without any NetworkPolicy (weaker isolation for any hostNetwork use) ==="
kubectl get ns -o json \
| jq -r '
.items[].metadata.name' \
| while read -r ns; do
count=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l | tr -d ' ')
if [ "$count" -eq 0 ]; then
echo "$ns"
fi
done

echo
echo "=== Interpretation ==="
cat <<'EOF'
Any line shown above indicates a configuration to review:

- "Pods currently using hostNetwork":
Each listed pod is already running with hostNetwork=true and bypasses
normal namespace-level network isolation and most NetworkPolicy controls.

- "Workload templates allowing hostNetwork":
Any listed Deployment, DaemonSet, or StatefulSet will create pods with
hostNetwork=true. These should exist only where strictly necessary and
should be covered by explicit admission / policy exceptions.

- "Namespaces without any NetworkPolicy":
Host-networked workloads in these namespaces are of higher concern, since
there is no NetworkPolicy layer at all. Consider introducing policies and/or
restricting hostNetwork via admission controls in these namespaces.

Use this report to decide:
- Which existing hostNetwork uses are truly required.
- Where to add or tighten admission controls and NetworkPolicy.
EOF