Description

Kubernetes supports a custom extension to represent networks in its object model, which is through its CustomResourceDefinition(CRD) feature. This extension adds support for a new kind of object called NetworkAttachmentDefinition , which represents a network in Kubernetes.

This article explains Contrail's support of Kubernetes NetworkAttachmentDefinition.

Solution

.NetworkAttachmentDefinition CRD

Contrail CNI follows the Kubernetes Network CRD (Custom Resource Definition) NetworkAttachmentDefinition to provide a standardized method to specify the configurations for additional network interfaces. There is no change to the standard kubernetes upstream APIs, making the implementation that comes with the most compatibility.

In Contrail setup, the NetworkAttachmentDefinition CRD is created by contrail-kube-manage r (KM). When bootup, KM validates if a network CRD ' network-attachment-definitions.k8s.cni.cncf.io ' is found in the Kubernetes API server, and creates one if there isn't one yet.

Example `CRD` object yaml:

----
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: network-attachment-definitions.k8s.cni.cncf.io
spec:
  group: k8s.cni.cncf.io
  version: v1
  scope: Namespaced
  names:
    plural: network-attachment-definitions
    singular: network-attachment-definition
    kind: NetworkAttachmentDefinition
    shortNames:
    - net-attach-def
  validation:
    openAPIV3Schema:
      properties:
        spec:
          properties:
            config:
             type: string
----

In Contrail Kubernetes setup, the CRD has been created and can be verified:

----
$ kubectl get crd
NAME                                             CREATED AT
network-attachment-definitions.k8s.cni.cncf.io   2019-06-07T03:43:52Z
----

Using this new ` NetworkAttachmentDefinition ` created from the above CRD, we have the ability to create a `vitual-network` in Contrail Kubernetes environments.

To create a virtual-network from kubernetes, use a yaml template like this:

----
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: <network-name>
  namespace: <namespace-name>
  annotations:
    "opencontrail.org/cidr" : [<ip-subnet>]
    "opencontrail.org/ip_fabric_snat" : <True/False>
    "opencontrail.org/ip_fabric_forwarding" : <True/False>
spec:
  config: '{
    “cniVersion”: “0.3.0”,
    "type": "contrail-k8s-cni"
}'
----

Like many other standard kubernetes objects, specify the VN name, namespace under 'metadata', and 'annotations' which is used to carry additional information about a network. In Contrail, the following annotations are used in 'NetworkAttachmentDefinition' CRD to enable certain attributes for the virtual-network:

  • opencontrail.org/cidr : CIDR, which defines the subnet for a VN
  • opencontrail.org/ip_fabric_forwarding : A flag to enable/disable 'ip fabric forwarding' feature
  • opencontrail.org/ip_fabric_snat : A flag to enable/disable 'ip fabric snat' feature


In contrail, the 'ip-fabric-forwarding' feature enables IP fabric based forwarding without tunneling for the VN. When two 'ip_fabric_forwrding' enabled virtual networks communicate with each other, overlay traffic will be forwarded directly using the underlay. 

With the Contrail 'ip-fabric-snat' feature, pods that are in the overlay can reach the Internet without floating IPs or a logical-router. The 'ip-fabric-snat' feature uses compute node IP for creating a source NAT to reach
the required services.

Alternatively, you can define a new VN by referring an existing VN:

----
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: extns-network
  annotations:
    "opencontrail.org/network" : '{"domain":"default-domain", "project": "k8s-extns", "name":"k8s-extns-pod-network"}'
spec:
  config: '{
    “cniVersion”: “0.3.1”,
    "type": "contrail-k8s-cni"
}'
----

As an example, we'll use the first template to define our VNs:

.define a VN

----
#vn-ns-default.yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    "opencontrail.org/cidr": "101.101.101.0/24"
  name: vn-ns-default
spec:
  config: '{
    "cniVersion": "0.3.0",
    "type": "contrail-k8s-cni"
  }'
----

.create the VN

----
$ kubectl apply -f vn-left-1.yaml
networkattachmentdefinition.k8s.cni.cncf.io/vn-left-1 created
----

.verify the VN

----
$ kubectl get network-attachment-definitions.k8s.cni.cncf.io
NAME            AGE
vn-left-1       22d
----
----
$ kubectl describe network-attachment-definitions.k8s.cni.cncf.io vn-left-1
Name:         vn-left-1
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"k8s.cni.cncf.io/v1","kind":"NetworkAttachmentDefinition","metadata":{"annotations":{"opencontrail.org/cidr":"10.10.10.0/24"...
              opencontrail.org/cidr: 10.10.10.0/24
              opencontrail.org/ip_fabric_forwarding: false
API Version:  k8s.cni.cncf.io/v1
Kind:         NetworkAttachmentDefinition
Metadata:
  Creation Timestamp:  2019-06-10T20:54:15Z
  Generation:          1
  Resource Version:    464975
  Self Link:           /apis/k8s.cni.cncf.io/v1/namespaces/default/network-attachment-definitions/vn-left-1
  UID:                 e8799b5e-8bc1-11e9-b924-0050569e6cfc
Spec:
  Config:  { "cniVersion": "0.3.0", "type": "contrail-k8s-cni" }
Events:    <none>
----