You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current implementation sets all the environment variables passed in
Process.Env in the current process, one by one, then uses os.Environ to
read those back.
As pointed out in [1], this is slow, as runc calls os.Setenv for every
variable, and there may be a few thousands of those. Looking into how
os.Setenv is implemented, it is indeed slow, especially when cgo is
enabled.
Looking into why it was implemented, I found commit 9744d72 and traced
it to [2], which discusses the actual reasons. At the time were:
- HOME is not passed into container as it is set in setupUser by
os.Setenv and has no effect on config.Env;
- there is no deduplication of environment variables.
Yet it was decided to not go ahead with this patch, but later [3] was
merged with the carry of this patch.
Now, from what I see:
1. Passing environment to exec is way faster than using os.Setenv and
os.Environ (tests show ~20x faster in simple Go test, and 2x faster
in real-world test, see below).
2. Setting environment variables in the runc context can result is ugly
side effects (think GODEBUG, LD_PRELOAD, or _LIBCONTAINER_*).
3. Nothing in runtime spec says that the environment needs to be
deduplicated, or the order of preference (whether the first or the
last value of a variable with the same name is to be used). We should
stick to what we have in order to maintain backward compatibility.
This patch:
- switches to passing env directly to exec;
- adds deduplication mechanism to retain backward compatibility;
- sets PATH from process.Env in the current process;
- adds HOME to process.Env if not set;
The benchmark added by the previous commit shows 2x improvement:
> name old time/op new time/op delta
> ExecInBigEnv-20 61.7ms ± 4% 24.9ms ±14% -59.73% (p=0.000 n=10+10)
The remaining questions are:
- are there any potential regressions (for example, from not setting
values from process.Env to the current process);
- should deduplication show warnings (maybe promoted to errors later);
- whether a default for PATH (e.g "/bin:/usr/bin" should be added,
when PATH is not set (most software does that).
[1]: #1983
[2]: docker-archive/libcontainer#418
[3]: docker-archive/libcontainer#432
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
0 commit comments