Kubernetes how-to

Kubernetes Network Policy: Default Deny With Examples

A NetworkPolicy selects pods and controls the traffic allowed to and from them. Without any policy selecting a pod, all traffic is allowed. Once a policy selects a pod for ingress or egress, only the traffic that policy allows gets through. Policies only take effect if the cluster network plugin enforces them.

By , Founder at SeaGit

·

Key takeaways

  • A policy with an empty podSelector selects every pod in its namespace. A default-deny policy is a policy with no allow rules for the chosen direction.
  • Creating a NetworkPolicy does nothing unless the network plugin implements it. The official page says so directly.
  • Default-deny egress also blocks DNS. Allow UDP and TCP port 53 to the cluster DNS, or every name lookup fails.
  • On EKS with the VPC CNI network policy agent, standard mode lets a new pod run with a default-allow policy until its policies arrive. Strict mode starts it denied.

How the selection and the defaults work

The NetworkPolicy resource has a podSelector, which picks the pods the policy applies to, and policyTypes, which says whether the policy governs ingress, egress or both. The official docs describe the two default shapes: a policy that allows all egress from the selected pods, and a default-deny ingress policy that selects every pod.

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: prod
spec:
  podSelector: {}          # every pod in prod
  policyTypes:
  - Ingress                # no ingress rules listed, so no ingress is allowed
Default-deny ingress for the prod namespace, from the official examples. It does not change egress for any pod.

The official page says this policy ensures even pods not selected by any other policy are isolated for ingress. The egress side needs its own policy.

Allow the frontend to reach the API, and nothing else

Once default-deny is in place, you open only the paths you need. This policy lets pods labelled app=frontend reach pods labelled app=api on port 8080. Everything else into the API stays blocked.

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow-frontend
  namespace: prod
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
The from and ports fields together form one rule. Multiple from entries under one ingress rule are an OR.

Test the rule from both sides

bash
# Should succeed: a frontend pod reaching the API
kubectl exec -n prod deploy/frontend -- wget -qO- -T 3 http://api:8080/healthz

# Should time out: a pod without the frontend label
kubectl run probe -n prod --rm -it --image=busybox:1.36 --restart=Never -- \
  wget -qO- -T 3 http://api:8080/healthz
A blocked connection usually times out rather than refusing. Use a short timeout so the test finishes quickly.

The DNS trap: default-deny egress blocks name lookups

If you deny egress, a pod can no longer reach the cluster DNS service either, and every connection that uses a name fails while IP-based calls still work. This is the most common surprise after a default-deny egress rollout. Allow DNS explicitly, to the DNS pods, on port 53.

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: prod
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53
Targets the kube-dns pods in kube-system. The label names match a standard cluster; check yours with kubectl get pods -n kube-system --show-labels.

EKS: the VPC CNI mode decides whether policies protect a new pod

On Amazon EKS, the Amazon VPC CNI plugin includes a network policy agent. Its README describes two modes that change what a new pod does while its policies are still being applied. In standard mode, the pod starts with a default-allow policy, and all ingress and egress is allowed until its policies are configured. In strict mode, the pod starts with a default-deny policy and nothing is allowed until policies exist.

  • Standard mode: a brief window at pod start where policies are not yet enforced. Fine for most workloads, but a security gap if it matters.
  • Strict mode: no window, but every pod needs a policy or it cannot talk. Host-network pods are exempt, according to the README.
  • Check the setting on your cluster before you rely on policies. A policy that is never applied gives no protection, even when it looks correct.
bash
# Confirm the network policy agent is present in the aws-node DaemonSet
kubectl get daemonset aws-node -n kube-system \
  -o jsonpath='{.spec.template.spec.containers[*].name}'

# List policies and what they select
kubectl get networkpolicy -n prod
kubectl describe networkpolicy api-allow-frontend -n prod
The container list shows whether the network policy agent is installed. Read the add-on docs for the mode variable on your version.

Debugging a policy that blocks too much

Policies are easy to get wrong because a missing rule looks like an application fault. Work through the checks in order: is the plugin enforcing policies, does the selector match the pod labels, and is the port the one the app really listens on.

  • Selector mismatch: kubectl get pods -n prod --show-labels against the policy podSelector. Labels are exact.
  • Wrong direction: an allow on ingress does not open egress from the same pod. Add the policyType you need.
  • Port: the policy lists the container port. A Service port that maps to a different target port is a common mismatch.

Frequently asked questions

Kubernetes Network Policy: Default Deny With Examples: FAQ

Does a NetworkPolicy work without any extra setup?

Not always. The official page says a NetworkPolicy has no effect unless the network plugin implements it. Confirm that your cluster network solution enforces policies before you rely on them.

Why are my pods unable to resolve service names after a policy change?

Usually a default-deny egress policy blocks DNS. Add an egress rule that allows UDP and TCP port 53 to the kube-dns pods.

Are NetworkPolicies a substitute for a firewall?

They are a Kubernetes-level control on pod traffic. They do not replace network controls outside the cluster, such as security groups on the nodes or the load balancer rules in front of an ingress.

Does a policy in one namespace affect pods in another?

A policy applies to the pods it selects in its own namespace. To allow traffic across namespaces, the rule must name the other namespace with a namespaceSelector.

Sources

Checked 11 October 2026.

  1. Kubernetes: Network Policies — Prerequisite that the network plugin implements policies, the default-deny ingress and allow-all egress examples, and the isolation behaviour.
  2. aws/amazon-vpc-cni-k8s README — Network policy agent modes, standard and strict, and what a new pod gets while its policies are applied.
  3. Kubernetes: Use a Service to Access an Application in a Cluster — Service ports and target ports, which a policy has to match.

Read next