-
Notifications
You must be signed in to change notification settings - Fork 15
Produce distroless minimized container images #312
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
base: master
Are you sure you want to change the base?
Conversation
This is a draft as I don't have a way to test it at present, aside from starting the container to see that the application code is indeed started properly. I don't know that this includes all the Debian files that the executable actually requires. I know ca-certificates is needed so that's included. If there are others, please advise. I also don't have a way to test against a split.io test tenant to ensure it works as expected. |
I have been able to execute this against one of our development environments. It appears to be working as expected with no failures seen so far. It does connect to the split.io servers, does receive updated feature flags as soon as they are changed, and does accurately update them in Redis. |
Startup has the messages:
Should the Dockerfiles be setting GIN_MODE=release? |
This change produces a minimal container image (~25MB) containing only the entrypoint bash (static) executable, the split-sync or split-proxy executable, and the minimal Debian files needed for these to execute. The dependency on the `tr` application was removed from functions.sh by using bash variable parameter expansion instead. We use a static bash executable to minimize libraries needed to include in the image. Bash executes only briefly in the entrypoint which then exec's into the application. split-sync and split-proxy are dynamically linked with libc because the go net library requires it. Therefore, libc is copied into the final image too. ca-certificates are copied into the image so TLS connections to split.io can be validated. The last build stage is used to produce a single-layer final container.
15c12fc
to
59cdb50
Compare
I'd also recommend replacing ENTRYPOINT with CMD, leaving ENTRYPOINT for any security tools that may be needed to wrap the running application. |
split-synchronizer doesn’t come with a health check program in the container callable by an ECS Task Definition. We can add one using bash only, which is already present in the image, so we don't have to add something large such as curl. The executable includes a GET /health/application endpoint on port 3010 which returns HTTP 200 OK on healthy, HTTP 500 on unhealthy. This script performs the minimal HTTP protocol call, placing the GET call and reading the first returned line for the status code, ignoring all other headers and body.
Since we already need glibc dynamically linked into the go applications, and bash only needs glibc plus one more small library, we can continue using the dynamically linked bash executable as long as we add libtinfo6 to the image as well. This reduces the size of the image by about 1MB and still works.
In support of feature request #311
This change produces a minimal container image (~25MB) containing only the entrypoint bash executable, the split-sync or split-proxy executable, and the minimal Debian files needed for these to execute.
The dependency on the
tr
application was removed from functions.sh by using bash variable parameter expansion instead.split-sync and split-proxy are dynamically linked with libc because the go net library requires it. Therefore, libc is copied into the final image too. bash needs libtinfo6 so we include that.
ca-certificates are copied into the image so TLS connections to split.io can be validated.
A healthcheck.sh script is added for use by container runtimes such as AWS ECS, which avoids needing to include curl or wget in the image - bash can do it for us.
The last build stage is used to produce a single-layer final container.