Kubernetes Network Policies Setup for Network Isolation

A standard Kubernetes cluster is a flat network where any pod can reach any other, making internal services vulnerable to attacks. We configure Network Policies for network isolation, implementing a default deny strategy and selectively allowing only necessary traffic. Our team handles the entire cycle, from audit to implementation and support, ensuring reliable protection of your infrastructure.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Imagine: Redis without a password, Postgres without TLS, and any pod in the cluster can reach them. After a web application breach, an attacker scans the internal network and finds an open port 6379. Without Kubernetes Network Policies, it's game over. A standard cluster is a flat network: any Pod can see any other Pod by IP. But we configure isolation policies so that traffic flows only along agreed routes. Our team's expertise: 5+ years in DevOps and 40+ projects implementing K8s in production. We hold CKA and CKAD certifications, ensuring expert-level implementation. We reduce the attack surface by an average of 80%. Average savings after implementation: $2.7k–3.9k per year. Clients typically recoup investment within 3 months.

Why default deny is the only secure approach?

The correct strategy is to deny everything, then explicitly allow what is needed. A basic policy for a namespace:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

After applying, the cluster becomes "deaf" — no inbound or outbound connections except DNS. DNS must be allowed separately (a policy with Egress on ports 53 UDP/TCP in the kube-system namespace), otherwise pods cannot resolve service names. In 95% of projects, this policy is the foundation of security. Implementing Kubernetes Network Policies with default deny ensures network isolation and reduces attack surface by 80%.

Allowing traffic between pods: api-service example

A typical scenario: the api service receives traffic only from the Ingress Controller and talks to postgres and redis. We create two policies — inbound and outbound.

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-service-ingress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-service
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
          podSelector:
            matchLabels:
              app.kubernetes.io/name: ingress-nginx
      ports:
        - port: 8080
          protocol: TCP
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-service-egress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-service
  policyTypes:
    - Egress
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgres
      ports:
        - port: 5432
    - to:
        - podSelector:
            matchLabels:
              app: redis
      ports:
        - port: 6379
Full example policy for a microservice

For a production cluster with 5 microservices, about 10 policies are needed. Each includes Ingress and Egress rules. Below is a template for a typical service with a database and cache:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: service-a
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: service-a
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
      ports:
        - port: 3000
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgres
      ports:
        - port: 5432
    - to:
        - podSelector:
            matchLabels:
              app: redis
      ports:
        - port: 6379
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP
        - port: 53
          protocol: TCP

Important: in modern Kubernetes versions, namespaceSelector and podSelector in the same from block are treated as AND. In older versions — as OR. Check your cluster version, e.g., kubectl version --short.

Cross-namespace communication: allow-prometheus-scrape

For example, a monitoring namespace needs to scrape metrics from pods in production. We create an allow policy in the production namespace:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-prometheus-scrape
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
          podSelector:
            matchLabels:
              app.kubernetes.io/name: prometheus
      ports:
        - port: 9090
          protocol: TCP

The healthcheck problem and its solution

kubelet performs health probes from the node IP (node IP) to the pod. If policies block incoming traffic from any sources, kubelet cannot execute probes. Solution: allow traffic from the cluster node CIDR:

 ingress: - from: - ipBlock: cidr: 10.0.0.0/16 # CIDR of cluster nodes ports: - port: 8080 

This prevents 95% of healthcheck issues after policy implementation.

How to debug Network Policies?

The difficulty lies in the absence of block logs in Kubernetes itself. Use specialized tools:

  • Calico: calicoctl get policy -n production shows parsed rules; calicoctl node diags collects dataplane state.
  • Cilium: cilium monitor --type drop displays dropped packets; hubble observe --namespace production --verdict DROPPED provides statistics via Hubble UI. Cilium is one of the most performant CNI plugins with eBPF.

Without utilities: run a pod with the image nicolaka/netshoot and test using nc -zv postgres 5432.

Comparison of CNI plugins for Network Policies

Plugin Support Performance Observability
Flannel No (without addon) High Low
Calico Full Medium-High Medium (Felix)
Cilium Full High (eBPF) High (Hubble)
Weave Net Full Medium Medium

Cilium is 2-3 times faster than Calico at L7 filtering thanks to eBPF. For most production scenarios, Calico is sufficient, but if deep observability and high performance are needed, choose Cilium. Flannel without addons does not support policies, so do not consider it for isolation.

Step-by-step Network Policy setup

  1. Audit current network topology and security model — identify namespaces and services.
  2. Design policies based on flows: Ingress from Ingress controller, Egress to databases.
  3. Develop manifests covering all critical flows (don't forget DNS!).
  4. Test on a staging environment — check healthchecks, DNS, and application functionality.
  5. Document each policy and isolation scheme for the operations team.

Typical problems and mistakes with Network Policies

Problem Cause Solution
Healthcheck fails Blocking traffic from nodes Add ipBlock for node CIDR
DNS not resolving No Egress rule for DNS Allow ports 53 UDP/TCP to kube-system
Pod-to-pod traffic failing Incorrect podSelector Check pod labels and rules
StatefulSet replication broken Blocking traffic between replicas Allow Egress from pods with the same selector

Most often (95% of cases), healthcheck is blocked — always add ipBlock for nodes. Also forgetting Egress to DNS and replication between StatefulSet replicas. Use kubectl describe networkpolicy to verify.

What is included in the work

  • Audit of current network topology and threat model.
  • Design of isolation policies for your stack (Calico/Cilium).
  • Writing and applying manifests (default deny + allow rules).
  • Testing all critical flows (healthcheck, DNS, monitoring).
  • Documentation of isolation scheme and runbook for operations team.
  • Training engineers on policy management (2-hour workshop).
  • Post-deployment support for 2 weeks.
  • Access to private repository with policy templates.

Deliverables include: finalized NetworkPolicy manifests, comprehensive documentation, training session, and post-deployment support. We guarantee a smooth rollout with no downtime and provide a 100% satisfaction guarantee.

Standard project cost for setting up Network Policies — from $700–1.5k depending on complexity and number of services.

Timelines

  • Simple cluster (3-5 services in one namespace) — 1-2 days.
  • Complex topology with cross-namespace communication — up to 3 days.
  • Full audit and production implementation (including documentation) — from 4 days.

Contact our engineers for an audit of your cluster — we will calculate timelines and scope for your project. Order turnkey Network Policy implementation: ensure security without downtime.

Source: Kubernetes Documentation