Deploy a Custom Default Pod Network
SUMMARY Starting in release 22.4, Juniper Cloud-Native Contrail Networking supports a custom Default Pod Network. The custom Default Pod Network enables Kubernetes to create pods with individual pod networks on a per-namespace or per-pod basis.
Custom Pod Network Overview
In traditional Kubernetes, the Default Pod Network is a single Classless Interdomain Routing (CIDR) used by all pods in the cluster, regardless of namespace. This approach doesn't allow for network layer segmentation between pods because Kubernetes assigns IPs from a shared CIDR. CN2 addresses this drawback with isolated namespaces. Isolated namespaces enable Kubernetes to create new default pod and service networks on a per-namespace basis. This means that when Kubernetes creates a new pod or service, that pod or service attaches to a default network within an individual isolated namespace. Isolated namespaces ensure network isolation between pods and services.
CN2 release 22.4 improves on this feature by enabling Kubernetes to create pods with
individual pod networks on a per-pod basis. Custom Default Pod Networks provide their own
VirtualNetworks
(VNs) and Subnets. CN2 assigns pod IPs based on the
Subnet parameters of a given Custom Default Pod Network. As a result of the Custom Default
Pod Network, you can create pods with their own networks in a given namespace. In other
words, CN2 supports network isolation at the namespace level and pod level.
Deploy a Custom Default Pod Network
You can deploy a Custom Default Pod Network using the following methods:
-
Define a
VirtualNetwork
as a Custom Default Pod Network: If you manually create aVirtualNetwork
object, you must set the field "podNetwork: true
" on the VirtualNetwork's spec. This field designates the new VN as the Custom Default Pod Network.The following is an example of a
VirtualNetwork
designated as a Custom Default Pod Network.apiVersion: core.contrail.juniper.net/v2 kind: VirtualNetwork metadata: namespace: cpn-snat name: cpn1 spec: podNetwork: true fabricSNAT: true v4SubnetReference: apiVersion: core.contrail.juniper.net/v2 kind: Subnet namespace: cpn-snat name: cpn1-sn
-
Install a Network Attachment Definiton (NAD) with "
podNetwork: true
" set at thejuniper.net/networks
annotation to create a Custom Default Pod Network: If you create this NAD, the NAD controller automatically creates a VN and sets the "podNetwork: true
" field duringVirtualNetwork
creation.The following is an example of a NAD designated as a Custom Default Pod Network.
apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: namespace: cpn-bgpaas name: cpn1 annotations: juniper.net/networks: | { "ipamV4Subnet": "140.140.140.0/24", "podNetwork": true } spec: config: | { "cniVersion": "0.3.1", "name": "contrail-k8s-cni", "type": "contrail-k8s-cni" }
-
Specify a Custom Default Pod Network per namespace: You can designate a Custom Pod Network on a per-namespace basis if all pods within a namespace use that network as the pod network. The
Namespace
annotationnet.juniper.contrail.podnetwork: network-namespace/network-name
designates the desired network as the Custom Pod Network.The following YAML section shows an example of an annotation with a Custom Pod Network defined for a namespace.
apiVersion: v1 kind: Namespace metadata: name: custom-podnet annotations: net.juniper.contrail.podnetwork: custom-podnet/ns-level-custom-podnet
Note:You don't need to specify a NAD annotation for pods within a namespace if this namespace uses the same network as the primary interface (eth0). In other words, since the namespace specifies a network with an annotation, pods within that namespace don't need to specify that same network.
Note:The annotation of a namespace must be present when you create the namespace. You cannot update the annotation on a namespace to change its network. You must recreate the namespace to change its network. If
kubemanager
detects an update to the Custom Pod Network annotation within a namespace,kubemanager
flags that namespace and any pod created within that namespace after the update does not start. Reverting the update removes the flag and the pods launch normally. -
Specify a Custom Default Pod Network per pod: In order to designate a Custom Pod Network on a per-pod basis, you must specify the following key value pair in the
cni-args
of aNetworkSelectionElement
:"net.juniper.contrail.podnetwork": true
.Note:You can only specify this key value pair once. If you specify this pair in more than one
cn-args
entry, an error occurs. -
Specify a Custom Default Pod Network for services: You can enable a service to select a pod that uses a Custom Default Pod Network. You must specify the desired pod network in the annotations of your
Service
YAML. The annotation format is:network-namespace/network-name
. The following YAML section is an example of aService
YAML with a designated Custom Pod Network.apiVersion: v1 kind: Service metadata: name: custom-podnet-svc namespace: custom-podnet annotations: net.juniper.contrail.podnetwork: custom-podnet/pod-level-custom-podnet
The following example YAML shows a namespace, VirtualNetwork
, and pod with
Custom Default Pod Networks defined.
apiVersion: v1 kind: Namespace metadata: name: cpn-intra-network-test-vn annotations: net.juniper.contrail.podnetwork: cpn-intra-network-test-vn/vn --- apiVersion: core.contrail.juniper.net/v1 kind: Subnet metadata: namespace: cpn-intra-network-test-vn name: vn-sn spec: cidr: 15.15.15.0/24 --- apiVersion: core.contrail.juniper.net/v1 kind: VirtualNetwork metadata: namespace: cpn-intra-network-test-vn name: vn spec: podNetwork: true v4SubnetReference: apiVersion: core.contrail.juniper.net/v1 kind: Subnet namespace: cpn-intra-network-test-vn name: vn-sn --- apiVersion: v1 kind: Pod metadata: name: ns-level-cpn-pod namespace: cpn-intra-network-test-vn spec: containers: - name: toolbox image: svl-artifactory.juniper.net/atom-docker/cn2/bazel-build/dev/netshoot:v1 imagePullPolicy: IfNotPresent command: ["bash", "-c", "while true; do sleep 60s; done"] securityContext: capabilities: add: - NET_ADMIN privileged: true tolerations: - key: "key" operator: "Equal" value: "value" effect: "NoSchedule" --- apiVersion: v1 kind: Pod metadata: name: pod-level-cpn-pod namespace: cpn-intra-network-test-vn annotations: k8s.v1.cni.cncf.io/networks: | [ { "name": "vn", "namespace": "cpn-intra-network-test-vn", "ips": ["15.15.15.3"], "cni-args": { "net.juniper.contrail.podnetwork": true } } ] spec: containers: - name: toolbox image: svl-artifactory.juniper.net/atom-docker/cn2/bazel-build/dev/netshoot:v1 imagePullPolicy: IfNotPresent command: ["bash", "-c", "while true; do sleep 60s; done"] securityContext: capabilities: add: - NET_ADMIN privileged: true tolerations: - key: "key" operator: "Equal" value: "value" effect: "NoSchedule"
Note that this YAML shows a Custom Pod Network defined in the annotations of both the pod and namespace. If you specify an annotation at both the pod and namespace level, the pod-level annotation takes priority.
Custom Default Pod Network Interactions
See the following sections for information about common Custom Pod Network interactions.
Multiple Interfaces Inside a Pod
A pod with a Custom Default Pod Network may still contain multiple interfaces. The
following YAML is an example of a NetworkSelectionElement
of a pod with a
custom network and multiple interfaces.
annotations: k8s.v1.cni.cncf.io/networks: | [ { "name": "custom-podnet-vn", "namespace": "custom-podnet", "cni-args": { "net.juniper.contrail.podnetwork": true } }, { "name": "vn1", "namespace": "vn1-ns", }, { "name": "vn2", "namespace": "vn2-ns", } ]
A pod with the annotations defined above would utilize eth0 from
custom-podnet-vn
, eth1 from vn1
, and eth2 from
vn2
. You can also create a namespace with a Custom Default Pod Network
and multiple interfaces. The following YAML shows the configuration above, replicated at the
namespace level.
apiVersion: v1 kind: Namespace metadata: name: custom-podnet annotations: net.juniper.contrail.podnetwork: custom-podnet/custom-podnet-vn --- # Pod annotations: k8s.v1.cni.cncf.io/networks: | [ { "name": "vn1", "namespace": "vn1-ns", }, { "name": "vn2", "namespace": "vn2-ns", } ]