Merge pull request #7814 from dcantah/hostnet-helper

CRI: Add host networking helper
This commit is contained in:
Derek McGowan 2022-12-15 11:21:45 -08:00 committed by GitHub
commit a4bc380b91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 68 additions and 90 deletions

View File

@ -21,6 +21,7 @@ import (
"fmt"
"path"
"path/filepath"
goruntime "runtime"
"strconv"
"strings"
"time"
@ -583,3 +584,22 @@ func (c *criService) getContainerStatuses(ctx context.Context, podSandboxID stri
}
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
}

View File

@ -21,7 +21,6 @@ import (
"fmt"
"os"
"path/filepath"
goruntime "runtime"
"sync"
"time"
@ -485,15 +484,8 @@ func (c *criService) loadSandbox(ctx context.Context, cntr containerd.Container)
}
func getNetNS(meta *sandboxstore.Metadata) *netns.NetNS {
if goruntime.GOOS != "windows" &&
meta.Config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
// 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" {
// Don't need to load netns for host network sandbox.
if hostNetwork(meta.Config) {
return nil
}
return netns.LoadNetNS(meta.NetNSPath)

View File

@ -25,8 +25,6 @@ import (
"github.com/containerd/containerd/log"
"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
@ -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)
}
var netNSDo func(func(ns.NetNS) error) error
// netNSPath is the network namespace path for logging.
var netNSPath string
securityContext := s.Config.GetLinux().GetSecurityContext()
hostNet := securityContext.GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE
if !hostNet {
var (
netNSDo func(func(ns.NetNS) error) error
// netNSPath is the network namespace path for logging.
netNSPath string
)
if !hostNetwork(s.Config) {
if closed, err := s.NetNS.Closed(); err != nil {
return fmt.Errorf("failed to check netwok namespace closed for sandbox %q: %w", id, err)
} else if closed {

View File

@ -23,7 +23,6 @@ import (
"fmt"
"math"
"path/filepath"
goruntime "runtime"
"strings"
"time"
@ -146,24 +145,8 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
}
}()
podNetwork := true
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
}
// No CNI on darwin yet
if goruntime.GOOS == "darwin" {
podNetwork = false
}
if podNetwork {
// Setup the network namespace if host networking wasn't requested.
if !hostNetwork(config) {
netStart := time.Now()
// 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

View File

@ -19,7 +19,6 @@ package sbserver
import (
"context"
"fmt"
goruntime "runtime"
"time"
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) {
config := sandbox.Config
if goruntime.GOOS != "windows" &&
config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
// For sandboxes using the node network we are not
// responsible for reporting the IP.
return "", nil, nil
}
if goruntime.GOOS == "windows" && config.GetWindows().GetSecurityContext().GetHostProcess() {
return "", nil, nil
}
if goruntime.GOOS == "darwin" {
// For sandboxes using the node network we are not
// responsible for reporting the IP.
if hostNetwork(config) {
return "", nil, nil
}

View File

@ -21,6 +21,7 @@ import (
"fmt"
"path"
"path/filepath"
goruntime "runtime"
"strconv"
"strings"
"time"
@ -582,3 +583,22 @@ func (c *criService) getContainerStatuses(ctx context.Context, podSandboxID stri
}
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
}

View File

@ -21,7 +21,6 @@ import (
"fmt"
"os"
"path/filepath"
goruntime "runtime"
"sync"
"time"
@ -426,15 +425,11 @@ func (c *criService) loadSandbox(ctx context.Context, cntr containerd.Container)
sandbox = sandboxstore.NewSandbox(*meta, s)
sandbox.Container = cntr
// Don't need to load netns for host network sandbox.
if hostNetwork(meta.Config) {
return sandbox, nil
}
// 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)
// It doesn't matter whether task is running or not. If it is running, sandbox

View File

@ -25,8 +25,6 @@ import (
"github.com/containerd/containerd/log"
"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
@ -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)
}
var netNSDo func(func(ns.NetNS) error) error
// netNSPath is the network namespace path for logging.
var netNSPath string
securityContext := s.Config.GetLinux().GetSecurityContext()
hostNet := securityContext.GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE
if !hostNet {
var (
netNSDo func(func(ns.NetNS) error) error
// netNSPath is the network namespace path for logging.
netNSPath string
)
if !hostNetwork(s.Config) {
if closed, err := s.NetNS.Closed(); err != nil {
return fmt.Errorf("failed to check netwok namespace closed for sandbox %q: %w", id, err)
} else if closed {

View File

@ -23,7 +23,6 @@ import (
"fmt"
"math"
"path/filepath"
goruntime "runtime"
"strings"
"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)
}
podNetwork := true
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 {
// Setup the network namespace if host networking wasn't requested.
if !hostNetwork(config) {
netStart := time.Now()
// If it is not in host network namespace then create a namespace and set the sandbox

View File

@ -20,7 +20,6 @@ import (
"context"
"encoding/json"
"fmt"
goruntime "runtime"
"github.com/containerd/containerd"
"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) {
config := sandbox.Config
if goruntime.GOOS != "windows" &&
config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
// For sandboxes using the node network we are not
// responsible for reporting the IP.
return "", nil, nil
}
if goruntime.GOOS == "windows" && config.GetWindows().GetSecurityContext().GetHostProcess() {
// For sandboxes using the node network we are not
// responsible for reporting the IP.
if hostNetwork(config) {
return "", nil, nil
}