Kubernetes NetworkPolicy Generator

Build a NetworkPolicy with the DNS rule included by default, the cloud metadata endpoint excluded from any broad CIDR, and an explicit choice between ANDing and ORing your selectors. The output is checked by our own NetworkPolicy analyzer as you type.

Policy
Ingress: who may connect in

Leave everything here empty and the policy denies all inbound traffic to the selected pods.

Egress: where these pods may reach

Turn this off and nothing the pod does will resolve a name. This is the mistake, not an optional extra.

Adds 169.254.169.254/32 to except. Without it, a rule allowing 0.0.0.0/0 also allows the node's instance credentials.

networkpolicy.yaml

updates as you type

    Common mistakes

    These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

    1. Applying a default deny with no DNS rule

      Egress to kube-dns is blocked, so every name resolution fails and the symptom looks like a network fault rather than a policy.

      Instead:Always include the DNS egress rule. This generator puts it in for that reason.

    2. Expecting the policy to work on any CNI

      The API server accepts NetworkPolicy objects whether or not the CNI implements them. On one that does not, they are stored and ignored.

      Instead:Confirm the CNI enforces them before relying on any of it.

    3. Adding an allow policy to carve an exception out of a deny

      Policies are additive with no precedence and no deny rule. Traffic is allowed if any policy allows it.

      Instead:Narrow the deny instead, or select a different set of pods.

    How a NetworkPolicy decides what to allow

    A NetworkPolicy is not a firewall rule, it is a whitelist that switches on. Pods are unrestricted until something selects them, and the moment anything does, everything not listed is denied. That switch is the source of nearly every surprise.

    Selecting a pod flips it to deny by default

    There is no ordering, no priority and no deny rule. Policies are purely additive: a pod's permitted traffic is the union of every policy that selects it. But a pod selected by no policy at all is completely open, and a pod selected by one policy is closed to everything that policy does not name. Applying your first policy to a namespace is the disruptive moment, not the tenth.

    no policy selects this pod   -> everything allowed
    one policy selects it,
      policyTypes: [Ingress]     -> ingress: only what is
                                     listed. egress: still
                                     completely open.
      policyTypes: [Ingress,
                    Egress]      -> both now closed

    DNS is the one everybody forgets

    The moment a policy gives a pod an Egress policyType, its outbound traffic is restricted, and DNS is outbound traffic. Without an explicit rule to kube-dns, nothing resolves. The application does not report a DNS failure: it reports that it cannot reach the database, so the investigation starts in the wrong place.

    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - {port: 53, protocol: UDP}
        - {port: 53, protocol: TCP}   # not optional
    
    # TCP matters: any response over 512 bytes falls back
    # to it, which includes SRV records and busy namespaces.

    One list item ANDs, two list items OR

    This is the difference between a correct policy and one far wider than intended, and the two forms differ by a single dash. Inside one item of the from list, namespaceSelector and podSelector must both match. As two separate items, either matching is enough.

    from:
      - namespaceSelector: {matchLabels: {env: prod}}
        podSelector: {matchLabels: {app: web}}
    # AND: pods labelled app=web, in prod namespaces only
    
    from:
      - namespaceSelector: {matchLabels: {env: prod}}
      - podSelector: {matchLabels: {app: web}}
    # OR: EVERY pod in prod namespaces, plus every
    #     app=web pod in this namespace

    Empty, absent, and what each one means

    An empty map is not a blank. podSelector: {} at the top level selects every pod in the namespace, which is how a default-deny is written. Inside a from block the distinction between an empty selector and an omitted one changes the scope from this namespace to all namespaces, and both look like unfinished YAML.

    spec:
      podSelector: {}          every pod in the namespace
      policyTypes: [Ingress]
      # no ingress key at all -> deny all inbound
    
    from:
      - podSelector: {}        every pod in THIS namespace
      - namespaceSelector: {}  every pod in EVERY namespace

    It is the CNI that enforces this, not Kubernetes

    The API server stores a NetworkPolicy whether or not anything implements it. On a cluster running plain flannel, or any CNI without policy support, the object is accepted, appears in kubectl get, and has no effect whatsoever. Calico, Cilium and the managed CNIs from the major clouds do enforce it. There is nothing in the object or in kubectl to tell you which case you are in.

    kubectl get networkpolicy
    NAME         POD-SELECTOR   AGE
    api-policy   app=api        3m
    
    # this output is identical whether the policy is being
    # enforced or completely ignored. Test it by actually
    # trying a connection that should now fail.

    More kubernetes tools

    Kubernetes YAML Generator Answer a few questions, get a manifest Kubernetes YAML Validator Is this YAML valid, and where is it wrong? Kubernetes Rollout & Probe Timing Restart loops, capacity dips and stuck drains Kubernetes Service Checker Will this Service have any endpoints? Kubernetes Network Policy Viewer What can reach what, and what just broke Kubernetes Manifest Diff What actually changed Kubernetes Resource Calculator What these manifests actually reserve Kubernetes RBAC Viewer Who can actually do what Kubernetes Deployment Generator See the capacity dip before you deploy Kubernetes Service Generator port, targetPort, and which one you meant Kubernetes StatefulSet Generator Stable names, and volumes that outlive you Kubernetes QoS Class Calculator And where you sit in the eviction order Kubernetes Node Capacity Planner Allocatable is not capacity Kubernetes Max Pods per Node Calculator The ENI limit, not the 110 default Kubernetes Label Selector Tester Which key failed, not just that one did Kubernetes Taint & Toleration Tester Tolerations permit, they do not attract Kubernetes Resource Name Validator RFC 1123 subdomain, label, or 1035 Kubernetes Label & Annotation Validator Why your image tag is not a legal label Kubernetes CrashLoopBackOff Guide The status is a timer, not a cause Kubernetes TLS Certificate Decoder When it expires, and what it covers Kubernetes ServiceAccount Token Decoder Bound or legacy, and when it dies Kubernetes imagePullSecret Generator The registry URL nobody gets right Kubernetes cert-manager Certificates Issuer scope, and the rate limit that costs a week Kubernetes Flux HelmRelease Generator With the source it cannot work without Kubernetes Helm Chart Generator Chart.yaml, values, and working templates Kubernetes Argo CD Application Generator The defaults that are off, turned on Kubernetes Ingress Generator pathType, and the TLS secret that fails quietly Kubernetes HPA Generator Why it says unknown and never scales Kubernetes SecurityContext Generator Pod level, container level, and which wins Kubernetes Probe Generator How long it gets to start before liveness kills it Kubernetes PVC Generator Access modes your storage can actually do Kubernetes ResourceQuota Generator And the LimitRange that stops it breaking deploys Kubernetes CronJob Generator The fields that decide whether it runs Kubernetes RBAC Generator And what it actually grants Kubernetes PodDisruptionBudget Generator Can this budget ever be satisfied? Kubernetes API Deprecation Checker What breaks on the next upgrade Kubernetes Kubeconfig Viewer Read it without handing it to anyone Kubernetes Quantity Parser What 512Mi, 100m and 1e3 actually mean Kubernetes Multi-Document YAML Splitter One file per object, in apply order Kubernetes .env to ConfigMap & Secret Split the credentials out on the way Kubernetes Secret Decoder See what is actually in there Kubernetes Ingress to Gateway API Which annotations silently stop working Kubernetes Manifest Visualizer What points at what, and what points at nothing Kubernetes Patch Tester Which --type, and what it deletes Kubernetes kubectl JSONPath Tester kubectl's dialect, not generic JSONPath Kubernetes Node Affinity Tester Required excludes, preferred only scores Kubernetes Helm Values Diff A missing key is a third value Kubernetes Pod and Service CIDR Fixed at cluster creation Kubernetes Secret Encoder base64 is not encryption Kubernetes API Version Checker Will this apply on that cluster Kubernetes Go Template Tester Go truthiness is not JavaScript's Kubernetes Cluster Cost Estimator At your rates, not a price table Kubernetes Kustomize Build Transformers run in kustomize's order Kubernetes Helm Chart Validator version is SemVer, appVersion is not

    Elsewhere on the site