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 KVBrokerFactory
- type NodeConfig
- type Option
- type Plugin
- func (plugin *Plugin) AfterInit() error
- func (plugin *Plugin) CleanupIdleNATSessions() bool
- func (plugin *Plugin) Close() error
- func (plugin *Plugin) GetContainerIndex() containeridx.Reader
- func (plugin *Plugin) GetDefaultInterface() (ifName string, ifAddress net.IP)
- func (plugin *Plugin) GetHostIPs() []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) GetMainVrfID() uint32
- func (plugin *Plugin) GetNatLoopbackIP() net.IP
- 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) GetOtherNATSessionTimeout() uint32
- 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) GetPodSubnet() *net.IPNet
- func (plugin *Plugin) GetPodVrfID() uint32
- func (plugin *Plugin) GetServiceLocalEndpointWeight() uint8
- func (plugin *Plugin) GetTCPNATSessionTimeout() uint32
- func (plugin *Plugin) GetVxlanBVIIfName() string
- func (plugin *Plugin) InSTNMode() bool
- func (plugin *Plugin) Init() error
- func (plugin *Plugin) IsTCPstackDisabled() bool
- func (plugin *Plugin) NatExternalTraffic() bool
- func (plugin *Plugin) RegisterPodPostAddHook(hook PodActionHook)
- func (plugin *Plugin) RegisterPodPreRemovalHook(hook PodActionHook)
- func (plugin *Plugin) WatchNodeIP(subscriber chan string)
- type PodActionHook
- type PodConfig
Constants ¶
const ( // ConfigFlagName is name of flag that can be used to define config for contiv plugin ConfigFlagName = "contiv" // ContivConfigPath is the default location of Agent's Contiv plugin. This path reflects configuration in k8s/contiv-vpp.yaml. ContivConfigPath = "/etc/agent/contiv.yaml" // ContivConfigPathUsage explains the purpose of 'kube-config' flag. ContivConfigPathUsage = "Path to the Agent's Contiv plugin configuration yaml file." )
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 ( // Prefix is versioned prefix for REST urls Prefix = "/contiv/v1/" // PluginURL is versioned URL (using prefix) for IPAM REST endpoint PluginURL = Prefix + "ipam" )
const MgmtIPSeparator = ","
MgmtIPSeparator is a delimiter inserted between management IPs in nodeInfo structure
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) // GetPodSubnet provides subnet used for allocating pod IP addresses across all nodes. GetPodSubnet() *net.IPNet // 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 VETHs/TAPs are configured IsTCPstackDisabled() bool // InSTNMode returns true if Contiv operates in the STN mode (single interface for each node). InSTNMode() 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 // CleanupIdleNATSessions returns true if cleanup of idle NAT sessions is enabled. CleanupIdleNATSessions() bool // GetTCPNATSessionTimeout returns NAT session timeout (in minutes) for TCP connections, used in case that CleanupIdleNATSessions is turned on. GetTCPNATSessionTimeout() uint32 // GetOtherNATSessionTimeout returns NAT session timeout (in minutes) for non-TCP connections, used in case that CleanupIdleNATSessions is turned on. GetOtherNATSessionTimeout() uint32 // GetServiceLocalEndpointWeight returns the load-balancing weight assigned to locally deployed service endpoints. GetServiceLocalEndpointWeight() uint8 // GetNatLoopbackIP returns the IP address of a virtual loopback, used to route traffic // between clients and services via VPP even if the source and destination are the same // IP addresses and would otherwise be routed locally. GetNatLoopbackIP() net.IP // 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) // GetHostIPs returns all IP addresses of this node present in the host network namespace (Linux). GetHostIPs() []net.IP // 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 // GetDefaultInterface returns the name and the IP address of the interface // used by the default route to send packets out from VPP towards the default gateway. // If the default GW is not configured, the function returns zero values. GetDefaultInterface() (ifName string, ifAddress net.IP) // RegisterPodPreRemovalHook allows to register callback that will be run for each // pod immediately before its removal. RegisterPodPreRemovalHook(hook PodActionHook) // RegisterPodPostAddHook allows to register callback that will be run for each // pod once it is added and before the CNI reply is sent. RegisterPodPostAddHook(hook PodActionHook) // GetMainVrfID returns the ID of the main network connectivity VRF. GetMainVrfID() uint32 // GetPodVrfID returns the ID of the POD VRF. GetPodVrfID() uint32 }
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 STNSocketFile string NatExternalTraffic bool // if enabled, traffic with cluster-outside destination is SNATed on node output (for all nodes) CleanupIdleNATSessions bool // if enabled, the agent will periodically check for idle NAT sessions and delete inactive ones TCPNATSessionTimeout uint32 // NAT session timeout (in minutes) for TCP connections, used in case that CleanupIdleNATSessions is turned on OtherNATSessionTimeout uint32 // NAT session timeout (in minutes) for non-TCP connections, used in case that CleanupIdleNATSessions is turned on ScanIPNeighbors bool // if enabled, periodically scans and probes IP neighbors to maintain the ARP table IPNeighborScanInterval uint8 IPNeighborStaleThreshold uint8 MainVRFID uint32 PodVRFID uint32 ServiceLocalEndpointWeight uint8 DisableNATVirtualReassembly bool // if true, NAT plugin will drop fragmented packets EnablePacketTrace bool IPAMConfig ipam.Config NodeConfig []NodeConfig }
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.
func (*Config) ApplyDefaults ¶ added in v1.4.0
func (cfg *Config) ApplyDefaults()
ApplyDefaults stores default values to undefined configuration fields.
func (*Config) ApplyIPAMConfig ¶ added in v1.4.0
ApplyIPAMConfig populates the Config struct with the calculated subnets
func (*Config) GetNodeConfig ¶ added in v1.4.0
func (cfg *Config) GetNodeConfig(nodeName string) *NodeConfig
GetNodeConfig returns configuration specific to a given node, or nil if none was found.
type Deps ¶
type Deps struct { infra.PluginDeps ServiceLabel servicelabel.ReaderAPI GRPC grpc.Server Proxy *kvdbproxy.Plugin VPP *vpp.Plugin GoVPP govppmux.API Resync resync.Subscriber ETCD *etcd.Plugin Bolt keyval.KvProtoPlugin Watcher datasync.KeyValProtoWatcher HTTPHandlers rest.HTTPHandlers }
Deps groups the dependencies of the Plugin.
type KVBrokerFactory ¶ added in v1.4.0
type KVBrokerFactory interface {
NewBroker(keyPrefix string) keyval.ProtoBroker
}
KVBrokerFactory is used to generalize different means of accessing KV-store for the purpose of reading CRD-defined node configuration.
type NodeConfig ¶ added in v1.4.0
type NodeConfig struct { NodeName string // name of the node, should match with the hostname nodeconfigcrd.NodeConfigSpec }
NodeConfig represents configuration specific to a given node.
func LoadNodeConfigFromCRD ¶ added in v1.4.0
func LoadNodeConfigFromCRD(nodeName string, remoteDB, localDB KVBrokerFactory, log logging.Logger) *NodeConfig
LoadNodeConfigFromCRD loads node configuration defined via CRD, which was reflected into a remote kv-store by contiv-crd and mirrored into local kv-store by the agent.
type Option ¶
type Option func(*Plugin)
Option is a function that acts on a Plugin to inject Dependencies or configuration
type Plugin ¶
Plugin represents the instance of the Contiv network plugin, that transforms CNI requests received 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) CleanupIdleNATSessions ¶
CleanupIdleNATSessions returns true if cleanup of idle NAT sessions is enabled.
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) GetDefaultInterface ¶
GetDefaultInterface returns the name and the IP address of the interface used by the default route to send packets out from VPP towards the default gateway. If the default GW is not configured, the function returns zero values.
func (*Plugin) GetHostIPs ¶
GetHostIPs returns all IP addresses of this node present in the host network namespace (Linux).
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) GetMainVrfID ¶
GetMainVrfID returns the ID of the main network connectivity VRF.
func (*Plugin) GetNatLoopbackIP ¶
GetNatLoopbackIP returns the IP address of a virtual loopback, used to route traffic between clients and services via VPP even if the source and destination are the same IP addresses and would otherwise be routed locally.
func (*Plugin) GetNsIndex ¶
GetNsIndex returns the index of the VPP session namespace associated with the given POD name.
func (*Plugin) GetOtherNATSessionTimeout ¶
GetOtherNATSessionTimeout returns NAT session timeout (in minutes) for non-TCP connections, used in case that CleanupIdleNATSessions is turned on.
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) GetPodSubnet ¶
GetPodSubnet provides subnet used for allocating pod IP addresses across all nodes.
func (*Plugin) GetPodVrfID ¶
GetPodVrfID returns the ID of the POD VRF.
func (*Plugin) GetServiceLocalEndpointWeight ¶
GetServiceLocalEndpointWeight returns the load-balancing weight assigned to locally deployed service endpoints.
func (*Plugin) GetTCPNATSessionTimeout ¶
GetTCPNATSessionTimeout returns NAT session timeout (in minutes) for TCP connections, used in case that CleanupIdleNATSessions is turned on.
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) InSTNMode ¶
InSTNMode returns true if Contiv operates in the STN mode (single interface for each node).
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) RegisterPodPostAddHook ¶
func (plugin *Plugin) RegisterPodPostAddHook(hook PodActionHook)
RegisterPodPostAddHook allows to register callback that will be run for each pod once it is added and before the CNI reply is sent.
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.STN_Rule // 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_ArpEntry // 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. |
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
|
|