Skip to content

Commit

Permalink
Merge pull request #187 from balena-os/beind
Browse files Browse the repository at this point in the history
contrib: Add balena-engine version of dind container
  • Loading branch information
robertgzr committed Nov 1, 2019
2 parents edfdcc0 + 405be42 commit 22ebbd4
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 0 deletions.
84 changes: 84 additions & 0 deletions contrib/beind/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
FROM docker.io/library/alpine:3.8 as balena

ARG BALENA_VERSION=v18.9.7

RUN apk add --no-cache \
ca-certificates

# set up nsswitch.conf for Go's "netgo" implementation (which Docker explicitly uses)
# - https://github.com/docker/docker-ce/blob/v17.09.0-ce/components/engine/hack/make.sh#L149
# - https://github.com/golang/go/blob/go1.9.1/src/net/conf.go#L194-L275
# - docker run --rm debian:stretch grep '^hosts:' /etc/nsswitch.conf
RUN [ ! -e /etc/nsswitch.conf ] && echo 'hosts: files dns' > /etc/nsswitch.conf

RUN set -eux; \
\
apkArch="$(apk --print-arch)"; \
case "$apkArch" in \
x86_64) dlArch='x86_64' ;; \
armhf) dlArch='armv7hf' ;; \
aarch64) dlArch='aarch64' ;; \
*) echo >&2 "error: unsupported architecture ($apkArch)"; exit 1 ;;\
esac; \
\
if ! wget -O balena-engine.tgz "https://github.com/balena-os/balena-engine/releases/download/${BALENA_VERSION}/balena-engine-${BALENA_VERSION}-${dlArch}.tar.gz"; then \
echo >&2 "error: failed to download balenaEngine ${BALENA_VERSION} for ${dlArch}"; \
exit 1; \
fi; \
\
tar --extract \
--file balena-engine.tgz \
--strip-components 1 \
--directory /usr/local/bin/ \
; \
rm balena-engine.tgz; \
\
balena-engine-daemon --version; \
balena-engine --version

COPY modprobe.sh /usr/local/bin/modprobe
COPY balena-entrypoint.sh /usr/local/bin/

ENTRYPOINT ["/usr/local/bin/balena-entrypoint.sh"]
CMD []


FROM balena as beind

# https://github.com/docker/docker/blob/master/project/PACKAGERS.md#runtime-dependencies
RUN set -eux; \
apk add --no-cache \
e2fsprogs \
e2fsprogs-extra \
iptables \
tini \
xz \
# pigz: https://github.com/moby/moby/pull/35697 (faster gzip implementation)
pigz \
; \
ln -sfv "$(which tini)" /usr/local/bin/balena-engine-init

# TODO aufs-tools

# set up subuid/subgid so that "--userns-remap=default" works out-of-the-box
RUN set -x \
&& addgroup -S dockremap \
&& adduser -S -G dockremap dockremap \
&& echo 'dockremap:165536:65536' >> /etc/subuid \
&& echo 'dockremap:165536:65536' >> /etc/subgid

# https://github.com/docker/docker/tree/master/hack/dind
# ENV DIND_COMMIT=37498f009d8bf25fbb6199e8ccd34bed84f2874b
ENV DIND_COMMIT=v18.9.7

RUN set -eux; \
wget -O /usr/local/bin/beind "https://raw.githubusercontent.com/balena-os/balena-engine/${DIND_COMMIT}/hack/dind"; \
chmod +x /usr/local/bin/beind

COPY balenad-entrypoint.sh /usr/local/bin/

VOLUME /var/lib/balena-engine
EXPOSE 2375

ENTRYPOINT ["/usr/local/bin/balenad-entrypoint.sh"]
CMD []
1 change: 1 addition & 0 deletions contrib/beind/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# balena-engine in docker
33 changes: 33 additions & 0 deletions contrib/beind/balena-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh
set -e

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- balena-engine "$@"
fi

# if our command is a valid Docker subcommand, let's invoke it through Docker instead
# (this allows for "docker run docker ps", etc)
if balena-engine help "$1" > /dev/null 2>&1; then
set -- balena-engine "$@"
fi

# if we have "--link some-docker:docker" and not DOCKER_HOST, let's set DOCKER_HOST automatically
if [ -z "$DOCKER_HOST" -a "$DOCKER_PORT_2375_TCP" ]; then
export DOCKER_HOST='tcp://balena:2375'
fi

if [ "$1" = 'balena-engine-daemon' -o "$1" = 'balenad' ]; then
cat >&2 <<-'EOW'
📎 Hey there! It looks like you're trying to run a balenaEngine daemon.
You probably should use the "beind" image variant instead, something like:
docker run --privileged --name some-overlay-balena -d balena/engine:beind --storage-driver=overlay2
EOW
sleep 3
fi

exec "$@"
22 changes: 22 additions & 0 deletions contrib/beind/balenad-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh
set -e

# no arguments passed
# or first arg is `-f` or `--some-option`
if [ "$#" -eq 0 ] || [ "${1#-}" != "$1" ]; then
# add our default arguments
set -- balena-engine-daemon \
--host=unix:///var/run/balena-engine.sock \
--host=tcp://0.0.0.0:2375 \
"$@"
fi

if [ "$1" = 'balena-engine-daemon' -o "$1" = 'balenad' ]; then
# if we're running Docker, let's pipe through dind
set -- "$(which beind)" "$@"

# explicitly remove Docker's default PID file to ensure that it can start properly if it was stopped uncleanly (and thus didn't clean up the PID file)
find /run /var/run -iname 'balena*.pid' -delete
fi

exec "$@"
20 changes: 20 additions & 0 deletions contrib/beind/modprobe.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh
set -eu

# "modprobe" without modprobe
# https://twitter.com/lucabruno/status/902934379835662336

# this isn't 100% fool-proof, but it'll have a much higher success rate than simply using the "real" modprobe

# Docker often uses "modprobe -va foo bar baz"
# so we ignore modules that start with "-"
for module; do
if [ "${module#-}" = "$module" ]; then
ip link show "$module" || true
lsmod | grep "$module" || true
fi
done

# remove /usr/local/... from PATH so we can exec the real modprobe as a last resort
export PATH='/usr/sbin:/usr/bin:/sbin:/bin'
exec modprobe "$@"

0 comments on commit 22ebbd4

Please sign in to comment.