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

Feat/docker alpine #277

Open
wants to merge 4 commits into
base: primary
Choose a base branch
from

Conversation

n-holmstedt
Copy link
Contributor

I've made a simple multistage build based on an alpine container. This should decrease the size of the image since it wont contain any dependencies.

  • uses "ALPINE_VERSION" as build argument, "latest", "3.12" etc.
  • Installs CA certificates
  • Installs dumb-init to handle kernel signals, more here
  • Copies a IPV4-version of default config to make the container start from scratch.
  • Adds a "skogul" group and user to use as default.

As earlier, any suggestions are welcome. Build flags for golang, for example.

docker build --build-arg ALPINE_VERSION=latest -t <image>:<tag> -f ./alpine.Dockerfile .

@sklirg
Copy link
Member

sklirg commented Nov 25, 2022

Hi! Thanks for the contribution! 🎉

Currently, this new Dockerfile is not picked up by any release automation, so it will not be built and released. Do you think it is useful to do so as well? Theoretically, it should be possible to modify .github/workflows/container-image.yml to add this to release builds.

The bit about dumb-init is interesting to me. I've seen various cases where signals aren't passed on into the process, but I haven't seen this when running Skogul in Kubernetes. I managed to reproduce this directly in docker on an old debian box (version details:)

root:~# docker --version
Docker version 20.10.8, build 3967b7d

In Docker here, sending SIGTERM to the running process does not make skogul stop.

However, when running in Kubernetes, this works as expected. I use "rollout restart" often which works fine and manages to gracefully stop the container, and I've tested by manually SIGTERM-ing the process from within the container (I think this is the closest way I have to easily reproduce this right now..). So I'm not sure if this is a docker issue or "something else". I can try to dig into it a bit further. Do you have any specifics where this resolved an issue?

I think I've seen some Skogul code regarding UNIX signals handling, and if we implement that, Skogul will be able to handle such signals itself just fine, at which point we won't need "dumb-init" to wrap the process. I'll see if I can get some more insight on that part :)


Regarding the IPv4 config... I think I'll CC in @KristianLyng here 😂. My preference is that Skogul should bind on anything the host prefers, and defaulting to IPv4 is a bit old-school 😬 What about updating the config to remove the loopback address, but rather bind on just the port (:8080), which will make Skogul listen on all interfaces? Either in an adapted Dockerfile-config, or in default.json. (This will make Skogul listen on IPv6 if supported and available, as well as IPv4, and if IPv6 is not configured, it will not try to bind on IPv6, which results in only binding on IPv4, which then works.. If an orchestrator is misconfigured with IPv6 it can be useful to force binding on IPv4, either through things such as the environment variable V6ONLY=0, or by manually altering the configuration. I know that Docker is a bit old-school, especially with default configuration, so I totally get where you're coming from - but IPv6 is supported in e.g. Kubernetes, so I think it's wrong to provide default config/building blocks using IPv4 if we can be agnostic to v4/v6.)


On to the actual Dockerfile!

What do you think of using a debian image instead of alpine? Debian slim is ~30 MB, which is more than the alpine base of 3 MB, but in reality, this doesn’t really matter that much as servers/orchestrators aren’t usually that sparse on disk space. It also has the default bindings for C (cgo) and openssl etc. more easily available. Furthermore, there can be various/spurious build errors when building Go in Alpine, and Alpine-based builders are not officially supported by Go. So, what do you think of using Debian instead of Alpine? :)

I'm also a bit curious about the build process. If we want to provide an alpine image of Skogul, I think we should build Skogul in an alpine (musl) environment, e.g. using golang:alpine. That way we will know that the build is correctly set up, rather than building it in a C environment (like it is now, by pulling the current image and rebuilding from that) for use in a musl-environment (even though we turn off CGO). The Golang Alpine image should do all the necessary steps for us here (but we need to add things like git and make and such).
Then, the "runtime container image" can be a fresh alpine image without git and all that, but we need to at least install ca-certificates again (maybe more, I haven't tested).


Whew, sorry, that was a wall of text. It's not meant as criticism because I am all for open source, it's more just "braindumping" what I thought of while looking through. Depending on some answers here, other questions will be totally irrelevant - at which point I'll make sure to follow up in some other ways later on!

I'm also in the Slack (@sklirg) if you want to have a more informal chat about any of this :)

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.

2 participants