mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-14 21:53:52 +00:00
Merge pull request #58751 from feiskyer/hyperv
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Add support of hyperv isolation for windows containers **What this PR does / why we need it**: Add support of hyperv isolation for windows containers. **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes #58750 **Special notes for your reviewer**: Only one container per pod is supported yet. **Release note**: ```release-note Windows containers now support experimental Hyper-V isolation by setting annotation `experimental.windows.kubernetes.io/isolation-type=hyperv` and feature gates HyperVContainer. Only one container per pod is supported yet. ```
This commit is contained in:
@@ -225,6 +225,12 @@ const (
|
|||||||
//
|
//
|
||||||
// Implement support for limiting pids in pods
|
// Implement support for limiting pids in pods
|
||||||
SupportPodPidsLimit utilfeature.Feature = "SupportPodPidsLimit"
|
SupportPodPidsLimit utilfeature.Feature = "SupportPodPidsLimit"
|
||||||
|
|
||||||
|
// owner: @feiskyer
|
||||||
|
// alpha: v1.10
|
||||||
|
//
|
||||||
|
// Enable Hyper-V containers on Windows
|
||||||
|
HyperVContainer utilfeature.Feature = "HyperVContainer"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -265,6 +271,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
|
|||||||
ResourceLimitsPriorityFunction: {Default: false, PreRelease: utilfeature.Alpha},
|
ResourceLimitsPriorityFunction: {Default: false, PreRelease: utilfeature.Alpha},
|
||||||
SupportIPVSProxyMode: {Default: false, PreRelease: utilfeature.Beta},
|
SupportIPVSProxyMode: {Default: false, PreRelease: utilfeature.Beta},
|
||||||
SupportPodPidsLimit: {Default: false, PreRelease: utilfeature.Alpha},
|
SupportPodPidsLimit: {Default: false, PreRelease: utilfeature.Alpha},
|
||||||
|
HyperVContainer: {Default: false, PreRelease: utilfeature.Alpha},
|
||||||
|
|
||||||
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||||
// unintentionally on either side:
|
// unintentionally on either side:
|
||||||
|
@@ -124,7 +124,13 @@ go_library(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
|
"//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
|
||||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||||
],
|
] + select({
|
||||||
|
"@io_bazel_rules_go//go/platform:windows": [
|
||||||
|
"//pkg/features:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
|
],
|
||||||
|
"//conditions:default": [],
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
go_test(
|
go_test(
|
||||||
|
@@ -587,6 +587,8 @@ func (ds *dockerService) makeSandboxDockerConfig(c *runtimeapi.PodSandboxConfig,
|
|||||||
return nil, fmt.Errorf("failed to generate sandbox security options for sandbox %q: %v", c.Metadata.Name, err)
|
return nil, fmt.Errorf("failed to generate sandbox security options for sandbox %q: %v", c.Metadata.Name, err)
|
||||||
}
|
}
|
||||||
hc.SecurityOpt = append(hc.SecurityOpt, securityOpts...)
|
hc.SecurityOpt = append(hc.SecurityOpt, securityOpts...)
|
||||||
|
|
||||||
|
applyExperimentalCreateConfig(createConfig, c.Annotations)
|
||||||
return createConfig, nil
|
return createConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -145,3 +145,7 @@ func getNetworkNamespace(c *dockertypes.ContainerJSON) (string, error) {
|
|||||||
}
|
}
|
||||||
return fmt.Sprintf(dockerNetNSFmt, c.State.Pid), nil
|
return fmt.Sprintf(dockerNetNSFmt, c.State.Pid), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// applyExperimentalCreateConfig applys experimental configures from sandbox annotations.
|
||||||
|
func applyExperimentalCreateConfig(createConfig *dockertypes.ContainerCreateConfig, annotations map[string]string) {
|
||||||
|
}
|
||||||
|
@@ -53,3 +53,7 @@ func (ds *dockerService) determinePodIPBySandboxID(uid string) string {
|
|||||||
func getNetworkNamespace(c *dockertypes.ContainerJSON) (string, error) {
|
func getNetworkNamespace(c *dockertypes.ContainerJSON) (string, error) {
|
||||||
return "", fmt.Errorf("unsupported platform")
|
return "", fmt.Errorf("unsupported platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// applyExperimentalCreateConfig applys experimental configures from sandbox annotations.
|
||||||
|
func applyExperimentalCreateConfig(createConfig *dockertypes.ContainerCreateConfig, annotations map[string]string) {
|
||||||
|
}
|
||||||
|
@@ -26,9 +26,19 @@ import (
|
|||||||
dockercontainer "github.com/docker/docker/api/types/container"
|
dockercontainer "github.com/docker/docker/api/types/container"
|
||||||
dockerfilters "github.com/docker/docker/api/types/filters"
|
dockerfilters "github.com/docker/docker/api/types/filters"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
hypervIsolationAnnotationKey = "experimental.windows.kubernetes.io/isolation-type"
|
||||||
|
|
||||||
|
// Refer https://aka.ms/hyperv-container.
|
||||||
|
hypervIsolation = "hyperv"
|
||||||
|
)
|
||||||
|
|
||||||
func DefaultMemorySwap() int64 {
|
func DefaultMemorySwap() int64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -40,6 +50,26 @@ func (ds *dockerService) getSecurityOpts(seccompProfile string, separator rune)
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shouldIsolatedByHyperV(annotations map[string]string) bool {
|
||||||
|
if !utilfeature.DefaultFeatureGate.Enabled(features.HyperVContainer) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
v, ok := annotations[hypervIsolationAnnotationKey]
|
||||||
|
return ok && v == hypervIsolation
|
||||||
|
}
|
||||||
|
|
||||||
|
// applyExperimentalCreateConfig applys experimental configures from sandbox annotations.
|
||||||
|
func applyExperimentalCreateConfig(createConfig *dockertypes.ContainerCreateConfig, annotations map[string]string) {
|
||||||
|
if shouldIsolatedByHyperV(annotations) {
|
||||||
|
createConfig.HostConfig.Isolation = hypervIsolation
|
||||||
|
|
||||||
|
if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode == "" {
|
||||||
|
createConfig.HostConfig.NetworkMode = dockercontainer.NetworkMode("none")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (ds *dockerService) updateCreateConfig(
|
func (ds *dockerService) updateCreateConfig(
|
||||||
createConfig *dockertypes.ContainerCreateConfig,
|
createConfig *dockertypes.ContainerCreateConfig,
|
||||||
config *runtimeapi.ContainerConfig,
|
config *runtimeapi.ContainerConfig,
|
||||||
@@ -47,11 +77,13 @@ func (ds *dockerService) updateCreateConfig(
|
|||||||
podSandboxID string, securityOptSep rune, apiVersion *semver.Version) error {
|
podSandboxID string, securityOptSep rune, apiVersion *semver.Version) error {
|
||||||
if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode != "" {
|
if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode != "" {
|
||||||
createConfig.HostConfig.NetworkMode = dockercontainer.NetworkMode(networkMode)
|
createConfig.HostConfig.NetworkMode = dockercontainer.NetworkMode(networkMode)
|
||||||
} else {
|
} else if !shouldIsolatedByHyperV(sandboxConfig.Annotations) {
|
||||||
// Todo: Refactor this call in future for calling methods directly in security_context.go
|
// Todo: Refactor this call in future for calling methods directly in security_context.go
|
||||||
modifyHostNetworkOptionForContainer(false, podSandboxID, createConfig.HostConfig)
|
modifyHostNetworkOptionForContainer(false, podSandboxID, createConfig.HostConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyExperimentalCreateConfig(createConfig, sandboxConfig.Annotations)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,8 +119,17 @@ func (ds *dockerService) determinePodIPBySandboxID(sandboxID string) string {
|
|||||||
// Todo: Add a kernel version check for more validation
|
// Todo: Add a kernel version check for more validation
|
||||||
|
|
||||||
if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode == "" {
|
if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode == "" {
|
||||||
// Do not return any IP, so that we would continue and get the IP of the Sandbox
|
if r.HostConfig.Isolation == hypervIsolation {
|
||||||
ds.getIP(sandboxID, r)
|
// Hyper-V only supports one container per Pod yet and the container will have a different
|
||||||
|
// IP address from sandbox. Return the first non-sandbox container IP as POD IP.
|
||||||
|
// TODO(feiskyer): remove this workaround after Hyper-V supports multiple containers per Pod.
|
||||||
|
if containerIP := ds.getIP(c.ID, r); containerIP != "" {
|
||||||
|
return containerIP
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Do not return any IP, so that we would continue and get the IP of the Sandbox
|
||||||
|
ds.getIP(sandboxID, r)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// On Windows, every container that is created in a Sandbox, needs to invoke CNI plugin again for adding the Network,
|
// On Windows, every container that is created in a Sandbox, needs to invoke CNI plugin again for adding the Network,
|
||||||
// with the shared container name as NetNS info,
|
// with the shared container name as NetNS info,
|
||||||
|
Reference in New Issue
Block a user