Documentation ¶
Overview ¶
Package contiv implements plugin providing GRPC-server that accepts requests from the contiv-CNI (acting as a GRPC-client) and configures the networking between VPP and the PODs.
The plugin is configurable via its config file that can be specified using `-contiv-config="<path to config>` argument when running the contiv-agent. This is usually being injected into the vswitch POD by a config map inside of the k8s deployment file of the contiv-VPP k8s networking plugin (see contiv-agent-cfg ConfigMap in ../../k8s/contiv-vpp.yaml).
Based on the configuration, the plugin can wire PODs in 3 different ways:
1. VETH-based pod-VPP connectivity (default)
Each POD is wired to VPP using a virtual ethernet interface pair, where one end is connected to VPP using AF_PACKET interface and the other end is placed into the POD's network namespace:
+-------------------------------------------------+ | vSwitch VPP host.go | +--------------+ | +--------------+ | | VETH VPP |____________| VETH Host | | routing | | | | | | +--------------+ | +--------------+ | +------+ +------+ | | | AF1 | | AFn | | | | | ... | | | | +------+ +------+ | | ^ | | | | +------|------------------------------------------+
v +------------+ | | | VETH1-VPP | | | +------------+ ^ | pod.go
+------|------------+ | NS1 v | | +------------+ | | | | | | | VETH1-POD | | | | | | | +------------+ | | | +-------------------+
2. TAP-based pod-VPP connectivity
Each POD is wired to VPP using a TAP interface created on VPP. Can be turned on by setting the UseTAPInterfaces: True in the config file. Legacy and the new virtio-based TAP interfaces are supported, the latter can be turned on by setting the TAPInterfaceVersion: 2.
+-------------------------------------------------+ | vSwitch VPP host.go | +--------------+ | +--------------+ | | VETH VPP |____________| VETH Host | | routing | | | | | | +--------------+ | +--------------+ | +-------+ +-------+ | | | TAP1 | | TAPn | | | | | ... | | | | +-------+ +-------+ | | ^ | | | | +------|------------------------------------------+
| | pod.go
+------|------------+ | NS1 v | | +------------+ | | | | | | | TAP1-POD | | | | | | | +------------+ | | | +-------------------+
3. VPP TCP stack based pod-VPP connectivity
The PODs communicate with VPP via shared memory between VPP TCP stack and VCL library in PODs. To enable this, the plugin needs to be configured with TCPstackDisabled: False in the plugin config file and the POD needs to be deployed with ldpreload: "true" label. If the label is not specified for a POD, the communication between the POD and the VPP falls back to the option 1 or 2.
+-------------------------------------------------+ | vSwitch VPP host.go | +--------------+ | +--------------+ | | VETH VPP |____________| VETH Host | | routing | | | | | | +--------------+ | +--------------+ | +-------+ +-------+ | | | LOOP1 | | LOOPn | | | | | ... | | | | +-------+ +-------+ | | ^ ^ | | | | | | v v | | +-----------------------+ | | | VPP TCP Stack | | | +-----------------------+ | | ^ | | | | +------|------------------------------------------+
| | pod.go
+------|---------------+ | NS1 v | | +-----------------+ | | | VCL | | | | (LD_PRELOAD-ed) | | | +-----------------+ | | ^ | | | | | v | | +------+ | | | APP | | | +------+ | +----------------------+
Note: the picture above is simplified, each LD_PRELOAD-ed POD is actually wired also with the veth/tap (option 1/2), for the non-TCP/UDP communications, or not LD_PRELOAD-ed applications.
Plugin Structure ================
The plugin consists of these components:
Plugin base: - plugin_*.go: plugin definition and setup - node_events.go: handler of changes in nodes within the k8s cluster (node add / delete)
Remote CNI Server - the main logic of the plugin that is in charge of wiring the PODs.
Node ID Allocator - manages allocation/deallocation of unique number identifying a node within the k8s cluster. Allocated identifier is used as an input of the IPAM calculations.
IPAM module (separate package, described in its own doc.go) - provides node-local IP address assignments.
Helper functions: - host.go: provides host-related helper functions and VPP-Agent NB API builders - pod.go: provides POD-related helper functions and VPP-Agent NB API builders
Index ¶
- Constants
- type API
- type Config
- type Deps
- type InterfaceWithIP
- type OneNodeConfig
- type Plugin
- func (plugin *Plugin) AfterInit() error
- func (plugin *Plugin) Close() error
- func (plugin *Plugin) GetContainerIndex() containeridx.Reader
- func (plugin *Plugin) GetDefaultGatewayIP() net.IP
- func (plugin *Plugin) GetHostInterconnectIfName() string
- func (plugin *Plugin) GetIfName(podNamespace string, podName string) (name string, exists bool)
- func (plugin *Plugin) GetMainPhysicalIfName() string
- func (plugin *Plugin) GetNodeIP() (ip net.IP, network *net.IPNet)
- func (plugin *Plugin) GetNsIndex(podNamespace string, podName string) (nsIndex uint32, exists bool)
- func (plugin *Plugin) GetOtherPhysicalIfNames() []string
- func (plugin *Plugin) GetPodByAppNsIndex(nsIndex uint32) (podNamespace string, podName string, exists bool)
- func (plugin *Plugin) GetPodByIf(ifname string) (podNamespace string, podName string, exists bool)
- func (plugin *Plugin) GetPodNetwork() *net.IPNet
- func (plugin *Plugin) GetVxlanBVIIfName() string
- func (plugin *Plugin) Init() error
- func (plugin *Plugin) IsTCPstackDisabled() bool
- func (plugin *Plugin) NatExternalTraffic() bool
- func (plugin *Plugin) RegisterPodPreRemovalHook(hook PodActionHook)
- func (plugin *Plugin) WatchNodeIP(subscriber chan string)
- type PodActionHook
- type PodConfig
Constants ¶
const ( // TapHostEndLogicalName is the logical name of the VPP-host interconnect TAP interface (host end) TapHostEndLogicalName = "tap-vpp1" // TapHostEndName is the physical name of the VPP-host interconnect TAP interface (host end) TapHostEndName = "vpp1" // TapVPPEndLogicalName is the logical name of the VPP-host interconnect TAP interface (VPP end) TapVPPEndLogicalName = "tap-vpp2" // TapVPPEndName is the physical name of the VPP-host interconnect TAP interface (VPP end) TapVPPEndName = "vpp2" // HostInterconnectMAC is MAC address of tap that interconnects VPP with host stack HostInterconnectMAC = "01:23:45:67:89:42" )
const ( // AllocatedIDsKeyPrefix is a key prefix used in ETCD to store information // about node ID and its IP addresses. AllocatedIDsKeyPrefix = "allocatedIDs/" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type API ¶
type API interface { // GetIfName looks up logical interface name that corresponds to the interface // associated with the given pod. GetIfName(podNamespace string, podName string) (name string, exists bool) // GetNsIndex returns the index of the VPP session namespace associated // with the given pod. GetNsIndex(podNamespace string, podName string) (nsIndex uint32, exists bool) // GetPodByIf looks up podName and podNamespace that is associated with logical interface name. GetPodByIf(ifname string) (podNamespace string, podName string, exists bool) // GetPodByAppNsIndex looks up podName and podNamespace that is associated with the VPP application namespace. GetPodByAppNsIndex(nsIndex uint32) (podNamespace string, podName string, exists bool) // GetPodNetwork provides subnet used for allocating pod IP addresses on this host node. GetPodNetwork() *net.IPNet // GetContainerIndex exposes index of configured containers GetContainerIndex() containeridx.Reader // IsTCPstackDisabled returns true if the TCP stack is disabled and only VETHSs/TAPs are configured IsTCPstackDisabled() bool // NatExternalTraffic returns true if traffic with cluster-outside destination should be S-NATed // with node IP before being sent out from the node. NatExternalTraffic() bool // GetNodeIP returns the IP+network address of this node. // With DHCP the node IP may get assigned later or change in the runtime, therefore it is preferred // to watch for node IP via WatchNodeIP(). GetNodeIP() (ip net.IP, network *net.IPNet) // WatchNodeIP adds given channel to the list of subscribers that are notified upon change // of nodeIP address. If the channel is not ready to receive notification, the notification is dropped. WatchNodeIP(subscriber chan string) // GetMainPhysicalIfName returns name of the "main" interface - i.e. physical interface connecting // the node with the rest of the cluster. GetMainPhysicalIfName() string // GetOtherPhysicalIfNames returns a slice of names of all physical interfaces configured additionally // to the main interface. GetOtherPhysicalIfNames() []string // GetHostInterconnectIfName returns the name of the TAP/AF_PACKET interface // interconnecting VPP with the host stack. GetHostInterconnectIfName() string // GetVxlanBVIIfName returns the name of an BVI interface facing towards VXLAN tunnels to other hosts. // Returns an empty string if VXLAN is not used (in L2 interconnect mode). GetVxlanBVIIfName() string // GetDefaultGatewayIP returns the IP address of the default gateway for external traffic. // If the default GW is not configured, the function returns nil. GetDefaultGatewayIP() net.IP // RegisterPodPreRemovalHook allows to register callback that will be run for each // pod immediately before its removal. RegisterPodPreRemovalHook(hook PodActionHook) }
API for other plugins to query network-related information.
type Config ¶
type Config struct { TCPChecksumOffloadDisabled bool TCPstackDisabled bool UseL2Interconnect bool UseTAPInterfaces bool TAPInterfaceVersion uint8 TAPv2RxRingSize uint16 TAPv2TxRingSize uint16 MTUSize uint32 StealFirstNIC bool StealInterface string NatExternalTraffic bool // if enabled, traffic with cluster-outside destination is SNATed on node output (for all nodes) IPAMConfig ipam.Config NodeConfig []OneNodeConfig }
Config represents configuration for the Contiv plugin. It can be injected or loaded from external config file. Injection has priority to external config. To use external config file, add `-contiv-config="<path to config>` argument when running the contiv-agent.
type Deps ¶
type Deps struct { local.PluginInfraDeps GRPC grpc.Server Proxy *kvdbproxy.Plugin VPP *defaultplugins.Plugin GoVPP govppmux.API Resync resync.Subscriber ETCD *etcdv3.Plugin Watcher datasync.KeyValProtoWatcher }
Deps groups the dependencies of the Plugin.
type InterfaceWithIP ¶
InterfaceWithIP binds interface name with IP address for configuration purposes.
type OneNodeConfig ¶
type OneNodeConfig struct { NodeName string // name of the node, should match withs the hostname MainVPPInterface InterfaceWithIP // main VPP interface used for the inter-node connectivity OtherVPPInterfaces []InterfaceWithIP // other interfaces on VPP, not necessarily used for inter-node connectivity StealInterface string // interface to be stolen from the host stack and bound to VPP Gateway string // IP address of the default gateway NatExternalTraffic bool // if enabled, traffic with cluster-outside destination is SNATed on node output }
OneNodeConfig represents configuration for one node. It contains only settings specific to given node.
type Plugin ¶
Plugin represents the instance of the Contiv network plugin, that transforms CNI requests recieved over GRPC into configuration for the vswitch VPP in order to connect/disconnect a container into/from the network.
func (*Plugin) AfterInit ¶
AfterInit is called by the plugin infra after Init of all plugins is finished. It registers to the ResyncOrchestrator. The registration is done in this phase in order to trigger the resync for this plugin once the resync of VPP plugins is finished.
func (*Plugin) Close ¶
Close is called by the plugin infra upon agent cleanup. It cleans up the resources allocated by the plugin.
func (*Plugin) GetContainerIndex ¶
func (plugin *Plugin) GetContainerIndex() containeridx.Reader
GetContainerIndex returns the index of configured containers/pods
func (*Plugin) GetDefaultGatewayIP ¶
GetDefaultGatewayIP returns the IP address of the default gateway for external traffic. If the default GW is not configured, the function returns nil.
func (*Plugin) GetHostInterconnectIfName ¶
GetHostInterconnectIfName returns the name of the TAP/AF_PACKET interface interconnecting VPP with the host stack.
func (*Plugin) GetIfName ¶
GetIfName looks up logical interface name that corresponds to the interface associated with the given POD name.
func (*Plugin) GetMainPhysicalIfName ¶
GetMainPhysicalIfName returns name of the "main" interface - i.e. physical interface connecting the node with the rest of the cluster.
func (*Plugin) GetNsIndex ¶
GetNsIndex returns the index of the VPP session namespace associated with the given POD name.
func (*Plugin) GetOtherPhysicalIfNames ¶
GetOtherPhysicalIfNames returns a slice of names of all physical interfaces configured additionally to the main interface.
func (*Plugin) GetPodByAppNsIndex ¶
func (plugin *Plugin) GetPodByAppNsIndex(nsIndex uint32) (podNamespace string, podName string, exists bool)
GetPodByAppNsIndex looks up podName and podNamespace that is associated with the VPP application namespace.
func (*Plugin) GetPodByIf ¶
GetPodByIf looks up podName and podNamespace that is associated with logical interface name.
func (*Plugin) GetPodNetwork ¶
GetPodNetwork provides subnet used for allocating pod IP addresses on this node.
func (*Plugin) GetVxlanBVIIfName ¶
GetVxlanBVIIfName returns the name of an BVI interface facing towards VXLAN tunnels to other hosts. Returns an empty string if VXLAN is not used (in L2 interconnect mode).
func (*Plugin) Init ¶
Init initializes the Contiv plugin. Called automatically by plugin infra upon contiv-agent startup.
func (*Plugin) IsTCPstackDisabled ¶
IsTCPstackDisabled returns true if the VPP TCP stack is disabled and only VETHs/TAPs are configured.
func (*Plugin) NatExternalTraffic ¶
NatExternalTraffic returns true if traffic with cluster-outside destination should be S-NATed with node IP before being sent out from the node.
func (*Plugin) RegisterPodPreRemovalHook ¶
func (plugin *Plugin) RegisterPodPreRemovalHook(hook PodActionHook)
RegisterPodPreRemovalHook allows to register callback that will be run for each pod immediately before its removal.
func (*Plugin) WatchNodeIP ¶
WatchNodeIP adds given channel to the list of subscribers that are notified upon change of nodeIP address. If the channel is not ready to receive notification, the notification is dropped.
type PodActionHook ¶
PodActionHook defines parameters and the return value of a callback triggered during an event associated with a pod.
type PodConfig ¶
type PodConfig struct { // ID identifies the Pod ID string // PodName from the CNI request PodName string // PodNamespace from the CNI request PodNamespace string // Veth1 one end end of veth pair that is in the given container namespace. // Nil if TAPs are used instead. Veth1 *linux_intf.LinuxInterfaces_Interface // Veth2 is the other end of veth pair in the default namespace // Nil if TAPs are used instead. Veth2 *linux_intf.LinuxInterfaces_Interface // VppIf is AF_PACKET/TAP interface connecting pod to VPP VppIf *vpp_intf.Interfaces_Interface // PodTap is the host end of the tap connecting pod to VPP // Nil if TAPs are not used PodTap *linux_intf.LinuxInterfaces_Interface // Loopback interface associated with the pod. // Nil if VPP TCP stack is disabled. Loopback *vpp_intf.Interfaces_Interface // StnRule is STN rule used to "punt" any traffic via VETHs/TAPs with no match in VPP TCP stack. // Nil if VPP TCP stack is disabled. StnRule *stn.StnRule // AppNamespace is the application namespace associated with the pod. // Nil if VPP TCP stack is disabled. AppNamespace *vpp_l4.AppNamespaces_AppNamespace // VppARPEntry is ARP entry configured in VPP to route traffic from VPP to pod. VppARPEntry *vpp_l3.ArpTable_ArpTableEntry // PodARPEntry is ARP entry configured in the pod to route traffic from pod to VPP. PodARPEntry *linux_l3.LinuxStaticArpEntries_ArpEntry // VppRoute is the route from VPP to the container VppRoute *vpp_l3.StaticRoutes_Route // PodLinkRoute is the route from pod to the default gateway. PodLinkRoute *linux_l3.LinuxStaticRoutes_Route // PodDefaultRoute is the default gateway for the pod. PodDefaultRoute *linux_l3.LinuxStaticRoutes_Route }
PodConfig groups applied configuration for a container
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package containeridx implements a mapping structure that allows to store configured container networking.
|
Package containeridx implements a mapping structure that allows to store configured container networking. |
model
Package container is a generated protocol buffer package.
|
Package container is a generated protocol buffer package. |
Package ipam provides node-local IPAM calculations: POD IP addresses, VPP-host interconnect and node interconnect IP addresses.
|
Package ipam provides node-local IPAM calculations: POD IP addresses, VPP-host interconnect and node interconnect IP addresses. |
model
Package model is a generated protocol buffer package.
|
Package model is a generated protocol buffer package. |
model
|
|
cni
Package cni is a generated protocol buffer package.
|
Package cni is a generated protocol buffer package. |
node
Package node is a generated protocol buffer package.
|
Package node is a generated protocol buffer package. |