Sdewan CRD Controller
- 1 Goal
- 2 Sdwan Design Principle
- 3 Architecture
- 4 CNF Deployment
- 4.1 CNF pod
- 5 Sdewan rule CRs
- 5.1 Mwan3Policy CR
- 5.2 Mwan3Rule CR
- 5.3 IPSec Proposal CR
- 5.4 IPSec Site CR
- 5.5 IPSec Host CR
- 6 CNF Service CR
- 6.1 CNF Service CR
- 7 Sdewan rule CRD Reconcile Logic
- 8 Unsual Cases
- 9 Admission Webhook Usage
- 10 Sdewan rule CR type level Permission Implementation
- 11 ServiceRule controller (For next release)
- 12 References
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-intentandk8s-service. We extend k8s user role permission so that we can set user permission at type level of Sdewan rule CRSdewan 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 namedpolicy-xexists. 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.nodeSelectorfor podCNF pod runs Sdewan CNF (based on openWRT in ICN). We use image
integratedcloudnative/openwrt:devCNF 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
sdewanPurposeto indicate which CNF should the rule be applied ontoEach Sdewan rule CR has the
statusfield which indicates if the latest rule is applied and when it's appliedMwan3Policy.spec.members[].networkshould match the networks defined in CNF pod annotationk8s.plugin.opnfv.org/nfn-network. As well asFirewallZone.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: TrueMwan3Rule 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