Skip to content

Instantly share code, notes, and snippets.

@jpralves
Created October 20, 2020 08:45
Show Gist options
  • Save jpralves/da0b76ddd9b76fa6c437a3f29594a967 to your computer and use it in GitHub Desktop.
Save jpralves/da0b76ddd9b76fa6c437a3f29594a967 to your computer and use it in GitHub Desktop.
Docker TWINs without docker
FROM alpine:3.12
MAINTAINER [email protected]
### Build with:
# docker build . --tag twin-api:latest
### Run with:
# docker run -ti -v /var/run/docker.sock:/var/run/docker.sock twin-api:latest [number of twin copies]
RUN apk add --no-cache curl jq
# Copy Scripts:
COPY *.sh /
# Make Scripts executable:
RUN chmod 755 /*.sh
# Define EntryPoint:
ENTRYPOINT ["/entrypoint.sh"]

Docker TWINs without docker

This is a new example on how to use docker along docker without docker, confused?, I'm using the docker API to create and run containers.

In this particular example the image self-replicates itself running multiple images.

To build:

docker build . --tag twin-api:latest

The image uses an alpine based container with curl and jq.

To run:

docker run -ti -v /var/run/docker.sock:/var/run/docker.sock twin-api:latest [number of twin copies]

Example:

$ docker run -ti -v /var/run/docker.sock:/var/run/docker.sock twin-api:latest 5
Twin docker container running with id=41bdabc1db11af51150c347a1e64e5789257cb826e8c5508d4a152521573e0f7 (Iteration=5)
Twin docker container running with id=ee0aa9c45d36df4f076c79ba69bfe2e685279a5e2cbac2118fd6c3896d35fd88 (Iteration=4)
Twin docker container running with id=bfb390da9aa64c73ef738ae6a99edfe6cdea219fc3ea3e358a16d8e581d0a3ba (Iteration=3)
Twin docker container running with id=5da0748c7f03348800196b4a8b8a329924ee34429b0b77df0b475c43134316d0 (Iteration=2)
Twin docker container running with id=03f45e1d597a11d2a895762519596328973b7128fb243f4b185f59532928ab57 (Iteration=1)

One particular useful command to see what happens in the back of the conversation between docker-cli and dockerd is:

socat -v UNIX-LISTEN:/tmp/fake,fork UNIX-CONNECT:/var/run/docker.sock

And on another terminal:

DOCKER_HOST=unix:///tmp/fake docker ps .....

The scripts are self-explanatory.

#!/bin/sh
IT=${1:-1}
# Obtain Instance ID:
INSTANCE_ID=$(cut -c9- </proc/1/cpuset)
docker_run () {
IMAGE_ID=$1
ITERATION=$2
ID=$(curl -s -XPOST --unix-socket /var/run/docker.sock -d "{ \"Image\": \"${IMAGE_ID}\", \"Cmd\": [\"${ITERATION}\"], \"Tty\": true, \"AttachStdout\":true,\"AttachStderr\":true,\"HostConfig\":{\"Binds\":[\"/var/run/docker.sock:/var/run/docker.sock\"]} }" -H 'Content-Type: application/json' http://localhost/containers/create | jq -r '.Id')
curl -s -XPOST --unix-socket /var/run/docker.sock "http://localhost/containers/${ID}/attach?stream=1&stdout=1&stderr=1" &
curl -s -XPOST --unix-socket /var/run/docker.sock "http://localhost/containers/${ID}/start"
curl -s -XPOST --unix-socket /var/run/docker.sock "http://localhost/containers/${ID}/wait?condition=next-exit" >/dev/null
}
if [ -e /var/run/docker.sock ] ; then
# Get Image ID:
IMAGE_ID=$(curl -s --unix-socket /var/run/docker.sock "http://localhost/containers/${INSTANCE_ID}/json" | jq -r '.Config.Image')
echo "Twin docker container running with id=${INSTANCE_ID} (Iteration=${IT})"
[ "${IT}" -le 1 ] || docker_run "${IMAGE_ID}" $(( IT - 1 ))
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment