Kubernetes cookbook · Intermediate

Default-deny network policies that keep DNS working

Lock down pod traffic in a namespace without breaking name resolution.

Create a free account to save this page, take notes and track your progress. Sign in

Approach

Deny all ingress and egress for the namespace, allow DNS to the cluster DNS pods, then allow each service's real dependencies explicitly.

Solution

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: default-deny}
spec:
  podSelector: {}
  policyTypes: [Ingress, Egress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: allow-dns}
spec:
  podSelector: {}
  policyTypes: [Egress]
  egress:
    - to:
        - namespaceSelector: {matchLabels: {kubernetes.io/metadata.name: kube-system}}
          podSelector: {matchLabels: {k8s-app: kube-dns}}
      ports: [{port: 53, protocol: UDP}, {port: 53, protocol: TCP}]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: api-to-db}
spec:
  podSelector: {matchLabels: {app: db}}
  policyTypes: [Ingress]
  ingress:
    - from: [{podSelector: {matchLabels: {app: api}}}]
      ports: [{port: 5432}]

Pitfalls

  • Forgetting the DNS policy: every lookup fails.
  • Assuming policies are enforced; check that your CNI implements NetworkPolicy (including egress).

Variations

  • Allow ingress from the Ingress controller's namespace for public services.
  • CNI-specific FQDN policies for egress to external APIs.

Further reading: Network Policies

Reference: https://kubernetes.io/docs/concepts/services-networking/network-policies/

More Kubernetes recipes

Was this page helpful?