Skip to content

[docker] use tini as entrypoint #407

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

Merged

Conversation

rockandska
Copy link
Contributor

Use tini as entrypoint to handle signals correctly and by abble to press Ctrl+C to cancel tests.

More infos

Regards,

@rockandska rockandska requested a review from a team as a code owner February 9, 2021 13:09
@06kellyjac
Copy link

NOTE: If you are using Docker 1.13 or greater, Tini is included in Docker itself. This includes all versions of Docker CE. To enable Tini, just pass the --init flag to docker run.

Can't you use --init?

Also just using -it without --init still lets me Ctrl+C to cancel tests fine

$ docker run -v $PWD:/pwd -it bats/bats /pwd/test
1..68
not ok 1 test dep - jq is installed
# (from function `assert_success' in file /pwd/test/./bin/bats-assert/src/assert.bash, line 114,
#  in test file /pwd/test/0_test_deps.bats, line 16)
#   `assert_success' failed
#
# -- command failed --
# status : 1
# output :
# --
#
ok 2 test dep - curl is installed (remote) # skip skip remaining tests
not ok 3 fails Pod with unconfined seccomp
# (from function `assert_output' in file /pwd/test/./bin/bats-assert/src/assert.bash, line 223,
#  from function `assert_lt_zero_points' in file /pwd/test/_helper.bash, line 112,
#  in test file /pwd/test/1_cli.bats, line 15)
#   `assert_lt_zero_points' failed with status 127
#
# -- regular expression does not match output --
# regexp : .*\with a score of \-[1-9][0-9]* points.*
# output : /pwd/test/_helper.bash: line 98: ../dist//kubesec: No such file or directory
# --
#
ok 4 fails with CAP_SYS_ADMIN # skip skip remaining tests
ok 5 fails with CAP_CHOWN # skip skip remaining tests
ok 6 fails with CAP_SYS_ADMIN and CAP_CHOWN # skip skip remaining tests
ok 7 passes with securityContext capabilities drop all # skip skip remaining tests
ok 8 passes deployment with securitycontext readOnlyRootFilesystem # skip skip remaining tests
ok 9 passes deployment with securitycontext runAsNonRoot # skip skip remaining tests
ok 10 fails deployment with securitycontext runAsUser 1 # skip skip remaining tests
ok 11 passes deployment with securitycontext runAsUser > 10000 # skip skip remaining tests
ok 12 fails deployment with empty security context # skip skip remaining tests
ok 13 fails deployment with invalid security context # skip skip remaining tests
^C%                                                                                                                                                                                                                 

@rockandska
Copy link
Contributor Author

Can't you use --init?

  • you need to remember to start your container with when starting it manually
  • it is not portable (not compatible with kubernetes for example)
  • --init could be another init process depending on the docker host and prevent to be real reproducible

Also just using -it without --init still lets me Ctrl+C to cancel tests fine

If you have a long-running test who spawn a subprocess you'll see that bats doesn't propagate the signal to the subprocess

@06kellyjac
Copy link

Why are you going to need Ctrl+C in kubernetes? Pods aren't interactive unless debugging and should be disposable.

I was able to Ctrl+C a bunch of sleeps

@test "sleep 5 1" {
  run sleep 5

  assert_success
}

@test "sleep 5 2" {
  run sleep 5

  assert_success
}
@test "sleep 5 3" {
  run sleep 5

  assert_success
}
@test "sleep 5 4" {
  run sleep 5

  assert_success
}
@test "sleep 5 5" {
  run sleep 5

  assert_success
}
@test "sleep 5 6" {
  run sleep 5

  assert_success
}
$ docker run -v $PWD:/pwd -it bats/bats /pwd/test
1..74
ok 1 sleep 5 1
ok 2 sleep 5 2
ok 3 sleep 5 3
^C%  

pkill sleep, pkill bash, killall bash, or kill -9 8 in a separate docker exec session worked and Ctrl+C on a docker attach


# containerd
$ nerdctl run -v $PWD:/pwd -it bats/bats bash -c "bats /pwd/test"
WARN[0000] To isolate bridge networks, CNI plugin "isolation" needs to be installed in CNI_PATH ("/nix/store/fr9fgw523f3ywg0wcibbb15ki0fdc3gq-cni-plugins-0.9.0/bin"), see https://github.com/AkihiroSuda/cni-isolation
1..74
ok 1 sleep 5 1
ok 2 sleep 5 2
^C

# no daemon
$ podman run -v $PWD:/pwd -it bats/bats /pwd/test
1..74
ok 1 sleep 5 1
ok 2 sleep 5 2
^C

@rockandska
Copy link
Contributor Author

Why are you going to need Ctrl+C in kubernetes? Pods aren't interactive unless debugging and should be disposable.

Handling signals correctly is not only about Ctrl+C.

I was able to Ctrl+C a bunch of sleeps

See below a quick example of how Ctrl+C is not propagate ( I had to kill the container to regain control ).

bats hang

@cyphar
Copy link
Contributor

cyphar commented Feb 10, 2021

Indeed, bash doesn't handle any maskable signals properly when running as pid1 (this is true of most programs). I think --init would be more ideal, but I agree that embedding it is preferable for users (so users don't have to remember to pass that flag each time).

@martin-schulze-vireso
Copy link
Member

This seems to be localized enough in the docker container. However, we need to be careful with the additional dependency. It is written in C so it is platform dependent which version we want to install. The current code supports x86_64.

@martin-schulze-vireso
Copy link
Member

@rockandska I added some commits on top of yours and rebased to sign yours. Please have a look if you are happy with the changes.

Copy link
Member

@sublimino sublimino left a comment

Choose a reason for hiding this comment

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

nits:

  • could be a multistage build
  • or could check GPG signatures when wget'd as per their docs

Happy to approve and note these as optimisations for the future

@rockandska
Copy link
Contributor Author

seems fine for me @martin-schulze-vireso
thanks @sublimino / @martin-schulze-vireso

Co-authored-by: Andrew Martin <sublimino@gmail.com>
@martin-schulze-vireso
Copy link
Member

martin-schulze-vireso commented Apr 9, 2021

nits:

  • could be a multistage build
  • or could check GPG signatures when wget'd as per their docs

Happy to approve and note these as optimisations for the future

I've been burned more than once with GPG signature checks due to keyserver issues. If we want to go this route I'd propose to have the key embedded. If we are just guarding against accidental errors, the sha256sum should be sufficient.

I don't have experience with multistage builds, maybe you can venture a PR @sublimino? I'd concur to postpone these points. Maybe you can write up a followup issue for that?

@rockandska
Copy link
Contributor Author

could be a multistage build

Since there is no additional requirements to install tini, I don't see clearly reasons to use multi stage build.
Anything I missed @sublimino ?

@sublimino
Copy link
Member

I'd concur to postpone these points.

100%, these are minor and don't block merge. When I find time I'll try to review other PRs rather than open new ones at the moment @martin-schulze-vireso, appreciate there's a few I could look at.

could be a multistage build

Since there is no additional requirements to install tini, I don't see clearly reasons to use multi stage build.
Anything I missed @sublimino ?

Not at all! It's just an alternative pattern (COPY --from=tini /tini /tini) to the wget approach, and I only suggested it in the light of the GPG validation (agreed key expiry is a pain here).

Multistages makes tini updates slightly easier (updating FROM in tini stage), changes our trust boundary to include the docker hub account (so referencing images by hash to pin the dependency instead of validating checksums/GPG), but is definitely a nit rather than a recommendation.

And as these are not roadblocks I'm totally happy with the current wget approach. Good to merge in my mind 📦👍

@martin-schulze-vireso
Copy link
Member

This could help if multistage does the architecture handling automatically.

@sublimino
Copy link
Member

TL;DR: Tini's github binaries are available for many (all?!) architectures. Containers aren't.

For amd64 vs ARM etc -- container contents have to be compiled and the container tagged appropriately. There's no mechanism for docker to transparently serve architecture-specific containers for the same tag, and not for the SHA256 reference.

In all honesty looking at the variety of compiled architectures for tini's binary releases on Github compared to the docker hub containers (exclusively linux/amd64) - this negates the container argument as there are only containers for amd64 architectures. We should use github as the PR suggests.

I didn't consider that, a good point well made @martin-schulze-vireso 🙏

@martin-schulze-vireso
Copy link
Member

Well, as long as we do amd64 only, this is fine. But there is a requests issue for arm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants