Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NetworkAttachmentDefinition support to NetWatcher #247

Merged
merged 2 commits into from
Mar 10, 2021
Merged

Conversation

Levovar
Copy link
Collaborator

@Levovar Levovar commented Feb 26, 2021

In an effort to expand the existing netwatcher to be a more generic "Network Management Operator", this commit enhances it to be able to "speak" NAD, in addition to currently existing the 3 DANM APIs.

The idea is pretty simple: the Controller component interprets the CNI config inside NAD.Spec.Config same way as the CNI config in Spec.Options of any DANM network, then call the existing VLAN, and VxLAN management functionalities regardless which API triggered the Operator.
As a result, MACVLAN and IPVLAN type NADs can now also enjoy the dynamic VLAN, and VxLAN host interface management functionalities previously exclusive to DANM API users.

Netwatcher also takes care of patching the name of the parent interface in Spec.Config, so the upstream CNIs connect the Pods to the right/newly created host interface.

In an effort to expand the existing netwatcher to be a more generic "Network Management Operator", this commit enhances it to be able to "speak" NAD, besides the 3 DANM APIs.
The idea is pretty simple: the Controller components can interpret the CNI config inside NAD.Spec.Config same way as the CNI config in Spec.Options inside any DANM network, then call the existing VLAN, and VxLAN management functionalities regardless which API triggered the Operator.
As a result, MACVLAN and IPVLAN type NADs can also enjoy the dynamic VLAN, and VxLAN host interface management functionalities previously exclusive to DANM API users.
Netwatcher also takes care of patching the name of the parent interface in Spec.Config, so the upstream CNIs connect the Pods to the right host interface.
@Levovar
Copy link
Collaborator Author

Levovar commented Mar 1, 2021

Keeping it in WIP still, some polishing left to do - but the concept works!

Initial test NAD:

# cat example_nad.yaml
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: ipvlan-conf
spec:
  config: '{
      "name": "vlantest",
      "cniVersion": "0.3.1",
      "type": "macvlan",
      "capabilities": { "ips": true },
      **"master": "tenant-bond",**
      "vlan": 500,
      "ipam": {
        "type": "static",
        "routes": [
          {
            "dst": "0.0.0.0/0",
            "gw": "10.1.1.1"
          }
        ]
      }
    }'

Interface created automatically on node when the network is created:

# ip l | grep vlantest
# kubectl create -f example_nad.yaml
networkattachmentdefinition.k8s.cni.cncf.io/ipvlan-conf created
# ip l | grep vlantest
568: vlantest.500@tenant-bond: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP mode DEFAULT group default

The correct device name is patched back into the network so the CNI connects child interfaces to the right parent:

# kubectl get network-attachment-definitions.k8s.cni.cncf.io ipvlan-conf  -o yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  creationTimestamp: "2021-03-01T17:21:11Z"
  generation: 2
  managedFields:
  - apiVersion: k8s.cni.cncf.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec: {}
    manager: kubectl-create
    operation: Update
    time: "2021-03-01T17:21:11Z"
  - apiVersion: k8s.cni.cncf.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        f:config: {}
    manager: netwatcher
    operation: Update
    time: "2021-03-01T17:21:11Z"
  name: ipvlan-conf
  namespace: default
  resourceVersion: "13636666"
  selfLink: /apis/k8s.cni.cncf.io/v1/namespaces/default/network-attachment-definitions/ipvlan-conf
  uid: a536024f-6ae8-46c8-9ad0-fe9ecbe80baf
spec:
  config: '{"capabilities":{"ips":true},"cniVersion":"0.3.1","ipam":{"routes":[{"dst":"0.0.0.0/0","gw":"10.1.1.1"}],"type":"static"},"master":"vlantest.500","name":"vlantest","type":"macvlan","vlan":500}'

Lastly, host interface is cleaned-up together with the network:

# kubectl delete -f  example_nad.yaml
networkattachmentdefinition.k8s.cni.cncf.io "ipvlan-conf" deleted
# ip l | grep vlantest

Also refactored CNI spec patching code to be re-usable from different packages
@Levovar Levovar changed the title [WIP] Add NetworkAttachmentDefinition support to NetWatcher Add NetworkAttachmentDefinition support to NetWatcher Mar 5, 2021
@Levovar
Copy link
Collaborator Author

Levovar commented Mar 5, 2021

@dougbtv you might find this add interesting. Let me know if you did! :)

@Levovar Levovar merged commit 41268df into master Mar 10, 2021
@Levovar Levovar deleted the netwatcher_nad branch March 10, 2021 14:46
@dougbtv
Copy link

dougbtv commented Mar 10, 2021 via email

@BurlyLuo
Copy link

Keeping it in WIP still, some polishing left to do - but the concept works!

Initial test NAD:

# cat example_nad.yaml
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: ipvlan-conf
spec:
  config: '{
      "name": "vlantest",
      "cniVersion": "0.3.1",
      "type": "macvlan",
      "capabilities": { "ips": true },
      **"master": "tenant-bond",**
      "vlan": 500,
      "ipam": {
        "type": "static",
        "routes": [
          {
            "dst": "0.0.0.0/0",
            "gw": "10.1.1.1"
          }
        ]
      }
    }'

Interface created automatically on node when the network is created:

# ip l | grep vlantest
# kubectl create -f example_nad.yaml
networkattachmentdefinition.k8s.cni.cncf.io/ipvlan-conf created
# ip l | grep vlantest
568: vlantest.500@tenant-bond: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP mode DEFAULT group default

The correct device name is patched back into the network so the CNI connects child interfaces to the right parent:

# kubectl get network-attachment-definitions.k8s.cni.cncf.io ipvlan-conf  -o yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  creationTimestamp: "2021-03-01T17:21:11Z"
  generation: 2
  managedFields:
  - apiVersion: k8s.cni.cncf.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec: {}
    manager: kubectl-create
    operation: Update
    time: "2021-03-01T17:21:11Z"
  - apiVersion: k8s.cni.cncf.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        f:config: {}
    manager: netwatcher
    operation: Update
    time: "2021-03-01T17:21:11Z"
  name: ipvlan-conf
  namespace: default
  resourceVersion: "13636666"
  selfLink: /apis/k8s.cni.cncf.io/v1/namespaces/default/network-attachment-definitions/ipvlan-conf
  uid: a536024f-6ae8-46c8-9ad0-fe9ecbe80baf
spec:
  config: '{"capabilities":{"ips":true},"cniVersion":"0.3.1","ipam":{"routes":[{"dst":"0.0.0.0/0","gw":"10.1.1.1"}],"type":"static"},"master":"vlantest.500","name":"vlantest","type":"macvlan","vlan":500}'

Lastly, host interface is cleaned-up together with the network:

# kubectl delete -f  example_nad.yaml
networkattachmentdefinition.k8s.cni.cncf.io "ipvlan-conf" deleted
# ip l | grep vlantest

metadata:
name: ipvlan-conf
....
"type": "macvlan",

mismatch..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants