tests: Enables a few Conformance tests for Windows

Some of these tests could not be run previously, especially on Windows
Docker containers. But now, by using Windows Containerd, we can finally
run them:

- HostNetwork=true tests: This can now be enabled on Windows Privileged Containers.
- /etc/hosts related tests: These were not supported because it required single
  file mappings, which is possible in Containerd.
- termination message as non-root user: Requires RunAsUsername, and single file
  mappings.
This commit is contained in:
Claudiu Belu 2021-11-17 02:25:35 -08:00
parent c964ef8d8a
commit 87123c49a0
7 changed files with 55 additions and 33 deletions

View File

@ -1191,8 +1191,7 @@
release: v1.20
file: test/e2e/instrumentation/core_events.go
- testname: DNS, cluster
codename: '[sig-network] DNS should provide /etc/hosts entries for the cluster [LinuxOnly]
[Conformance]'
codename: '[sig-network] DNS should provide /etc/hosts entries for the cluster [Conformance]'
description: When a Pod is created, the pod MUST be able to resolve cluster dns
entries such as kubernetes.default via /etc/hosts.
release: v1.14
@ -1206,8 +1205,7 @@
release: v1.15
file: test/e2e/network/dns.go
- testname: DNS, resolve the hostname
codename: '[sig-network] DNS should provide DNS for pods for Hostname [LinuxOnly]
[Conformance]'
codename: '[sig-network] DNS should provide DNS for pods for Hostname [Conformance]'
description: Create a headless service with label. Create a Pod with label to match
service's label, with hostname and a subdomain same as service name. Pod MUST
be able to resolve its fully qualified domain name as well as hostname by serving
@ -1358,7 +1356,7 @@
file: test/e2e/common/network/networking.go
- testname: Networking, intra pod http, from node
codename: '[sig-network] Networking Granular Checks: Pods should function for node-pod
communication: http [LinuxOnly] [NodeConformance] [Conformance]'
communication: http [NodeConformance] [Conformance]'
description: Create a hostexec pod that is capable of curl to netcat commands. Create
a test Pod that will act as a webserver front end exposing ports 8080 for tcp
and 8081 for udp. The netserver service proxies are created on specified number
@ -1366,13 +1364,12 @@
the each of service proxy endpoints in the cluster using a http post(protocol=tcp) and
the request MUST be successful. Container will execute curl command to reach the
service port within specified max retry limit and MUST result in reporting unique
hostnames. This test is marked LinuxOnly since HostNetwork is not supported on
other platforms like Windows.
hostnames.
release: v1.9
file: test/e2e/common/network/networking.go
- testname: Networking, intra pod http, from node
codename: '[sig-network] Networking Granular Checks: Pods should function for node-pod
communication: udp [LinuxOnly] [NodeConformance] [Conformance]'
communication: udp [NodeConformance] [Conformance]'
description: Create a hostexec pod that is capable of curl to netcat commands. Create
a test Pod that will act as a webserver front end exposing ports 8080 for tcp
and 8081 for udp. The netserver service proxies are created on specified number
@ -1380,8 +1377,7 @@
the each of service proxy endpoints in the cluster using a http post(protocol=udp) and
the request MUST be successful. Container will execute curl command to reach the
service port within specified max retry limit and MUST result in reporting unique
hostnames. This test is marked LinuxOnly since HostNetwork is not supported on
other platforms like Windows.
hostnames.
release: v1.9
file: test/e2e/common/network/networking.go
- testname: Proxy, validate Proxy responses
@ -1690,18 +1686,6 @@
server pod to validate that the pre-stop is executed.
release: v1.9
file: test/e2e/common/node/lifecycle_hook.go
- testname: Container Runtime, TerminationMessagePath, non-root user and non-default
path
codename: '[sig-node] Container Runtime blackbox test on terminated container should
report termination message [LinuxOnly] if TerminationMessagePath is set as non-root
user and at a non-default path [NodeConformance] [Conformance]'
description: 'Create a pod with a container to run it as a non-root user with a
custom TerminationMessagePath set. Pod redirects the output to the provided path
successfully. When the container is terminated, the termination message MUST match
the expected output logged in the provided custom path. [LinuxOnly]: Tagged LinuxOnly
due to use of ''uid'' and unable to mount files in Windows Containers.'
release: v1.15
file: test/e2e/common/node/runtime.go
- testname: Container Runtime, TerminationMessage, from log output of succeeding container
codename: '[sig-node] Container Runtime blackbox test on terminated container should
report termination message as empty when pod succeeds and TerminationMessagePolicy
@ -1730,6 +1714,17 @@
MUST match the expected output recorded from container's log.
release: v1.15
file: test/e2e/common/node/runtime.go
- testname: Container Runtime, TerminationMessagePath, non-root user and non-default
path
codename: '[sig-node] Container Runtime blackbox test on terminated container should
report termination message if TerminationMessagePath is set as non-root user and
at a non-default path [NodeConformance] [Conformance]'
description: Create a pod with a container to run it as a non-root user with a custom
TerminationMessagePath set. Pod redirects the output to the provided path successfully.
When the container is terminated, the termination message MUST match the expected
output logged in the provided custom path.
release: v1.15
file: test/e2e/common/node/runtime.go
- testname: Container Runtime, Restart Policy, Pod Phases
codename: '[sig-node] Container Runtime blackbox test when starting a container
that exits should run with the expected status [NodeConformance] [Conformance]'

View File

@ -98,9 +98,8 @@ var _ = SIGDescribe("Networking", func() {
Testname: Networking, intra pod http, from node
Description: Create a hostexec pod that is capable of curl to netcat commands. Create a test Pod that will act as a webserver front end exposing ports 8080 for tcp and 8081 for udp. The netserver service proxies are created on specified number of nodes.
The kubectl exec on the webserver container MUST reach a http port on the each of service proxy endpoints in the cluster using a http post(protocol=tcp) and the request MUST be successful. Container will execute curl command to reach the service port within specified max retry limit and MUST result in reporting unique hostnames.
This test is marked LinuxOnly since HostNetwork is not supported on other platforms like Windows.
*/
framework.ConformanceIt("should function for node-pod communication: http [LinuxOnly] [NodeConformance]", func() {
framework.ConformanceIt("should function for node-pod communication: http [NodeConformance]", func() {
config := e2enetwork.NewCoreNetworkingTestConfig(f, true)
for _, endpointPod := range config.EndpointPods {
err := config.DialFromNode("http", endpointPod.Status.PodIP, e2enetwork.EndpointHTTPPort, config.MaxTries, 0, sets.NewString(endpointPod.Name))
@ -115,9 +114,8 @@ var _ = SIGDescribe("Networking", func() {
Testname: Networking, intra pod http, from node
Description: Create a hostexec pod that is capable of curl to netcat commands. Create a test Pod that will act as a webserver front end exposing ports 8080 for tcp and 8081 for udp. The netserver service proxies are created on specified number of nodes.
The kubectl exec on the webserver container MUST reach a http port on the each of service proxy endpoints in the cluster using a http post(protocol=udp) and the request MUST be successful. Container will execute curl command to reach the service port within specified max retry limit and MUST result in reporting unique hostnames.
This test is marked LinuxOnly since HostNetwork is not supported on other platforms like Windows.
*/
framework.ConformanceIt("should function for node-pod communication: udp [LinuxOnly] [NodeConformance]", func() {
framework.ConformanceIt("should function for node-pod communication: udp [NodeConformance]", func() {
config := e2enetwork.NewCoreNetworkingTestConfig(f, true)
for _, endpointPod := range config.EndpointPods {
err := config.DialFromNode("udp", endpointPod.Status.PodIP, e2enetwork.EndpointUDPPort, config.MaxTries, 0, sets.NewString(endpointPod.Name))

View File

@ -188,11 +188,8 @@ while true; do sleep 1; done
Release: v1.15
Testname: Container Runtime, TerminationMessagePath, non-root user and non-default path
Description: Create a pod with a container to run it as a non-root user with a custom TerminationMessagePath set. Pod redirects the output to the provided path successfully. When the container is terminated, the termination message MUST match the expected output logged in the provided custom path.
[LinuxOnly]: Tagged LinuxOnly due to use of 'uid' and unable to mount files in Windows Containers.
*/
framework.ConformanceIt("should report termination message [LinuxOnly] if TerminationMessagePath is set as non-root user and at a non-default path [NodeConformance]", func() {
// TODO(claudiub): Remove [LinuxOnly] tag once Containerd becomes the default
// container runtime on Windows
framework.ConformanceIt("should report termination message if TerminationMessagePath is set as non-root user and at a non-default path [NodeConformance]", func() {
container := v1.Container{
Image: framework.BusyBoxImage,
Command: []string{"/bin/sh", "-c"},

View File

@ -848,6 +848,11 @@ func (config *NetworkingTestConfig) createNetProxyPods(podName string, selector
pod := config.createNetShellPodSpec(podName, hostname)
pod.ObjectMeta.Labels = selector
pod.Spec.HostNetwork = config.EndpointsHostNetwork
// NOTE(claudiub): In order to use HostNetwork on Windows, we need to use Privileged Containers.
if pod.Spec.HostNetwork && framework.NodeOSDistroIs("windows") {
e2epod.WithWindowsHostProcess(pod, "")
}
createdPod := config.createPod(pod)
createdPods = append(createdPods, createdPod)
}

View File

@ -576,6 +576,28 @@ func CreateExecPodOrFail(client clientset.Interface, ns, generateName string, tw
return execPod
}
// WithWindowsHostProcess sets the Pod's Windows HostProcess option to true. When this option is set,
// HostNetwork can be enabled.
// Containers running as HostProcess will require certain usernames to be set, otherwise the Pod will
// not start: NT AUTHORITY\SYSTEM, NT AUTHORITY\Local service, NT AUTHORITY\NetworkService.
// If the given username is empty, NT AUTHORITY\SYSTEM will be used instead.
// See: https://kubernetes.io/docs/tasks/configure-pod-container/create-hostprocess-pod/
func WithWindowsHostProcess(pod *v1.Pod, username string) {
if pod.Spec.SecurityContext == nil {
pod.Spec.SecurityContext = &v1.PodSecurityContext{}
}
if pod.Spec.SecurityContext.WindowsOptions == nil {
pod.Spec.SecurityContext.WindowsOptions = &v1.WindowsSecurityContextOptions{}
}
trueVar := true
if username == "" {
username = "NT AUTHORITY\\SYSTEM"
}
pod.Spec.SecurityContext.WindowsOptions.HostProcess = &trueVar
pod.Spec.SecurityContext.WindowsOptions.RunAsUserName = &username
}
// CheckPodsRunningReady returns whether all pods whose names are listed in
// podNames in namespace ns are running and ready, using c and waiting at most
// timeout.

View File

@ -112,7 +112,7 @@ var _ = common.SIGDescribe("DNS", func() {
Testname: DNS, cluster
Description: When a Pod is created, the pod MUST be able to resolve cluster dns entries such as kubernetes.default via /etc/hosts.
*/
framework.ConformanceIt("should provide /etc/hosts entries for the cluster [LinuxOnly]", func() {
framework.ConformanceIt("should provide /etc/hosts entries for the cluster", func() {
hostFQDN := fmt.Sprintf("%s.%s.%s.svc.%s", dnsTestPodHostName, dnsTestServiceName, f.Namespace.Name, framework.TestContext.ClusterDNSDomain)
hostEntries := []string{hostFQDN, dnsTestPodHostName}
// TODO: Validate both IPv4 and IPv6 families for dual-stack
@ -243,7 +243,7 @@ var _ = common.SIGDescribe("DNS", func() {
Description: Create a headless service with label. Create a Pod with label to match service's label, with hostname and a subdomain same as service name.
Pod MUST be able to resolve its fully qualified domain name as well as hostname by serving an A record at that name.
*/
framework.ConformanceIt("should provide DNS for pods for Hostname [LinuxOnly]", func() {
framework.ConformanceIt("should provide DNS for pods for Hostname", func() {
// Create a test headless service.
ginkgo.By("Creating a test headless service")
testServiceSelector := map[string]string{

View File

@ -406,10 +406,15 @@ func createProbeCommand(namesToResolve []string, hostEntries []string, ptrLookup
probeCmd += fmt.Sprintf(`check="$$(dig +tcp +noall +answer +search %s)" && test -n "$$check" && echo OK > /results/%s;`, lookup, fileName)
}
hostEntryCmd := `test -n "$$(getent hosts %s)" && echo OK > /results/%s;`
if framework.NodeOSDistroIs("windows") {
// We don't have getent on Windows, but we can still check the hosts file.
hostEntryCmd = `test -n "$$(grep '%s' C:/Windows/System32/drivers/etc/hosts)" && echo OK > /results/%s;`
}
for _, name := range hostEntries {
fileName := fmt.Sprintf("%s_hosts@%s", fileNamePrefix, name)
fileNames = append(fileNames, fileName)
probeCmd += fmt.Sprintf(`test -n "$$(getent hosts %s)" && echo OK > /results/%s;`, name, fileName)
probeCmd += fmt.Sprintf(hostEntryCmd, name, fileName)
}
if len(ptrLookupIP) > 0 {