Skip to main content

OCI OKE CNI Plugin Should Support Network Policies

More Info:

The clusters CNI plugin should support Kubernetes NetworkPolicy enforcement (for example, OCI VCN-Native Pod Networking or Flannel with a policy-aware add-on). Without this support, NetworkPolicy resources are accepted but never enforced.

Risk Level

Medium

Address

Compliance, Security

Compliance Standards

  • CIS OKE

Triage and Remediation

Remediation

Using Console

To have the OKE CNI plugin support Kubernetes NetworkPolicies, the cluster must be:

  • Using VCN-native (OCI VCN CNI) networking, and
  • Have Network Policy enabled at cluster creation time.

This cannot be retroactively enabled on an existing non–VCN-native cluster; you must create a new cluster with the correct options, then migrate workloads.


1. Check your current cluster networking mode

  1. In the OCI Console, go to: Developer Services → Kubernetes Clusters (OKE).
  2. Select your Cluster.
  3. On the Cluster Details page, check:
    • Cluster Type / Networking:
      • If it says VCN-native or similar: good.
      • If it says Flannel or Overlay: you must create a new cluster; network policies aren’t supported on this CNI.

If your cluster is not VCN-native, skip to section 2 (create a new cluster).


1a. If cluster is already VCN-native: verify Network Policy add-on

For recent console versions, Network Policy is controlled via an add-on:

  1. In your Cluster Details page, check the Add-ons or Add-ons Management tab (name may vary).
  2. Look for something like Network Policy or Kubernetes Network Policy:
    • If it is Enabled / Installed, your CNI already supports NetworkPolicies. You just need to apply NetworkPolicy objects with kubectl.
    • If it is Disabled / Not installed and the UI allows toggling:
      1. Click Edit Add-ons (or similar).
      2. Enable the Network Policy add-on.
      3. Save/Apply and wait until the status is Active.

If you do not see any way to enable it on an existing VCN-native cluster, Oracle’s current restriction is that it must be turned on at cluster creation; then proceed to section 2 and create a new cluster.


2. Create a new OKE cluster with CNI network policies enabled (OCI Console)

  1. In the OCI Console, go to Developer Services → Kubernetes Clusters (OKE).
  2. Click Create Cluster.
  3. Choose the Compartment.
  4. Select Quick Create or Custom Create:
    • Custom Create gives explicit control; recommended.

2.1. Configure networking as VCN-native

  1. In the Cluster Configuration step:

    • Ensure Kubernetes version is a supported, recent version.
    • Under Networking (or Network Type):
      • Select VCN-native (or “Use existing VCN with native pod networking” / similar wording).
      • Do not select Flannel/Overlay networking.
  2. Choose or create the VCN and subnets as prompted (node subnets and pod subnet if requested).

2.2. Enable Network Policy (CNI plugin support)

  1. In the Add-ons or Optional Features section (typically later in the wizard):

    • Locate Network Policy / Kubernetes Network Policy.
    • Check/enable the Network Policy option.
    • Confirm any related settings (there are typically no extra fields; it’s just On/Off).
  2. Finish configuring:

    • Configure Node Pools (shape, number of nodes, etc.).
    • Click Create Cluster.
  3. Wait for:

    • Cluster status: Active
    • Node Pools status: Active
    • Add-ons: Network Policy shows Active / Installed.

3. Migrate workloads from old cluster (if applicable)

  1. From your existing cluster:
    • Export Kubernetes manifests (Deployments, Services, etc.) with kubectl get ... -o yaml or from your Git/CI.
  2. Point kubectl to the new cluster (download kubeconfig from the cluster details page via Access Cluster).
  3. Apply the manifests:
    kubectl apply -f your-apps/
  4. Configure NetworkPolicy objects in the new cluster as needed.
  5. Update DNS, ingress, or external references to point to the new cluster; then decommission the old cluster when traffic has drained.

4. Validate NetworkPolicy support

  1. Create a simple NetworkPolicy in the new cluster (e.g., deny all ingress to a namespace):
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
    name: deny-all
    namespace: default
    spec:
    podSelector: {}
    policyTypes:
    - Ingress
  2. Apply it:
    kubectl apply -f deny-all.yaml
  3. Verify that traffic to pods in that namespace is blocked as expected from other pods/namespaces. If behavior enforces the policy, the OKE CNI Network Policy support is working.

If you tell me your cluster’s current networking type (VCN-native vs Flannel) from the console, I can give a more exact “change vs recreate” path.

Using CLI

In OKE, Kubernetes NetworkPolicy is enforced only when the OKE CNI plugin has network policy enabled on the cluster. That is controlled in the cluster’s options via the OCI CLI.

Below is the minimal, practical way to do this via OCI CLI.


1. Prerequisites

  • OCI CLI configured with a user that can manage OKE clusters.
  • The cluster is VCN-native (OCI VCN IP Native) or at least using an OKE CNI version that supports network policies.
  • You know your:
    • Compartment OCID
    • Cluster OCID
    • VCN subnets for pods/services if required

2. Inspect current cluster options (check if network policy is enabled)

CLUSTER_ID="<your_cluster_ocid>"

oci ce cluster get \
--cluster-id "$CLUSTER_ID" \
--query 'data."options"' \
--output json

Look for a structure under options (or options.kubernetesNetworkConfig / options.networkConfig) related to network policy, for example:

  • networkPolicyConfig.isNetworkPolicyEnabled
  • or kubernetesNetworkConfig.networkPolicyConfig.isNetworkPolicyEnabled

If it’s false or missing, you need to update.


3. Generate the JSON skeleton for a cluster update

This avoids guessing field names:

oci ce cluster update --generate-full-command-json-input > cluster-update.json

Open cluster-update.json. Find the options section. Within it you should see or add the network policy part, for example (schema names may differ slightly per OKE version; align with what you saw in step 2):

"options": {
"kubernetesNetworkConfig": {
"podsCidr": "10.244.0.0/16",
"servicesCidr": "10.96.0.0/16",
"networkPolicyConfig": {
"isNetworkPolicyEnabled": true
}
}
/* keep all other existing fields as they were */
}

Key rules:

  • Do not remove or change other existing fields you don’t intend to modify.
  • Only set "isNetworkPolicyEnabled": true within the appropriate network config section that already exists.

If your generated JSON instead shows networkConfig or similar, mirror that exact structure and field name; the key is to set the isNetworkPolicyEnabled flag to true in the right place.


4. Apply the update to enable network policy

oci ce cluster update \
--cluster-id "$CLUSTER_ID" \
--from-json file://cluster-update.json \
--force

Wait for the work request to complete:

oci ce work-request list \
--compartment-id "<your_compartment_ocid>" \
--query "data[?\"operation-type\"=='CLUSTER_UPDATE']"

or get the last work request ID from the previous command’s output and:

oci ce work-request get --work-request-id "<work_request_ocid>"

5. Verify network policy support is enabled

Re-check the options:

oci ce cluster get \
--cluster-id "$CLUSTER_ID" \
--query 'data."options"' \
--output json

Confirm that the network policy flag (e.g., isNetworkPolicyEnabled) is now true.


6. Use Kubernetes NetworkPolicy resources

Once enabled, you can apply standard Kubernetes NetworkPolicy YAML:

kubectl apply -f your-network-policy.yaml

These policies will now be enforced by the OKE CNI plugin.


If your generated JSON doesn’t show any network-policy-related field at all, your cluster/OCI CLI version may not yet expose that feature; in that case, upgrade the cluster to a supported version or recreate the cluster with the correct options, then repeat the steps above.

Using Python

For OKE, network policies are only supported when using the OCI VCN-Native CNI with network policy mode enabled. You cannot “flip a switch” on an existing non‑VCN‑native cluster; you must create (or already have) a cluster with the right CNI options.

Below are step‑by‑step remediation instructions using Python and the OCI SDK.


1. Prerequisites

  1. Install/upgrade SDK:

    pip install --upgrade oci
  2. Have a configured OCI CLI/profile (used by the SDK): ~/.oci/config with a profile, e.g. [DEFAULT].

  3. Collect:

    • compartment_id
    • vcn_id
    • kubernetes_version
    • cluster_name
    • Subnets for:
      • endpoint_subnet_id (API endpoint)
      • service_lb_subnet_ids (Service LB subnets)

2. Understand the Required CNI Settings

For OKE to support Kubernetes NetworkPolicies with the OCI CNI, you need a cluster with:

  • network_configtype = "VCN_NATIVE"
  • options.kubernetes_network_config.pod_network_options including:
    • cni_type = "OCI_VCN_IP_NATIVE"
    • nsg_mode = "POLICY" (this turns on network-policy mode)

These options are immutable on an existing cluster; you must create a new cluster with them, then migrate workloads.


3. Create a New OKE Cluster with Network Policy–Capable CNI (Python)

import oci
from oci.container_engine import ContainerEngineClient
from oci.container_engine.models import (
CreateClusterDetails,
ClusterCreateOptions,
KubernetesNetworkConfig,
ClusterPodNetworkOptionDetails,
ClusterNetworkConfig
)

# ----- CONFIGURE THIS BLOCK -----
config = oci.config.from_file("~/.oci/config", "DEFAULT")

compartment_id = "<your_compartment_ocid>"
vcn_id = "<your_vcn_ocid>"
cluster_name = "oke-with-network-policies"
kubernetes_version = "v1.29.1" # example; use a supported version

endpoint_subnet_id = "<endpoint_subnet_ocid>" # private or public
service_lb_subnet_ids = ["<lb_subnet1_ocid>", "<lb_subnet2_ocid>"]
# -------------------------------

ce_client = ContainerEngineClient(config)

# Define pod network options for OCI VCN IP Native + Network Policy mode
pod_network_options = ClusterPodNetworkOptionDetails(
cni_type="OCI_VCN_IP_NATIVE",
nsg_ids=[], # optionally attach NSGs; can be managed later
nsg_mode="POLICY" # enables network policy mode
)

k8s_network_config = KubernetesNetworkConfig(
pods_cidr=None, # not required for VCN-native pod networking
services_cidr=None # optional; can be specified if needed
)

network_config = ClusterNetworkConfig(
type="VCN_NATIVE",
vcn_id=vcn_id,
kubernetes_network_config=k8s_network_config,
pod_network_options=[pod_network_options]
)

cluster_options = ClusterCreateOptions(
service_lb_subnet_ids=service_lb_subnet_ids
)

create_cluster_details = CreateClusterDetails(
name=cluster_name,
compartment_id=compartment_id,
vcn_id=vcn_id,
kubernetes_version=kubernetes_version,
endpoint_config={
"isPublicIpEnabled": False, # or True if you want public endpoint
"subnetId": endpoint_subnet_id
},
options=cluster_options,
network_config=network_config
)

response = ce_client.create_cluster(create_cluster_details)
cluster_id = response.data.id
print("Creating cluster:", cluster_id)

Optionally, wait for the cluster to become ACTIVE:

from oci.waiter import wait_until

get_cluster_response = ce_client.get_cluster(cluster_id)
wait_until(ce_client, get_cluster_response, 'lifecycle_state', 'ACTIVE')
print("Cluster is ACTIVE:", cluster_id)

4. Create Node Pools for the New Cluster (Python)

from oci.container_engine.models import CreateNodePoolDetails, NodePoolNodeConfigDetails

node_image_id = "<node_image_ocid>" # an OKE-supported node image
node_shape = "VM.Standard3.Flex" # example
node_subnet_ids = ["<worker_subnet_ocid>"]

node_config = NodePoolNodeConfigDetails(
placement_configs=[{"availabilityDomain": "<AD-1>", "subnetId": node_subnet_ids[0]}],
size=3 # number of nodes
)

create_node_pool_details = CreateNodePoolDetails(
compartment_id=compartment_id,
cluster_id=cluster_id,
name="node-pool-with-network-policies",
kubernetes_version=kubernetes_version,
node_shape=node_shape,
node_image_id=node_image_id,
node_config_details=node_config
)

np_response = ce_client.create_node_pool(create_node_pool_details)
node_pool_id = np_response.data.id
print("Creating node pool:", node_pool_id)

get_np_response = ce_client.get_node_pool(node_pool_id)
wait_until(ce_client, get_np_response, 'lifecycle_state', 'ACTIVE')
print("Node pool is ACTIVE:", node_pool_id)

5. Migrate Workloads from the Old Cluster

  1. Get kubeconfig for the new cluster (can also be done with the Python SDK using ce_client.create_kubeconfig):

    from oci.container_engine.models import CreateClusterKubeconfigDetails

    details = CreateClusterKubeconfigDetails(token_version="2.0.0")
    kubeconfig_response = ce_client.create_kubeconfig(cluster_id, details)
    with open("kubeconfig-new-oke", "wb") as f:
    f.write(kubeconfig_response.data.content)
  2. Use kubectl to:

    • Export manifests from the old cluster (or use your IaC manifests/Helm charts).
    • Apply them to the new cluster:
      KUBECONFIG=./kubeconfig-new-oke kubectl apply -f <your-manifests>
  3. Cut traffic over (e.g., update DNS / load balancer targets if necessary).

  4. Decommission the old cluster and its node pools once traffic is fully moved.


6. Apply Kubernetes NetworkPolicies

Now that your cluster uses the OCI VCN-native CNI in POLICY mode, you can define NetworkPolicies as usual:

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

Apply with:

KUBECONFIG=./kubeconfig-new-oke kubectl apply -f deny-all.yaml

7. Verifying CNI and Network Policy Support (Python snippet)

To confirm the cluster is using the correct CNI options:

cluster = ce_client.get_cluster(cluster_id).data

print("Network type:", cluster.network_config.type)
for opt in cluster.network_config.kubernetes_network_config.pod_network_options:
print("CNI type:", opt.cni_type, "NSG mode:", opt.nsg_mode)

You should see:

  • Network type: VCN_NATIVE
  • CNI type: OCI_VCN_IP_NATIVE
  • NSG mode: POLICY

If you provide your existing cluster’s details (network type and pod_network_options), I can tailor a Python migration script to mirror its settings while enabling NSG_MODE=POLICY.

Using Terraform
resource "oci_containerengine_cluster" "OKE_CLUSTER" {
# Replace with your existing cluster arguments
name = "OKE_CLUSTER_NAME" # set to your cluster name
compartment_id = "COMPARTMENT_OCID" # set to your compartment OCID
vcn_id = "VCN_OCID" # set to your VCN OCID
kubernetes_version = "K8S_VERSION" # e.g. "v1.29.1"

# Other required cluster arguments (endpoint_config, kms_key_id, etc.) go here

options {
# Ensure the CNI plugin supports NetworkPolicy:
# Set to OCI VCN-native pod networking, which is policy-aware.
cluster_pod_network_options {
cni_type = "OCI_VCN_IP_NATIVE"
}

# keep/merge any other options you already configure here
}
}

Setting cni_type = "OCI_VCN_IP_NATIVE" enables a CNI that enforces Kubernetes NetworkPolicy. Changing the CNI type on an existing OKE cluster forces replacement; terraform apply will destroy and recreate the cluster to apply this setting, causing an outage for workloads on that cluster.

Verification: terraform plan should show options[0].cluster_pod_network_options[0].cni_type changing from its current value (for example "FLANNEL_OVERLAY" or null) to "OCI_VCN_IP_NATIVE", with the plan indicating that the oci_containerengine_cluster resource will be replaced.