@@ -25,6 +25,7 @@ import (
2525 "path/filepath"
2626 goruntime "runtime"
2727 "strings"
28+ "sync"
2829 "time"
2930
3031 "github.com/containerd/containerd"
@@ -59,6 +60,12 @@ func init() {
5960// RunPodSandbox creates and starts a pod-level sandbox. Runtimes should ensure
6061// the sandbox is in ready state.
6162func (c * criService ) RunPodSandbox (ctx context.Context , r * runtime.RunPodSandboxRequest ) (_ * runtime.RunPodSandboxResponse , retErr error ) {
63+ var (
64+ wg sync.WaitGroup
65+ netStart time.Time
66+ )
67+ rc := make (chan error )
68+
6269 config := r .GetConfig ()
6370 log .G (ctx ).Debugf ("Sandbox config %+v" , config )
6471
@@ -125,7 +132,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
125132 }
126133
127134 if podNetwork {
128- netStart : = time .Now ()
135+ netStart = time .Now ()
129136 // If it is not in host network namespace then create a namespace and set the sandbox
130137 // handle. NetNSPath in sandbox metadata and NetNS is non empty only for non host network
131138 // namespaces. If the pod is in host network namespace then both are empty and should not
@@ -163,10 +170,8 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
163170 // In this case however caching the IP will add a subtle performance enhancement by avoiding
164171 // calls to network namespace of the pod to query the IP of the veth interface on every
165172 // SandboxStatus request.
166- if err := c .setupPodNetwork (ctx , & sandbox ); err != nil {
167- return nil , fmt .Errorf ("failed to setup network for sandbox %q: %w" , id , err )
168- }
169- sandboxCreateNetworkTimer .UpdateSince (netStart )
173+ wg .Add (1 )
174+ go c .setupPodNetwork (ctx , & sandbox , & wg , rc )
170175 }
171176
172177 runtimeStart := time .Now ()
@@ -355,6 +360,15 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
355360
356361 sandboxRuntimeCreateTimer .WithValues (ociRuntime .Type ).UpdateSince (runtimeStart )
357362
363+ if podNetwork {
364+ err := <- rc
365+ if err != nil {
366+ return nil , fmt .Errorf ("failed to setup network for sandbox %q: %w" , id , err )
367+ }
368+ sandboxCreateNetworkTimer .UpdateSince (netStart )
369+
370+ wg .Wait ()
371+ }
358372 return & runtime.RunPodSandboxResponse {PodSandboxId : id }, nil
359373}
360374
@@ -374,34 +388,39 @@ func (c *criService) getNetworkPlugin(runtimeClass string) cni.CNI {
374388}
375389
376390// setupPodNetwork setups up the network for a pod
377- func (c * criService ) setupPodNetwork (ctx context.Context , sandbox * sandboxstore.Sandbox ) error {
391+ func (c * criService ) setupPodNetwork (ctx context.Context , sandbox * sandboxstore.Sandbox , wg * sync.WaitGroup , rc chan error ) {
392+ defer wg .Done ()
378393 var (
379394 id = sandbox .ID
380395 config = sandbox .Config
381396 path = sandbox .NetNSPath
382397 netPlugin = c .getNetworkPlugin (sandbox .RuntimeHandler )
383398 )
384399 if netPlugin == nil {
385- return errors .New ("cni config not initialized" )
400+ rc <- errors .New ("cni config not initialized" )
401+ return
386402 }
387403
388404 opts , err := cniNamespaceOpts (id , config )
389405 if err != nil {
390- return fmt .Errorf ("get cni namespace options: %w" , err )
406+ rc <- fmt .Errorf ("get cni namespace options: %w" , err )
407+ return
391408 }
392409 log .G (ctx ).WithField ("podsandboxid" , id ).Debugf ("begin cni setup" )
393410 result , err := netPlugin .Setup (ctx , id , path , opts ... )
394411 if err != nil {
395- return err
412+ rc <- err
413+ return
396414 }
397415 logDebugCNIResult (ctx , id , result )
398416 // Check if the default interface has IP config
399417 if configs , ok := result .Interfaces [defaultIfName ]; ok && len (configs .IPConfigs ) > 0 {
400418 sandbox .IP , sandbox .AdditionalIPs = selectPodIPs (ctx , configs .IPConfigs , c .config .IPPreference )
401419 sandbox .CNIResult = result
402- return nil
420+ rc <- nil
421+ return
403422 }
404- return fmt .Errorf ("failed to find network info for sandbox %q" , id )
423+ rc <- fmt .Errorf ("failed to find network info for sandbox %q" , id )
405424}
406425
407426// cniNamespaceOpts get CNI namespace options from sandbox config.
0 commit comments