Merge pull request #1623 from mheon/static_ip

Add ability to specify static IPs with --ip flag
This commit is contained in:
OpenShift Merge Robot
2018-10-11 10:40:37 -07:00
committed by GitHub
14 changed files with 189 additions and 23 deletions

View File

@@ -3,6 +3,7 @@ package ocicni
import (
"errors"
"fmt"
"net"
"os"
"path"
"sort"
@@ -351,14 +352,14 @@ func (plugin *cniNetworkPlugin) getNetwork(name string) (*cniNetwork, error) {
return net, nil
}
func (plugin *cniNetworkPlugin) getDefaultNetworkName() string {
func (plugin *cniNetworkPlugin) GetDefaultNetworkName() string {
plugin.RLock()
defer plugin.RUnlock()
return plugin.defaultNetName
}
func (plugin *cniNetworkPlugin) getDefaultNetwork() *cniNetwork {
defaultNetName := plugin.getDefaultNetworkName()
defaultNetName := plugin.GetDefaultNetworkName()
if defaultNetName == "" {
return nil
}
@@ -383,7 +384,7 @@ func (plugin *cniNetworkPlugin) Name() string {
func (plugin *cniNetworkPlugin) forEachNetwork(podNetwork *PodNetwork, forEachFunc func(*cniNetwork, string, *PodNetwork) error) error {
networks := podNetwork.Networks
if len(networks) == 0 {
networks = append(networks, plugin.getDefaultNetworkName())
networks = append(networks, plugin.GetDefaultNetworkName())
}
for i, netName := range networks {
// Interface names start at "eth0" and count up for each network
@@ -408,7 +409,7 @@ func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]cnitypes.Resu
plugin.podLock(podNetwork).Lock()
defer plugin.podUnlock(podNetwork)
_, err := plugin.loNetwork.addToNetwork(plugin.cacheDir, &podNetwork, "lo")
_, err := plugin.loNetwork.addToNetwork(plugin.cacheDir, &podNetwork, "lo", "")
if err != nil {
logrus.Errorf("Error while adding to cni lo network: %s", err)
return nil, err
@@ -416,7 +417,12 @@ func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]cnitypes.Resu
results := make([]cnitypes.Result, 0)
if err := plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork) error {
result, err := network.addToNetwork(plugin.cacheDir, podNetwork, ifName)
ip := ""
if conf, ok := podNetwork.NetworkConfig[network.name]; ok {
ip = conf.IP
}
result, err := network.addToNetwork(plugin.cacheDir, podNetwork, ifName, ip)
if err != nil {
logrus.Errorf("Error while adding pod to CNI network %q: %s", network.name, err)
return err
@@ -439,7 +445,12 @@ func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error {
defer plugin.podUnlock(podNetwork)
return plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork) error {
if err := network.deleteFromNetwork(plugin.cacheDir, podNetwork, ifName); err != nil {
ip := ""
if conf, ok := podNetwork.NetworkConfig[network.name]; ok {
ip = conf.IP
}
if err := network.deleteFromNetwork(plugin.cacheDir, podNetwork, ifName, ip); err != nil {
logrus.Errorf("Error while removing pod from CNI network %q: %s", network.name, err)
return err
}
@@ -491,8 +502,8 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]cn
return results, nil
}
func (network *cniNetwork) addToNetwork(cacheDir string, podNetwork *PodNetwork, ifName string) (cnitypes.Result, error) {
rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName)
func (network *cniNetwork) addToNetwork(cacheDir string, podNetwork *PodNetwork, ifName, ip string) (cnitypes.Result, error) {
rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName, ip)
if err != nil {
logrus.Errorf("Error adding network: %v", err)
return nil, err
@@ -509,8 +520,8 @@ func (network *cniNetwork) addToNetwork(cacheDir string, podNetwork *PodNetwork,
return res, nil
}
func (network *cniNetwork) deleteFromNetwork(cacheDir string, podNetwork *PodNetwork, ifName string) error {
rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName)
func (network *cniNetwork) deleteFromNetwork(cacheDir string, podNetwork *PodNetwork, ifName, ip string) error {
rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName, ip)
if err != nil {
logrus.Errorf("Error deleting network: %v", err)
return err
@@ -526,7 +537,7 @@ func (network *cniNetwork) deleteFromNetwork(cacheDir string, podNetwork *PodNet
return nil
}
func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName string) (*libcni.RuntimeConf, error) {
func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName, ip string) (*libcni.RuntimeConf, error) {
logrus.Infof("Got pod network %+v", podNetwork)
rt := &libcni.RuntimeConf{
@@ -542,6 +553,14 @@ func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName string)
},
}
// Add requested static IP to CNI_ARGS
if ip != "" {
if tstIP := net.ParseIP(ip); tstIP == nil {
return nil, fmt.Errorf("unable to parse IP address %q", ip)
}
rt.Args = append(rt.Args, [2]string{"IP", ip})
}
if len(podNetwork.PortMappings) == 0 {
return rt, nil
}

View File

@@ -24,6 +24,14 @@ type PortMapping struct {
HostIP string `json:"hostIP"`
}
// NetworkConfig is additional configuration for a single CNI network.
type NetworkConfig struct {
// IP is a static IP to be specified in the network. Can only be used
// with the hostlocal IP allocator. If left unset, an IP will be
// dynamically allocated.
IP string
}
// PodNetwork configures the network of a pod sandbox.
type PodNetwork struct {
// Name is the name of the sandbox.
@@ -40,6 +48,11 @@ type PodNetwork struct {
// Networks is a list of CNI network names to attach to the sandbox
// Leave this list empty to attach the default network to the sandbox
Networks []string
// NetworkConfig is configuration specific to a single CNI network.
// It is optional, and can be omitted for some or all specified networks
// without issue.
NetworkConfig map[string]NetworkConfig
}
// CNIPlugin is the interface that needs to be implemented by a plugin
@@ -48,6 +61,10 @@ type CNIPlugin interface {
// for a plugin by name, e.g.
Name() string
// GetDefaultNetworkName returns the name of the plugin's default
// network.
GetDefaultNetworkName() string
// SetUpPod is the method called after the sandbox container of
// the pod has been created but before the other containers of the
// pod are launched.