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
Remediation
Manual Steps
-
Identify all pods using
hostNetworkacross 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.
-
Review existing admission controls / policies per namespace
- Run on: any machine with kubectl access
- Commands:
kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io -o widekubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io -o widekubectl 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.
-
Determine business/operational need for each
hostNetworkpod- 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
hostNetworkis truly necessary (e.g., low-latency network access, node-local ports). Document which workloads can drophostNetworkand which must retain it.
- For each user-workload pod from step 1, review deployment manifests and owners:
-
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.
- Denies new pods (and controllers: Deployments, DaemonSets, etc.) with
- 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.
-
Refactor or reconfigure existing workloads to stop using
hostNetworkwhere possible- For each pod that does not strictly require
hostNetwork:- Update the workload manifest (Deployment/StatefulSet/DaemonSet/etc.) to remove or set
hostNetwork: false.
- Update the workload manifest (Deployment/StatefulSet/DaemonSet/etc.) to remove or set
- 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.
- For each pod that does not strictly require
-
Verify effectiveness of policies and remaining
hostNetworkusage- Confirm that new
hostNetworkpods 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
hostNetworkpods are documented, approved exceptions and that corresponding namespaces still have admission policies in place.
- Confirm that new
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