mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-08 03:33:56 +00:00
kubelet/dockershim/network: pass ipRange dynamically to the CNI plugin
CNI now supports passing ipRanges dynamically. Pass podCIDR so that plugins no longer have to look it up.
This commit is contained in:
parent
c5d15cb0b8
commit
5d9ec20d7e
@ -50,6 +50,7 @@ type cniNetworkPlugin struct {
|
|||||||
nsenterPath string
|
nsenterPath string
|
||||||
confDir string
|
confDir string
|
||||||
binDirs []string
|
binDirs []string
|
||||||
|
podCidr string
|
||||||
}
|
}
|
||||||
|
|
||||||
type cniNetwork struct {
|
type cniNetwork struct {
|
||||||
@ -83,6 +84,11 @@ type cniBandwidthEntry struct {
|
|||||||
EgressBurst int `json:"egressBurst,omitempty"`
|
EgressBurst int `json:"egressBurst,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cniIpRange maps to the standard CNI ip range Capability
|
||||||
|
type cniIpRange struct {
|
||||||
|
Subnet string `json:"subnet"`
|
||||||
|
}
|
||||||
|
|
||||||
func SplitDirs(dirs string) []string {
|
func SplitDirs(dirs string) []string {
|
||||||
// Use comma rather than colon to work better with Windows too
|
// Use comma rather than colon to work better with Windows too
|
||||||
return strings.Split(dirs, ",")
|
return strings.Split(dirs, ",")
|
||||||
@ -152,6 +158,8 @@ func getDefaultCNINetwork(confDir string, binDirs []string) (*cniNetwork, error)
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glog.V(4).Infof("Using CNI configuration file %s", confFile)
|
||||||
|
|
||||||
network := &cniNetwork{
|
network := &cniNetwork{
|
||||||
name: confList.Name,
|
name: confList.Name,
|
||||||
NetworkConfig: confList,
|
NetworkConfig: confList,
|
||||||
@ -199,9 +207,43 @@ func (plugin *cniNetworkPlugin) checkInitialized() error {
|
|||||||
if plugin.getDefaultNetwork() == nil {
|
if plugin.getDefaultNetwork() == nil {
|
||||||
return errors.New("cni config uninitialized")
|
return errors.New("cni config uninitialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the CNI configuration has the ipRanges capability, we need a PodCIDR assigned
|
||||||
|
for _, p := range plugin.getDefaultNetwork().NetworkConfig.Plugins {
|
||||||
|
if p.Network.Capabilities["ipRanges"] {
|
||||||
|
if plugin.podCidr == "" {
|
||||||
|
return errors.New("no PodCIDR set")
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Event handles any change events. The only event ever sent is the PodCIDR change.
|
||||||
|
// No network plugins support changing an already-set PodCIDR
|
||||||
|
func (plugin *cniNetworkPlugin) Event(name string, details map[string]interface{}) {
|
||||||
|
if name != network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.Lock()
|
||||||
|
defer plugin.Unlock()
|
||||||
|
|
||||||
|
podCIDR, ok := details[network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR].(string)
|
||||||
|
if !ok {
|
||||||
|
glog.Warningf("%s event didn't contain pod CIDR", network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if plugin.podCidr != "" {
|
||||||
|
glog.Warningf("Ignoring subsequent pod CIDR update to %s", podCIDR)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.podCidr = podCIDR
|
||||||
|
}
|
||||||
|
|
||||||
func (plugin *cniNetworkPlugin) Name() string {
|
func (plugin *cniNetworkPlugin) Name() string {
|
||||||
return CNIPluginName
|
return CNIPluginName
|
||||||
}
|
}
|
||||||
@ -346,5 +388,8 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string
|
|||||||
rt.CapabilityArgs["bandwidth"] = bandwidthParam
|
rt.CapabilityArgs["bandwidth"] = bandwidthParam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the PodCIDR
|
||||||
|
rt.CapabilityArgs["ipRanges"] = [][]cniIpRange{{{Subnet: plugin.podCidr}}}
|
||||||
|
|
||||||
return rt, nil
|
return rt, nil
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ func installPluginUnderTest(t *testing.T, testBinDir, testConfDir, testDataDir,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to install plugin %s: %v", confFile, err)
|
t.Fatalf("Failed to install plugin %s: %v", confFile, err)
|
||||||
}
|
}
|
||||||
networkConfig := fmt.Sprintf(`{ "name": "%s", "type": "%s", "capabilities": {"portMappings": true, "bandwidth": true} }`, confName, binName)
|
networkConfig := fmt.Sprintf(`{ "name": "%s", "type": "%s", "capabilities": {"portMappings": true, "bandwidth": true, "ipRanges": true} }`, confName, binName)
|
||||||
_, err = f.WriteString(networkConfig)
|
_, err = f.WriteString(networkConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to write network config file (%v)", err)
|
t.Fatalf("Failed to write network config file (%v)", err)
|
||||||
@ -218,6 +218,19 @@ func TestCNIPlugin(t *testing.T) {
|
|||||||
|
|
||||||
mockLoCNI.On("AddNetworkList", cniPlugin.loNetwork.NetworkConfig, mock.AnythingOfType("*libcni.RuntimeConf")).Return(&types020.Result{IP4: &types020.IPConfig{IP: net.IPNet{IP: []byte{127, 0, 0, 1}}}}, nil)
|
mockLoCNI.On("AddNetworkList", cniPlugin.loNetwork.NetworkConfig, mock.AnythingOfType("*libcni.RuntimeConf")).Return(&types020.Result{IP4: &types020.IPConfig{IP: net.IPNet{IP: []byte{127, 0, 0, 1}}}}, nil)
|
||||||
|
|
||||||
|
// Check that status returns an error
|
||||||
|
if err := cniPlugin.Status(); err == nil {
|
||||||
|
t.Fatalf("cniPlugin returned non-err with no podCidr")
|
||||||
|
}
|
||||||
|
|
||||||
|
cniPlugin.Event(network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE, map[string]interface{}{
|
||||||
|
network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR: "10.0.2.0/24",
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := cniPlugin.Status(); err != nil {
|
||||||
|
t.Fatalf("unexpected status err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
ports := map[string][]*hostport.PortMapping{
|
ports := map[string][]*hostport.PortMapping{
|
||||||
containerID.ID: {
|
containerID.ID: {
|
||||||
{
|
{
|
||||||
@ -259,8 +272,9 @@ func TestCNIPlugin(t *testing.T) {
|
|||||||
// Verify the correct network configuration was passed
|
// Verify the correct network configuration was passed
|
||||||
inputConfig := struct {
|
inputConfig := struct {
|
||||||
RuntimeConfig struct {
|
RuntimeConfig struct {
|
||||||
Bandwidth map[string]interface{} `json:"bandwidth"`
|
|
||||||
PortMappings []map[string]interface{} `json:"portMappings"`
|
PortMappings []map[string]interface{} `json:"portMappings"`
|
||||||
|
Bandwidth map[string]interface{} `json:"bandwidth"`
|
||||||
|
IpRanges [][]map[string]interface{} `json:"ipRanges"`
|
||||||
} `json:"runtimeConfig"`
|
} `json:"runtimeConfig"`
|
||||||
}{}
|
}{}
|
||||||
inputBytes, inerr := ioutil.ReadFile(inputFile)
|
inputBytes, inerr := ioutil.ReadFile(inputFile)
|
||||||
@ -282,6 +296,16 @@ func TestCNIPlugin(t *testing.T) {
|
|||||||
t.Errorf("mismatch in expected bandwidth. expected %v got %v", expectedBandwidth, inputConfig.RuntimeConfig.Bandwidth)
|
t.Errorf("mismatch in expected bandwidth. expected %v got %v", expectedBandwidth, inputConfig.RuntimeConfig.Bandwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expectedIpRange := [][]map[string]interface{}{
|
||||||
|
{
|
||||||
|
{"subnet": "10.0.2.0/24"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(inputConfig.RuntimeConfig.IpRanges, expectedIpRange) {
|
||||||
|
t.Errorf("mismatch in expected ipRange. expected %v got %v", expectedIpRange, inputConfig.RuntimeConfig.IpRanges)
|
||||||
|
}
|
||||||
|
|
||||||
// Get its IP address
|
// Get its IP address
|
||||||
status, err := plug.GetPodNetworkStatus("podNamespace", "podName", containerID)
|
status, err := plug.GetPodNetworkStatus("podNamespace", "podName", containerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user