aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuralamudhan Ramakrishnan <kuralamudhan.ramakrishnan@intel.com>2020-09-18 00:29:11 -0700
committerKuralamudhan Ramakrishnan <kuralamudhan.ramakrishnan@intel.com>2020-09-18 12:04:41 -0700
commitabc86b0782d8d1ea41b5b5dd04b4c6c8755e7210 (patch)
treecc926aa58c564504471a6113429e3a26cd4343c6
parent13ccea1a14dd12e585ef34680fcbcab5fd17550b (diff)
adding sfc demo with icn sdewan cnf
- vagrant is used to create 5 VMs master, minion01, minion02, TM1 and TM2 - node.sh enables nested VTx - README.md documentated all steps to bring up the sfc Signed-off-by: Kuralamudhan Ramakrishnan <kuralamudhan.ramakrishnan@intel.com> Change-Id: Id382f734dedb50354e7986fbf954663b374c1ff3
-rw-r--r--.gitignore1
-rw-r--r--demo/sfc-setup/README.md113
-rw-r--r--demo/sfc-setup/Vagrantfile99
-rw-r--r--demo/sfc-setup/config/default.yml30
-rw-r--r--demo/sfc-setup/demo/firewall-dyn-net-2.yaml14
-rw-r--r--demo/sfc-setup/demo/firewall-right-pnetwork.yaml16
-rw-r--r--demo/sfc-setup/demo/firewall-rule-reject-icmp-right-pnetwork.yaml13
-rw-r--r--demo/sfc-setup/demo/ms1.yaml40
-rw-r--r--demo/sfc-setup/demo/sfc-network.yaml67
-rw-r--r--demo/sfc-setup/demo/sfc.yaml18
-rw-r--r--demo/sfc-setup/demo/slb-ngfw-sdewan-cnf-deployment.yaml200
-rw-r--r--demo/sfc-setup/insecure_keys/key27
-rw-r--r--demo/sfc-setup/insecure_keys/key.pub1
-rwxr-xr-xdemo/sfc-setup/node.sh88
-rw-r--r--demo/sfc-setup/ovn4nfv-pod-network/ovn-daemonset.yaml239
-rw-r--r--demo/sfc-setup/ovn4nfv-pod-network/ovn4nfv-k8s-plugin.yml714
-rwxr-xr-xdemo/sfc-setup/setup.sh201
17 files changed, 1881 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 33defe4..c909adf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
.tox/
+demo/sfc-setup/.vagrant
diff --git a/demo/sfc-setup/README.md b/demo/sfc-setup/README.md
new file mode 100644
index 0000000..6f58b82
--- /dev/null
+++ b/demo/sfc-setup/README.md
@@ -0,0 +1,113 @@
+# Service Function Chaining(SFC) - setup
+
+## Summary
+
+This project offers a means for deploying a Kubernetes cluster
+that satisfies the requirements of ovn4nfv sfc-setup
+
+## Virtual Machines
+
+This project uses [Vagrant tool][2] for provisioning Virtual Machines
+automatically. The [setup](setup.sh) bash script contains the
+Linux instructions to install dependencies and plugins required for
+its usage. This script supports two Virtualization technologies
+(Libvirt and VirtualBox).
+
+```
+ $ sudo ./setup.sh -p libvirt
+```
+There is a `default.yml` in the `./config` directory which creates multiple vm.
+
+Once Vagrant is installed, it's possible to provision a vm using
+the following instructions:
+```
+ $ vagrant up
+```
+In-depth documentation and use cases of various Vagrant commands [Vagrant commands][3]
+is available on the Vagrant site.
+
+## Deployment
+
+### kubeadm
+
+Install the [docker](https://docs.docker.com/engine/install/ubuntu/) in the master, minion01 and minion02 vm.
+Follow the steps in [create cluster kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) to create kubernetes cluster in master
+In the master vm run the `kubeadm init` as below. The ovn4nfv uses same pod network cidr `10.244.64.0/18`
+```
+ $ kubeadm init --kubernetes-version=1.19.0 --pod-network-cidr=10.244.64.0/18 --apiserver-advertise-address=<master_eth0_ip_address>
+```
+Deploy the ovn4nfv Pod network to the cluster.
+```
+ $ kubectl apply -f ovn4nfv-pod-network/ovn-daemonset.yaml
+ $ kubectl apply -f ovn4nfv-pod-network/ovn4nfv-k8s-plugin.yaml
+```
+Join minion01 and minion02 by running the `kubeadm join` on each node as root as mentioned in [create cluster kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/)
+
+### TM1 server
+
+ssh into the TM1 vm and run the following command to attach TM1 to the left provider network.
+```
+ $ ip addr flush dev eth1
+ $ ip link add link eth1 name eth1.100 type vlan id 100
+ $ ip link set dev eth1.100 up
+ $ ip addr add 172.30.10.101/24 dev eth1.100
+ $ ip route del default
+ $ ip route add default via 172.30.10.3
+```
+### TM2 server
+
+ssh into the TM2 vm and run the following command to attach TM2 to the right provider network.
+```
+ $ ip addr flush dev eth1
+ $ ip link add link eth1 name eth1.200 type vlan id 200
+ $ ip link set dev eth1.200 up
+ $ ip addr add 172.30.20.2/24 dev eth1.200
+```
+Run the following commands to create virutal router
+```
+ $ ip route add 172.30.10.0/24 via 172.30.20.3
+ $ ip route add 172.30.33.0/24 via 172.30.20.3
+ $ ip route add 172.30.44.0/24 via 172.30.20.3
+```
+```
+ $ echo 1 > /proc/sys/net/ipv4/ip_forward
+ $ /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
+ $ iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
+ $ iptables -A FORWARD -i eth1.200 -o eth0 -j ACCEPT
+```
+## Demo
+
+Deploy the SDEWAN controller in cluster
+```
+ $ git clone https://github.com/akraino-edge-stack/icn-sdwan.git
+ $ cd icn-sdwan/platform/crd-ctrlr
+ $ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v0.11.0/cert-manager.yaml --validate=false
+ $ kubectl apply -f examples/sdewan-controller.yaml
+```
+From TM1 try to ping google.com, the ping operation will fails.
+Deploy the SFC as following
+```
+ $ kubectl apply -f sfc-network.yaml
+ $ kubectl apply -f slb-ngfw-sdewan-cnf-deployment.yaml
+ $ kubectl apply -f ms1.yaml
+```
+Pinging for goole.com or curl example.com should fail in both ms1 and TM1
+```
+ $ kubectl apply -f sfc.yaml
+```
+Pinging for google.com or curl example.com should be successful in both ms1 and TM1
+
+Let try to apply icmp reject rule in SDEWAN cnf
+```
+ $ kubectl apply -f firewall-dyn-net-2.yaml
+ $ kubectl apply -f firewall-right-pnetwork.yaml
+ $ kubectl apply -f firewall-rule-reject-icmp-right-pnetwork.yaml
+```
+Pinging for google.com will fail and curl example.com should be successful in both ms1 and TM1
+
+## License
+
+Apache-2.0
+
+[1]: https://www.vagrantup.com/
+[2]: https://www.vagrantup.com/docs/cli/
diff --git a/demo/sfc-setup/Vagrantfile b/demo/sfc-setup/Vagrantfile
new file mode 100644
index 0000000..ad11927
--- /dev/null
+++ b/demo/sfc-setup/Vagrantfile
@@ -0,0 +1,99 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2018
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+box = {
+ :virtualbox => { :name => 'elastic/ubuntu-18.04-x86_64', :version => '20191013.0.0'},
+ :libvirt => { :name => 'intergratedcloudnative/ubuntu1804', :version => '1.0.0'}
+}
+
+require 'yaml'
+pdf = File.dirname(__FILE__) + '/config/default.yml'
+nodes = YAML.load_file(pdf)
+
+provider = (ENV['VAGRANT_DEFAULT_PROVIDER'] || :libvirt).to_sym
+puts "[INFO] Provider: #{provider} "
+
+if ENV['no_proxy'] != nil or ENV['NO_PROXY']
+ $no_proxy = ENV['NO_PROXY'] || ENV['no_proxy'] || "127.0.0.1,localhost"
+ nodes.each do |node|
+ $no_proxy += "," + node['ip']
+ end
+ $subnet = "192.168.121"
+ if provider == :virtualbox
+ $subnet = "10.0.2"
+ end
+ # NOTE: This range is based on vagrant-libvirt network definition CIDR 192.168.121.0/27
+ (1..31).each do |i|
+ $no_proxy += ",#{$subnet}.#{i}"
+ end
+end
+
+Vagrant.configure("2") do |config|
+ config.vm.box = box[provider][:name]
+ config.vm.box_version = box[provider][:version]
+ config.ssh.insert_key = false
+
+ if ENV['http_proxy'] != nil and ENV['https_proxy'] != nil
+ if Vagrant.has_plugin?('vagrant-proxyconf')
+ config.proxy.http = ENV['http_proxy'] || ENV['HTTP_PROXY'] || ""
+ config.proxy.https = ENV['https_proxy'] || ENV['HTTPS_PROXY'] || ""
+ config.proxy.no_proxy = $no_proxy
+ config.proxy.enabled = { docker: false }
+ end
+ end
+ config.vm.provider 'libvirt' do |v|
+ v.nested = true
+ v.cpu_mode = 'host-passthrough'
+ v.management_network_address = "192.168.121.0/27"
+ v.random_hostname = true
+ end
+
+ sync_type = "virtualbox"
+ if provider == :libvirt
+ sync_type = "nfs"
+ end
+
+ nodes.each do |node|
+ config.vm.define node['name'] do |nodeconfig|
+ nodeconfig.vm.hostname = node['name']
+ nodeconfig.vm.network :private_network, :ip => node['ip'], :type => :static
+ nodeconfig.vm.provider 'virtualbox' do |v|
+ v.customize ["modifyvm", :id, "--memory", node['memory']]
+ v.customize ["modifyvm", :id, "--cpus", node['cpus']]
+ if node.has_key? "volumes"
+ node['volumes'].each do |volume|
+ $volume_file = "#{node['name']}-#{volume['name']}.vdi"
+ unless File.exist?($volume_file)
+ v.customize ['createmedium', 'disk', '--filename', $volume_file, '--size', volume['size']]
+ end
+ v.customize ['storageattach', :id, '--storagectl', 'IDE Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium', $volume_file]
+ end
+ end
+ end
+ nodeconfig.vm.provider 'libvirt' do |v|
+ v.memory = node['memory']
+ v.cpus = node['cpus']
+ nodeconfig.vm.provision 'shell' do |sh|
+ sh.path = "node.sh"
+ if node.has_key? "volumes"
+ $volume_mounts_dict = ''
+ node['volumes'].each do |volume|
+ $volume_mounts_dict += "#{volume['name']}=#{volume['mount']},"
+ $volume_file = "./#{node['name']}-#{volume['name']}.qcow2"
+ v.storage :file, :bus => 'sata', :device => volume['name'], :size => volume['size']
+ end
+ sh.args = ['-v', $volume_mounts_dict[0...-1]]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/demo/sfc-setup/config/default.yml b/demo/sfc-setup/config/default.yml
new file mode 100644
index 0000000..f312a6a
--- /dev/null
+++ b/demo/sfc-setup/config/default.yml
@@ -0,0 +1,30 @@
+---
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2018
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+- name: "master"
+ ip: "10.10.10.13"
+ memory: 16384
+ cpus: 16
+- name: "minion01"
+ ip: "10.10.10.14"
+ memory: 18432
+ cpus: 16
+- name: "minion02"
+ ip: "10.10.10.15"
+ memory: 18432
+ cpus: 16
+- name: "tm1-node"
+ ip: "10.10.10.16"
+ memory: 512
+ cpus: 2
+- name: "tm2-node"
+ ip: "10.10.10.17"
+ memory: 512
+ cpus: 2
diff --git a/demo/sfc-setup/demo/firewall-dyn-net-2.yaml b/demo/sfc-setup/demo/firewall-dyn-net-2.yaml
new file mode 100644
index 0000000..4ceac59
--- /dev/null
+++ b/demo/sfc-setup/demo/firewall-dyn-net-2.yaml
@@ -0,0 +1,14 @@
+apiVersion: batch.sdewan.akraino.org/v1alpha1
+kind: FirewallZone
+metadata:
+ name: dynnet2
+ namespace: default
+ labels:
+ sdewanPurpose: cnf1
+
+spec:
+ network:
+ - dync-net2
+ input: ACCEPT
+ output: ACCEPT
+ forward: ACCEPT
diff --git a/demo/sfc-setup/demo/firewall-right-pnetwork.yaml b/demo/sfc-setup/demo/firewall-right-pnetwork.yaml
new file mode 100644
index 0000000..f7e3283
--- /dev/null
+++ b/demo/sfc-setup/demo/firewall-right-pnetwork.yaml
@@ -0,0 +1,16 @@
+apiVersion: batch.sdewan.akraino.org/v1alpha1
+kind: FirewallZone
+metadata:
+ name: rpnetwork
+ namespace: default
+ labels:
+ sdewanPurpose: cnf1
+
+spec:
+ network:
+ - right-pnetwork
+ input: ACCEPT
+ output: ACCEPT
+ forward: ACCEPT
+ masq: "0"
+ mtu_fix: "1"
diff --git a/demo/sfc-setup/demo/firewall-rule-reject-icmp-right-pnetwork.yaml b/demo/sfc-setup/demo/firewall-rule-reject-icmp-right-pnetwork.yaml
new file mode 100644
index 0000000..3493bb6
--- /dev/null
+++ b/demo/sfc-setup/demo/firewall-rule-reject-icmp-right-pnetwork.yaml
@@ -0,0 +1,13 @@
+apiVersion: batch.sdewan.akraino.org/v1alpha1
+kind: FirewallRule
+metadata:
+ name: firewallrule-icmp-right-pnetwork
+ namespace: default
+ labels:
+ sdewanPurpose: cnf1
+
+spec:
+ src: dynnet2
+ dest: rpnetwork
+ proto: icmp
+ target: REJECT
diff --git a/demo/sfc-setup/demo/ms1.yaml b/demo/sfc-setup/demo/ms1.yaml
new file mode 100644
index 0000000..d910257
--- /dev/null
+++ b/demo/sfc-setup/demo/ms1.yaml
@@ -0,0 +1,40 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: ms1
+ labels:
+ app: ms1
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: ms1
+ template:
+ metadata:
+ labels:
+ app: ms1
+ annotations:
+ k8s.plugin.opnfv.org/nfn-network: '{ "type": "ovn4nfv", "interface": [{ "name": "left-pnetwork", "interface": "net0", "defaultgateway": "true", "gwipaddress": "172.30.10.3" }]}'
+
+ spec:
+ containers:
+ - name: ms1
+ image: rkamudhan/netshoot:v1.0
+ imagePullPolicy: IfNotPresent
+ stdin: true
+ tty: true
+ securityContext:
+ privileged: true
+ capabilities:
+ add: ["NET_ADMIN"]
+ dnsPolicy: "None"
+ dnsConfig:
+ nameservers:
+ - 8.8.8.8
+ searches:
+ - default.svc.cluster.local
+ - svc.cluster.local
+ - cluster.local
+ options:
+ - name: ndots
+ value: "5"
diff --git a/demo/sfc-setup/demo/sfc-network.yaml b/demo/sfc-setup/demo/sfc-network.yaml
new file mode 100644
index 0000000..9a6aa2c
--- /dev/null
+++ b/demo/sfc-setup/demo/sfc-network.yaml
@@ -0,0 +1,67 @@
+apiVersion: k8s.plugin.opnfv.org/v1alpha1
+kind: Network
+metadata:
+ name: dync-net1
+spec:
+ cniType : ovn4nfv
+ ipv4Subnets:
+ - subnet: 172.30.33.0/24
+ name: subnet1
+ gateway: 172.30.33.1/24
+
+---
+
+apiVersion: k8s.plugin.opnfv.org/v1alpha1
+kind: Network
+metadata:
+ name: dync-net2
+spec:
+ cniType : ovn4nfv
+ ipv4Subnets:
+ - subnet: 172.30.44.0/24
+ name: subnet1
+ gateway: 172.30.44.1/24
+
+---
+
+apiVersion: k8s.plugin.opnfv.org/v1alpha1
+kind: ProviderNetwork
+metadata:
+ name: left-pnetwork
+spec:
+ cniType: ovn4nfv
+ ipv4Subnets:
+ - subnet: 172.30.10.0/24
+ name: subnet1
+ gateway: 172.30.10.1/24
+ excludeIps: 172.30.10.2
+ providerNetType: VLAN
+ vlan:
+ vlanId: "100"
+ providerInterfaceName: eth1
+ logicalInterfaceName: eth1.100
+ vlanNodeSelector: specific
+ nodeLabelList:
+ - kubernetes.io/os=linux
+
+---
+
+apiVersion: k8s.plugin.opnfv.org/v1alpha1
+kind: ProviderNetwork
+metadata:
+ name: right-pnetwork
+spec:
+ cniType: ovn4nfv
+ ipv4Subnets:
+ - subnet: 172.30.20.0/24
+ name: subnet1
+ gateway: 172.30.20.1/24
+ excludeIps: 172.30.20.2
+ providerNetType: VLAN
+ vlan:
+ vlanId: "200"
+ providerInterfaceName: eth1
+ logicalInterfaceName: eth1.200
+ vlanNodeSelector: specific
+ nodeLabelList:
+ - kubernetes.io/os=linux
diff --git a/demo/sfc-setup/demo/sfc.yaml b/demo/sfc-setup/demo/sfc.yaml
new file mode 100644
index 0000000..98af02a
--- /dev/null
+++ b/demo/sfc-setup/demo/sfc.yaml
@@ -0,0 +1,18 @@
+apiVersion: k8s.plugin.opnfv.org/v1alpha1
+kind: NetworkChaining
+metadata:
+ name: example-networkchaining
+spec:
+ # Add fields here
+ chainType: "Routing"
+ routingSpec:
+ namespace: "default"
+ networkChain: "app=slb,dync-net1,app=ngfw,dync-net2,app=sdwan"
+ leftNetwork:
+ - networkName: "right-pnetwork"
+ gatewayIp: "172.30.10.2"
+ subnet: "172.30.10.0/24"
+ rightNetwork:
+ - networkName: "left-pnetwork"
+ gatewayIp: "172.30.20.2"
+ subnet: "172.30.20.0/24"
diff --git a/demo/sfc-setup/demo/slb-ngfw-sdewan-cnf-deployment.yaml b/demo/sfc-setup/demo/slb-ngfw-sdewan-cnf-deployment.yaml
new file mode 100644
index 0000000..4a1a9cd
--- /dev/null
+++ b/demo/sfc-setup/demo/slb-ngfw-sdewan-cnf-deployment.yaml
@@ -0,0 +1,200 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: slb
+ labels:
+ app: slb
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: slb
+ template:
+ metadata:
+ labels:
+ app: slb
+ annotations:
+ k8s.plugin.opnfv.org/nfn-network: '{ "type": "ovn4nfv", "interface": [{ "name": "left-pnetwork", "interface": "net0" }, { "name": "dync-net1", "interface": "net1" }]}'
+
+ spec:
+ containers:
+ - name: slb
+ image: rkamudhan/netshoot:v1.0
+ imagePullPolicy: IfNotPresent
+ stdin: true
+ tty: true
+ securityContext:
+ privileged: true
+ capabilities:
+ add: ["NET_ADMIN"]
+
+---
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: ngfw
+ labels:
+ app: ngfw
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: ngfw
+ template:
+ metadata:
+ labels:
+ app: ngfw
+ annotations:
+ k8s.plugin.opnfv.org/nfn-network: '{ "type": "ovn4nfv", "interface": [{ "name": "dync-net1", "interface": "net0" }, { "name": "dync-net2", "interface": "net1" }]}'
+
+ spec:
+ containers:
+ - name: ngfw
+ image: rkamudhan/netshoot:v1.0
+ imagePullPolicy: IfNotPresent
+ stdin: true
+ tty: true
+ securityContext:
+ privileged: true
+ capabilities:
+ add: ["NET_ADMIN"]
+
+
+---
+
+apiVersion: v1
+data:
+ entrypoint.sh: |-
+ #!/bin/bash
+ # Always exit on errors.
+ set -ex
+ echo "" > /etc/config/network
+ cat > /etc/config/mwan3 <<EOF
+ config globals 'globals'
+ option mmx_mask '0x3F00'
+ option local_source 'lan'
+ EOF
+ eval "networks=$(grep nfn-network /tmp/podinfo/annotations | awk -F '=' '{print $2}')"
+ for net in $(echo -e $networks | jq -c ".interface[]")
+ do
+ interface=$(echo $net | jq -r .interface)
+ ipaddr=$(ifconfig $interface | awk '/inet/{print $2}' | cut -f2 -d ":" | awk 'NR==1 {print $1}')
+ vif="$interface"
+ cat >> /etc/config/network <<EOF
+ config interface '$vif'
+ option ifname '$interface'
+ option proto 'static'
+ option ipaddr '$ipaddr'
+ option netmask '255.255.255.0'
+ EOF
+ cat >> /etc/config/mwan3 <<EOF
+ config interface '$vif'
+ option enabled '1'
+ option family 'ipv4'
+ option reliability '2'
+ option count '1'
+ option timeout '2'
+ option failure_latency '1000'
+ option recovery_latency '500'
+ option failure_loss '20'
+ option recovery_loss '5'
+ option interval '5'
+ option down '3'
+ option up '8'
+ EOF
+ done
+ /sbin/procd &
+ /sbin/ubusd &
+ iptables -t nat -L
+ sleep 1
+ /etc/init.d/rpcd start
+ /etc/init.d/dnsmasq start
+ /etc/init.d/network start
+ /etc/init.d/odhcpd start
+ /etc/init.d/uhttpd start
+ /etc/init.d/log start
+ /etc/init.d/dropbear start
+ /etc/init.d/mwan3 restart
+ /etc/init.d/firewall restart
+ echo "Entering sleep... (success)"
+ # Sleep forever.
+ while true; do sleep 100; done
+kind: ConfigMap
+metadata:
+ name: sdewan-sh
+ namespace: default
+...
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: sdwan
+ namespace: default
+ labels:
+ app: sdwan
+ sdewanPurpose: cnf1
+spec:
+ progressDeadlineSeconds: 600
+ replicas: 1
+ selector:
+ matchLabels:
+ app: sdwan
+ sdewanPurpose: cnf1
+ strategy:
+ rollingUpdate:
+ maxSurge: 25%
+ maxUnavailable: 25%
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+ k8s.plugin.opnfv.org/nfn-network: '{ "type": "ovn4nfv", "interface": [{ "name": "dync-net2", "interface": "net0" }, { "name": "right-pnetwork", "interface": "net1" }]}'
+ labels:
+ app: sdwan
+ sdewanPurpose: cnf1
+ spec:
+ containers:
+ - command:
+ #- sleep
+ #- "3600"
+ - /bin/sh
+ - /tmp/sdewan/entrypoint.sh
+ image: integratedcloudnative/openwrt:0.3.0
+ imagePullPolicy: IfNotPresent
+ name: sdewan
+ readinessProbe:
+ failureThreshold: 5
+ httpGet:
+ path: /
+ port: 80
+ scheme: HTTP
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ successThreshold: 1
+ timeoutSeconds: 1
+ securityContext:
+ privileged: true
+ capabilities:
+ add: ["NET_ADMIN"]
+ procMount: Default
+ volumeMounts:
+ - mountPath: /tmp/sdewan
+ name: sdewan-sh
+ readOnly: true
+ - mountPath: /tmp/podinfo
+ name: podinfo
+ readOnly: true
+ restartPolicy: Always
+ volumes:
+ - configMap:
+ defaultMode: 420
+ name: sdewan-sh
+ name: sdewan-sh
+ - name: podinfo
+ downwardAPI:
+ items:
+ - path: "annotations"
+ fieldRef:
+ fieldPath: metadata.annotations
diff --git a/demo/sfc-setup/insecure_keys/key b/demo/sfc-setup/insecure_keys/key
new file mode 100644
index 0000000..7d6a083
--- /dev/null
+++ b/demo/sfc-setup/insecure_keys/key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI
+w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP
+kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2
+hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO
+Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW
+yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd
+ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1
+Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf
+TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK
+iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A
+sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf
+4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP
+cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk
+EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN
+CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX
+3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG
+YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj
+3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+
+dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz
+6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC
+P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF
+llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ
+kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH
++vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ
+NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s=
+-----END RSA PRIVATE KEY-----
diff --git a/demo/sfc-setup/insecure_keys/key.pub b/demo/sfc-setup/insecure_keys/key.pub
new file mode 100644
index 0000000..18a9c00
--- /dev/null
+++ b/demo/sfc-setup/insecure_keys/key.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
diff --git a/demo/sfc-setup/node.sh b/demo/sfc-setup/node.sh
new file mode 100755
index 0000000..a51be19
--- /dev/null
+++ b/demo/sfc-setup/node.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2018
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+set -o nounset
+set -o pipefail
+
+# usage() - Prints the usage of the program
+function usage {
+ cat <<EOF
+usage: $0 [-v volumes]
+Optional Argument:
+ -v List of key pair values for volumes and mount points ( e. g. sda=/var/lib/docker/,sdb=/var/lib/libvirt/ )
+EOF
+}
+
+# mount_external_partition() - Create partition and mount the external volume
+function mount_external_partition {
+ local dev_name="/dev/$1"
+ local mount_dir=$2
+
+ sfdisk $dev_name --no-reread << EOF
+;
+EOF
+ mkfs -t ext4 ${dev_name}1
+ mkdir -p $mount_dir
+ mount ${dev_name}1 $mount_dir
+ echo "${dev_name}1 $mount_dir ext4 errors=remount-ro,noatime,barrier=0 0 1" >> /etc/fstab
+}
+
+while getopts "h?v:" opt; do
+ case $opt in
+ v)
+ dict_volumes="$OPTARG"
+ ;;
+ h|\?)
+ usage
+ exit
+ ;;
+ esac
+done
+
+swapoff -a
+if [[ -n "${dict_volumes+x}" ]]; then
+ for kv in ${dict_volumes//,/ } ;do
+ mount_external_partition ${kv%=*} ${kv#*=}
+ done
+fi
+
+vendor_id=$(lscpu|grep "Vendor ID")
+if [[ $vendor_id == *GenuineIntel* ]]; then
+ kvm_ok=$(cat /sys/module/kvm_intel/parameters/nested)
+ if [[ $kvm_ok == 'N' ]]; then
+ echo "Enable Intel Nested-Virtualization"
+ rmmod kvm-intel
+ echo 'options kvm-intel nested=y' >> /etc/modprobe.d/dist.conf
+ modprobe kvm-intel
+ echo kvm-intel >> /etc/modules
+ fi
+else
+ kvm_ok=$(cat /sys/module/kvm_amd/parameters/nested)
+ if [[ $kvm_ok == '0' ]]; then
+ echo "Enable AMD Nested-Virtualization"
+ rmmod kvm-amd
+ sh -c "echo 'options kvm-amd nested=1' >> /etc/modprobe.d/dist.conf"
+ modprobe kvm-amd
+ echo kvm-amd >> /etc/modules
+ fi
+fi
+modprobe vhost_net
+echo vhost_net >> /etc/modules
+source /etc/os-release || source /usr/lib/os-release
+case ${ID,,} in
+ *suse)
+ ;;
+ ubuntu|debian)
+ apt-get install -y cpu-checker
+ kvm-ok
+ ;;
+ rhel|centos|fedora)
+ ;;
+esac
diff --git a/demo/sfc-setup/ovn4nfv-pod-network/ovn-daemonset.yaml b/demo/sfc-setup/ovn4nfv-pod-network/ovn-daemonset.yaml
new file mode 100644
index 0000000..677a9bc
--- /dev/null
+++ b/demo/sfc-setup/ovn4nfv-pod-network/ovn-daemonset.yaml
@@ -0,0 +1,239 @@
+---
+kind: Service
+apiVersion: v1
+metadata:
+ name: ovn-nb-tcp
+ namespace: kube-system
+spec:
+ ports:
+ - name: ovn-nb-tcp
+ protocol: TCP
+ port: 6641
+ targetPort: 6641
+ type: ClusterIP
+ selector:
+ app: ovn-control-plane
+ sessionAffinity: None
+
+---
+kind: Service
+apiVersion: v1
+metadata:
+ name: ovn-sb-tcp
+ namespace: kube-system
+spec:
+ ports:
+ - name: ovn-sb-tcp
+ protocol: TCP
+ port: 6642
+ targetPort: 6642
+ type: ClusterIP
+ selector:
+ app: ovn-control-plane
+ sessionAffinity: None
+
+---
+kind: Deployment
+apiVersion: apps/v1
+metadata:
+ name: ovn-control-plane
+ namespace: kube-system
+ annotations:
+ kubernetes.io/description: |
+ OVN control plane deployment using tcp: ovn-northd-tcp, ovn-nb-tcp and ovn-sb-tcp.
+spec:
+ replicas: 1
+ strategy:
+ rollingUpdate:
+ maxSurge: 0%
+ maxUnavailable: 100%
+ type: RollingUpdate
+ selector:
+ matchLabels:
+ app: ovn-control-plane
+ template:
+ metadata:
+ labels:
+ app: ovn-control-plane
+ spec:
+ tolerations:
+ - operator: Exists
+ effect: NoSchedule
+ affinity:
+ podAntiAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchLabels:
+ app: ovn-control-plane
+ topologyKey: kubernetes.io/hostname
+ priorityClassName: system-cluster-critical
+ hostNetwork: true
+ containers:
+ - name: ovn-control-plane
+ image: docker.io/integratedcloudnative/ovn-images:v1.0.0
+ imagePullPolicy: IfNotPresent
+ command: ["ovn4nfv-k8s", "start_ovn_control_plane"]
+ securityContext:
+ capabilities:
+ add: ["SYS_NICE"]
+ env:
+ - name: POD_IP
+ valueFrom:
+ fieldRef:
+ fieldPath: status.podIP
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ resources:
+ requests:
+ cpu: 500m
+ memory: 300Mi
+ volumeMounts:
+ - mountPath: /var/run/openvswitch
+ name: host-run-ovs
+ - mountPath: /var/run/ovn
+ name: host-run-ovn
+ - mountPath: /sys
+ name: host-sys
+ readOnly: true
+ - mountPath: /etc/openvswitch
+ name: host-config-openvswitch
+ - mountPath: /var/log/openvswitch
+ name: host-log-ovs
+ - mountPath: /var/log/ovn
+ name: host-log-ovn
+ readinessProbe:
+ exec:
+ command: ["ovn4nfv-k8s", "check_ovn_control_plane"]
+ periodSeconds: 3
+ livenessProbe:
+ exec:
+ command: ["ovn4nfv-k8s", "check_ovn_control_plane"]
+ initialDelaySeconds: 30
+ periodSeconds: 7
+ failureThreshold: 5
+ nodeSelector:
+ beta.kubernetes.io/os: "linux"
+ ovn4nfv-k8s-plugin: ovn-control-plane
+ volumes:
+ - name: host-run-ovs
+ hostPath:
+ path: /run/openvswitch
+ - name: host-run-ovn
+ hostPath:
+ path: /run/ovn
+ - name: host-sys
+ hostPath:
+ path: /sys
+ - name: host-config-openvswitch
+ hostPath:
+ path: /etc/origin/openvswitch
+ - name: host-log-ovs
+ hostPath:
+ path: /var/log/openvswitch
+ - name: host-log-ovn
+ hostPath:
+ path: /var/log/ovn
+
+---
+kind: DaemonSet
+apiVersion: apps/v1
+metadata:
+ name: ovn-controller
+ namespace: kube-system
+ annotations:
+ kubernetes.io/description: |
+ OVN controller: Start ovsdb-server & ovs-vswitchd components, and ovn controller
+spec:
+ selector:
+ matchLabels:
+ app: ovn-controller
+ updateStrategy:
+ type: OnDelete
+ template:
+ metadata:
+ labels:
+ app: ovn-controller
+ spec:
+ tolerations:
+ - operator: Exists
+ effect: NoSchedule
+ priorityClassName: system-cluster-critical
+ hostNetwork: true
+ hostPID: true
+ containers:
+ - name: ovn-controller
+ image: docker.io/integratedcloudnative/ovn-images:v1.0.0
+ imagePullPolicy: IfNotPresent
+ command: ["ovn4nfv-k8s", "start_ovn_controller"]
+ securityContext:
+ runAsUser: 0
+ privileged: true
+ env:
+ - name: POD_IP
+ valueFrom:
+ fieldRef:
+ fieldPath: status.podIP
+ volumeMounts:
+ - mountPath: /lib/modules
+ name: host-modules
+ readOnly: true
+ - mountPath: /var/run/openvswitch
+ name: host-run-ovs
+ - mountPath: /var/run/ovn
+ name: host-run-ovn
+ - mountPath: /sys
+ name: host-sys
+ readOnly: true
+ - mountPath: /etc/openvswitch
+ name: host-config-openvswitch
+ - mountPath: /var/log/openvswitch
+ name: host-log-ovs
+ - mountPath: /var/log/ovn
+ name: host-log-ovn
+ readinessProbe:
+ exec:
+ command: ["ovn4nfv-k8s", "check_ovn_controller"]
+ periodSeconds: 5
+ livenessProbe:
+ exec:
+ command: ["ovn4nfv-k8s", "check_ovn_controller"]
+ initialDelaySeconds: 10
+ periodSeconds: 5
+ failureThreshold: 5
+ resources:
+ requests:
+ cpu: 200m
+ memory: 300Mi
+ limits:
+ cpu: 1000m
+ memory: 800Mi
+ nodeSelector:
+ beta.kubernetes.io/os: "linux"
+ volumes:
+ - name: host-modules
+ hostPath:
+ path: /lib/modules
+ - name: host-run-ovs
+ hostPath:
+ path: /run/openvswitch
+ - name: host-run-ovn
+ hostPath:
+ path: /run/ovn
+ - name: host-sys
+ hostPath:
+ path: /sys
+ - name: host-config-openvswitch
+ hostPath:
+ path: /etc/origin/openvswitch
+ - name: host-log-ovs
+ hostPath:
+ path: /var/log/openvswitch
+ - name: host-log-ovn
+ hostPath:
+ path: /var/log/ovn
diff --git a/demo/sfc-setup/ovn4nfv-pod-network/ovn4nfv-k8s-plugin.yml b/demo/sfc-setup/ovn4nfv-pod-network/ovn4nfv-k8s-plugin.yml
new file mode 100644
index 0000000..5adf786
--- /dev/null
+++ b/demo/sfc-setup/ovn4nfv-pod-network/ovn4nfv-k8s-plugin.yml
@@ -0,0 +1,714 @@
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: networkchainings.k8s.plugin.opnfv.org
+spec:
+ group: k8s.plugin.opnfv.org
+ names:
+ kind: NetworkChaining
+ listKind: NetworkChainingList
+ plural: networkchainings
+ singular: networkchaining
+ scope: Namespaced
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ description: NetworkChaining is the Schema for the networkchainings API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: NetworkChainingSpec defines the desired state of NetworkChaining
+ properties:
+ chainType:
+ type: string
+ routingSpec:
+ properties:
+ leftNetwork:
+ items:
+ properties:
+ gatewayIp:
+ type: string
+ networkName:
+ type: string
+ required:
+ - gatewayIp
+ - networkName
+ type: object
+ type: array
+ namespace:
+ type: string
+ networkChain:
+ type: string
+ rightNetwork:
+ items:
+ properties:
+ gatewayIp:
+ type: string
+ networkName:
+ type: string
+ required:
+ - gatewayIp
+ - networkName
+ type: object
+ type: array
+ required:
+ - leftNetwork
+ - namespace
+ - networkChain
+ - rightNetwork
+ type: object
+ required:
+ - chainType
+ - routingSpec
+ type: object
+ status:
+ description: NetworkChainingStatus defines the observed state of NetworkChaining
+ properties:
+ state:
+ type: string
+ required:
+ - state
+ type: object
+ type: object
+ version: v1alpha1
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: networks.k8s.plugin.opnfv.org
+spec:
+ group: k8s.plugin.opnfv.org
+ names:
+ kind: Network
+ listKind: NetworkList
+ plural: networks
+ singular: network
+ scope: Namespaced
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ properties:
+ cniType:
+ description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ Important: Run "operator-sdk generate k8s" to regenerate code after
+ modifying this file Add custom validation using kubebuilder tags:
+ https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
+ type: string
+ dns:
+ properties:
+ domain:
+ type: string
+ nameservers:
+ items:
+ type: string
+ type: array
+ options:
+ items:
+ type: string
+ type: array
+ search:
+ items:
+ type: string
+ type: array
+ type: object
+ ipv4Subnets:
+ items:
+ properties:
+ excludeIps:
+ type: string
+ gateway:
+ type: string
+ name:
+ type: string
+ subnet:
+ type: string
+ required:
+ - name
+ - subnet
+ type: object
+ type: array
+ ipv6Subnets:
+ items:
+ properties:
+ excludeIps:
+ type: string
+ gateway:
+ type: string
+ name:
+ type: string
+ subnet:
+ type: string
+ required:
+ - name
+ - subnet
+ type: object
+ type: array
+ routes:
+ items:
+ properties:
+ dst:
+ type: string
+ gw:
+ type: string
+ required:
+ - dst
+ type: object
+ type: array
+ required:
+ - cniType
+ - ipv4Subnets
+ type: object
+ status:
+ properties:
+ state:
+ description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
+ of cluster Important: Run "operator-sdk generate k8s" to regenerate
+ code after modifying this file Add custom validation using kubebuilder
+ tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
+ type: string
+ required:
+ - state
+ type: object
+ version: v1alpha1
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: providernetworks.k8s.plugin.opnfv.org
+spec:
+ group: k8s.plugin.opnfv.org
+ names:
+ kind: ProviderNetwork
+ listKind: ProviderNetworkList
+ plural: providernetworks
+ singular: providernetwork
+ scope: Namespaced
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ description: ProviderNetwork is the Schema for the providernetworks API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: ProviderNetworkSpec defines the desired state of ProviderNetwork
+ properties:
+ cniType:
+ description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ Important: Run "operator-sdk generate k8s" to regenerate code after
+ modifying this file Add custom validation using kubebuilder tags:
+ https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
+ type: string
+ direct:
+ properties:
+ directNodeSelector:
+ type: string
+ nodeLabelList:
+ items:
+ type: string
+ type: array
+ providerInterfaceName:
+ type: string
+ required:
+ - directNodeSelector
+ - providerInterfaceName
+ type: object
+ dns:
+ properties:
+ domain:
+ type: string
+ nameservers:
+ items:
+ type: string
+ type: array
+ options:
+ items:
+ type: string
+ type: array
+ search:
+ items:
+ type: string
+ type: array
+ type: object
+ ipv4Subnets:
+ items:
+ properties:
+ excludeIps:
+ type: string
+ gateway:
+ type: string
+ name:
+ type: string
+ subnet:
+ type: string
+ required:
+ - name
+ - subnet
+ type: object
+ type: array
+ ipv6Subnets:
+ items:
+ properties:
+ excludeIps:
+ type: string
+ gateway:
+ type: string
+ name:
+ type: string
+ subnet:
+ type: string
+ required:
+ - name
+ - subnet
+ type: object
+ type: array
+ providerNetType:
+ type: string
+ routes:
+ items:
+ properties:
+ dst:
+ type: string
+ gw:
+ type: string
+ required:
+ - dst
+ type: object
+ type: array
+ vlan:
+ properties:
+ logicalInterfaceName:
+ type: string
+ nodeLabelList:
+ items:
+ type: string
+ type: array
+ providerInterfaceName:
+ type: string
+ vlanId:
+ type: string
+ vlanNodeSelector:
+ type: string
+ required:
+ - providerInterfaceName
+ - vlanId
+ - vlanNodeSelector
+ type: object
+ required:
+ - cniType
+ - ipv4Subnets
+ - providerNetType
+ type: object
+ status:
+ description: ProviderNetworkStatus defines the observed state of ProviderNetwork
+ properties:
+ state:
+ description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
+ of cluster Important: Run "operator-sdk generate k8s" to regenerate
+ code after modifying this file Add custom validation using kubebuilder
+ tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
+ type: string
+ required:
+ - state
+ type: object
+ type: object
+ version: v1alpha1
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+---
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: k8s-nfn-sa
+ namespace: kube-system
+
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ creationTimestamp: null
+ name: k8s-nfn-cr
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - pods
+ - pods/status
+ - services
+ - endpoints
+ - persistentvolumeclaims
+ - events
+ - configmaps
+ - secrets
+ - nodes
+ verbs:
+ - '*'
+- apiGroups:
+ - apps
+ resources:
+ - deployments
+ - daemonsets
+ - replicasets
+ - statefulsets
+ verbs:
+ - '*'
+- apiGroups:
+ - monitoring.coreos.com
+ resources:
+ - servicemonitors
+ verbs:
+ - get
+ - create
+- apiGroups:
+ - apps
+ resourceNames:
+ - nfn-operator
+ resources:
+ - deployments/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - k8s.plugin.opnfv.org
+ resources:
+ - '*'
+ - providernetworks
+ verbs:
+ - '*'
+
+---
+
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: k8s-nfn-crb
+subjects:
+- kind: Group
+ name: system:serviceaccounts
+ apiGroup: rbac.authorization.k8s.io
+roleRef:
+ kind: ClusterRole
+ name: k8s-nfn-cr
+ apiGroup: rbac.authorization.k8s.io
+
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: nfn-operator
+ namespace: kube-system
+spec:
+ type: NodePort
+ ports:
+ - port: 50000
+ protocol: TCP
+ targetPort: 50000
+ selector:
+ name: nfn-operator
+
+
+---
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: ovn-controller-network
+ namespace: kube-system
+data:
+ OVN_SUBNET: "10.233.64.0/18"
+ OVN_GATEWAYIP: "10.233.64.1/18"
+
+---
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: nfn-operator
+ namespace: kube-system
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ name: nfn-operator
+ template:
+ metadata:
+ labels:
+ name: nfn-operator
+ spec:
+ hostNetwork: true
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: ovn4nfv-k8s-plugin
+ operator: In
+ values:
+ - ovn-control-plane
+ tolerations:
+ - key: "node-role.kubernetes.io/master"
+ effect: "NoSchedule"
+ operator: "Exists"
+ serviceAccountName: k8s-nfn-sa
+ containers:
+ - name: nfn-operator
+ image: docker.io/rkamudhan/ovn4nfv-k8s-plugin:alpha-v0.0.5.4
+ command: ["/usr/local/bin/entrypoint", "operator"]
+ imagePullPolicy: IfNotPresent
+ envFrom:
+ - configMapRef:
+ name: ovn-controller-network
+ ports:
+ - containerPort: 50000
+ protocol: TCP
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: OPERATOR_NAME
+ value: "nfn-operator"
+
+---
+kind: ConfigMap
+apiVersion: v1
+metadata:
+ name: ovn4nfv-cni-config
+ namespace: kube-system
+ labels:
+ app: ovn4nfv
+data:
+ ovn4nfv_k8s.conf: |
+ [logging]
+ loglevel=5
+ logfile=/var/log/openvswitch/ovn4k8s.log
+
+ [cni]
+ conf-dir=/etc/cni/net.d
+ plugin=ovn4nfvk8s-cni
+
+ [kubernetes]
+ kubeconfig=/etc/cni/net.d/ovn4nfv-k8s.d/ovn4nfv-k8s.kubeconfig
+ 00-network.conf: |
+ {
+ "name": "ovn4nfv-k8s-plugin",
+ "type": "ovn4nfvk8s-cni",
+ "cniVersion": "0.3.1"
+ }
+
+---
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+ name: ovn4nfv-cni
+ namespace: kube-system
+ labels:
+ app: ovn4nfv
+spec:
+ updateStrategy:
+ type: RollingUpdate
+ selector:
+ matchLabels:
+ app: ovn4nfv
+ template:
+ metadata:
+ labels:
+ app: ovn4nfv
+ spec:
+ hostNetwork: true
+ nodeSelector:
+ beta.kubernetes.io/arch: amd64
+ tolerations:
+ - operator: Exists
+ effect: NoSchedule
+ serviceAccountName: k8s-nfn-sa
+ containers:
+ - name: ovn4nfv
+ image: docker.io/rkamudhan/ovn4nfv-k8s-plugin:alpha-v0.0.5.4
+ command: ["/usr/local/bin/entrypoint", "cni"]
+ imagePullPolicy: IfNotPresent
+ resources:
+ requests:
+ cpu: 100m
+ memory: 50Mi
+ limits:
+ cpu: 100m
+ memory: 50Mi
+ securityContext:
+ privileged: true
+ volumeMounts:
+ - name: cni
+ mountPath: /host/etc/cni/net.d
+ - name: cnibin
+ mountPath: /host/opt/cni/bin
+ - name: cniconf
+ mountPath: /host/etc/openvswitch
+ - name: ovn4nfv-cfg
+ mountPath: /tmp/ovn4nfv-conf
+ - name: ovn4nfv-cni-net-conf
+ mountPath: /tmp/ovn4nfv-cni
+ volumes:
+ - name: cni
+ hostPath:
+ path: /etc/cni/net.d
+ - name: cnibin
+ hostPath:
+ path: /opt/cni/bin
+ - name: cniconf
+ hostPath:
+ path: /etc/openvswitch
+ - name: ovn4nfv-cfg
+ configMap:
+ name: ovn4nfv-cni-config
+ items:
+ - key: ovn4nfv_k8s.conf
+ path: ovn4nfv_k8s.conf
+ - name: ovn4nfv-cni-net-conf
+ configMap:
+ name: ovn4nfv-cni-config
+ items:
+ - key: 00-network.conf
+ path: 00-network.conf
+---
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+ name: nfn-agent
+ namespace: kube-system
+ labels:
+ app: nfn-agent
+spec:
+ selector:
+ matchLabels:
+ app: nfn-agent
+ updateStrategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: nfn-agent
+ spec:
+ hostNetwork: true
+ hostPID: true
+ nodeSelector:
+ beta.kubernetes.io/arch: amd64
+ tolerations:
+ - operator: Exists
+ effect: NoSchedule
+ serviceAccountName: k8s-nfn-sa
+ containers:
+ - name: nfn-agent
+ image: docker.io/rkamudhan/ovn4nfv-k8s-plugin:alpha-v0.0.5.4
+ command: ["/usr/local/bin/entrypoint", "agent"]
+ imagePullPolicy: IfNotPresent
+ resources:
+ requests:
+ cpu: 100m
+ memory: 50Mi
+ limits:
+ cpu: 100m
+ memory: 50Mi
+ env:
+ - name: NFN_NODE_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.nodeName
+ securityContext:
+ runAsUser: 0
+ capabilities:
+ add: ["NET_ADMIN", "SYS_ADMIN", "SYS_PTRACE"]
+ privileged: true
+ volumeMounts:
+ - mountPath: /var/run/dbus/
+ name: host-var-run-dbus
+ readOnly: true
+ - mountPath: /run/openvswitch
+ name: host-run-ovs
+ - mountPath: /var/run/openvswitch
+ name: host-var-run-ovs
+ - mountPath: /var/run
+ name: host-var-run
+ - mountPath: /host/proc
+ name: host-proc
+ - mountPath: /host/sys
+ name: host-sys
+ - mountPath: /var/run/ovn4nfv-k8s-plugin
+ name: host-var-cniserver-socket-dir
+ volumes:
+ - name: host-run-ovs
+ hostPath:
+ path: /run/openvswitch
+ - name: host-var-run-ovs
+ hostPath:
+ path: /var/run/openvswitch
+ - name: host-var-run-dbus
+ hostPath:
+ path: /var/run/dbus
+ - name: host-var-cniserver-socket-dir
+ hostPath:
+ path: /var/run/ovn4nfv-k8s-plugin
+ - name: host-var-run
+ hostPath:
+ path: /var/run
+ - name: host-proc
+ hostPath:
+ path: /proc
+ - name: host-sys
+ hostPath:
+ path: /sys
diff --git a/demo/sfc-setup/setup.sh b/demo/sfc-setup/setup.sh
new file mode 100755
index 0000000..79bf60c
--- /dev/null
+++ b/demo/sfc-setup/setup.sh
@@ -0,0 +1,201 @@
+#!/bin/bash
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2018
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+set -o nounset
+set -o pipefail
+
+vagrant_version=2.2.4
+if ! vagrant version &>/dev/null; then
+ enable_vagrant_install=true
+else
+ if [[ "$vagrant_version" != "$(vagrant version | awk 'NR==1{print $3}')" ]]; then
+ enable_vagrant_install=true
+ fi
+fi
+
+function usage {
+ cat <<EOF
+usage: $0 -p <PROVIDER>
+Installation of vagrant and its dependencies in Linux OS
+
+Argument:
+ -p Vagrant provider
+EOF
+}
+
+while getopts ":p:" OPTION; do
+ case $OPTION in
+ p)
+ provider=$OPTARG
+ ;;
+ \?)
+ usage
+ exit 1
+ ;;
+ esac
+done
+if [[ -z "${provider+x}" ]]; then
+ usage
+ exit 1
+fi
+
+case $provider in
+ "virtualbox" | "libvirt" )
+ export VAGRANT_DEFAULT_PROVIDER=${provider}
+ ;;
+ * )
+ usage
+ exit 1
+esac
+source /etc/os-release || source /usr/lib/os-release
+
+libvirt_group="libvirt"
+packages=()
+case ${ID,,} in
+ *suse)
+ INSTALLER_CMD="sudo -H -E zypper -q install -y --no-recommends"
+ packages+=(python-devel)
+
+ # Vagrant installation
+ if [[ "${enable_vagrant_install+x}" ]]; then
+ vagrant_pgp="pgp_keys.asc"
+ wget -q https://keybase.io/hashicorp/$vagrant_pgp
+ wget -q https://releases.hashicorp.com/vagrant/$vagrant_version/vagrant_${vagrant_version}_x86_64.rpm
+ gpg --quiet --with-fingerprint $vagrant_pgp
+ sudo rpm --import $vagrant_pgp
+ sudo rpm --checksig vagrant_${vagrant_version}_x86_64.rpm
+ sudo rpm --install vagrant_${vagrant_version}_x86_64.rpm
+ rm vagrant_${vagrant_version}_x86_64.rpm
+ rm $vagrant_pgp
+ fi
+
+ case $VAGRANT_DEFAULT_PROVIDER in
+ virtualbox)
+ wget -q "http://download.virtualbox.org/virtualbox/rpm/opensuse/$VERSION/virtualbox.repo" -P /etc/zypp/repos.d/
+ $INSTALLER_CMD --enablerepo=epel dkms
+ wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | rpm --import -
+ packages+=(VirtualBox-5.1)
+ ;;
+ libvirt)
+ # vagrant-libvirt dependencies
+ packages+=(qemu libvirt libvirt-devel ruby-devel gcc qemu-kvm zlib-devel libxml2-devel libxslt-devel make)
+ # NFS
+ packages+=(nfs-kernel-server)
+ ;;
+ esac
+ sudo zypper -n ref
+ ;;
+
+ ubuntu|debian)
+ libvirt_group="libvirtd"
+ INSTALLER_CMD="sudo -H -E apt-get -y -q=3 install"
+ packages+=(python-dev)
+
+ # Vagrant installation
+ if [[ "${enable_vagrant_install+x}" ]]; then
+ wget -q https://releases.hashicorp.com/vagrant/$vagrant_version/vagrant_${vagrant_version}_x86_64.deb
+ sudo dpkg -i vagrant_${vagrant_version}_x86_64.deb
+ rm vagrant_${vagrant_version}_x86_64.deb
+ fi
+
+ case $VAGRANT_DEFAULT_PROVIDER in
+ virtualbox)
+ echo "deb http://download.virtualbox.org/virtualbox/debian bionic contrib" >> /etc/apt/sources.list
+ wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -
+ wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -
+ packages+=(virtualbox-5.1 dkms)
+ ;;
+ libvirt)
+ # vagrant-libvirt dependencies
+ packages+=(qemu libvirt-bin ebtables dnsmasq libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev cpu-checker)
+ # NFS
+ packages+=(nfs-kernel-server)
+ ;;
+ esac
+ sudo apt-get update
+ ;;
+
+ rhel|centos|fedora)
+ PKG_MANAGER=$(which dnf || which yum)
+ sudo "$PKG_MANAGER" updateinfo
+ INSTALLER_CMD="sudo -H -E ${PKG_MANAGER} -q -y install"
+ packages+=(python-devel)
+
+ # Vagrant installation
+ if [[ "${enable_vagrant_install+x}" ]]; then
+ wget -q https://releases.hashicorp.com/vagrant/$vagrant_version/vagrant_${vagrant_version}_x86_64.rpm
+ $INSTALLER_CMD vagrant_${vagrant_version}_x86_64.rpm
+ rm vagrant_${vagrant_version}_x86_64.rpm
+ fi
+
+ case $VAGRANT_DEFAULT_PROVIDER in
+ virtualbox)
+ wget -q http://download.virtualbox.org/virtualbox/rpm/rhel/virtualbox.repo -P /etc/yum.repos.d
+ $INSTALLER_CMD --enablerepo=epel dkms
+ wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | rpm --import -
+ packages+=(VirtualBox-5.1)
+ ;;
+ libvirt)
+ # vagrant-libvirt dependencies
+ packages+=(qemu libvirt libvirt-devel ruby-devel gcc qemu-kvm)
+ # NFS
+ packages+=(nfs-utils nfs-utils-lib)
+ ;;
+ esac
+ ;;
+
+esac
+
+# Enable Nested-Virtualization
+vendor_id=$(lscpu|grep "Vendor ID")
+if [[ $vendor_id == *GenuineIntel* ]]; then
+ kvm_ok=$(cat /sys/module/kvm_intel/parameters/nested)
+ if [[ $kvm_ok == 'N' ]]; then
+ echo "Enable Intel Nested-Virtualization"
+ sudo rmmod kvm-intel
+ echo 'options kvm-intel nested=y' | sudo tee --append /etc/modprobe.d/dist.conf
+ sudo modprobe kvm-intel
+ fi
+else
+ kvm_ok=$(cat /sys/module/kvm_amd/parameters/nested)
+ if [[ $kvm_ok == '0' ]]; then
+ echo "Enable AMD Nested-Virtualization"
+ sudo rmmod kvm-amd
+ echo 'options kvm-amd nested=1' | sudo tee --append /etc/modprobe.d/dist.conf
+ sudo modprobe kvm-amd
+ fi
+fi
+sudo modprobe vhost_net
+
+${INSTALLER_CMD} "${packages[@]}"
+if ! which pip; then
+ curl -sL https://bootstrap.pypa.io/get-pip.py | sudo python
+else
+ sudo -H -E pip install --no-cache-dir --upgrade pip
+fi
+sudo -H -E pip install --no-cache-dir tox
+if [[ ${http_proxy+x} ]]; then
+ vagrant plugin install vagrant-proxyconf
+fi
+if [ "$VAGRANT_DEFAULT_PROVIDER" == libvirt ]; then
+ vagrant plugin install vagrant-libvirt
+ sudo usermod -a -G $libvirt_group "$USER" # This might require to reload user's group assigments
+ sudo systemctl restart libvirtd
+
+ # Start statd service to prevent NFS lock errors
+ sudo systemctl enable rpc-statd
+ sudo systemctl start rpc-statd
+
+ case ${ID,,} in
+ ubuntu|debian)
+ kvm-ok
+ ;;
+ esac
+fi