> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy network policies with CKS

> Enforce Pod-level network segmentation on CKS clusters.

This tutorial demonstrates how to implement basic network policies on CoreWeave Kubernetes Service (CKS) clusters. These policies segment and secure Pod-to-Pod communication. By the end, you have a working default-deny network policy and a targeted allow rule, validated with test Pods. You learn the rationale behind each step, CoreWeave-specific best practices, and how to validate your configuration.

This tutorial is for platform engineers and cluster operators who need to enforce Pod-level network segmentation on CKS.

## Prerequisites

* **CKS cluster:** You need access to a CKS cluster. CKS clusters use either the Cilium or Calico container network interface (CNI). Cilium enforces network policies with extended Berkeley Packet Filter (eBPF).
* **`kubectl` access:** Ensure `kubectl` is installed and configured for your cluster identity and namespace.

### Create or use an existing namespace

Namespaces provide logical segmentation and isolation in Kubernetes. They are foundational for multi-tenancy and enforcing network policies scoped to individual teams or workloads. This step ensures your resources don't interfere with others and that network policies apply only within your segment.

Replace `[NAMESPACE]` in the following examples with a name relevant to your application.

```bash theme={"system"}
kubectl create ns [NAMESPACE]
```

With a namespace ready, the next step is to deploy the Pods that your network policies govern.

## Deploy sample workloads

Deploy two Pods and a Service:

* `backend`: an NGINX server exposing port `80`, labeled `app: backend`.
* `backend` Service: a stable endpoint that sends port `80` traffic to the `backend` Pod.
* `frontend`: a BusyBox Pod running `sleep`, labeled `app: frontend`.

These two Pods let you demonstrate segmentation: by restricting which Pods can reach `backend`, you exercise least privilege for service access.

```bash theme={"system"}
kubectl apply -n [NAMESPACE] -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: backend
  labels:
    app: backend
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: backend
  ports:
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP
---
apiVersion: v1
kind: Pod
metadata:
  name: frontend
  labels:
    app: frontend
spec:
  containers:
  - name: busybox
    image: busybox
    command: ["sleep", "3600"]
EOF
```

Wait for both Pods to become ready:

```bash theme={"system"}
kubectl wait -n [NAMESPACE] --for=condition=Ready pod/backend pod/frontend --timeout=120s
```

With the workloads running, you can define the network policies that control traffic between them.

## Create a default-deny policy for your namespace

By default, Kubernetes doesn't restrict communication between Pods. Apply explicit Kubernetes network policies for application-level segmentation.

This introductory policy blocks all ingress traffic to Pods in the namespace unless another policy permits it. It leaves egress traffic unchanged so that the sample Pods retain access to DNS and CoreWeave platform services:

```bash theme={"system"}
kubectl apply -n [NAMESPACE] -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
EOF
```

This policy implements default-deny ingress, which supports microsegmentation and helps prevent lateral movement if a Pod is compromised.

Cilium enforces Kubernetes NetworkPolicy rules in the Node kernel using eBPF. On supported Nodes, the DPU provides a separate hardware boundary for infrastructure networking.

With the default-deny policy applied, unsolicited ingress traffic to every Pod in the namespace is now blocked. The next step is to selectively allow the specific traffic your application requires.

## Create an allow policy for frontend to backend access

Among Pod traffic governed by these policies, only the `frontend` Pod can access the `backend` Pod on TCP port `80`.

```bash theme={"system"}
kubectl apply -n [NAMESPACE] -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 80
EOF
```

This policy targets the `backend` Pod and allows ingress traffic on TCP port `80` only from Pods labeled `app: frontend` within the same namespace. All other ingress traffic remains denied.

At this point, your namespace has both a default-deny policy and a targeted allow rule. The following section confirms that these policies work as expected.

## CKS-specific considerations

Depending on when they were provisioned, CKS clusters run Cilium or Calico as the CNI. The platform-services CIDR guidance applies to both CNIs. The remaining rules in this section apply only to Cilium-based clusters. For the full Cilium reference, see [Cilium network policy on CKS: cluster-specific patterns](/products/networking/cilium-network-policy-cks-patterns).

* **Allow the CoreWeave platform services CIDR before denying egress.** If you extend this tutorial with a default-deny egress policy, allow egress to `100.124.0.0/18` first. This range covers the Kubernetes API server, cluster DNS, and other CoreWeave-managed infrastructure. Without the allow rule, Pods can't reach these platform services.

* **Target `node-local-dns` for DNS egress, not `kube-dns`.** CKS uses NodeLocal DNSCache. In a `CiliumNetworkPolicy`, the DNS egress selector must use the `k8s:` label prefix:

  ```yaml theme={"system"}
  egress:
    - toEndpoints:
        - matchLabels:
            k8s:k8s-app: node-local-dns
            k8s:io.kubernetes.pod.namespace: kube-system
  ```

  Omitting the `k8s:` prefix or targeting `kube-dns` doesn't match on CKS.

* **`toFQDN` rules require a Layer 7 feature flag.** Egress rules that match a fully qualified domain name use Cilium's Layer 7 DNS proxy, which depends on the `enable-bpf-tproxy` setting being `false`. You can't change this yourself. Open a support ticket to request it for your cluster. Applying a `toFQDN` policy before the flag is set can break DNS resolution entirely.

* **Roll out with audit mode first.** Cilium audit mode logs policy violations without enforcing them, so you can validate a policy against real traffic before enforcing it. To enable audit mode, follow the audit mode instructions in that reference.

## Validate your network policies

Test your policies to confirm that they have the intended effect:

1. Enter the `frontend` Pod and attempt to reach `backend`:

   ```bash theme={"system"}
   kubectl exec -n [NAMESPACE] frontend -- sh -c "wget -qO- http://backend:80"
   ```

   You should receive the NGINX welcome message.

2. Deploy a third Pod to test isolation:

   ```bash theme={"system"}
   kubectl run other --rm -i -t -n [NAMESPACE] --image=busybox --restart=Never -- sh
   ```

   Inside this shell, run:

   ```bash theme={"system"}
   wget -qO- http://backend:80
   ```

   The connection should time out, demonstrating that the policy doesn't allow this Pod to access `backend`.

3. Inspect the network policy configuration:

   Confirm that Kubernetes stored the expected selectors and rules:

   ```bash theme={"system"}
   # List network policies
   kubectl get networkpolicy -n [NAMESPACE]

   # Inspect policy configuration
   kubectl describe networkpolicy deny-all -n [NAMESPACE]
   kubectl describe networkpolicy allow-frontend-to-backend -n [NAMESPACE]
   ```

   You should see both policies with the expected Pod selectors and rules.

   If Hubble is enabled on your cluster, use it to inspect policy verdicts. Hubble isn't enabled by default. For help enabling it, contact [CoreWeave Support](/support).

With your network policies in place and validated, you've implemented microsegmentation. The cluster CNI enforces these application-level controls. On supported Nodes, DPU-based infrastructure controls provide an additional hardware boundary. For additional audit capabilities, deploy Cilium Tetragon for [eBPF-based observability](/security/tutorials/ebpf-observability) or Falco for runtime threat detection.
