SlideShare une entreprise Scribd logo
1  sur  45
Télécharger pour lire hors ligne
OvS manipulation with Go at
DigitalOcean
Matt Layher, Software Engineer
OvSCon 2017
digitalocean.com
● Software Engineer at DO for ~3.5 years
● Focused on virtual networking primitives
● Huge fan of Go programming language
● GitHub + Twitter: @mdlayher
digitalocean.com
Cloud computing designed for developers
● Cloud provider with focus on simplicity
● “Droplet” product is a virtual machine
● Compute, storage, networking, and monitoring primitives
○ Load Balancers as a Service
○ Floating IPs
○ Cloud Firewalls (learn more at Kei Nohguchi’s talk!)
digitalocean.com
DO is powered by Open vSwitch!
● 10,000+ of instances of OvS!
● One of the most crucial components in our entire stack.
digitalocean.com
Open vSwitch at DigitalOcean:
The Past
digitalocean.com
Open vSwitch and Perl
● Events (create droplet, power on, etc.) reach a hypervisor
● Perl event handlers pick up events and performs a series of
actions to prepare a droplet
● Perl builds flow strings and calls ovs-ofctl
digitalocean.com
Building flows with Perl
my $ipv4_flow_rules = [
[
# Flow priority.
2020,
# Hash of flow matches.
{
dl_src => $mac,
in_port => $ovs_port_id,
ip => undef,
nw_src => "${ip}/32",
},
# Literal string of flow actions.
"mod_vlan_vid:${ipv4vlan},resubmit(,1)"
],
# … many more flows
]
digitalocean.com
Applying flows with Perl
# Build comma-separated matches from hash.
my $flow = _construct_flow_string($flow_hash);
# Build the flow string with usual fields.
my $cmd = "priority=${priority},idle_timeout=${timeout},${flow},actions=${actions}";
# Once a flow is added, we need a way to delete it later on!
if ($add_delete_hook && defined($delete_hook_handle)) {
# Flows written into a libvirt hook to be deleted later.
if (_write_flow_to_be_deleted($bridge, $delete_hook_handle, $flow) != PASS) {
return FAIL;
}
}
# Shell out to ovs-ofctl and do the work!
return _run_ovs_cmd("ovs-ofctl add-flow ${bridge} '${cmd}'");
digitalocean.com
Conclusions: Open vSwitch and Perl
● Pros:
○ Straightforward code
○ Perl is well-suited to manipulating strings
● Cons:
○ No sanity checking (other than OvS applying the flow)
○ Lacking test coverage
○ libvirt flow deletion hooks for individual flows proved problematic
○ Shell out once per flow; no atomicity
digitalocean.com
Open vSwitch at DigitalOcean:
The Present
digitalocean.com
Open vSwitch and Go
● Events reach a hypervisor
● Perl/Go (it depends) systems perform a series of actions to
prepare a droplet
● Go builds flow strings and calls ovs-ofctl
digitalocean.com
package ovs
Package ovs is a client library for Open vSwitch which enables programmatic control of
the virtual switch.
digitalocean.com
package ovs
● Go package for manipulating Open vSwitch
● No DigitalOcean-specific code!
● Open source (soon)!
○ https://github.com/digitalocean/go-openvswitch
digitalocean.com
Building flows with Go
flow := &ovs.Flow{
// Commonly used flow pieces are struct fields.
Priority: 2000,
Protocol: ovs.ProtocolIPv4,
InPort: droplet.PortID,
// Matches and Actions are Go interfaces; functions create a
// type that implements the interface.
Matches: []ovs.Match{
ovs.DataLinkSource(r.HardwareAddr.String()),
ovs.NetworkSource(r.IP.String()),
},
Actions: []ovs.Action{
ovs.Resubmit(0, tableL2Rewrite),
},
}
digitalocean.com
Building flows with Go (cont.)
● Our example flow marshaled to textual format:
priority=2000,ip,in_port=1,dl_src=de:ad:be:ef:de:ad, 
nw_src=192.168.1.1,table=0,idle_timeout=0,actions=resubmit(,10)
● Mostly string manipulation behind the scenes; just like Perl
● Go is statically typed, reducing chance of programmer errors
● Can validate each match and action for correctness without hitting OvS
digitalocean.com
The ovs.Match Go interface
type Match interface {
// MarshalText() (text []byte, err error)
encoding.TextMarshaler
}
● Because of the way Go interfaces work, any type with a MarshalText method can be
used as an ovs.Match
● The error return value can be used to catch any bad input
● ovs.Action’s definition is identical
digitalocean.com
The ovs.Client Go type
// Configure ovs.Client with our required OpenFlow flow format and protocol.
client := ovs.New(ovs.FlowFormat("OXM-OpenFlow14"), ovs.Protocols("OpenFlow14"))
// $ ovs-vsctl --may-exist add-br br0
err := client.VSwitch.AddBridge("br0")
// $ ovs-ofctl add-flow --flow-format=OXM-OpenFlow14 --protocols=OpenFlow14 br0 ${flow}
err = client.OpenFlow.AddFlow("br0", exampleFlow())
● ovs.Client is a wrapper around ovs-vsctl and ovs-ofctl commands
● ovs.New constructor uses “functional options” pattern for sane defaults
● We can still only apply one flow at a time… right?
digitalocean.com
ovs.Client flow bundle transactions
// Assume we want to apply a new flow set and remove old one.
add, remove := newFlows(), oldFlows()
// We can apply all of these flows atomically using a flow bundle!
err := client.OpenFlow.AddFlowBundle(bridge, func(tx *ovs.FlowTransaction) error {
// $ echo -e “delete priority=10,cookie=1,actions=dropn” >> mem
tx.Delete(remove...)
// $ echo -e “add priority=10,cookie=1,actions=output:1n” >> mem
tx.Add(add...)
// $ cat mem | ovs-ofctl --bundle add-flow --flow-format=OXM-OpenFlow14 --protocols=OpenFlow14 br0 -
return tx.Commit()
})
● Flow bundle stored in memory, passed directly from buffer to ovs-ofctl
● Modifications are processed by OvS in a single, atomic transaction
digitalocean.com
package hvflow
Package hvflow provides Open vSwitch flow manipulation at the hypervisor level.
digitalocean.com
package hvflow
● DigitalOcean-specific wrapper for package ovs
● Provides higher-level constructs, such as:
○ enable public IPv4 and IPv6 connectivity
○ reset and apply security policies
○ disable all connectivity
digitalocean.com
The hvflow.Client Go type
// Configure hvflow.Client to modify bridge “br0”.
client, err := hvflow.NewClient("br0", ovs.New(
ovs.FlowFormat("OXM-OpenFlow14"), ovs.Protocols("OpenFlow14"),
))
● hvflow.Client is a high-level wrapper around ovs.Client
● hvflow.NewClient constructor uses “functional options” pattern for sane defaults
digitalocean.com
Network parameters - “netparams”
● Encode all necessary information about
how to enable networking for a given
VNIC
● Carries IPv4 and IPv6 addresses, firewall
configurations, floating IPs…
● netparams used to configure OvS with
hvflow.Client.Transaction method
{
"droplet_id": 1,
"vnics": [
{
"mac": "de:ad:be:ef:de:ad",
"enabled": 1,
"name": "tapext1",
"interface_type": "public",
"addresses": {
"ipv4": [
{
"ip_address": "10.0.0.10",
"masklen": 20,
"gateway": "10.0.0.1"
}
]
}
}
]
}
digitalocean.com
hvflow.Client transactions
// Assume a netparams structure similar to the one just shown.
params, ifi := networkParams(), "public"
err := client.Transaction(ctx, func(ctx context.Context, tx *hvflow.Transaction) error {
// Convert netparams into hvflow simplified representation.
req, ok, err := hvflow.NewIPv4Request(params, ifi)
if err != nil {
return err
}
if ok {
// If IPv4 configuration present, apply it!
if err := tx.EnableIPv4(ctx, req); err != nil {
return wrapError(err, "failed to enable IPv4 networking")
}
}
return tx.Commit()
})
digitalocean.com
hvflow.Client transactions (cont.)
● Each operation accumulates additional
flows to be applied within the context of
the transaction.
● Flow set sizes can vary from a couple
dozen to several hundred flows.
● Flows are always applied using a flow
bundle; non-transactional
hvflow.Client API was deleted!
// IPv4 configuration.
err := tx.EnableIPv4(ctx, req4)
// IPv6 configuration.
err = tx.EnableIPv6(ctx, req6)
// Floating IPv4 configuration.
err = tx.EnableFloatingIPv4(ctx, req4F)
// Disable networking on an interface.
err = tx.Disable(ctx, 10, "public")
// Apply flow set to OvS.
err = tx.Commit()
digitalocean.com
The hvflow.Cookie Go interface
type Cookie interface {
Marshal() (uint64, error)
Unmarshal(i uint64) error
}
● Cookie structs packed and unpacked from uint64 form
● Cookies are versioned using a 4-bit identifier
● Used to store identification metadata about a flow
● Easy deletions of flows; much simpler deletion hooks with libvirt
digitalocean.com
hvflowctl and hvflowd
gRPC client and server that manipulate Open vSwitch
digitalocean.com
hvflowctl and hvflowd
● gRPC client and server written in Go
● hvflowctl passes netparams and other data to hvflowd
● hvflowd manipulates OvS flows via hvflow package
digitalocean.com
hvflowd’s gRPC interface
● gRPC uses protocol buffers
(“protobuf”) for RPC
communication
● RPCs accept one message type
and return another
● netparamspb package for
encoding netparams in
protobuf
// The set of RPCs that make up the “HVFlow” service.
service HVFlow {
// Add flows using the parameters specified in request.
rpc AddFlows(AddFlowsRequest) returns (AddFlowsResponse);
}
// RPC parameters encoded within a request message.
message AddFlowsRequest {
// netparams have a protobuf representation too.
netparamspb.NetworkParams network_params = 1;
string interface_type = 2;
}
// No need to return any data on success.
message AddFlowsResponse {}
digitalocean.com
hvflowd AddFlows RPC
// AddFlows requests that hvflowd add flows to enable connectivity for one or more droplets.
func (s *server) AddFlows(ctx context.Context, req *hpb.AddFlowsRequest) (*hpb.AddFlowsResponse, error) {
// Fetch netparams from gRPC request message.
params := req.GetNetworkParams()
// Perform the necessary transaction logic to establish connectivity.
err := s.hvflowc.Transaction(ctx, func(ctx context.Context, tx *hvflow.Transaction) error {
// hvflow.Client transaction logic …
return tx.Commit()
})
// Inform the caller if the request was successful.
return &hvflowpb.AddFlowsResponse{}, err
}
● RPCs enable orchestration among multiple hypervisors and hvflowd instances
digitalocean.com
Testing hvflowctl and hvflowd
● Unit tests verify a flow looks a certain way
○ go test ./...
● Integration tests verify the behavior of flows applied to OvS
○ mininet, OvS, hvflowctl, hvflowd
digitalocean.com
Testing with mininet
● Network topology created with multi-namespace OvS in mininet
● hvflowd spun up in each “hypervisor namespace”
# Spin up hvflowd in the background and set per-hypervisor environment
# variables needed to enable multiple instances to run together.
for key in self.hvflowdEnv:
self.cmd('export %s=%s' % (key, self.hvflowdEnv[key]))
self.cmd('%s &' % (self.hvflowdPath))
● hvflowctl issues RPCs using JSON netparams fixtures
# Issue RPCs to hvflowd using flags and netparams JSON.
self.switch.cmd("echo '%s' | %s %s --rpc %s %s" % (stdinBuf, self.hvflowctlPath, command, rpcAddr, opts))
digitalocean.com
Testing with mininet (cont.)
● Docker image built and pulled by Concourse CI
● Virtual droplet and hypervisor topology spun up by mininet
● Tests run on every pull request to hvflow package
Beginning testing with /configs/production.json
==> Outside to public droplet d1 should pass
out1 (8.8.8.8) ----> d1 (192.0.2.10) *** Results: 0% dropped (1/1 received)
==> Outside to floating on d1 should pass
out1 (8.8.8.8) ----> d1 (192.0.2.100) *** Results: 0% dropped (1/1 received)
==> Outside to private d1 should fail
out1 (8.8.8.8) ----> X(d1) (10.60.5.5) *** Results: 100% dropped (0/1 received)
digitalocean.com
Conclusions: Open vSwitch and Go
● Pros:
○ Go is well-suited to building large, highly concurrent, network systems
○ Go compiles to a single, statically-linked binary for trivial deployment
○ Flows are easier to read for those who aren’t familiar with OvS
○ Data is statically typed and checked before hitting OvS
○ Flows can be bundled and committed atomically
● Cons:
○ Flows structures are verbose if you are familiar with OvS
○ We are still shelling out to OvS tools
digitalocean.com
Open vSwitch at DigitalOcean:
The Future
digitalocean.com
Orchestrated Open vSwitch and Go
● RPC performed to a “regional network service” (RNS)
● RNS determines actions, sends RPCs to hvflowd
● hvflowd builds flows and speaks OpenFlow directly
digitalocean.com
Use cases for an OvS orchestration system
● High level networking actions that apply to many hypervisors and their droplets
○ Apply firewall “open TCP/22” to all droplets for customer X
○ Disable connectivity to all droplets for customer Y
hvflowd
hvflowd
hvflowd
hvflowd
hvflowd
RNS
DO
systems
digitalocean.com
Why speak OpenFlow directly?
● Difficulty parsing unstable OvS tool text output
○ ovs-ofctl dump-ports br0 tap0
● Tedious generation and parsing of flow strings
digitalocean.com
Why not use an OpenFlow controller?
● Industry is moving to a distributed control plane approach
○ Need to carefully avoid architectures where it would
be difficult to scale a central controller
● We considered OVN, but were concerned about its maturity
○ The “RNS” architecture is similar to OVN
● A distributed OpenFlow controller is not off the table!
○ Maybe hvflowd becomes OvS’s “controller”?
digitalocean.com
ovs.Client with OpenFlow
// Configure ovs.Client with our required OpenFlow flow format and protocol.
client := ovs.New(
ovs.FlowFormat("OXM-OpenFlow14"),
ovs.Protocols("OpenFlow14"),
// Toggle on direct OpenFlow support.
ovs.UseOpenFlow("localhost:6633"),
)
// Flow marshaled to binary instead of text format, and sent via OpenFlow.
err = client.OpenFlow.AddFlow("br0", exampleFlow())
● ovs.New constructor gains a new option to toggle on OpenFlow
● ovs.Client opens a socket and sends raw OpenFlow commands
digitalocean.com
ovs.Match gains a new method
type Match interface {
// MarshalText() (text []byte, err error)
encoding.TextMarshaler
// New: MarshalBinary() (bin []byte, err error)
encoding.BinaryMarshaler
}
● Implement a MarshalBinary method for all Match types
● ovs.Action would be updated in the same way
digitalocean.com
Conclusions: orchestrated Open vSwitch and Go
● Pros:
○ Easy to orchestrate changes amongst multiple servers
○ No more parsing OvS tool string output
○ No more generating and parsing the flow text format!
● Cons:
○ Too early to tell!
digitalocean.com
Open vSwitch at DigitalOcean:
Conclusions
digitalocean.com
DO is powered by Open vSwitch!
● We’ve deployed more than 10,000 instances of OvS and
have run it in production for three years.
● We’ve moved from Perl to Go, and our OvS tooling has too.
● We’re excited for the future of OvS and OVN!
Thank you!
Matt Layher
mdlayher@do.co
GitHub + Twitter: @mdlayher
https://github.com/digitalocean/go-openvswitch

Contenu connexe

Tendances

LF_DPDK17_ OpenVswitch hardware offload over DPDK
LF_DPDK17_ OpenVswitch hardware offload over DPDKLF_DPDK17_ OpenVswitch hardware offload over DPDK
LF_DPDK17_ OpenVswitch hardware offload over DPDK
LF_DPDK
 
LF_DPDK17_Event Adapters - Connecting Devices to Eventdev
LF_DPDK17_Event Adapters - Connecting Devices to EventdevLF_DPDK17_Event Adapters - Connecting Devices to Eventdev
LF_DPDK17_Event Adapters - Connecting Devices to Eventdev
LF_DPDK
 
OpenStack 2012 fall summit observation - Quantum/SDN
OpenStack 2012 fall summit observation - Quantum/SDNOpenStack 2012 fall summit observation - Quantum/SDN
OpenStack 2012 fall summit observation - Quantum/SDN
Te-Yen Liu
 

Tendances (20)

LF_OVS_17_OVS-DPDK Installation and Gotchas
LF_OVS_17_OVS-DPDK Installation and GotchasLF_OVS_17_OVS-DPDK Installation and Gotchas
LF_OVS_17_OVS-DPDK Installation and Gotchas
 
OVS Hardware Offload with TC Flower
OVS Hardware Offload with TC FlowerOVS Hardware Offload with TC Flower
OVS Hardware Offload with TC Flower
 
LF_DPDK17_ OpenVswitch hardware offload over DPDK
LF_DPDK17_ OpenVswitch hardware offload over DPDKLF_DPDK17_ OpenVswitch hardware offload over DPDK
LF_DPDK17_ OpenVswitch hardware offload over DPDK
 
Ovs dpdk hwoffload way to full offload
Ovs dpdk hwoffload way to full offloadOvs dpdk hwoffload way to full offload
Ovs dpdk hwoffload way to full offload
 
LF_OVS_17_OVS/OVS-DPDK connection tracking for Mobile usecases
LF_OVS_17_OVS/OVS-DPDK connection tracking for Mobile usecasesLF_OVS_17_OVS/OVS-DPDK connection tracking for Mobile usecases
LF_OVS_17_OVS/OVS-DPDK connection tracking for Mobile usecases
 
DPDK Summit 2015 - HP - Al Sanders
DPDK Summit 2015 - HP - Al SandersDPDK Summit 2015 - HP - Al Sanders
DPDK Summit 2015 - HP - Al Sanders
 
LF_OVS_17_Ingress Scheduling
LF_OVS_17_Ingress SchedulingLF_OVS_17_Ingress Scheduling
LF_OVS_17_Ingress Scheduling
 
Accelerating Neutron with Intel DPDK
Accelerating Neutron with Intel DPDKAccelerating Neutron with Intel DPDK
Accelerating Neutron with Intel DPDK
 
Accelerate Service Function Chaining Vertical Solution with DPDK
Accelerate Service Function Chaining Vertical Solution with DPDKAccelerate Service Function Chaining Vertical Solution with DPDK
Accelerate Service Function Chaining Vertical Solution with DPDK
 
DPACC Acceleration Progress and Demonstration
DPACC Acceleration Progress and DemonstrationDPACC Acceleration Progress and Demonstration
DPACC Acceleration Progress and Demonstration
 
LF_DPDK17_Event Adapters - Connecting Devices to Eventdev
LF_DPDK17_Event Adapters - Connecting Devices to EventdevLF_DPDK17_Event Adapters - Connecting Devices to Eventdev
LF_DPDK17_Event Adapters - Connecting Devices to Eventdev
 
OVS v OVS-DPDK
OVS v OVS-DPDKOVS v OVS-DPDK
OVS v OVS-DPDK
 
DPDK Support for New HW Offloads
DPDK Support for New HW OffloadsDPDK Support for New HW Offloads
DPDK Support for New HW Offloads
 
Open vSwitch Implementation Options
Open vSwitch Implementation Options Open vSwitch Implementation Options
Open vSwitch Implementation Options
 
High Performance Networking Leveraging the DPDK and Growing Community
High Performance Networking Leveraging the DPDK and Growing CommunityHigh Performance Networking Leveraging the DPDK and Growing Community
High Performance Networking Leveraging the DPDK and Growing Community
 
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
Taking Security Groups to Ludicrous Speed with OVS (OpenStack Summit 2015)
 
OpenStack 2012 fall summit observation - Quantum/SDN
OpenStack 2012 fall summit observation - Quantum/SDNOpenStack 2012 fall summit observation - Quantum/SDN
OpenStack 2012 fall summit observation - Quantum/SDN
 
OpenvSwitch Deep Dive
OpenvSwitch Deep DiveOpenvSwitch Deep Dive
OpenvSwitch Deep Dive
 
Open vSwitch Introduction
Open vSwitch IntroductionOpen vSwitch Introduction
Open vSwitch Introduction
 
Open vSwitch Offload: Conntrack and the Upstream Kernel
Open vSwitch Offload: Conntrack and the Upstream KernelOpen vSwitch Offload: Conntrack and the Upstream Kernel
Open vSwitch Offload: Conntrack and the Upstream Kernel
 

En vedette (10)

LF_OVS_17_OVN and Kelda
LF_OVS_17_OVN and KeldaLF_OVS_17_OVN and Kelda
LF_OVS_17_OVN and Kelda
 
LF_OVS_17_Day 2 Closing Remarks
LF_OVS_17_Day 2 Closing RemarksLF_OVS_17_Day 2 Closing Remarks
LF_OVS_17_Day 2 Closing Remarks
 
LF_OVS_17_OvS Hardware Offload with TC Flower
LF_OVS_17_OvS Hardware Offload with TC FlowerLF_OVS_17_OvS Hardware Offload with TC Flower
LF_OVS_17_OvS Hardware Offload with TC Flower
 
LF_OVS_17_OVS-DPDK for NFV: go live feedback!
LF_OVS_17_OVS-DPDK for NFV: go live feedback!LF_OVS_17_OVS-DPDK for NFV: go live feedback!
LF_OVS_17_OVS-DPDK for NFV: go live feedback!
 
LF_OVS_17_The birth of SmartNICs -- offloading dataplane traffic to...software
LF_OVS_17_The birth of SmartNICs -- offloading dataplane traffic to...softwareLF_OVS_17_The birth of SmartNICs -- offloading dataplane traffic to...software
LF_OVS_17_The birth of SmartNICs -- offloading dataplane traffic to...software
 
LF_OVS_17_CORD: An open source platform to reinvent the network edge
LF_OVS_17_CORD: An open source platform to reinvent the network edgeLF_OVS_17_CORD: An open source platform to reinvent the network edge
LF_OVS_17_CORD: An open source platform to reinvent the network edge
 
LF_OVS_17_OVN at Nutanix
LF_OVS_17_OVN at NutanixLF_OVS_17_OVN at Nutanix
LF_OVS_17_OVN at Nutanix
 
LF_OVS_17_IPSEC and OVS DPDK
LF_OVS_17_IPSEC and OVS DPDKLF_OVS_17_IPSEC and OVS DPDK
LF_OVS_17_IPSEC and OVS DPDK
 
LF_OVS_17_DigitalOcean Cloud Firewalls: powered by OvS and conntrack
LF_OVS_17_DigitalOcean Cloud Firewalls: powered by OvS and conntrackLF_OVS_17_DigitalOcean Cloud Firewalls: powered by OvS and conntrack
LF_OVS_17_DigitalOcean Cloud Firewalls: powered by OvS and conntrack
 
LF_OVS_17_Day 2 Opening Remarks
LF_OVS_17_Day 2 Opening RemarksLF_OVS_17_Day 2 Opening Remarks
LF_OVS_17_Day 2 Opening Remarks
 

Similaire à LF_OVS_17_OvS manipulation with Go at DigitalOcean

Who needs containers in a serverless world
Who needs containers in a serverless worldWho needs containers in a serverless world
Who needs containers in a serverless world
Matthias Luebken
 
USP presentation of CHOReOS @ FISL Conference
USP presentation of CHOReOS @ FISL ConferenceUSP presentation of CHOReOS @ FISL Conference
USP presentation of CHOReOS @ FISL Conference
choreos
 
Docker in production service discovery with consul - road to opscon 2015
Docker in production  service discovery with consul - road to opscon 2015Docker in production  service discovery with consul - road to opscon 2015
Docker in production service discovery with consul - road to opscon 2015
Giovanni Toraldo
 

Similaire à LF_OVS_17_OvS manipulation with Go at DigitalOcean (20)

BKK16-409 VOSY Switch Port to ARMv8 Platforms and ODP Integration
BKK16-409 VOSY Switch Port to ARMv8 Platforms and ODP IntegrationBKK16-409 VOSY Switch Port to ARMv8 Platforms and ODP Integration
BKK16-409 VOSY Switch Port to ARMv8 Platforms and ODP Integration
 
9th docker meetup 2016.07.13
9th docker meetup 2016.07.139th docker meetup 2016.07.13
9th docker meetup 2016.07.13
 
BaseX user-group-talk XML Prague 2013
BaseX user-group-talk XML Prague 2013BaseX user-group-talk XML Prague 2013
BaseX user-group-talk XML Prague 2013
 
Developing Java based microservices ready for the world of containers
Developing Java based microservices ready for the world of containersDeveloping Java based microservices ready for the world of containers
Developing Java based microservices ready for the world of containers
 
Kubernetes #1 intro
Kubernetes #1   introKubernetes #1   intro
Kubernetes #1 intro
 
Developing Java based microservices ready for the world of containers
Developing Java based microservices ready for the world of containersDeveloping Java based microservices ready for the world of containers
Developing Java based microservices ready for the world of containers
 
Networking and Go: An Engineer's Journey (Strangeloop 2019)
Networking and Go: An Engineer's Journey (Strangeloop 2019)Networking and Go: An Engineer's Journey (Strangeloop 2019)
Networking and Go: An Engineer's Journey (Strangeloop 2019)
 
OpenStack Networking
OpenStack NetworkingOpenStack Networking
OpenStack Networking
 
Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...
Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...
Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...
 
JS Fest 2019: Comparing Node.js processes and threads for clustering HTTP, TC...
JS Fest 2019: Comparing Node.js processes and threads for clustering HTTP, TC...JS Fest 2019: Comparing Node.js processes and threads for clustering HTTP, TC...
JS Fest 2019: Comparing Node.js processes and threads for clustering HTTP, TC...
 
JS Fest 2019/Autumn. Виталий Кухар. Сравнение кластеризации HTTP, TCP и UDP н...
JS Fest 2019/Autumn. Виталий Кухар. Сравнение кластеризации HTTP, TCP и UDP н...JS Fest 2019/Autumn. Виталий Кухар. Сравнение кластеризации HTTP, TCP и UDP н...
JS Fest 2019/Autumn. Виталий Кухар. Сравнение кластеризации HTTP, TCP и UDP н...
 
FreeSWITCH as a Microservice
FreeSWITCH as a MicroserviceFreeSWITCH as a Microservice
FreeSWITCH as a Microservice
 
Nodejs
NodejsNodejs
Nodejs
 
Kubernetes Intro
Kubernetes IntroKubernetes Intro
Kubernetes Intro
 
Short journey into the serverless world
Short journey into the serverless worldShort journey into the serverless world
Short journey into the serverless world
 
Day in the life event-driven workshop
Day in the life  event-driven workshopDay in the life  event-driven workshop
Day in the life event-driven workshop
 
Who needs containers in a serverless world
Who needs containers in a serverless worldWho needs containers in a serverless world
Who needs containers in a serverless world
 
What is a Service Mesh and what can it do for your Microservices
What is a Service Mesh and what can it do for your MicroservicesWhat is a Service Mesh and what can it do for your Microservices
What is a Service Mesh and what can it do for your Microservices
 
USP presentation of CHOReOS @ FISL Conference
USP presentation of CHOReOS @ FISL ConferenceUSP presentation of CHOReOS @ FISL Conference
USP presentation of CHOReOS @ FISL Conference
 
Docker in production service discovery with consul - road to opscon 2015
Docker in production  service discovery with consul - road to opscon 2015Docker in production  service discovery with consul - road to opscon 2015
Docker in production service discovery with consul - road to opscon 2015
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Dernier (20)

"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 

LF_OVS_17_OvS manipulation with Go at DigitalOcean

  • 1. OvS manipulation with Go at DigitalOcean Matt Layher, Software Engineer OvSCon 2017
  • 2. digitalocean.com ● Software Engineer at DO for ~3.5 years ● Focused on virtual networking primitives ● Huge fan of Go programming language ● GitHub + Twitter: @mdlayher
  • 3.
  • 4. digitalocean.com Cloud computing designed for developers ● Cloud provider with focus on simplicity ● “Droplet” product is a virtual machine ● Compute, storage, networking, and monitoring primitives ○ Load Balancers as a Service ○ Floating IPs ○ Cloud Firewalls (learn more at Kei Nohguchi’s talk!)
  • 5. digitalocean.com DO is powered by Open vSwitch! ● 10,000+ of instances of OvS! ● One of the most crucial components in our entire stack.
  • 6. digitalocean.com Open vSwitch at DigitalOcean: The Past
  • 7. digitalocean.com Open vSwitch and Perl ● Events (create droplet, power on, etc.) reach a hypervisor ● Perl event handlers pick up events and performs a series of actions to prepare a droplet ● Perl builds flow strings and calls ovs-ofctl
  • 8. digitalocean.com Building flows with Perl my $ipv4_flow_rules = [ [ # Flow priority. 2020, # Hash of flow matches. { dl_src => $mac, in_port => $ovs_port_id, ip => undef, nw_src => "${ip}/32", }, # Literal string of flow actions. "mod_vlan_vid:${ipv4vlan},resubmit(,1)" ], # … many more flows ]
  • 9. digitalocean.com Applying flows with Perl # Build comma-separated matches from hash. my $flow = _construct_flow_string($flow_hash); # Build the flow string with usual fields. my $cmd = "priority=${priority},idle_timeout=${timeout},${flow},actions=${actions}"; # Once a flow is added, we need a way to delete it later on! if ($add_delete_hook && defined($delete_hook_handle)) { # Flows written into a libvirt hook to be deleted later. if (_write_flow_to_be_deleted($bridge, $delete_hook_handle, $flow) != PASS) { return FAIL; } } # Shell out to ovs-ofctl and do the work! return _run_ovs_cmd("ovs-ofctl add-flow ${bridge} '${cmd}'");
  • 10. digitalocean.com Conclusions: Open vSwitch and Perl ● Pros: ○ Straightforward code ○ Perl is well-suited to manipulating strings ● Cons: ○ No sanity checking (other than OvS applying the flow) ○ Lacking test coverage ○ libvirt flow deletion hooks for individual flows proved problematic ○ Shell out once per flow; no atomicity
  • 11. digitalocean.com Open vSwitch at DigitalOcean: The Present
  • 12. digitalocean.com Open vSwitch and Go ● Events reach a hypervisor ● Perl/Go (it depends) systems perform a series of actions to prepare a droplet ● Go builds flow strings and calls ovs-ofctl
  • 13. digitalocean.com package ovs Package ovs is a client library for Open vSwitch which enables programmatic control of the virtual switch.
  • 14. digitalocean.com package ovs ● Go package for manipulating Open vSwitch ● No DigitalOcean-specific code! ● Open source (soon)! ○ https://github.com/digitalocean/go-openvswitch
  • 15. digitalocean.com Building flows with Go flow := &ovs.Flow{ // Commonly used flow pieces are struct fields. Priority: 2000, Protocol: ovs.ProtocolIPv4, InPort: droplet.PortID, // Matches and Actions are Go interfaces; functions create a // type that implements the interface. Matches: []ovs.Match{ ovs.DataLinkSource(r.HardwareAddr.String()), ovs.NetworkSource(r.IP.String()), }, Actions: []ovs.Action{ ovs.Resubmit(0, tableL2Rewrite), }, }
  • 16. digitalocean.com Building flows with Go (cont.) ● Our example flow marshaled to textual format: priority=2000,ip,in_port=1,dl_src=de:ad:be:ef:de:ad, nw_src=192.168.1.1,table=0,idle_timeout=0,actions=resubmit(,10) ● Mostly string manipulation behind the scenes; just like Perl ● Go is statically typed, reducing chance of programmer errors ● Can validate each match and action for correctness without hitting OvS
  • 17. digitalocean.com The ovs.Match Go interface type Match interface { // MarshalText() (text []byte, err error) encoding.TextMarshaler } ● Because of the way Go interfaces work, any type with a MarshalText method can be used as an ovs.Match ● The error return value can be used to catch any bad input ● ovs.Action’s definition is identical
  • 18. digitalocean.com The ovs.Client Go type // Configure ovs.Client with our required OpenFlow flow format and protocol. client := ovs.New(ovs.FlowFormat("OXM-OpenFlow14"), ovs.Protocols("OpenFlow14")) // $ ovs-vsctl --may-exist add-br br0 err := client.VSwitch.AddBridge("br0") // $ ovs-ofctl add-flow --flow-format=OXM-OpenFlow14 --protocols=OpenFlow14 br0 ${flow} err = client.OpenFlow.AddFlow("br0", exampleFlow()) ● ovs.Client is a wrapper around ovs-vsctl and ovs-ofctl commands ● ovs.New constructor uses “functional options” pattern for sane defaults ● We can still only apply one flow at a time… right?
  • 19. digitalocean.com ovs.Client flow bundle transactions // Assume we want to apply a new flow set and remove old one. add, remove := newFlows(), oldFlows() // We can apply all of these flows atomically using a flow bundle! err := client.OpenFlow.AddFlowBundle(bridge, func(tx *ovs.FlowTransaction) error { // $ echo -e “delete priority=10,cookie=1,actions=dropn” >> mem tx.Delete(remove...) // $ echo -e “add priority=10,cookie=1,actions=output:1n” >> mem tx.Add(add...) // $ cat mem | ovs-ofctl --bundle add-flow --flow-format=OXM-OpenFlow14 --protocols=OpenFlow14 br0 - return tx.Commit() }) ● Flow bundle stored in memory, passed directly from buffer to ovs-ofctl ● Modifications are processed by OvS in a single, atomic transaction
  • 20. digitalocean.com package hvflow Package hvflow provides Open vSwitch flow manipulation at the hypervisor level.
  • 21. digitalocean.com package hvflow ● DigitalOcean-specific wrapper for package ovs ● Provides higher-level constructs, such as: ○ enable public IPv4 and IPv6 connectivity ○ reset and apply security policies ○ disable all connectivity
  • 22. digitalocean.com The hvflow.Client Go type // Configure hvflow.Client to modify bridge “br0”. client, err := hvflow.NewClient("br0", ovs.New( ovs.FlowFormat("OXM-OpenFlow14"), ovs.Protocols("OpenFlow14"), )) ● hvflow.Client is a high-level wrapper around ovs.Client ● hvflow.NewClient constructor uses “functional options” pattern for sane defaults
  • 23. digitalocean.com Network parameters - “netparams” ● Encode all necessary information about how to enable networking for a given VNIC ● Carries IPv4 and IPv6 addresses, firewall configurations, floating IPs… ● netparams used to configure OvS with hvflow.Client.Transaction method { "droplet_id": 1, "vnics": [ { "mac": "de:ad:be:ef:de:ad", "enabled": 1, "name": "tapext1", "interface_type": "public", "addresses": { "ipv4": [ { "ip_address": "10.0.0.10", "masklen": 20, "gateway": "10.0.0.1" } ] } } ] }
  • 24. digitalocean.com hvflow.Client transactions // Assume a netparams structure similar to the one just shown. params, ifi := networkParams(), "public" err := client.Transaction(ctx, func(ctx context.Context, tx *hvflow.Transaction) error { // Convert netparams into hvflow simplified representation. req, ok, err := hvflow.NewIPv4Request(params, ifi) if err != nil { return err } if ok { // If IPv4 configuration present, apply it! if err := tx.EnableIPv4(ctx, req); err != nil { return wrapError(err, "failed to enable IPv4 networking") } } return tx.Commit() })
  • 25. digitalocean.com hvflow.Client transactions (cont.) ● Each operation accumulates additional flows to be applied within the context of the transaction. ● Flow set sizes can vary from a couple dozen to several hundred flows. ● Flows are always applied using a flow bundle; non-transactional hvflow.Client API was deleted! // IPv4 configuration. err := tx.EnableIPv4(ctx, req4) // IPv6 configuration. err = tx.EnableIPv6(ctx, req6) // Floating IPv4 configuration. err = tx.EnableFloatingIPv4(ctx, req4F) // Disable networking on an interface. err = tx.Disable(ctx, 10, "public") // Apply flow set to OvS. err = tx.Commit()
  • 26. digitalocean.com The hvflow.Cookie Go interface type Cookie interface { Marshal() (uint64, error) Unmarshal(i uint64) error } ● Cookie structs packed and unpacked from uint64 form ● Cookies are versioned using a 4-bit identifier ● Used to store identification metadata about a flow ● Easy deletions of flows; much simpler deletion hooks with libvirt
  • 27. digitalocean.com hvflowctl and hvflowd gRPC client and server that manipulate Open vSwitch
  • 28. digitalocean.com hvflowctl and hvflowd ● gRPC client and server written in Go ● hvflowctl passes netparams and other data to hvflowd ● hvflowd manipulates OvS flows via hvflow package
  • 29. digitalocean.com hvflowd’s gRPC interface ● gRPC uses protocol buffers (“protobuf”) for RPC communication ● RPCs accept one message type and return another ● netparamspb package for encoding netparams in protobuf // The set of RPCs that make up the “HVFlow” service. service HVFlow { // Add flows using the parameters specified in request. rpc AddFlows(AddFlowsRequest) returns (AddFlowsResponse); } // RPC parameters encoded within a request message. message AddFlowsRequest { // netparams have a protobuf representation too. netparamspb.NetworkParams network_params = 1; string interface_type = 2; } // No need to return any data on success. message AddFlowsResponse {}
  • 30. digitalocean.com hvflowd AddFlows RPC // AddFlows requests that hvflowd add flows to enable connectivity for one or more droplets. func (s *server) AddFlows(ctx context.Context, req *hpb.AddFlowsRequest) (*hpb.AddFlowsResponse, error) { // Fetch netparams from gRPC request message. params := req.GetNetworkParams() // Perform the necessary transaction logic to establish connectivity. err := s.hvflowc.Transaction(ctx, func(ctx context.Context, tx *hvflow.Transaction) error { // hvflow.Client transaction logic … return tx.Commit() }) // Inform the caller if the request was successful. return &hvflowpb.AddFlowsResponse{}, err } ● RPCs enable orchestration among multiple hypervisors and hvflowd instances
  • 31. digitalocean.com Testing hvflowctl and hvflowd ● Unit tests verify a flow looks a certain way ○ go test ./... ● Integration tests verify the behavior of flows applied to OvS ○ mininet, OvS, hvflowctl, hvflowd
  • 32. digitalocean.com Testing with mininet ● Network topology created with multi-namespace OvS in mininet ● hvflowd spun up in each “hypervisor namespace” # Spin up hvflowd in the background and set per-hypervisor environment # variables needed to enable multiple instances to run together. for key in self.hvflowdEnv: self.cmd('export %s=%s' % (key, self.hvflowdEnv[key])) self.cmd('%s &' % (self.hvflowdPath)) ● hvflowctl issues RPCs using JSON netparams fixtures # Issue RPCs to hvflowd using flags and netparams JSON. self.switch.cmd("echo '%s' | %s %s --rpc %s %s" % (stdinBuf, self.hvflowctlPath, command, rpcAddr, opts))
  • 33. digitalocean.com Testing with mininet (cont.) ● Docker image built and pulled by Concourse CI ● Virtual droplet and hypervisor topology spun up by mininet ● Tests run on every pull request to hvflow package Beginning testing with /configs/production.json ==> Outside to public droplet d1 should pass out1 (8.8.8.8) ----> d1 (192.0.2.10) *** Results: 0% dropped (1/1 received) ==> Outside to floating on d1 should pass out1 (8.8.8.8) ----> d1 (192.0.2.100) *** Results: 0% dropped (1/1 received) ==> Outside to private d1 should fail out1 (8.8.8.8) ----> X(d1) (10.60.5.5) *** Results: 100% dropped (0/1 received)
  • 34. digitalocean.com Conclusions: Open vSwitch and Go ● Pros: ○ Go is well-suited to building large, highly concurrent, network systems ○ Go compiles to a single, statically-linked binary for trivial deployment ○ Flows are easier to read for those who aren’t familiar with OvS ○ Data is statically typed and checked before hitting OvS ○ Flows can be bundled and committed atomically ● Cons: ○ Flows structures are verbose if you are familiar with OvS ○ We are still shelling out to OvS tools
  • 35. digitalocean.com Open vSwitch at DigitalOcean: The Future
  • 36. digitalocean.com Orchestrated Open vSwitch and Go ● RPC performed to a “regional network service” (RNS) ● RNS determines actions, sends RPCs to hvflowd ● hvflowd builds flows and speaks OpenFlow directly
  • 37. digitalocean.com Use cases for an OvS orchestration system ● High level networking actions that apply to many hypervisors and their droplets ○ Apply firewall “open TCP/22” to all droplets for customer X ○ Disable connectivity to all droplets for customer Y hvflowd hvflowd hvflowd hvflowd hvflowd RNS DO systems
  • 38. digitalocean.com Why speak OpenFlow directly? ● Difficulty parsing unstable OvS tool text output ○ ovs-ofctl dump-ports br0 tap0 ● Tedious generation and parsing of flow strings
  • 39. digitalocean.com Why not use an OpenFlow controller? ● Industry is moving to a distributed control plane approach ○ Need to carefully avoid architectures where it would be difficult to scale a central controller ● We considered OVN, but were concerned about its maturity ○ The “RNS” architecture is similar to OVN ● A distributed OpenFlow controller is not off the table! ○ Maybe hvflowd becomes OvS’s “controller”?
  • 40. digitalocean.com ovs.Client with OpenFlow // Configure ovs.Client with our required OpenFlow flow format and protocol. client := ovs.New( ovs.FlowFormat("OXM-OpenFlow14"), ovs.Protocols("OpenFlow14"), // Toggle on direct OpenFlow support. ovs.UseOpenFlow("localhost:6633"), ) // Flow marshaled to binary instead of text format, and sent via OpenFlow. err = client.OpenFlow.AddFlow("br0", exampleFlow()) ● ovs.New constructor gains a new option to toggle on OpenFlow ● ovs.Client opens a socket and sends raw OpenFlow commands
  • 41. digitalocean.com ovs.Match gains a new method type Match interface { // MarshalText() (text []byte, err error) encoding.TextMarshaler // New: MarshalBinary() (bin []byte, err error) encoding.BinaryMarshaler } ● Implement a MarshalBinary method for all Match types ● ovs.Action would be updated in the same way
  • 42. digitalocean.com Conclusions: orchestrated Open vSwitch and Go ● Pros: ○ Easy to orchestrate changes amongst multiple servers ○ No more parsing OvS tool string output ○ No more generating and parsing the flow text format! ● Cons: ○ Too early to tell!
  • 43. digitalocean.com Open vSwitch at DigitalOcean: Conclusions
  • 44. digitalocean.com DO is powered by Open vSwitch! ● We’ve deployed more than 10,000 instances of OvS and have run it in production for three years. ● We’ve moved from Perl to Go, and our OvS tooling has too. ● We’re excited for the future of OvS and OVN!
  • 45. Thank you! Matt Layher mdlayher@do.co GitHub + Twitter: @mdlayher https://github.com/digitalocean/go-openvswitch