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

# 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        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

        5. 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.

        6. Choose or create the **VCN** and **subnets** as prompted (node subnets and pod subnet if requested).

        #### 2.2. Enable Network Policy (CNI plugin support)

        7. 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).

        8. Finish configuring:
           * Configure **Node Pools** (shape, number of nodes, etc.).
           * Click **Create Cluster**.

        9. 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:
           ```bash theme={null}
           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):
           ```yaml theme={null}
           apiVersion: networking.k8s.io/v1
           kind: NetworkPolicy
           metadata:
             name: deny-all
             namespace: default
           spec:
             podSelector: {}
             policyTypes:
               - Ingress
           ```
        2. Apply it:
           ```bash theme={null}
           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.
      </Accordion>

      <Accordion title="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)

        ```bash theme={null}
        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:

        ```bash theme={null}
        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):

        ```json theme={null}
        "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

        ```bash theme={null}
        oci ce cluster update \
          --cluster-id "$CLUSTER_ID" \
          --from-json file://cluster-update.json \
          --force
        ```

        Wait for the work request to complete:

        ```bash theme={null}
        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:

        ```bash theme={null}
        oci ce work-request get --work-request-id "<work_request_ocid>"
        ```

        ***

        ### 5. Verify network policy support is enabled

        Re-check the options:

        ```bash theme={null}
        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:

        ```bash theme={null}
        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.
      </Accordion>

      <Accordion title="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:
           ```bash theme={null}
           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_config` → `type = "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)

        ```python theme={null}
        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`:

        ```python theme={null}
        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)

        ```python theme={null}
        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`):

           ```python theme={null}
           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:
             ```bash theme={null}
             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:

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

        Apply with:

        ```bash theme={null}
        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:

        ```python theme={null}
        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`.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        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.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
