Implementing Dual-Stack (IPv4 & IPv6) in Oracle Kubernetes Engine (OKE): Pod Networking and Traffic Flow Explained

As IPv4 exhaustion becomes increasingly real, dual-stack Kubernetes is no longer just an experiment it’s a strategic decision. Recently, I implemented and validated a dual-stack cluster in Oracle Kubernetes Engine on Oracle Cloud Infrastructure, and this article shares the real networking behavior behind it not just configuration steps, but how traffic actually flows.
This is not theory. This is what happens in a live cluster.
What Dual-Stack Really Means in OKE
In a dual-stack Kubernetes cluster, every Pod receives:
One IPv4 address
One IPv6 address
Both addresses are active simultaneously.
This enables:
Backward compatibility with IPv4 systems
Native IPv6 communication
Future-proof cloud networking
In OCI, dual-stack works natively with VCN networking. There is no overlay tunnel involved. Pod IPs are directly routable inside the VCN.
That architectural decision makes a significant difference in how traffic behaves.
How a Pod Receives Both IPv4 and IPv6
When a Pod is scheduled onto a node, the OCI VCN-native CNI allocates IP addresses from the configured Pod subnet.
For example, a single Pod may receive:
IPv4 → 100.0.5.102
IPv6 → fd00:100:0:4:0:6ed9:2497:6dd8
Both addresses are bound to the Pod’s network interface.
To confirm this in a running cluster:
PRATIK_BOR@cloudshell:~ (ap-sydney-1)$ kubectl get pods -A \
> -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,IPv4:.status.podIPs[0].ip,IPv6:.status.podIPs[1].ip
NS NAME IPv4 IPv6
default nginx-568f7cfd68-g4h2c 100.0.5.102 fd00:100:0:4:0:6ed9:2497:6dd8
default nginx-568f7cfd68-pvgct 100.0.5.215 fd00:100:0:4:0:bc9b:fecf:997
default nginx-568f7cfd68-vprr8 100.0.5.106 fd00:100:0:4:0:c05c:cfe5:7593
kube-system coredns-bfd957d6b-ddr79 100.0.5.110 fd00:100:0:4:0:a800:ed61:1c0d
kube-system coredns-bfd957d6b-slxml 100.0.5.104 fd00:100:0:4:0:3717:f114:d94d
kube-system coredns-bfd957d6b-w2tgj 100.0.5.122 fd00:100:0:4:0:d046:deaf:a1f0
kube-system csi-oci-node-rfmkw 100.0.3.90 fd00:100:0:3:0:d02f:752e:66c7
kube-system csi-oci-node-s2thk 100.0.3.117 fd00:100:0:3:0:eab9:9713:9d05
kube-system csi-oci-node-tc5rc 100.0.3.174 fd00:100:0:3:0:d4c0:26f3:8990
kube-system kube-dns-autoscaler-7f9c9ddb55-c4vdd 100.0.5.125 fd00:100:0:4:0:6eee:830e:daf7
kube-system kube-proxy-5cwj5 100.0.3.117 fd00:100:0:3:0:eab9:9713:9d05
kube-system kube-proxy-pb427 100.0.3.90 fd00:100:0:3:0:d02f:752e:66c7
kube-system kube-proxy-zldlk 100.0.3.174 fd00:100:0:3:0:d4c0:26f3:8990
kube-system proxymux-client-g9bhp 100.0.3.174 fd00:100:0:3:0:d4c0:26f3:8990
kube-system proxymux-client-tbqdm 100.0.3.90 fd00:100:0:3:0:d02f:752e:66c7
kube-system proxymux-client-w9cdf 100.0.3.117 fd00:100:0:3:0:eab9:9713:9d05
kube-system vcn-native-ip-cni-8qfhn 100.0.3.117 fd00:100:0:3:0:eab9:9713:9d05
kube-system vcn-native-ip-cni-fqdx7 100.0.3.90 fd00:100:0:3:0:d02f:752e:66c7
kube-system vcn-native-ip-cni-gszjb 100.0.3.174 fd00:100:0:3:0:d4c0:26f3:8990
PRATIK_BOR@cloudshell:~ (ap-sydney-1)$
The output clearly shows both IP versions assigned to the same Pod.
Inside the container:
kubectl exec -it nginx-568f7cfd68-g4h2c -- hostname -i
fd00:100:0:4:0:6ed9:2497:6dd8 100.0.5.102
You’ll see both inet (IPv4) and inet6 entries.
This confirms that dual-stack is not just enabled at the control plane level it is active at the workload level.
Pod-to-Pod Traffic: What Actually Happens
Same Node Communication
When two Pods run on the same node:
Traffic stays local.
Linux networking handles routing internally.
No VCN-level routing occurs.
Dual-stack does not change this behavior. IPv4 and IPv6 packets are both handled locally by the node’s networking stack.
Latency is minimal because packets never leave the host.
Cross-Node Communication
When Pods are on different nodes, the behavior becomes more interesting.
In OCI’s VCN-native networking:
The source Pod sends traffic.
The node routes it directly into the VCN.
The destination node receives it.
The packet is delivered to the target Pod.
There is no overlay tunnel.
There is no encapsulation.
There is no extra hop.
For IPv6 traffic specifically:
OCI routes IPv6 natively.
No NAT is required.
IPv6 packets travel directly using the assigned IPv6 CIDR.
This creates a very clean routing model compared to many overlay-based CNI implementations.
External Traffic Flow (World → Pod)
When exposing a workload using a Kubernetes LoadBalancer service, OCI provisions a native load balancer.
In a dual-stack subnet, that Load Balancer can have:
Public IPv4
Public IPv6
Traffic flow looks like this:
Client → OCI Load Balancer → Node → Pod
If the client connects over IPv6:
IPv6 Client → LB IPv6 → Pod IPv6
This enables true end-to-end IPv6 connectivity without translation.
That’s a significant architectural advantage.'
Pod to External World (Egress)
Outbound traffic behaves differently for IPv4 and IPv6.
IPv4 Egress
Requires NAT Gateway
Private IPv4 → Translated → Public IPv4
IPv6 Egress
No NAT required (if using globally routable IPv6)
Direct routing possible
IPv6 removes an entire NAT layer from the architecture.
This simplifies troubleshooting and reduces stateful dependencies in network design.
Final Thoughts
Dual-stack Kubernetes is no longer experimental.
In OCI, it is stable, practical, and production-ready — provided that:
Subnets are properly designed
IPv6 CIDRs are correctly allocated
Traffic flows are understood
Observability tools are updated
IPv6 adoption is accelerating globally. Running dual-stack today prepares your Kubernetes platform for what’s coming tomorrow.





