mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 22:46:12 +00:00
Kubelet updates for Windows HostProcess Containers
This commit is contained in:
parent
51a02fdb80
commit
fd94032b21
@ -31,6 +31,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
||||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||||
|
sc "k8s.io/kubernetes/pkg/securitycontext"
|
||||||
hashutil "k8s.io/kubernetes/pkg/util/hash"
|
hashutil "k8s.io/kubernetes/pkg/util/hash"
|
||||||
"k8s.io/kubernetes/third_party/forked/golang/expansion"
|
"k8s.io/kubernetes/third_party/forked/golang/expansion"
|
||||||
utilsnet "k8s.io/utils/net"
|
utilsnet "k8s.io/utils/net"
|
||||||
@ -310,6 +311,34 @@ func HasPrivilegedContainer(pod *v1.Pod) bool {
|
|||||||
return hasPrivileged
|
return hasPrivileged
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasWindowsHostProcessContainer returns true if any of the containers in a pod are HostProcess containers.
|
||||||
|
func HasWindowsHostProcessContainer(pod *v1.Pod) bool {
|
||||||
|
var hasHostProcess bool
|
||||||
|
podutil.VisitContainers(&pod.Spec, podutil.AllFeatureEnabledContainers(), func(c *v1.Container, containerType podutil.ContainerType) bool {
|
||||||
|
if sc.HasWindowsHostProcessRequest(pod, c) {
|
||||||
|
hasHostProcess = true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
return hasHostProcess
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllContainersAreWindowsHostProcess returns true if all containres in a pod are HostProcess containers.
|
||||||
|
func AllContainersAreWindowsHostProcess(pod *v1.Pod) bool {
|
||||||
|
allHostProcess := true
|
||||||
|
podutil.VisitContainers(&pod.Spec, podutil.AllFeatureEnabledContainers(), func(c *v1.Container, containerType podutil.ContainerType) bool {
|
||||||
|
if !sc.HasWindowsHostProcessRequest(pod, c) {
|
||||||
|
allHostProcess = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
return allHostProcess
|
||||||
|
}
|
||||||
|
|
||||||
// MakePortMappings creates internal port mapping from api port mapping.
|
// MakePortMappings creates internal port mapping from api port mapping.
|
||||||
func MakePortMappings(container *v1.Container) (ports []PortMapping) {
|
func MakePortMappings(container *v1.Container) (ports []PortMapping) {
|
||||||
names := make(map[string]struct{})
|
names := make(map[string]struct{})
|
||||||
|
@ -19,14 +19,16 @@ limitations under the License.
|
|||||||
package kuberuntime
|
package kuberuntime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
"k8s.io/kubernetes/pkg/securitycontext"
|
"k8s.io/kubernetes/pkg/securitycontext"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// applyPlatformSpecificContainerConfig applies platform specific configurations to runtimeapi.ContainerConfig.
|
// applyPlatformSpecificContainerConfig applies platform specific configurations to runtimeapi.ContainerConfig.
|
||||||
@ -122,5 +124,12 @@ func (m *kubeGenericRuntimeManager) generateWindowsContainerConfig(container *v1
|
|||||||
wc.SecurityContext.RunAsUsername = *effectiveSc.WindowsOptions.RunAsUserName
|
wc.SecurityContext.RunAsUsername = *effectiveSc.WindowsOptions.RunAsUserName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if securitycontext.HasWindowsHostProcessRequest(pod, container) {
|
||||||
|
if !utilfeature.DefaultFeatureGate.Enabled(features.WindowsHostProcessContainers) {
|
||||||
|
return nil, fmt.Errorf("pod contains HostProcess containers but feature 'WindowsHostProcessContainers' is not enabled")
|
||||||
|
}
|
||||||
|
wc.SecurityContext.HostProcess = true
|
||||||
|
}
|
||||||
|
|
||||||
return wc, nil
|
return wc, nil
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,10 @@ import (
|
|||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
kubetypes "k8s.io/apimachinery/pkg/types"
|
kubetypes "k8s.io/apimachinery/pkg/types"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/types"
|
"k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/util"
|
"k8s.io/kubernetes/pkg/kubelet/util"
|
||||||
@ -138,6 +140,14 @@ func (m *kubeGenericRuntimeManager) generatePodSandboxConfig(pod *v1.Pod, attemp
|
|||||||
}
|
}
|
||||||
podSandboxConfig.Linux = lc
|
podSandboxConfig.Linux = lc
|
||||||
|
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
wc, err := m.generatePodSandboxWindowsConfig(pod)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
podSandboxConfig.Windows = wc
|
||||||
|
}
|
||||||
|
|
||||||
return podSandboxConfig, nil
|
return podSandboxConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,6 +216,54 @@ func (m *kubeGenericRuntimeManager) generatePodSandboxLinuxConfig(pod *v1.Pod) (
|
|||||||
return lc, nil
|
return lc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generatePodSandboxWindowsConfig generates WindowsPodSandboxConfig from v1.Pod.
|
||||||
|
// On Windows this will get called in addition to LinuxPodSandboxConfig because not all relevant fields have been added to
|
||||||
|
// WindowsPodSandboxConfig at this time.
|
||||||
|
func (m *kubeGenericRuntimeManager) generatePodSandboxWindowsConfig(pod *v1.Pod) (*runtimeapi.WindowsPodSandboxConfig, error) {
|
||||||
|
wc := &runtimeapi.WindowsPodSandboxConfig{
|
||||||
|
SecurityContext: &runtimeapi.WindowsSandboxSecurityContext{},
|
||||||
|
}
|
||||||
|
|
||||||
|
sc := pod.Spec.SecurityContext
|
||||||
|
if sc == nil || sc.WindowsOptions == nil {
|
||||||
|
return wc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
wo := sc.WindowsOptions
|
||||||
|
if wo.GMSACredentialSpec != nil {
|
||||||
|
wc.SecurityContext.CredentialSpec = *wo.GMSACredentialSpec
|
||||||
|
}
|
||||||
|
|
||||||
|
if wo.RunAsUserName != nil {
|
||||||
|
wc.SecurityContext.RunAsUsername = *wo.RunAsUserName
|
||||||
|
}
|
||||||
|
|
||||||
|
if kubecontainer.HasWindowsHostProcessContainer(pod) {
|
||||||
|
// Pods containing HostProcess containers should fail to schedule if feature is not
|
||||||
|
// enabled instead of trying to schedule containers as regular containers as stated in
|
||||||
|
// PRR review.
|
||||||
|
if !utilfeature.DefaultFeatureGate.Enabled(features.WindowsHostProcessContainers) {
|
||||||
|
return nil, fmt.Errorf("pod contains HostProcess containers but feature 'WindowsHostProcessContainers' is not enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
if wo.HostProcess != nil && !*wo.HostProcess {
|
||||||
|
return nil, fmt.Errorf("pod must not contain any HostProcess containers if Pod's WindowsOptions.HostProcess is set to false")
|
||||||
|
}
|
||||||
|
// At present Windows all containers in a Windows pod must be HostProcess containers
|
||||||
|
// and HostNetwork is required to be set.
|
||||||
|
if !kubecontainer.AllContainersAreWindowsHostProcess(pod) {
|
||||||
|
return nil, fmt.Errorf("pod must not contain both HostProcess and non-HostProcess containers")
|
||||||
|
}
|
||||||
|
if !kubecontainer.IsHostNetworkPod(pod) {
|
||||||
|
return nil, fmt.Errorf("hostNetwork is required if Pod contains HostProcess containers")
|
||||||
|
}
|
||||||
|
|
||||||
|
wc.SecurityContext.HostProcess = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return wc, nil
|
||||||
|
}
|
||||||
|
|
||||||
// getKubeletSandboxes lists all (or just the running) sandboxes managed by kubelet.
|
// getKubeletSandboxes lists all (or just the running) sandboxes managed by kubelet.
|
||||||
func (m *kubeGenericRuntimeManager) getKubeletSandboxes(all bool) ([]*runtimeapi.PodSandbox, error) {
|
func (m *kubeGenericRuntimeManager) getKubeletSandboxes(all bool) ([]*runtimeapi.PodSandbox, error) {
|
||||||
var filter *runtimeapi.PodSandboxFilter
|
var filter *runtimeapi.PodSandboxFilter
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package kuberuntime
|
package kuberuntime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
@ -25,7 +26,10 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
|
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/runtimeclass"
|
"k8s.io/kubernetes/pkg/kubelet/runtimeclass"
|
||||||
rctest "k8s.io/kubernetes/pkg/kubelet/runtimeclass/testing"
|
rctest "k8s.io/kubernetes/pkg/kubelet/runtimeclass/testing"
|
||||||
@ -172,3 +176,187 @@ func newSeccompPod(podFieldProfile, containerFieldProfile *v1.SeccompProfile, po
|
|||||||
}
|
}
|
||||||
return pod
|
return pod
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGeneratePodSandboxWindowsConfig(t *testing.T) {
|
||||||
|
_, _, m, err := createTestRuntimeManager()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
const containerName = "container"
|
||||||
|
gmsaCreds := "gmsa-creds"
|
||||||
|
userName := "SYSTEM"
|
||||||
|
trueVar := true
|
||||||
|
falseVar := false
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
hostProcessFeatureEnabled bool
|
||||||
|
podSpec *v1.PodSpec
|
||||||
|
expectedWindowsConfig *runtimeapi.WindowsPodSandboxConfig
|
||||||
|
expectedError error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Empty PodSecurityContext",
|
||||||
|
hostProcessFeatureEnabled: false,
|
||||||
|
podSpec: &v1.PodSpec{
|
||||||
|
Containers: []v1.Container{{
|
||||||
|
Name: containerName,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
expectedWindowsConfig: &runtimeapi.WindowsPodSandboxConfig{
|
||||||
|
SecurityContext: &runtimeapi.WindowsSandboxSecurityContext{},
|
||||||
|
},
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GMSACredentialSpec in PodSecurityContext",
|
||||||
|
hostProcessFeatureEnabled: false,
|
||||||
|
podSpec: &v1.PodSpec{
|
||||||
|
SecurityContext: &v1.PodSecurityContext{
|
||||||
|
WindowsOptions: &v1.WindowsSecurityContextOptions{
|
||||||
|
GMSACredentialSpec: &gmsaCreds,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Containers: []v1.Container{{
|
||||||
|
Name: containerName,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
expectedWindowsConfig: &runtimeapi.WindowsPodSandboxConfig{
|
||||||
|
SecurityContext: &runtimeapi.WindowsSandboxSecurityContext{
|
||||||
|
CredentialSpec: "gmsa-creds",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "RunAsUserName in PodSecurityContext",
|
||||||
|
hostProcessFeatureEnabled: false,
|
||||||
|
podSpec: &v1.PodSpec{
|
||||||
|
SecurityContext: &v1.PodSecurityContext{
|
||||||
|
WindowsOptions: &v1.WindowsSecurityContextOptions{
|
||||||
|
RunAsUserName: &userName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Containers: []v1.Container{{
|
||||||
|
Name: containerName,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
expectedWindowsConfig: &runtimeapi.WindowsPodSandboxConfig{
|
||||||
|
SecurityContext: &runtimeapi.WindowsSandboxSecurityContext{
|
||||||
|
RunAsUsername: "SYSTEM",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Pod with HostProcess containers and feature gate disabled",
|
||||||
|
hostProcessFeatureEnabled: false,
|
||||||
|
podSpec: &v1.PodSpec{
|
||||||
|
SecurityContext: &v1.PodSecurityContext{
|
||||||
|
WindowsOptions: &v1.WindowsSecurityContextOptions{
|
||||||
|
HostProcess: &trueVar,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Containers: []v1.Container{{
|
||||||
|
Name: containerName,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
expectedWindowsConfig: nil,
|
||||||
|
expectedError: fmt.Errorf("pod contains HostProcess containers but feature 'WindowsHostProcessContainers' is not enabled"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Pod with HostProcess containers and non-HostProcess containers",
|
||||||
|
hostProcessFeatureEnabled: true,
|
||||||
|
podSpec: &v1.PodSpec{
|
||||||
|
SecurityContext: &v1.PodSecurityContext{
|
||||||
|
WindowsOptions: &v1.WindowsSecurityContextOptions{
|
||||||
|
HostProcess: &trueVar,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Containers: []v1.Container{{
|
||||||
|
Name: containerName,
|
||||||
|
}, {
|
||||||
|
Name: containerName,
|
||||||
|
SecurityContext: &v1.SecurityContext{
|
||||||
|
WindowsOptions: &v1.WindowsSecurityContextOptions{
|
||||||
|
HostProcess: &falseVar,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
expectedWindowsConfig: nil,
|
||||||
|
expectedError: fmt.Errorf("pod must not contain both HostProcess and non-HostProcess containers"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Pod with HostProcess containers and HostNetwork not set",
|
||||||
|
hostProcessFeatureEnabled: true,
|
||||||
|
podSpec: &v1.PodSpec{
|
||||||
|
SecurityContext: &v1.PodSecurityContext{
|
||||||
|
WindowsOptions: &v1.WindowsSecurityContextOptions{
|
||||||
|
HostProcess: &trueVar,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Containers: []v1.Container{{
|
||||||
|
Name: containerName,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
expectedWindowsConfig: nil,
|
||||||
|
expectedError: fmt.Errorf("hostNetwork is required if Pod contains HostProcess containers"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Pod with HostProcess containers and HostNetwork set",
|
||||||
|
hostProcessFeatureEnabled: true,
|
||||||
|
podSpec: &v1.PodSpec{
|
||||||
|
HostNetwork: true,
|
||||||
|
SecurityContext: &v1.PodSecurityContext{
|
||||||
|
WindowsOptions: &v1.WindowsSecurityContextOptions{
|
||||||
|
HostProcess: &trueVar,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Containers: []v1.Container{{
|
||||||
|
Name: containerName,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
expectedWindowsConfig: &runtimeapi.WindowsPodSandboxConfig{
|
||||||
|
SecurityContext: &runtimeapi.WindowsSandboxSecurityContext{
|
||||||
|
HostProcess: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Pod's WindowsOptions.HostProcess set to false and pod has HostProcess containers",
|
||||||
|
hostProcessFeatureEnabled: true,
|
||||||
|
podSpec: &v1.PodSpec{
|
||||||
|
HostNetwork: true,
|
||||||
|
SecurityContext: &v1.PodSecurityContext{
|
||||||
|
WindowsOptions: &v1.WindowsSecurityContextOptions{
|
||||||
|
HostProcess: &falseVar,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Containers: []v1.Container{{
|
||||||
|
Name: containerName,
|
||||||
|
SecurityContext: &v1.SecurityContext{
|
||||||
|
WindowsOptions: &v1.WindowsSecurityContextOptions{
|
||||||
|
HostProcess: &trueVar,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
expectedWindowsConfig: nil,
|
||||||
|
expectedError: fmt.Errorf("pod must not contain any HostProcess containers if Pod's WindowsOptions.HostProcess is set to false"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.WindowsHostProcessContainers, testCase.hostProcessFeatureEnabled)()
|
||||||
|
pod := &v1.Pod{}
|
||||||
|
pod.Spec = *testCase.podSpec
|
||||||
|
|
||||||
|
wc, err := m.generatePodSandboxWindowsConfig(pod)
|
||||||
|
|
||||||
|
assert.Equal(t, wc, testCase.expectedWindowsConfig)
|
||||||
|
assert.Equal(t, err, testCase.expectedError)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,13 +18,17 @@ package kuberuntime
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
kubetypes "k8s.io/apimachinery/pkg/types"
|
kubetypes "k8s.io/apimachinery/pkg/types"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/types"
|
"k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
|
sc "k8s.io/kubernetes/pkg/securitycontext"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -38,6 +42,12 @@ const (
|
|||||||
containerTerminationMessagePolicyLabel = "io.kubernetes.container.terminationMessagePolicy"
|
containerTerminationMessagePolicyLabel = "io.kubernetes.container.terminationMessagePolicy"
|
||||||
containerPreStopHandlerLabel = "io.kubernetes.container.preStopHandler"
|
containerPreStopHandlerLabel = "io.kubernetes.container.preStopHandler"
|
||||||
containerPortsLabel = "io.kubernetes.container.ports"
|
containerPortsLabel = "io.kubernetes.container.ports"
|
||||||
|
|
||||||
|
// TODO: remove this annotation when moving to beta for Windows hostprocess containers
|
||||||
|
// xref: https://github.com/kubernetes/kubernetes/pull/99576/commits/42fb66073214eed6fe43fa8b1586f396e30e73e3#r635392090
|
||||||
|
// Currently, ContainerD on Windows does not yet fully support HostProcess containers
|
||||||
|
// but will pass annotations to hcsshim which does have support.
|
||||||
|
windowsHostProcessContainer = "microsoft.com/hostprocess-container"
|
||||||
)
|
)
|
||||||
|
|
||||||
type labeledPodSandboxInfo struct {
|
type labeledPodSandboxInfo struct {
|
||||||
@ -89,7 +99,23 @@ func newPodLabels(pod *v1.Pod) map[string]string {
|
|||||||
|
|
||||||
// newPodAnnotations creates pod annotations from v1.Pod.
|
// newPodAnnotations creates pod annotations from v1.Pod.
|
||||||
func newPodAnnotations(pod *v1.Pod) map[string]string {
|
func newPodAnnotations(pod *v1.Pod) map[string]string {
|
||||||
return pod.Annotations
|
annotations := map[string]string{}
|
||||||
|
|
||||||
|
// Get annotations from v1.Pod
|
||||||
|
for k, v := range pod.Annotations {
|
||||||
|
annotations[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS == "windows" && utilfeature.DefaultFeatureGate.Enabled(features.WindowsHostProcessContainers) {
|
||||||
|
if kubecontainer.HasWindowsHostProcessContainer(pod) {
|
||||||
|
// While WindowsHostProcessContainers is in alpha pass 'microsoft.com/hostprocess-container' annotation
|
||||||
|
// to pod sandbox creations request. ContainerD on Windows does not yet fully support HostProcess
|
||||||
|
// containers but will pass annotations to hcsshim which does have support.
|
||||||
|
annotations[windowsHostProcessContainer] = "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return annotations
|
||||||
}
|
}
|
||||||
|
|
||||||
// newContainerLabels creates container labels from v1.Container and v1.Pod.
|
// newContainerLabels creates container labels from v1.Container and v1.Pod.
|
||||||
@ -143,6 +169,15 @@ func newContainerAnnotations(container *v1.Container, pod *v1.Pod, restartCount
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS == "windows" && utilfeature.DefaultFeatureGate.Enabled(features.WindowsHostProcessContainers) {
|
||||||
|
if sc.HasWindowsHostProcessRequest(pod, container) {
|
||||||
|
// While WindowsHostProcessContainers is in alpha pass 'microsoft.com/hostprocess-container' annotation
|
||||||
|
// to create containers request. ContainerD on Windows does not yet fully support HostProcess containers
|
||||||
|
// but will pass annotations to hcsshim which does have support.
|
||||||
|
annotations[windowsHostProcessContainer] = "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return annotations
|
return annotations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,20 @@ func HasCapabilitiesRequest(container *v1.Container) bool {
|
|||||||
return len(container.SecurityContext.Capabilities.Add) > 0 || len(container.SecurityContext.Capabilities.Drop) > 0
|
return len(container.SecurityContext.Capabilities.Add) > 0 || len(container.SecurityContext.Capabilities.Drop) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasWindowsHostProcessRequest returns true if container should run as HostProcess container,
|
||||||
|
// taking into account nils
|
||||||
|
func HasWindowsHostProcessRequest(pod *v1.Pod, container *v1.Container) bool {
|
||||||
|
effectiveSc := DetermineEffectiveSecurityContext(pod, container)
|
||||||
|
|
||||||
|
if effectiveSc.WindowsOptions == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if effectiveSc.WindowsOptions.HostProcess == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return *effectiveSc.WindowsOptions.HostProcess
|
||||||
|
}
|
||||||
|
|
||||||
// DetermineEffectiveSecurityContext returns a synthesized SecurityContext for reading effective configurations
|
// DetermineEffectiveSecurityContext returns a synthesized SecurityContext for reading effective configurations
|
||||||
// from the provided pod's and container's security context. Container's fields take precedence in cases where both
|
// from the provided pod's and container's security context. Container's fields take precedence in cases where both
|
||||||
// are set
|
// are set
|
||||||
@ -79,6 +93,9 @@ func DetermineEffectiveSecurityContext(pod *v1.Pod, container *v1.Container) *v1
|
|||||||
if containerSc.WindowsOptions.RunAsUserName != nil {
|
if containerSc.WindowsOptions.RunAsUserName != nil {
|
||||||
effectiveSc.WindowsOptions.RunAsUserName = containerSc.WindowsOptions.RunAsUserName
|
effectiveSc.WindowsOptions.RunAsUserName = containerSc.WindowsOptions.RunAsUserName
|
||||||
}
|
}
|
||||||
|
if containerSc.WindowsOptions.HostProcess != nil {
|
||||||
|
effectiveSc.WindowsOptions.HostProcess = containerSc.WindowsOptions.HostProcess
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if containerSc.Capabilities != nil {
|
if containerSc.Capabilities != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user