Merge pull request #80482 from mars1024/bugfix/cni_validation

add CNI config validation to getDefaultCNINetwork
This commit is contained in:
Kubernetes Prow Robot 2019-08-19 10:11:31 -07:00 committed by GitHub
commit 29c87cbfff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 21 deletions

View File

@ -19,6 +19,7 @@ go_library(
"//pkg/kubelet/container:go_default_library", "//pkg/kubelet/container:go_default_library",
"//pkg/kubelet/dockershim/network:go_default_library", "//pkg/kubelet/dockershim/network:go_default_library",
"//pkg/util/bandwidth:go_default_library", "//pkg/util/bandwidth:go_default_library",
"//pkg/util/slice:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library", "//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library",
"//vendor/github.com/containernetworking/cni/libcni:go_default_library", "//vendor/github.com/containernetworking/cni/libcni:go_default_library",

View File

@ -19,7 +19,6 @@ package cni
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"math" "math"
"sort" "sort"
@ -36,6 +35,7 @@ import (
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockershim/network" "k8s.io/kubernetes/pkg/kubelet/dockershim/network"
"k8s.io/kubernetes/pkg/util/bandwidth" "k8s.io/kubernetes/pkg/util/bandwidth"
utilslice "k8s.io/kubernetes/pkg/util/slice"
utilexec "k8s.io/utils/exec" utilexec "k8s.io/utils/exec"
) )
@ -46,6 +46,13 @@ const (
// defaultSyncConfigPeriod is the default period to sync CNI config // defaultSyncConfigPeriod is the default period to sync CNI config
// TODO: consider making this value configurable or to be a more appropriate value. // TODO: consider making this value configurable or to be a more appropriate value.
defaultSyncConfigPeriod = time.Second * 5 defaultSyncConfigPeriod = time.Second * 5
// supported capabilities
// https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md
portMappingsCapability = "portMappings"
ipRangesCapability = "ipRanges"
bandwidthCapability = "bandwidth"
dnsCapability = "dns"
) )
type cniNetworkPlugin struct { type cniNetworkPlugin struct {
@ -69,6 +76,7 @@ type cniNetwork struct {
name string name string
NetworkConfig *libcni.NetworkConfigList NetworkConfig *libcni.NetworkConfigList
CNIConfig libcni.CNI CNIConfig libcni.CNI
Capabilities []string
} }
// cniPortMapping maps to the standard CNI portmapping Capability // cniPortMapping maps to the standard CNI portmapping Capability
@ -149,9 +157,11 @@ func getDefaultCNINetwork(confDir string, binDirs []string) (*cniNetwork, error)
case err != nil: case err != nil:
return nil, err return nil, err
case len(files) == 0: case len(files) == 0:
return nil, fmt.Errorf("No networks found in %s", confDir) return nil, fmt.Errorf("no networks found in %s", confDir)
} }
cniConfig := &libcni.CNIConfig{Path: binDirs}
sort.Strings(files) sort.Strings(files)
for _, confFile := range files { for _, confFile := range files {
var confList *libcni.NetworkConfigList var confList *libcni.NetworkConfigList
@ -185,16 +195,24 @@ func getDefaultCNINetwork(confDir string, binDirs []string) (*cniNetwork, error)
continue continue
} }
// Before using this CNI config, we have to validate it to make sure that
// all plugins of this config exist on disk
caps, err := cniConfig.ValidateNetworkList(context.TODO(), confList)
if err != nil {
klog.Warningf("Error validating CNI config %v: %v", confList, err)
continue
}
klog.V(4).Infof("Using CNI configuration file %s", confFile) klog.V(4).Infof("Using CNI configuration file %s", confFile)
network := &cniNetwork{ return &cniNetwork{
name: confList.Name, name: confList.Name,
NetworkConfig: confList, NetworkConfig: confList,
CNIConfig: &libcni.CNIConfig{Path: binDirs}, CNIConfig: cniConfig,
} Capabilities: caps,
return network, nil }, nil
} }
return nil, fmt.Errorf("No valid networks found in %s", confDir) return nil, fmt.Errorf("no valid networks found in %s", confDir)
} }
func (plugin *cniNetworkPlugin) Init(host network.Host, hairpinMode kubeletconfig.HairpinMode, nonMasqueradeCIDR string, mtu int) error { func (plugin *cniNetworkPlugin) Init(host network.Host, hairpinMode kubeletconfig.HairpinMode, nonMasqueradeCIDR string, mtu int) error {
@ -236,18 +254,13 @@ func (plugin *cniNetworkPlugin) setDefaultNetwork(n *cniNetwork) {
func (plugin *cniNetworkPlugin) checkInitialized() error { func (plugin *cniNetworkPlugin) checkInitialized() error {
if plugin.getDefaultNetwork() == nil { if plugin.getDefaultNetwork() == nil {
return errors.New("cni config uninitialized") return fmt.Errorf("cni config uninitialized")
} }
// If the CNI configuration has the ipRanges capability, we need a PodCIDR assigned if utilslice.ContainsString(plugin.getDefaultNetwork().Capabilities, ipRangesCapability, nil) && plugin.podCidr == "" {
for _, p := range plugin.getDefaultNetwork().NetworkConfig.Plugins { return fmt.Errorf("cni config needs ipRanges but no PodCIDR set")
if p.Network.Capabilities["ipRanges"] {
if plugin.podCidr == "" {
return errors.New("no PodCIDR set")
}
break
}
} }
return nil return nil
} }
@ -395,12 +408,12 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string
}) })
} }
rt.CapabilityArgs = map[string]interface{}{ rt.CapabilityArgs = map[string]interface{}{
"portMappings": portMappingsParam, portMappingsCapability: portMappingsParam,
} }
ingress, egress, err := bandwidth.ExtractPodBandwidthResources(annotations) ingress, egress, err := bandwidth.ExtractPodBandwidthResources(annotations)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error reading pod bandwidth annotations: %v", err) return nil, fmt.Errorf("failed to get pod bandwidth from annotations: %v", err)
} }
if ingress != nil || egress != nil { if ingress != nil || egress != nil {
bandwidthParam := cniBandwidthEntry{} bandwidthParam := cniBandwidthEntry{}
@ -415,11 +428,11 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string
bandwidthParam.EgressRate = int(egress.Value()) bandwidthParam.EgressRate = int(egress.Value())
bandwidthParam.EgressBurst = math.MaxInt32 // no limit bandwidthParam.EgressBurst = math.MaxInt32 // no limit
} }
rt.CapabilityArgs["bandwidth"] = bandwidthParam rt.CapabilityArgs[bandwidthCapability] = bandwidthParam
} }
// Set the PodCIDR // Set the PodCIDR
rt.CapabilityArgs["ipRanges"] = [][]cniIPRange{{{Subnet: plugin.podCidr}}} rt.CapabilityArgs[ipRangesCapability] = [][]cniIPRange{{{Subnet: plugin.podCidr}}}
// Set dns capability args. // Set dns capability args.
if dnsOptions, ok := options["dns"]; ok { if dnsOptions, ok := options["dns"]; ok {
@ -429,7 +442,7 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string
return nil, fmt.Errorf("failed to unmarshal dns config %q: %v", dnsOptions, err) return nil, fmt.Errorf("failed to unmarshal dns config %q: %v", dnsOptions, err)
} }
if dnsParam := buildDNSCapabilities(&dnsConfig); dnsParam != nil { if dnsParam := buildDNSCapabilities(&dnsConfig); dnsParam != nil {
rt.CapabilityArgs["dns"] = *dnsParam rt.CapabilityArgs[dnsCapability] = *dnsParam
} }
} }