Sdewan CRD Controller

Sdewan CRD Controller

Goal

Sdewan CRD Controller (config agent) is the controller of Sdewan CRDs. With the CRD Controller, we are able to deploy Sdewan CRs to configure CNF rules. In this page, we have the following terms, let's define them here.

  • CNF Deployment: A deployment running network function process(openWRT)

  • Sdewan rule: The rule defines the CNF behaves. We have 3 classes of rules: mwan3, firewall, ipsec. Each class includes several kinds of rules. For example, mwan3 has 2 kinds: mwan3_policy and mwan3_rule. Firewall has 5 kinds: firewall_zone, firewall_snat, firewall_dnat, firewall_forwarding, firewall_rule. Ipsec has xx(ruoyu) kinds: xx, xx.

  • Sdewan rule CRD: The CRD defines each kind of sdewan rule. For each kind of Sdewan rule, we have a Sdewan rule CRD. Sdewan rule CRD is namespaced resource.

  • Sdewan rule CR: Instance of Sdewan rule CRD.

  • Sdewan controller: The controller watching Sdewan rule CRs.

  • CNF: A network function running in container.

To deploy a CNF, user needs to create one CNF deployment and some Sdewan rule CRs. In a Kubernetes namespace, there could be more than one CNF deployment and many Sdewan rule CRs. We use label to correlate one CNF with some Sdewan rule CRs. The Sdewan controller watches Sdewan rule CRs and applies them onto the correlated CNF by calling CNF REST api.

Sdwan Design Principle

  • There could be multiple tenants/namespaces in a Kubernetes cluster. User may deploy multiple CNFs in any one or more tenants.

  • The replica of CNF deployment could be more than one for active/backup purpose. We should apply rules for all the pods under CNF deployment. (This release doesn't implement VRRP between pods)

  • CNF deployment and Sdewan rule CRs can be created/updated/deleted in any order

  • The Sdewan controller and CNF process could be crash/restart at anytime for some reasons. We need to handle these scenarios

  • Each Sdewan rule CR has labels to identify the type it belongs to. 3 types are available at this time: basic, app-intent and k8s-service. We extend k8s user role permission so that we can set user permission at type level of Sdewan rule CR

  • Sdewan rule CR dependencies are checked on creating/updating/deleting. For example, if we create a mwan3_rule CR which uses policy policy-x, but no mwan3_policy CR named policy-x exists. Then we block the request

Architecture

SDEWAN CRD Controller internally calls SDEWAN Restful API to do CNF configuration. And a remote client (e.g. SDEWAN Overlay Controller) can manage SDEWAN CNF configuration through creating/updating/deleting SDEWAN CRs. It includes below components:

  • MWAN3 Controller: monitor mwan3 related CR change then do mwan3 configuration in SDEWAN CNF

  • Firewall Controller: monitor firewall related CR change then do firewall configuration in SDEWAN CNF

  • IpSec Controller: monitor ipsec related CR change then do ipsec configuration in SDEWAN CNF

  • Service/Application Controller: configure firewall/NAT rule for in-cluster service and application

  • Runtime controller: collect runtime information of CNF include IPSec, IKE, firewall/NAT connections, DHCP leases,  DNS entries, ARP entries etc..

  • BucketPerssion/LabelValidateWebhook: do sdewan CR request permission check based on CR label and user

CNF Deployment

In this section we describe what the CNF deployment should be like, as well as the pod under the deployment.

  • CNF pod should has multiple network interfaces attached. We use multus and ovn4nfv CNIs to enable multiple interfaces. So in the CNF pod yaml, we set annotations: k8s.v1.cni.cncf.io/networks, k8s.plugin.opnfv.org/nfn-network.

  • When user deploys a CNF, she/he most likely want to deploy the CNF on a specified node instead of a random node. Because some nodes may don't have provider network connected. So we set spec.nodeSelector for pod

  • CNF pod runs Sdewan CNF (based on openWRT in ICN). We use image integratedcloudnative/openwrt:dev

  • CNF pod should setup with rediness probe. Sdewan controller would check pod readiness before calling CNF REST api.

CNF pod
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: cnf-1 namespace: default labels: sdewanPurpose: cnf-1 spec: replicas: 1 strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: annotations: k8s.plugin.opnfv.org/nfn-network: |- { "type": "ovn4nfv", "interface": [ { "defaultGateway": "false", "interface": "net0", "name": "ovn-priv-net" }, { "defaultGateway": "false", "interface": "net1", "name": "ovn-provider-net1" }, { "defaultGateway": "false", "interface": "net2", "name": "ovn-provider-net2" } ]} k8s.v1.cni.cncf.io/networks: '[{ "name": "ovn-networkobj"}]' spec: containers: - command: - /bin/sh - /tmp/sdewan/entrypoint.sh image: integratedcloudnative/openwrt:dev name: sdewan readinessProbe: failureThreshold: 5 httpGet: path: / port: 80 scheme: HTTP initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 securityContext: privileged: true procMount: Default volumeMounts: - mountPath: /tmp/sdewan name: example-sdewan readOnly: true nodeSelector: kubernetes.io/hostname: ubuntu18

 

Sdewan rule CRs

CRD defines all properties of a resource, but it's not human friendly. So we paste Sdewan rule CR samples instead of CRDs.

  • Each Sdewan rule CR has a label named sdewanPurpose to indicate which CNF should the rule be applied onto

  • Each Sdewan rule CR has the status field which indicates if the latest rule is applied and when it's applied

  • Mwan3Policy.spec.members[].network should match the networks defined in CNF pod annotation k8s.plugin.opnfv.org/nfn-network. As well as FirewallZone.spec[].network

CR samples of Mwan3 type:

Mwan3Policy CR
apiVersion: batch.sdewan.akraino.org/v1alpha1 kind: Mwan3Policy metadata: name: balance1 namespace: default labels: sdewanPurpose: cnf-1 spec: members: - network: ovn-net1 weight: 2 metric: 2 - network: ovn-net2 weight: 3 metric: 3 status: appliedVersion: "2" appliedTime: "2020-03-29T04:21:48Z" inSync: True
Mwan3Rule CR
apiVersion: batch.sdewan.akraino.org/v1alpha1 kind: Mwan3Rule metadata: name: http_rule namespace: default labels: sdewanPurpose: cnf-1 spec: policy: balance1 src_ip: 192.168.1.2 dest_ip: 0.0.0.0/0 dest_port: 80 proto: tcp status: appliedVersion: "2" appliedTime: "2020-03-29T04:21:48Z" inSync: True

 

CR samples of Firewall type:

apiVersion: batch.sdewan.akraino.org/v1alpha1 kind: FirewallZone metadata: name: lan1 namespace: default labels: sdewanPurpose: cnf-1 spec: newtork: - ovn-net1 input: ACCEPT output: ACCEPT status: appliedVersion: "2" appliedTime: "2020-03-29T04:21:48Z" inSync: True

 

apiVersion: batch.sdewan.akraino.org/v1alpha1 kind: FirewallRule metadata: name: reject_80 namespace: default labels: sdewanPurpose: cnf-1 spec: src: lan1 src_ip: 192.168.1.2 src_port: 80 proto: tcp target: REJECT status: appliedVersion: "2" appliedTime: "2020-03-29T04:21:48Z" inSync: True

 

apiVersion: batch.sdewan.akraino.org/v1alpha1 kind: FirewallSNAT metadata: name: snat_lan1 namespace: default labels: sdewanPurpose: cnf-1 spec: src: lan1 src_ip: 192.168.1.2 src_dip: 1.2.3.4 dest: wan1 proto: icmp status: appliedVersion: "2" appliedTime: "2020-03-29T04:21:48Z" inSync: True

 

apiVersion: batch.sdewan.akraino.org/v1alpha1 kind: FirewallDNAT metadata: name: dnat_wan1 namespace: default labels: sdewanPurpose: cnf-1 spec: src: wan1 src_dport: 19900 dest: lan1 dest_ip: 192.168.1.1 dest_port: 22 proto: tcp status: appliedVersion: "2" appliedTime: "2020-03-29T04:21:48Z" inSync: True

 

apiVersion: batch.sdewan.akraino.org/v1alpha1 kind: FirewallForwarding metadata: name: forwarding_lan_to_wan namespace: default labels: sdewanPurpose: cnf-1 spec: src: lan1 dest: wan1 status: appliedVersion: "2" appliedTime: "2020-03-29T04:21:48Z" inSync: True

 

CR samples of IPSec type(ruoyu):

IPSec Proposal CR
apiVersion: sdewan.akraino.org/v1alpha1 kind: IpsecProposal metadata:   name: test_proposal_1 namespace: default labels: sdewanPurpose: cnf-1 spec: encryption_algorithm: aes128 hash_algorithm: sha256 dh_group: modp3072 status: appliedVersion: "1" appliedTime: "2020-04-12T09:28:38Z" inSync: True
IPSec Site CR
apiVersion: sdewan.akraino.org/v1alpha1 kind: IpsecSite metadata:   name: ipsecsite-sample namespace: default labels: sdewanPurpose: cnf-1 spec: remote: xx.xx.xx.xx authentication_method: psk pre_shared_key: xxx local_public_cert: local_private_cert: shared_ca: local_identifier: remote_identifier: crypto_proposal: - test_proposal_1 connections: - connection_name: connection_A type: tunnel mode: start local_subnet: 172.12.0.0/24, 10.239.160.22 remote_sourceip: 172.12.0.30-172.12.0.45 remote_subnet: crypto_proposal: - test_proposal_1 status: appliedVersion: "1" appliedTime: "2020-04-12T09:28:38Z" inSync: True
IPSec Host CR
apiVersion: sdewan.akraino.org/v1alpha1 kind: IpsecHost metadata:   name: ipsechost-sample namespace: default labels: sdewanPurpose: cnf-1 spec: remote: xx.xx.xx.xx/%any authentication_method: psk pre_shared_key: xxx local_public_cert: local_private_cert: shared_ca: local_identifier: remote_identifier: crypto_proposal: - test_proposal_1 connections: - connection_name: connection_A type: tunnel mode: start local_sourceip: %config remote_sourceip: xx.xx.xx.xx remote_subnet: xx.xx.xx.xx/xx crypto_proposal: - test_proposal_1 status: appliedVersion: "1" appliedTime: "2020-04-12T09:28:38Z" inSync: True

 

CNF Service CR