Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optionally run e2e pod as privileged for SELinux #83727

Merged
merged 1 commit into from Oct 31, 2019

Conversation

bertinatto
Copy link
Member

@bertinatto bertinatto commented Oct 10, 2019

This PR adds back the SecurityContext field missed during the consolidation of redundant code in #79730.

Also, it only runs the pod as privileged if the system has SELinux enabled and the volume isn't block (due to moby/moby#35991).

What type of PR is this?

/kind flake

What this PR does / why we need it:

This is necessary for running some e2e tests on SELinux systems.

Does this PR introduce a user-facing change?:

NONE

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:


/sig storage
CC @jsafrane @msau42

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. kind/flake Categorizes issue or PR as related to a flaky test. sig/storage Categorizes an issue or PR as relevant to SIG Storage. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. area/e2e-test-framework Issues or PRs related to refactoring the kubernetes e2e test framework area/test sig/testing Categorizes an issue or PR as relevant to SIG Testing. labels Oct 10, 2019
@neolit123
Copy link
Member

/approve
/retest

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 10, 2019
@@ -564,7 +565,7 @@ func testVolumeContent(client clientset.Interface, pod *v1.Pod, fsGroup *int64,
// Multiple Tests can be specified to mount multiple volumes to a single
// pod.
func TestVolumeClient(client clientset.Interface, config TestConfig, fsGroup *int64, fsType string, tests []Test) {
clientPod, err := runVolumeTesterPod(client, config, "client", fsGroup, tests)
clientPod, err := runVolumeTesterPod(client, config, "client", fsGroup, false, tests)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come this one is false and the other is true?

Can we also make privileged a configurable parameter? I would like to be able to have most e2es not use privileged pods if the system doesn't support SELinux: #80186

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do that, but because of #83727 (comment), we may have to go privileged if the system supports SELinux and the volume is not block.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also make privileged a configurable parameter?

So I figured this is a bit tricky to solve. These are the possible solutions that I thought about and their problems:

  1. Make pods privileged:
    • We don't want this, specially where they are not required (on non-SELinux systems)
  2. Make pods unprivileged and add label svirt_sandbox_file_t to node dirs where pods manipulate data (currently it's /tmp for hostPath)
    • Need to manually chcon -R -t svirt_sandbox_file_t /dir_where_container_writes_files in the host where test runs
  3. Detect if node, where test is running, has SELinux enabled and make the pod privileged
    • I attempted this one, but it's tricky because we don't always know the node where the pod is going to be scheduled (so we could send `getenforcea command there and
  4. Have an env variable that toggles privileged
    • Not sure if this is a good idea, it needs to be toggled manually
      • It's not node-specific

Are there other alternatives?

@bertinatto
Copy link
Member Author

Two jobs are failing because of a docker issue that prevents a privileged pod from mapping devices:

$ docker versioni

Client:
 Version:           18.09.9
 API version:       1.39
 Go version:        go1.11.13
 Git commit:        039a7df9ba
 Built:             Wed Sep  4 16:51:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.9
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.11.13
  Git commit:       039a7df
  Built:            Wed Sep  4 16:22:32 2019
  OS/Arch:          linux/amd64
  Experimental:     false

$ docker run -w /opt  --rm -it --device=/dev/console:/opt/10 busybox /bin/sh -c 'ls -l /opt/'
total 0
crw-------    1 root     root        5,   1 Oct 11 12:27 10
 
$ docker run -w /opt  --privileged --rm -it --device=/dev/console:/opt/10 busybox /bin/sh -c 'ls -l /opt/'
total 0

@bertinatto bertinatto force-pushed the e2e_hostpath_selinux branch 2 times, most recently from 7137c6b to c41dc58 Compare October 11, 2019 13:16
@k8s-ci-robot k8s-ci-robot removed the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 11, 2019
test/e2e/0 Outdated Show resolved Hide resolved
test/e2e/framework/volume/fixtures.go Outdated Show resolved Hide resolved
@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 11, 2019
// a privileged container, so we don't go privileged for block volumes.
// https://github.com/moby/moby/issues/35991
privileged := false
if selinux.SELinuxEnabled() && test.Mode != v1.PersistentVolumeBlock {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be replaced by something else because it doesn't detect if SELinux is enabled on the host

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bertinatto could you please create an issue for this action item ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll create an issue as soon as I figure this out

@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Oct 14, 2019
Copy link
Contributor

@alejandrox1 alejandrox1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/priority important-soon
/milestone v1.17

@k8s-ci-robot k8s-ci-robot added the priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. label Oct 14, 2019
@k8s-ci-robot k8s-ci-robot added this to the v1.17 milestone Oct 14, 2019
@k8s-ci-robot k8s-ci-robot removed the needs-priority Indicates a PR lacks a `priority/foo` label and requires one. label Oct 14, 2019
@bertinatto
Copy link
Member Author

/retest

@msau42
Copy link
Member

msau42 commented Oct 15, 2019

/assign @jingxu97
to check impact on windows tests

@k8s-ci-robot k8s-ci-robot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Oct 15, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: bertinatto, neolit123

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 15, 2019
// We need to make the container privileged when SELinux is enabled on the
// host, so the test can write data to a location like /tmp. Also, due to
// the Docker bug below, it's not currently possible to map a device with
// a privileged container, so we don't go privileged for block volumes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does mean for block volume, we cannot set SELinux enabled?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, for block volume, we cannot make the container privileged. Specially if the container runtime is docker (due to the bug below).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, it shouldn't be a problem to run the test with a unprivileged container for block volumes.

The reason we make it privileged for FS volumes is that the test writes data to the host's /tmp directory, which is not the case for block volumes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there another directory we can safely write to that does not require privileged?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there another directory we can safely write to that does not require privileged?

Not that I'm aware of.

By default, containers can only RW to files/directories labeled svirt_sandbox_file_t. So if a process breaks out of the container, it won't be able to change the host FS.

We could add the label above to a pre-defined directory, say /tmp/k8s-e2e, and change the test to read/write data there, rather than the default /tmp. See my comment #83727 (comment). I've tried this and it worked.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The downside of the approach above is that we need to change the test bootstrap to do chcon -R -t svirt_sandbox_file_t /tmp/k8s-e2e in the host before running the test.

I don't know if we are able to do that, however, this is IMO the right approach to solve our SELinux issues in e2e tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer we look into this approach of prepping a special test directory first if the environment uses SELinux. That way we can remove the privileged setting on many tests (and maybe be able to add them to the conformance suite). But this is sufficient for now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify: we can remove the privileged setting if we prep a special test directory on SELinux environments. All containers would run as unprivileged.

FYI, I created the issue #84585 to track this.

@@ -577,7 +588,7 @@ func TestVolumeClient(client clientset.Interface, config TestConfig, fsGroup *in
// starting and auxiliary pod which writes the file there.
// The volume must be writable.
func InjectContent(client clientset.Interface, config TestConfig, fsGroup *int64, fsType string, tests []Test) {
injectorPod, err := runVolumeTesterPod(client, config, "injector", fsGroup, tests)
injectorPod, err := runVolumeTesterPod(client, config, "injector", true, fsGroup, tests)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we cannot set this to true for all cases. For example, for windows, we cannot run privileged container.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a check for Windows

Copy link
Member Author

@bertinatto bertinatto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jingxu97, PTAL

// We need to make the container privileged when SELinux is enabled on the
// host, so the test can write data to a location like /tmp. Also, due to
// the Docker bug below, it's not currently possible to map a device with
// a privileged container, so we don't go privileged for block volumes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, for block volume, we cannot make the container privileged. Specially if the container runtime is docker (due to the bug below).

@@ -577,7 +588,7 @@ func TestVolumeClient(client clientset.Interface, config TestConfig, fsGroup *in
// starting and auxiliary pod which writes the file there.
// The volume must be writable.
func InjectContent(client clientset.Interface, config TestConfig, fsGroup *int64, fsType string, tests []Test) {
injectorPod, err := runVolumeTesterPod(client, config, "injector", fsGroup, tests)
injectorPod, err := runVolumeTesterPod(client, config, "injector", true, fsGroup, tests)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a check for Windows

@kikisdeliveryservice
Copy link
Member

kikisdeliveryservice commented Oct 26, 2019

Bug Triage Release Team checking in. Code freeze for the 1.17 release is on November 14. Is this still intended for 1.17? Thanks!

@timothysc
Copy link
Member

/assign @BCLAU @timothysc

@BCLAU - could you verify that this will work for windows use cases?

@claudiubelu
Copy link
Contributor

/assign @BCLAU @timothysc

@BCLAU - could you verify that this will work for windows use cases?

As far as this PR goes, lgtm. The only case where privileged could be true, it has been treated and set to false for windows, which is good. I don't think those tests can run on Windows at the moment, especially because of the SecurityContext here: https://github.com/kubernetes/kubernetes/pull/83727/files#diff-2ff410ea588732f4fe497de3d8dbb7deR482 But It's good that extra work is not being added for the time when we'll have those running on Windows as well.

Copy link
Member

@msau42 msau42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm
/approve

// We need to make the container privileged when SELinux is enabled on the
// host, so the test can write data to a location like /tmp. Also, due to
// the Docker bug below, it's not currently possible to map a device with
// a privileged container, so we don't go privileged for block volumes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer we look into this approach of prepping a special test directory first if the environment uses SELinux. That way we can remove the privileged setting on many tests (and maybe be able to add them to the conformance suite). But this is sufficient for now.

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 31, 2019
@k8s-ci-robot
Copy link
Contributor

k8s-ci-robot commented Oct 31, 2019

@bertinatto: The following test failed, say /retest to rerun them all:

Test name Commit Details Rerun command
pull-kubernetes-e2e-gce-csi-serial 816b325dd84310acfbf0503be14aa102a58b4a9f link /test pull-kubernetes-e2e-gce-csi-serial

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@k8s-ci-robot k8s-ci-robot merged commit 10ded88 into kubernetes:master Oct 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/e2e-test-framework Issues or PRs related to refactoring the kubernetes e2e test framework area/test cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/flake Categorizes issue or PR as related to a flaky test. lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. release-note-none Denotes a PR that doesn't merit a release note. sig/storage Categorizes an issue or PR as relevant to SIG Storage. sig/testing Categorizes an issue or PR as relevant to SIG Testing. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet