Merge pull request #7814 from dcantah/hostnet-helper
CRI: Add host networking helper
This commit is contained in:
commit
a4bc380b91
@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
goruntime "runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -583,3 +584,22 @@ func (c *criService) getContainerStatuses(ctx context.Context, podSandboxID stri
|
|||||||
}
|
}
|
||||||
return containerStatuses, nil
|
return containerStatuses, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hostNetwork handles checking if host networking was requested.
|
||||||
|
func hostNetwork(config *runtime.PodSandboxConfig) bool {
|
||||||
|
var hostNet bool
|
||||||
|
switch goruntime.GOOS {
|
||||||
|
case "windows":
|
||||||
|
// Windows HostProcess pods can only run on the host network
|
||||||
|
hostNet = config.GetWindows().GetSecurityContext().GetHostProcess()
|
||||||
|
case "darwin":
|
||||||
|
// No CNI on Darwin yet.
|
||||||
|
hostNet = true
|
||||||
|
default:
|
||||||
|
// Even on other platforms, the logic containerd uses is to check if NamespaceMode == NODE.
|
||||||
|
// So this handles Linux, as well as any other platforms not governed by the cases above
|
||||||
|
// that have special quirks.
|
||||||
|
hostNet = config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE
|
||||||
|
}
|
||||||
|
return hostNet
|
||||||
|
}
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
goruntime "runtime"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -485,15 +484,8 @@ func (c *criService) loadSandbox(ctx context.Context, cntr containerd.Container)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getNetNS(meta *sandboxstore.Metadata) *netns.NetNS {
|
func getNetNS(meta *sandboxstore.Metadata) *netns.NetNS {
|
||||||
if goruntime.GOOS != "windows" &&
|
// Don't need to load netns for host network sandbox.
|
||||||
meta.Config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
if hostNetwork(meta.Config) {
|
||||||
// Don't need to load netns for host network sandbox.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if goruntime.GOOS == "windows" && meta.Config.GetWindows().GetSecurityContext().GetHostProcess() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if goruntime.GOOS == "darwin" {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return netns.LoadNetNS(meta.NetNSPath)
|
return netns.LoadNetNS(meta.NetNSPath)
|
||||||
|
@ -25,8 +25,6 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containernetworking/plugins/pkg/ns"
|
"github.com/containernetworking/plugins/pkg/ns"
|
||||||
|
|
||||||
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// portForward uses netns to enter the sandbox namespace, and forwards a stream inside the
|
// portForward uses netns to enter the sandbox namespace, and forwards a stream inside the
|
||||||
@ -37,12 +35,12 @@ func (c *criService) portForward(ctx context.Context, id string, port int32, str
|
|||||||
return fmt.Errorf("failed to find sandbox %q in store: %w", id, err)
|
return fmt.Errorf("failed to find sandbox %q in store: %w", id, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var netNSDo func(func(ns.NetNS) error) error
|
var (
|
||||||
// netNSPath is the network namespace path for logging.
|
netNSDo func(func(ns.NetNS) error) error
|
||||||
var netNSPath string
|
// netNSPath is the network namespace path for logging.
|
||||||
securityContext := s.Config.GetLinux().GetSecurityContext()
|
netNSPath string
|
||||||
hostNet := securityContext.GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE
|
)
|
||||||
if !hostNet {
|
if !hostNetwork(s.Config) {
|
||||||
if closed, err := s.NetNS.Closed(); err != nil {
|
if closed, err := s.NetNS.Closed(); err != nil {
|
||||||
return fmt.Errorf("failed to check netwok namespace closed for sandbox %q: %w", id, err)
|
return fmt.Errorf("failed to check netwok namespace closed for sandbox %q: %w", id, err)
|
||||||
} else if closed {
|
} else if closed {
|
||||||
|
@ -23,7 +23,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
goruntime "runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -146,24 +145,8 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
podNetwork := true
|
// Setup the network namespace if host networking wasn't requested.
|
||||||
if goruntime.GOOS != "windows" &&
|
if !hostNetwork(config) {
|
||||||
config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
|
||||||
// Pod network is not needed on linux with host network.
|
|
||||||
podNetwork = false
|
|
||||||
}
|
|
||||||
if goruntime.GOOS == "windows" &&
|
|
||||||
config.GetWindows().GetSecurityContext().GetHostProcess() {
|
|
||||||
// Windows HostProcess pods can only run on the host network
|
|
||||||
podNetwork = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// No CNI on darwin yet
|
|
||||||
if goruntime.GOOS == "darwin" {
|
|
||||||
podNetwork = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if podNetwork {
|
|
||||||
netStart := time.Now()
|
netStart := time.Now()
|
||||||
// If it is not in host network namespace then create a namespace and set the sandbox
|
// If it is not in host network namespace then create a namespace and set the sandbox
|
||||||
// handle. NetNSPath in sandbox metadata and NetNS is non empty only for non host network
|
// handle. NetNSPath in sandbox metadata and NetNS is non empty only for non host network
|
||||||
|
@ -19,7 +19,6 @@ package sbserver
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
goruntime "runtime"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox"
|
sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox"
|
||||||
@ -67,18 +66,9 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox
|
|||||||
func (c *criService) getIPs(sandbox sandboxstore.Sandbox) (string, []string, error) {
|
func (c *criService) getIPs(sandbox sandboxstore.Sandbox) (string, []string, error) {
|
||||||
config := sandbox.Config
|
config := sandbox.Config
|
||||||
|
|
||||||
if goruntime.GOOS != "windows" &&
|
// For sandboxes using the node network we are not
|
||||||
config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
// responsible for reporting the IP.
|
||||||
// For sandboxes using the node network we are not
|
if hostNetwork(config) {
|
||||||
// responsible for reporting the IP.
|
|
||||||
return "", nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if goruntime.GOOS == "windows" && config.GetWindows().GetSecurityContext().GetHostProcess() {
|
|
||||||
return "", nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if goruntime.GOOS == "darwin" {
|
|
||||||
return "", nil, nil
|
return "", nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
goruntime "runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -582,3 +583,22 @@ func (c *criService) getContainerStatuses(ctx context.Context, podSandboxID stri
|
|||||||
}
|
}
|
||||||
return containerStatuses, nil
|
return containerStatuses, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hostNetwork handles checking if host networking was requested.
|
||||||
|
func hostNetwork(config *runtime.PodSandboxConfig) bool {
|
||||||
|
var hostNet bool
|
||||||
|
switch goruntime.GOOS {
|
||||||
|
case "windows":
|
||||||
|
// Windows HostProcess pods can only run on the host network
|
||||||
|
hostNet = config.GetWindows().GetSecurityContext().GetHostProcess()
|
||||||
|
case "darwin":
|
||||||
|
// No CNI on Darwin yet.
|
||||||
|
hostNet = true
|
||||||
|
default:
|
||||||
|
// Even on other platforms, the logic containerd uses is to check if NamespaceMode == NODE.
|
||||||
|
// So this handles Linux, as well as any other platforms not governed by the cases above
|
||||||
|
// that have special quirks.
|
||||||
|
hostNet = config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE
|
||||||
|
}
|
||||||
|
return hostNet
|
||||||
|
}
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
goruntime "runtime"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -426,15 +425,11 @@ func (c *criService) loadSandbox(ctx context.Context, cntr containerd.Container)
|
|||||||
sandbox = sandboxstore.NewSandbox(*meta, s)
|
sandbox = sandboxstore.NewSandbox(*meta, s)
|
||||||
sandbox.Container = cntr
|
sandbox.Container = cntr
|
||||||
|
|
||||||
|
// Don't need to load netns for host network sandbox.
|
||||||
|
if hostNetwork(meta.Config) {
|
||||||
|
return sandbox, nil
|
||||||
|
}
|
||||||
// Load network namespace.
|
// Load network namespace.
|
||||||
if goruntime.GOOS != "windows" &&
|
|
||||||
meta.Config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
|
||||||
// Don't need to load netns for host network sandbox.
|
|
||||||
return sandbox, nil
|
|
||||||
}
|
|
||||||
if goruntime.GOOS == "windows" && meta.Config.GetWindows().GetSecurityContext().GetHostProcess() {
|
|
||||||
return sandbox, nil
|
|
||||||
}
|
|
||||||
sandbox.NetNS = netns.LoadNetNS(meta.NetNSPath)
|
sandbox.NetNS = netns.LoadNetNS(meta.NetNSPath)
|
||||||
|
|
||||||
// It doesn't matter whether task is running or not. If it is running, sandbox
|
// It doesn't matter whether task is running or not. If it is running, sandbox
|
||||||
|
@ -25,8 +25,6 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containernetworking/plugins/pkg/ns"
|
"github.com/containernetworking/plugins/pkg/ns"
|
||||||
|
|
||||||
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// portForward uses netns to enter the sandbox namespace, and forwards a stream inside the
|
// portForward uses netns to enter the sandbox namespace, and forwards a stream inside the
|
||||||
@ -37,12 +35,12 @@ func (c *criService) portForward(ctx context.Context, id string, port int32, str
|
|||||||
return fmt.Errorf("failed to find sandbox %q in store: %w", id, err)
|
return fmt.Errorf("failed to find sandbox %q in store: %w", id, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var netNSDo func(func(ns.NetNS) error) error
|
var (
|
||||||
// netNSPath is the network namespace path for logging.
|
netNSDo func(func(ns.NetNS) error) error
|
||||||
var netNSPath string
|
// netNSPath is the network namespace path for logging.
|
||||||
securityContext := s.Config.GetLinux().GetSecurityContext()
|
netNSPath string
|
||||||
hostNet := securityContext.GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE
|
)
|
||||||
if !hostNet {
|
if !hostNetwork(s.Config) {
|
||||||
if closed, err := s.NetNS.Closed(); err != nil {
|
if closed, err := s.NetNS.Closed(); err != nil {
|
||||||
return fmt.Errorf("failed to check netwok namespace closed for sandbox %q: %w", id, err)
|
return fmt.Errorf("failed to check netwok namespace closed for sandbox %q: %w", id, err)
|
||||||
} else if closed {
|
} else if closed {
|
||||||
|
@ -23,7 +23,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
goruntime "runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -245,20 +244,8 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
|
|||||||
return nil, fmt.Errorf("failed to get sandbox container info: %w", err)
|
return nil, fmt.Errorf("failed to get sandbox container info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
podNetwork := true
|
// Setup the network namespace if host networking wasn't requested.
|
||||||
|
if !hostNetwork(config) {
|
||||||
if goruntime.GOOS != "windows" &&
|
|
||||||
config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
|
||||||
// Pod network is not needed on linux with host network.
|
|
||||||
podNetwork = false
|
|
||||||
}
|
|
||||||
if goruntime.GOOS == "windows" &&
|
|
||||||
config.GetWindows().GetSecurityContext().GetHostProcess() {
|
|
||||||
// Windows HostProcess pods can only run on the host network
|
|
||||||
podNetwork = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if podNetwork {
|
|
||||||
netStart := time.Now()
|
netStart := time.Now()
|
||||||
|
|
||||||
// If it is not in host network namespace then create a namespace and set the sandbox
|
// If it is not in host network namespace then create a namespace and set the sandbox
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
goruntime "runtime"
|
|
||||||
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
@ -70,13 +69,9 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox
|
|||||||
func (c *criService) getIPs(sandbox sandboxstore.Sandbox) (string, []string, error) {
|
func (c *criService) getIPs(sandbox sandboxstore.Sandbox) (string, []string, error) {
|
||||||
config := sandbox.Config
|
config := sandbox.Config
|
||||||
|
|
||||||
if goruntime.GOOS != "windows" &&
|
// For sandboxes using the node network we are not
|
||||||
config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
// responsible for reporting the IP.
|
||||||
// For sandboxes using the node network we are not
|
if hostNetwork(config) {
|
||||||
// responsible for reporting the IP.
|
|
||||||
return "", nil, nil
|
|
||||||
}
|
|
||||||
if goruntime.GOOS == "windows" && config.GetWindows().GetSecurityContext().GetHostProcess() {
|
|
||||||
return "", nil, nil
|
return "", nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user