@@ -19,7 +19,6 @@ package cni
19
19
import (
20
20
"context"
21
21
"encoding/json"
22
- "errors"
23
22
"fmt"
24
23
"math"
25
24
"sort"
@@ -36,6 +35,7 @@ import (
36
35
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
37
36
"k8s.io/kubernetes/pkg/kubelet/dockershim/network"
38
37
"k8s.io/kubernetes/pkg/util/bandwidth"
38
+ utilslice "k8s.io/kubernetes/pkg/util/slice"
39
39
utilexec "k8s.io/utils/exec"
40
40
)
41
41
@@ -46,6 +46,13 @@ const (
46
46
// defaultSyncConfigPeriod is the default period to sync CNI config
47
47
// TODO: consider making this value configurable or to be a more appropriate value.
48
48
defaultSyncConfigPeriod = time .Second * 5
49
+
50
+ // supported capabilities
51
+ // https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md
52
+ portMappingsCapability = "portMappings"
53
+ ipRangesCapability = "ipRanges"
54
+ bandwidthCapability = "bandwidth"
55
+ dnsCapability = "dns"
49
56
)
50
57
51
58
type cniNetworkPlugin struct {
@@ -69,6 +76,7 @@ type cniNetwork struct {
69
76
name string
70
77
NetworkConfig * libcni.NetworkConfigList
71
78
CNIConfig libcni.CNI
79
+ Capabilities []string
72
80
}
73
81
74
82
// cniPortMapping maps to the standard CNI portmapping Capability
@@ -149,9 +157,11 @@ func getDefaultCNINetwork(confDir string, binDirs []string) (*cniNetwork, error)
149
157
case err != nil :
150
158
return nil , err
151
159
case len (files ) == 0 :
152
- return nil , fmt .Errorf ("No networks found in %s" , confDir )
160
+ return nil , fmt .Errorf ("no networks found in %s" , confDir )
153
161
}
154
162
163
+ cniConfig := & libcni.CNIConfig {Path : binDirs }
164
+
155
165
sort .Strings (files )
156
166
for _ , confFile := range files {
157
167
var confList * libcni.NetworkConfigList
@@ -185,16 +195,24 @@ func getDefaultCNINetwork(confDir string, binDirs []string) (*cniNetwork, error)
185
195
continue
186
196
}
187
197
198
+ // Before using this CNI config, we have to validate it to make sure that
199
+ // all plugins of this config exist on disk
200
+ caps , err := cniConfig .ValidateNetworkList (context .TODO (), confList )
201
+ if err != nil {
202
+ klog .Warningf ("Error validating CNI config %v: %v" , confList , err )
203
+ continue
204
+ }
205
+
188
206
klog .V (4 ).Infof ("Using CNI configuration file %s" , confFile )
189
207
190
- network := & cniNetwork {
208
+ return & cniNetwork {
191
209
name : confList .Name ,
192
210
NetworkConfig : confList ,
193
- CNIConfig : & libcni. CNIConfig { Path : binDirs } ,
194
- }
195
- return network , nil
211
+ CNIConfig : cniConfig ,
212
+ Capabilities : caps ,
213
+ } , nil
196
214
}
197
- return nil , fmt .Errorf ("No valid networks found in %s" , confDir )
215
+ return nil , fmt .Errorf ("no valid networks found in %s" , confDir )
198
216
}
199
217
200
218
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) {
236
254
237
255
func (plugin * cniNetworkPlugin ) checkInitialized () error {
238
256
if plugin .getDefaultNetwork () == nil {
239
- return errors . New ("cni config uninitialized" )
257
+ return fmt . Errorf ("cni config uninitialized" )
240
258
}
241
259
242
- // If the CNI configuration has the ipRanges capability, we need a PodCIDR assigned
243
- for _ , p := range plugin .getDefaultNetwork ().NetworkConfig .Plugins {
244
- if p .Network .Capabilities ["ipRanges" ] {
245
- if plugin .podCidr == "" {
246
- return errors .New ("no PodCIDR set" )
247
- }
248
- break
249
- }
260
+ if utilslice .ContainsString (plugin .getDefaultNetwork ().Capabilities , ipRangesCapability , nil ) && plugin .podCidr == "" {
261
+ return fmt .Errorf ("cni config needs ipRanges but no PodCIDR set" )
250
262
}
263
+
251
264
return nil
252
265
}
253
266
@@ -395,12 +408,12 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string
395
408
})
396
409
}
397
410
rt .CapabilityArgs = map [string ]interface {}{
398
- "portMappings" : portMappingsParam ,
411
+ portMappingsCapability : portMappingsParam ,
399
412
}
400
413
401
414
ingress , egress , err := bandwidth .ExtractPodBandwidthResources (annotations )
402
415
if err != nil {
403
- return nil , fmt .Errorf ("Error reading pod bandwidth annotations: %v" , err )
416
+ return nil , fmt .Errorf ("failed to get pod bandwidth from annotations: %v" , err )
404
417
}
405
418
if ingress != nil || egress != nil {
406
419
bandwidthParam := cniBandwidthEntry {}
@@ -415,11 +428,11 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string
415
428
bandwidthParam .EgressRate = int (egress .Value ())
416
429
bandwidthParam .EgressBurst = math .MaxInt32 // no limit
417
430
}
418
- rt .CapabilityArgs ["bandwidth" ] = bandwidthParam
431
+ rt .CapabilityArgs [bandwidthCapability ] = bandwidthParam
419
432
}
420
433
421
434
// Set the PodCIDR
422
- rt .CapabilityArgs ["ipRanges" ] = [][]cniIPRange {{{Subnet : plugin .podCidr }}}
435
+ rt .CapabilityArgs [ipRangesCapability ] = [][]cniIPRange {{{Subnet : plugin .podCidr }}}
423
436
424
437
// Set dns capability args.
425
438
if dnsOptions , ok := options ["dns" ]; ok {
@@ -429,7 +442,7 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string
429
442
return nil , fmt .Errorf ("failed to unmarshal dns config %q: %v" , dnsOptions , err )
430
443
}
431
444
if dnsParam := buildDNSCapabilities (& dnsConfig ); dnsParam != nil {
432
- rt .CapabilityArgs ["dns" ] = * dnsParam
445
+ rt .CapabilityArgs [dnsCapability ] = * dnsParam
433
446
}
434
447
}
435
448
0 commit comments