Description

This rule verifies that the pod (cluster) network CIDR configured for a DOKS cluster falls within private, non-routable RFC 1918 address space rather than a publicly routable range. On DigitalOcean this is the cluster_subnet used for pod addressing in VPC-native clusters.

DigitalOcean requires VPC-native cluster and service subnets to follow RFC 1918 and not overlap with each other or with any VPCs or VPC-native clusters in the team. Using private space for pod addressing keeps internal cluster traffic off public address ranges and avoids collisions with legitimate external addresses.

  • Clusters whose cluster_subnet (pod CIDR) is outside RFC 1918 private ranges.

  • Pod subnets that overlap with peered VPC ranges.

  • Legacy clusters configured before VPC-native networking whose ranges warrant review.

Rationale

Pod networks carry internal, east-west cluster traffic. Assigning them from public IP space blurs the line between internal and internet-routable addresses, invites routing ambiguity, and can cause conflicts when the cluster peers with other VPCs. Keeping the pod CIDR inside RFC 1918 space ensures internal addressing stays clearly private and non-routable from the internet.

Private, non-overlapping ranges are also what make DigitalOcean's VPC-native transparent pod-to-VPC communication work, so this is both a security hygiene and a correct-operation concern.

  • Keeps pod addressing clearly internal and non-internet-routable.

  • Prevents CIDR collisions with peered VPCs and other clusters.

Impact

Pros:

  • Internal cluster traffic uses unambiguous private addressing.

  • Enables clean, translation-free peering with node and other VPCs.

  • Reduces the risk of accidental exposure through misrouting.

Cons:

  • The cluster subnet is set at creation and is generally immutable, so fixing a bad range means rebuilding the cluster.

  • Requires up-front IP address planning to avoid overlaps across VPCs and clusters.

  • VPC-native networking requires Kubernetes 1.31+ (and doctl 1.115.0+).

Default Value

As of 12 December 2024, new clusters created with Kubernetes 1.31+ use VPC-native networking and require RFC 1918 subnets; the specific default CIDRs are not documented, so verify the value in your account.

Pre-Requisite

  • Control Panel access to view the cluster's networking, or an API token / authenticated doctl (v1.115.0+).

  • An IP address plan of your RFC 1918 ranges to check for overlaps.

  • For remediation: ability to create a replacement cluster, since the subnet is immutable after creation.

Remediation

Test Plan

Using the DigitalOcean Control Panel:

  1. Sign in to cloud.digitalocean.com and open Kubernetes.

  2. Select the cluster and open its Overview/Settings to view the cluster (pod) subnet, or inspect it via the API below.

  3. Confirm the pod/cluster CIDR sits within 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16.

  4. Pass: the cluster_subnet is a private RFC 1918 range.

  5. Fail: the cluster_subnet uses a public (non-RFC 1918) range.

Using doctl or the API:

Read the cluster_subnet and confirm it is within RFC 1918 space.

doctl kubernetes cluster get <cluster-id> --format Name,ClusterSubnet
curl -s -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/kubernetes/clusters/$CLUSTER_ID" | jq '.kubernetes_cluster.cluster_subnet'

Pass if cluster_subnet falls within 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16. Fail if it falls outside those RFC 1918 ranges.

Implementation Steps

Using the DigitalOcean Control Panel:

  1. The cluster (pod) subnet is fixed at creation and cannot be edited on a running cluster.

  2. To remediate, create a new cluster and specify a private cluster subnet, then migrate workloads.

  3. In the Create Kubernetes Cluster flow (or via doctl), set the VPC-native cluster subnet to an RFC 1918 range such as 192.168.0.0/16.

Using doctl or the API:

Cluster subnet is immutable, so remediation is create-new-then-migrate; set the private subnet at creation.

doctl kubernetes cluster create <new-name> --region nyc1 --version 1.31 --node-pool "name=pool1;size=s-2vcpu-2gb;count=3" --cluster-subnet "192.168.0.0/16" --service-subnet "172.16.0.0/19"
curl -s -X POST -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" -H 'Content-Type: application/json' -d '{"name":"<new-name>","region":"nyc1","version":"1.31","cluster_subnet":"192.168.0.0/16","service_subnet":"172.16.0.0/19","node_pools":[{"size":"s-2vcpu-2gb","count":3,"name":"pool1"}]}' "https://api.digitalocean.com/v2/kubernetes/clusters"

Backout Plan:

  1. Keep the original cluster running until workloads are validated on the replacement.

  2. If the new range causes problems, cut traffic back to the original cluster.

  3. Delete the replacement cluster only after confirming the original is serving correctly.

References:

  1. DOKS - Create clusters (VPC-native networking, subnets)

  2. DOKS - Features (networking)

  3. RFC 1918 - Private address allocation