From abc86b0782d8d1ea41b5b5dd04b4c6c8755e7210 Mon Sep 17 00:00:00 2001 From: Kuralamudhan Ramakrishnan Date: Fri, 18 Sep 2020 00:29:11 -0700 Subject: 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 Change-Id: Id382f734dedb50354e7986fbf954663b374c1ff3 --- .gitignore | 1 + demo/sfc-setup/README.md | 113 ++++ demo/sfc-setup/Vagrantfile | 99 +++ demo/sfc-setup/config/default.yml | 30 + demo/sfc-setup/demo/firewall-dyn-net-2.yaml | 14 + demo/sfc-setup/demo/firewall-right-pnetwork.yaml | 16 + .../firewall-rule-reject-icmp-right-pnetwork.yaml | 13 + demo/sfc-setup/demo/ms1.yaml | 40 ++ demo/sfc-setup/demo/sfc-network.yaml | 67 ++ demo/sfc-setup/demo/sfc.yaml | 18 + .../demo/slb-ngfw-sdewan-cnf-deployment.yaml | 200 ++++++ demo/sfc-setup/insecure_keys/key | 27 + demo/sfc-setup/insecure_keys/key.pub | 1 + demo/sfc-setup/node.sh | 88 +++ .../ovn4nfv-pod-network/ovn-daemonset.yaml | 239 +++++++ .../ovn4nfv-pod-network/ovn4nfv-k8s-plugin.yml | 714 +++++++++++++++++++++ demo/sfc-setup/setup.sh | 201 ++++++ 17 files changed, 1881 insertions(+) create mode 100644 demo/sfc-setup/README.md create mode 100644 demo/sfc-setup/Vagrantfile create mode 100644 demo/sfc-setup/config/default.yml create mode 100644 demo/sfc-setup/demo/firewall-dyn-net-2.yaml create mode 100644 demo/sfc-setup/demo/firewall-right-pnetwork.yaml create mode 100644 demo/sfc-setup/demo/firewall-rule-reject-icmp-right-pnetwork.yaml create mode 100644 demo/sfc-setup/demo/ms1.yaml create mode 100644 demo/sfc-setup/demo/sfc-network.yaml create mode 100644 demo/sfc-setup/demo/sfc.yaml create mode 100644 demo/sfc-setup/demo/slb-ngfw-sdewan-cnf-deployment.yaml create mode 100644 demo/sfc-setup/insecure_keys/key create mode 100644 demo/sfc-setup/insecure_keys/key.pub create mode 100755 demo/sfc-setup/node.sh create mode 100644 demo/sfc-setup/ovn4nfv-pod-network/ovn-daemonset.yaml create mode 100644 demo/sfc-setup/ovn4nfv-pod-network/ovn4nfv-k8s-plugin.yml create mode 100755 demo/sfc-setup/setup.sh 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= +``` +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 <> /etc/config/network <> /etc/config/mwan3 <> /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 < +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 -- cgit 1.2.3-korg