ON THIS PAGE
Customize Virtual Networks for Pod Deployments, Services, and Namespaces
SUMMARY Starting in release 23.1, Juniper Cloud-Native Contrail Networking (CN2) supports the ability to apply a custom default network for namespaces, Deployments, and Services. This feature also supports environments with Multus CNI enabled. With Multus as the CNI of your CN2 environment, you can deploy pods that have multiple interfaces for different use cases.
Custom Namespace Network Overview
In traditional Kubernetes, the default pod network is a single 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. CN2 isolated namespaces enable Kubernetes to create custom default
namespace networks on a per-namespace basis. This means that when you configure a
Deployment
in a namespace with a custom namespace network, new pods and
services use the custom network within an individual isolated namespace. Isolated namespaces
ensure network isolation between pods and services without the need for a Kubernetes network
policy.
CN2 improves on this feature by enabling Kubernetes to create pods that use custom
namespace networks on a per-pod basis. Custom namespace networks provide their own
VirtualNetworks
(VNs) and Subnets. CN2 assigns pod IPs based on the
Subnet parameters of a given custom namespace network. In other words, you can create pods
with their own networks in a given namespace. This means that CN2 supports network isolation
at the namespace level and pod level.
Apply a Custom Namespace Network to a Namespace
You can specify a custom default namespace network per namespace. Designate a custom
namespace network on a per-namespace basis and all pods and services created within that
namespace use that network as the pod or service network. The Namespace
annotation net.juniper.contrail.podnetwork: network-namespace/network-name
designates the desired network as the custom namespace network.
The following YAML shows an example of namespace with a custom namespace network annotation.
apiVersion: v1 kind: Namespace metadata: name: custom-podnet annotations: net.juniper.contrail.podnetwork: custom-podnet/ns-level-custom-podnets
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 Namespace 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.
Apply a Custom Service Network to a Service
You can specify a custom default network for services in the annotations
of a Service
object. As a result, the service can select pods that use the
custom service network. Services that select pods with a custom network are isolated from
other networks. The annotation format is: network-namespace/network-name
.
The following is an example of a Service
with a custom service network.
apiVersion: v1 kind: Service metadata: name: custom-podnet-svc namespace: custom-podnet annotations: net.juniper.contrail.podnetwork: custom-podnet/pod-level-custom-podnet
Designate a Virtual Network as a Custom Default Pod Network
You can designate a VN as a custom default pod network. If you manually create a
VirtualNetwork
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. CN2 assigns IPs to pods from this 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: custom-podnet name: vn-network spec: podNetwork: true v4SubnetReference: apiVersion: core.contrail.juniper.net/v2 kind: Subnet namespace: custom-podnet name: vn-network-subnet
Use a NAD to Create a Custom Default Pod Network
Install a Network Attachment Definiton (NAD) with podNetwork: true
set at
the juniper.net/networks
annotation to create a custom default pod network.
After you create this NAD, the NAD controller automatically creates a VN and sets the
"podNetwork: true
" field during VirtualNetwork
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: name: nad-network namespace: custom-podnet annotations: juniper.net/networks: '{ "ipamV4Subnet": "5.5.5.0/24", "podNetwork": true }'
-
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.
Deploy a Custom Pod Network per Pod
You can also 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
annotations
of a pod: "net.juniper.contrail.podnetwork":
network-namespace/network-name
. This feature provides pod isolation because pods
that use a custom pod network are isolated from other networks.
The following example shows a namespace, VirtualNetwork
, and pod with
custom default 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: <repository>:<tag> 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: net.juniper.contrail.podnetwork: cpn-intra-network-test-vn/vn # namespace/name of the network net.juniper.contrail.podnetwork.ip: 15.15.15.3 # ip request for the interface net.juniper.contrail.podnetwork.cni-args: | # any cni-args needed for this interface spec: containers: - name: toolbox image: <repository>:<tag> 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 the following pod annotations
:
annotations: net.juniper.contrail.podnetwork: cpn-mc-cc/cpn1 # namespace/name of the network net.juniper.contrail.podnetwork.ip: 100.100.100.3 # ip request for the interface net.juniper.contrail.podnetwork.cni-args: | # any cni-args needed for this interface { "net.juniper.contrail.interfacegroup": "eth0" }
You define a custom pod network in the annotations of both the pod
(pod-level-cpn-pod
) and namespace
(cpn-intra-network-test-vn
). As part of the 23.1 release, you must
configure a pod to use a custom pod network in the annotations
at the pod
level. If you specify an annotation at both the pod and namespace level, the pod-level
annotation takes priority.
Custom Default Namespace Network Interactions
See the following sections for information about common custom namespace network interactions.
Multi-NIC Pod
A pod with a custom default namespace 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.
apiVersion: v1 kind: Namespace metadata: name: custom-podnet annotations: net.juniper.contrail.podnetwork: cpn-intra-network-test/vn --- # Pod annotations: k8s.v1.cni.cncf.io/networks: | [ { "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 namespace network and
multiple interfaces. The following YAML shows the configuration above, replicated at the
namespace level.
apiVersion: v1 kind: Namespace metadata: name: vn0-ns annotations: net.juniper.contrail.podnetwork: vn0-ns/vn0 --- # Pod annotations: k8s.v1.cni.cncf.io/networks: | [ { "name": "vn1", "namespace": "vn1-ns", }, { "name": "vn2", "namespace": "vn2-ns", } ]