Documentation
¶
Index ¶
- Constants
- Variables
- func AllocateFor(ctx context.Context, i *ipam.T, p naming.Path, rid string) (net.IP, error)
- func CNIConfigFile(dir string, nw Networker) string
- func ClaimFits(ctx context.Context, networkName, namespace string, p naming.Path, rid string) (bool, string, error)
- func ClaimHeldByKey(ctx context.Context, networkName, namespace string) (int, map[string]bool, error)
- func ClaimLimit(namespace, networkName string) (int, bool, error)
- func Driver(t string) func() Networker
- func GetNodeAddr(nodename string, network string) (net.IP, error)
- func IPReachableFrom(peerIP net.IP) (net.IP, *net.IPNet, error)
- func IncIP(ip net.IP)
- func IncIPN(ip net.IP, n int)
- func IsDisabled(t Networker) bool
- func IsSameNetwork(localIP, peerIP net.IP) (bool, error)
- func IsValid(t Networker) bool
- func List(noder Noder) []string
- func MACFromIP4(ip net.IP) (net.HardwareAddr, error)
- func NewAllocator(nw Networker, nodename string) (*ipam.T, error)
- func Setup(n *object.Node, names ...string) error
- type By
- type CNIer
- type Grants
- type IPAMer
- type Networker
- type Noder
- type Route
- type Routes
- type Setuper
- type Status
- type StatusList
- type T
- func (t *T) AllowEmptyNetwork() bool
- func (t *T) Config() *xconfig.T
- func (t *T) FilterIPs(ips clusterip.L) clusterip.L
- func (t *T) GetBool(s string) bool
- func (t *T) GetInt(s string) int
- func (t *T) GetString(s string) string
- func (t *T) GetStringAs(s, nodename string) string
- func (t *T) GetStrings(s string) []string
- func (t *T) GetSubnetAs(nodename string) string
- func (t *T) IPNet() (*net.IPNet, error)
- func (t *T) IPsPerNode() (int, error)
- func (t *T) IsIP6() bool
- func (t *T) IsImplicit() bool
- func (t *T) Kops() keyop.L
- func (t *T) Log() *plog.Logger
- func (t *T) Name() string
- func (t *T) NeedCommit() bool
- func (t *T) Network() string
- func (t *T) NodeSubnet(nodename string) (*net.IPNet, error)
- func (t *T) NodeSubnetIP(nodename string) (net.IP, error)
- func (t *T) Nodes() ([]string, error)
- func (t *T) Set(option, value string) error
- func (t *T) SetAllowEmptyNetwork(v bool)
- func (t *T) SetDriver(name string)
- func (t *T) SetImplicit(v bool)
- func (t *T) SetName(name string)
- func (t *T) SetNeedCommit(v bool)
- func (t *T) SetNetwork(s string)
- func (t *T) SetNoder(noder Noder)
- func (t *T) Tables() []string
- func (t *T) Type() string
- type Usage
Constants ¶
const (
// CNIVersion is the version we write in the generated CNI network configuration files
CNIVersion = "0.3.0"
)
Variables ¶
var (
ErrInvalidType = errors.New("invalid network type")
)
Functions ¶
func AllocateFor ¶
AllocateFor reserves an address for a resource, refusing when the namespace has already taken all it claimed of the network.
The claim is checked only when the reservation is a new one. An allocator is idempotent for a key, and it is asked again on every start, so a resource that already holds its address is not taking one more: refusing it there would stop an object the cluster let take the address in the first place, and a namespace that reached its limit could no longer restart what it runs.
func CNIConfigFile ¶
func ClaimFits ¶
func ClaimFits(ctx context.Context, networkName, namespace string, p naming.Path, rid string) (bool, string, error)
ClaimFits says whether a namespace may take one more address of a network for a resource of an object, and why not when it may not.
A namespace with no claim on the network is not capped on it, and is answered from the local configuration alone, which is what most allocations are.
A capped one is brokered. The claim is asked of the daemon, which hands the question to the node speaking for the cluster: what the namespace holds is read from what the objects of the cluster publish, an object publishes its address after it has taken it, and two claims answered from the same reading both fit where together they do not. One node answering them, counting what it has granted since, is what makes them fit one at a time.
Failing to reach the daemon leaves the claim unchecked rather than refused, for the same reason a pool claim is: a cap is something the cluster brokers, and where there is no daemon to ask there is nothing brokering.
func ClaimHeldByKey ¶
func ClaimHeldByKey(ctx context.Context, networkName, namespace string) (int, map[string]bool, error)
ClaimHeldByKey is how many addresses of a network a namespace holds, and the reservations they are held for.
Addresses are counted, not reservations: a failover object holds the same address on every node it is configured on, and that is one address taken from the network, while the instances of a flex each hold one of their own. The reservations are answered alongside so that a claim granted a moment ago and not yet reported can be told apart from one the cluster has caught up with.
Two views are merged. The cluster reports the addresses its objects publish in their status, which is the only way to see the other nodes, but a status is published after the fact: an address reserved a moment ago is not in it yet. The allocator of this node has no such lag, and this is read where every claim is answered, so what it adds is this node's own reservations, including the ones made before there was anything brokering. An address in both is one address.
func ClaimLimit ¶
ClaimLimit is the most addresses a namespace may hold in a network, and whether it is capped on it at all.
func IsDisabled ¶
IsDisabled returns true if the network keyword value is "none"
func MACFromIP4 ¶
func MACFromIP4(ip net.IP) (net.HardwareAddr, error)
MACFromIP4 returns a mac address using a 0a:58 prefix followed by the bridge ipv4 address converted to hexa (same algorithm used in k8s).
When the device with the lowest mac is removed from the bridge or when a new device with the lowest mac is added to the bridge, all containers can experience tcp hangs while the arp table resynchronizes.
Setting a mac address to the bridge explicitly avoids these mac address changes.
func NewAllocator ¶
NewAllocator returns the allocator of a network on a node, or nil when the network is one om allocates no address in.
Types ¶
type Grants ¶
type Grants struct {
// contains filtered or unexported fields
}
Grants is the addresses a node has let namespaces take of the networks, waiting for the cluster to report them.
A claim counts the addresses the namespace holds, read from what the objects of the cluster publish. An object publishes its address after it has taken it, so a claim answered from that reading alone misses every address taken since: two resources reserving at once are each answered as though the other had not. Counting the grants too closes that window, and holding them here is what makes the answer and the record one step rather than two.
A grant is held for the reservation it was granted for, which is a resource of an object, so that the cluster reporting an address for that resource is what releases it.
func (*Grants) Fits ¶
func (t *Grants) Fits(namespace, networkName, key string, limit, held int, seen map[string]bool, now time.Time) (bool, string)
Fits says whether a namespace may take one more address of a network for a reservation, and records the grant when it may.
held is how many addresses of the network the namespace is known to hold, and seen is the reservations those addresses are held for. A reservation already holding an address takes no new one: an object failing over to another node reserves the address it already has, and a claim asked twice for the same resource is the same address twice.
func (*Grants) Seed ¶
Seed records a grant this node did not answer.
It is how a table lost is rebuilt. The grants of a node are in memory, so a node that has just started, or has just become the one answering claims, has none of them and answers from what the objects of the cluster have published alone, which is the reading the grants exist to complete.
What was granted and reserved is not lost, though: the node that reserved it publishes it before the others hear of it. What was granted and never reserved is lost, and expiring is what would have become of it anyway.
type IPAMer ¶
type IPAMer interface {
// AllocatableRange returns the addresses a node draws from in this
// network. The gateway of that range is its first address plus one,
// which is how both drivers derive the address of their bridge.
AllocatableRange(nodename string) (*net.IPNet, error)
}
IPAMer is implemented by the network drivers whose addresses om allocates. A driver that does not implement it has om allocate nothing in it, which is what the lo network wants.
type Networker ¶
type Networker interface {
// SetDriver sets the driver name, which is obtained from the
// "type" keyword in the network configuration.
SetDriver(string)
// SetName sets the network name. See Name().
SetName(string)
// SetImplicit sets isImplicit. See IsImplicit().
SetImplicit(bool)
// SetNetwork sets the network CIDR. Normally read from the
// merged cluster configuration.
SetNetwork(string)
// SetNeedCommit can be called by drivers to signal network
// configuration changes are staged and // need to be written
// to file.
SetNeedCommit(bool)
// SetNoder stores the Noder
SetNoder(Noder)
// IsImplicit returns true if the network is a builtin with
// no override section in the configuration.
IsImplicit() bool
// IsIP6 returns true if the network is a CIDR representation
// of a IPv6 network.
IsIP6() bool
// Name returns the name of the network. Which is the part
// after the dash in the configuration section name.
Name() string
// Kops returns the list of cluster config changes queued by the
// driver upon Setup.
Kops() keyop.L
// Network returns the CIDR representation of the network.
Network() string
// IPNet returns the result of ParseCIDR() on the Network()
// CIDR string, without the net.IP
IPNet() (*net.IPNet, error)
// NeedCommit return true if the network configuration cache
// has staged changes. This can be used by Networks() users to
// do one commit per action instead of one per network.
NeedCommit() bool
// Type return the driver name.
Type() string
FilterIPs(clusterip.L) clusterip.L
AllowEmptyNetwork() bool
// Config is a wrapper for the noder MergedConfig
Config() *xconfig.T
// Log returns a zerolog Logger configured to add the network
// name to log entries.
Log() *plog.Logger
// Nodes is a wrapper for the noder Nodes, which returns the
// list of cluster nodes to make the network available on.
Nodes() ([]string, error)
NodeSubnet(nodename string) (*net.IPNet, error)
NodeSubnetIP(nodename string) (net.IP, error)
}
func NewFromNoder ¶
type Route ¶
type Status ¶
type StatusList ¶
type StatusList []Status
func NewStatusList ¶
func NewStatusList() StatusList
func ShowNetworks ¶
func ShowNetworks(noder Noder, ips clusterip.L) StatusList
func ShowNetworksByName ¶
func ShowNetworksByName(noder Noder, name string, ips clusterip.L) StatusList
func (StatusList) Add ¶
func (t StatusList) Add(p Networker, ips clusterip.L) StatusList
func (StatusList) Len ¶
func (t StatusList) Len() int
func (StatusList) Less ¶
func (t StatusList) Less(i, j int) bool
func (StatusList) Swap ¶
func (t StatusList) Swap(i, j int)
type T ¶
type T struct {
// contains filtered or unexported fields
}
func (*T) AllowEmptyNetwork ¶
AllowEmptyNetwork returns true if the driver supports empty "network" keyword value. For one, the loopback driver does support that.
func (*T) GetStringAs ¶
func (*T) GetStrings ¶
func (*T) GetSubnetAs ¶
func (*T) IPsPerNode ¶
func (*T) IsImplicit ¶
func (*T) NeedCommit ¶
func (*T) NodeSubnet ¶
NodeSubnet returns the network subnet assigned to a cluster node, as a *net.IPNet. This subnet is usually found in the network configuration, as a subnet@<nodename> option. If not found there, allocate and write one.
The subnet allocator uses ips_per_node to compute a netmask (narrower than the network mask). The subnet first ip is computed using the position of the node in the cluster nodes list.
Example: With
cluster.nodes = n1 n2 n3 net1.network = 10.0.0.0/24 net1.ips_per_node = 64
=>
subnet@n1 = 10.0.0.0/26 subnet@n2 = 10.0.0.64/26 subnet@n3 = 10.0.0.128/26