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-podnetsThe 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-podnetDesignate 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-subnetUse 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",
}
]