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

rootlessport: reduce memory usage of the process #11565

Merged
merged 1 commit into from
Oct 13, 2021

Conversation

Luap99
Copy link
Member

@Luap99 Luap99 commented Sep 14, 2021

Don't use reexec for the rootlessport process, instead make it a
separate binary to reduce the memory usage. The problem with reexec is
that it will import all packages that podman uses and therefore loads a
lot of stuff into the heap. The rootlessport process however only needs
the rootlesskit library.
The memory usage is a concern since the rootlessport process will spawn
two process per container which has ports forwarded. The processes stay
until the container dies. On my laptop the current reexec version uses
47800 KB RSS. The new separate binary only uses 4540 KB RSS. This is
more than a 90% improvement.

The Makefile has been updated to compile the new binary and install it
to the libexec directory.

Fixes #10790

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 14, 2021
Makefile Outdated Show resolved Hide resolved
@openshift-ci openshift-ci bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 19, 2021
@openshift-ci openshift-ci bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 21, 2021
@Luap99 Luap99 force-pushed the rootlessport-bin branch 3 times, most recently from 2a55a97 to ce3e659 Compare October 6, 2021 19:51
@rhatdan
Copy link
Member

rhatdan commented Oct 6, 2021

Should we do the same for the pause process?

@Luap99 Luap99 force-pushed the rootlessport-bin branch 2 times, most recently from c51864f to bc4e311 Compare October 11, 2021 15:53
@Luap99
Copy link
Member Author

Luap99 commented Oct 11, 2021

Should we do the same for the pause process?

If you want do it for the pause process then it should be a small c program to safe the unnecessary overhead from go.

@@ -236,7 +236,7 @@ case "$TEST_FLAVOR" in
# Use existing host bits when testing is to happen inside a container
# since this script will run again in that environment.
# shellcheck disable=SC2154
if ((CONTAINER==0)) && [[ "$TEST_ENVIRON" == "host" ]]; then
if ((CONTAINER==0)); then
Copy link
Member Author

Choose a reason for hiding this comment

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

@cevich @edsantiago PTAL. This was required to build the new binary on the host and then I mount it in the container for the tests. I think this change is correct, otherwise this was never called for container tests since TEST_ENVIRON was set to container

Copy link
Member

Choose a reason for hiding this comment

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

Deferring to @cevich. I don't grok this code, and even tig blame doesn't help me understand the reasoning behind it. I can't even understand the comment. Sorry.

Copy link
Member

Choose a reason for hiding this comment

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

Right, this is because setup_environment.sh is called by runner.sh (a second time) when testing is to happen inside a container:

https://github.com/containers/podman/pull/11565/files#diff-db575befc56ec85f83b824430b9b62e20eb19d08b351dc743db26848639896a6R126

So the volume mount for /var/libexec/podman doesn't seem right either, normally the podman binary for testing would be compiled + installed inside the container environment (again, by way of calling setup_environment.sh again).

Note: I haven't seen the rest of this PR, so I'm not sure what it's all about. I'll take a look 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.

TEST_ENVIRON is always set to container for all container test, regardless if we are outside or inside the container, thus it was never compiled in the 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.

Also the container==0 condition means that this happens outside the container. If you want to compile only inside it should be container==1 AFAICT

Copy link
Member

Choose a reason for hiding this comment

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

Ya, there's a test setup bug here, it's entirely my fault 😢

@@ -119,6 +119,7 @@ exec_container() {
exec podman run --rm --privileged --net=host --cgroupns=host \
-v /dev/fuse:/dev/fuse \
-v "$GOPATH:$GOPATH:Z" \
-v /usr/libexec/podman:/usr/libexec/podman \
Copy link
Member

Choose a reason for hiding this comment

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

This isn't right. For the TEST_ENVIRON=container case, we basically treat the container like a VM. Very little should leak into the container from the host.

@cevich
Copy link
Member

cevich commented Oct 12, 2021

Okay I think I follow what you're after, and there's a test-setup bug here. I believe the comment is correct, and the conditional is wrong. Which is why the comment is confusing 😕 Damn. This may expose a bunch of bugs...I believe the intended logic should be:

CONTAINER TEST_ENVIRON behavior
0 host replace podman RPM + build/install from source
0 container do nothing
1 host Impossible, throw an error and panic.
1 container replace podman RPM + build/install from source

So we want something like:

        if [[ "$TEST_ENVIRON" == "host" ]]; then
            if ((CONTAINER)); then
                die ("Refusing to config. host-test in container");
            fi
            remove_packaged_podman_files
            make install PREFIX=/usr ETCDIR=/etc
        elif [[ "$TEST_ENVIRON" == "container" ]]; then
            if ((CONTAINER)); then
                remove_packaged_podman_files
                make install PREFIX=/usr ETCDIR=/etc
            fi
        else
            die("Invalid value for $$TEST_ENVIRON=$TEST_ENVIRON")
        fi

I dunno if maybe there's a simpler/cleaner way to structure that or not. Just what I can think of off-hand.

@Luap99
Copy link
Member Author

Luap99 commented Oct 12, 2021

@cevich That looks good to me. I will add this and remove the volume mount.

Don't use reexec for the rootlessport process, instead make it a
separate binary to reduce the memory usage. The problem with reexec is
that it will import all packages that podman uses and therefore loads a
lot of stuff into the heap. The rootlessport process however only needs
the rootlesskit library.
The memory usage is a concern since the rootlessport process will spawn
two process per container which has ports forwarded. The processes stay
until the container dies. On my laptop the current reexec version uses
47800 KB RSS. The new separate binary only uses 4540 KB RSS. This is
more than a 90% improvement.

The Makefile has been updated to compile the new binary and install it
to the libexec directory.

Fixes containers#10790

[NO TESTS NEEDED]

Signed-off-by: Paul Holzinger <[email protected]>
@Luap99
Copy link
Member Author

Luap99 commented Oct 12, 2021

@containers/podman-maintainers PTAL. This is a good improvement.
Please note that this requires packaging changes. @lsm5 FYI

Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

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

LGTM

Nice work, @Luap99 !

@giuseppe
Copy link
Member

Should we do the same for the pause process?

the pause process doesn't load the go runtime, but still it keeps the podman executable in memory. So a custom binary would be better, and we could also re-use it for the pod init process to not require an image

Copy link
Member

@giuseppe giuseppe left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Oct 13, 2021
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 13, 2021

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: giuseppe, Luap99

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

@openshift-merge-robot openshift-merge-robot merged commit f12dc28 into containers:main Oct 13, 2021
@vrothberg
Copy link
Member

Should we do the same for the pause process?

the pause process doesn't load the go runtime, but still it keeps the podman executable in memory. So a custom binary would be better, and we could also re-use it for the pod init process to not require an image

I started working on that yesterday :^)

@Luap99 Luap99 deleted the rootlessport-bin branch October 13, 2021 08:44
@vrothberg
Copy link
Member

FYI, @siretart for Debian / Ubuntu packaging

@github-actions github-actions bot added the locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. label Sep 22, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

containers-rootlessport memory hungry
9 participants