From 32500c7dd1bea7c7901a18489d29c568ab8b50f9 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 10 Sep 2019 19:00:49 +0200 Subject: [PATCH 1/2] First version of a Krill Dockerfile. --- Dockerfile | 72 +++++++++++++++++++++++++++++++++++++ docker/entrypoint.sh | 85 ++++++++++++++++++++++++++++++++++++++++++++ docker/krill.conf | 4 +++ 3 files changed, 161 insertions(+) create mode 100644 Dockerfile create mode 100755 docker/entrypoint.sh create mode 100644 docker/krill.conf diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..a36ff29dc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,72 @@ +# +# -- stage 1: build krilld and krill_admin +# Use Ubuntu 16.04 because this is what the Travis CI Krill build uses. +# +FROM ubuntu:16.04 AS builder + +# Install Rust +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + curl \ + libssl-dev \ + pkg-config + +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y +ENV PATH "/root/.cargo/bin:$PATH" + +# Build the Krill daemon and krill_admin CLI tool +# Due to https://github.com/rust-lang/cargo/issues/2644#issuecomment-526931209 +# we do a hacky first step to build dependencies first so that we don't have to +# COPY directories and files individually because COPY . . causes the entire +# build to be repeated if any file is changed, even if it was a docker/ file +# that only affects the second stage of the build. +WORKDIR /tmp/krill +COPY Cargo.toml . +COPY yarn.lock . +COPY client client +COPY commons commons +COPY daemon daemon +COPY pubc pubc +COPY pubd pubd +RUN cargo build --release --bin krilld --bin krill_admin + +# +# -- stage 2: create an image containing just the binaries, configs & +# scripts needed to run Krill, and not the things needed to build +# it. +# +FROM ubuntu:16.04 +COPY --from=builder /tmp/krill/target/release/krilld /usr/local/bin/ +COPY --from=builder /tmp/krill/target/release/krill_admin /usr/local/bin/ + +# Build variables for uid and guid of user to run container +ARG RUN_USER=krill +ARG RUN_USER_UID=1012 +ARG RUN_USER_GID=1012 + +# Install openssl as Krill depends on it. +# Install uuid-runtime for generating an authorization token on startup. +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + openssl \ + uuid-runtime + +RUN groupadd -g ${RUN_USER_GID} ${RUN_USER} && \ + useradd -g ${RUN_USER_GID} -u ${RUN_USER_UID} ${RUN_USER} + +# Create the data directory structure and install a config file that uses it +WORKDIR /var/krill/data +COPY docker/krill.conf . +RUN chown -R ${RUN_USER}: . + +# Install a Docker entrypoint script that will be executed when the container +# runs +COPY docker/entrypoint.sh /opt/ +RUN chown ${RUN_USER}: /opt/entrypoint.sh + +EXPOSE 3000/tcp + +ENTRYPOINT ["/opt/entrypoint.sh"] +CMD ["krilld", "-c", "/var/krill/data/krill.conf"] diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100755 index 000000000..be35b146e --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# Prepare the environment and config file for the Krill daemon. +# This script supports several scenarios: +# A. The operator wants to run the Krill daemon using the default setup: +# We have to fix a couple of things before running the Krill daemon: +# - Krill doesn't know the FQDN at which it's HTTPS, RSYNC and RRDP +# endpoints are published but needs to include that FQDN in data that +# it produces. Configure it based on env var KRILL_FQDN. +# - Krill doesn't have a default API token value, we have to supply one. +# Generate one and announce it, if no KRILL_AUTH_TOKEN env var was +# supplied by the operator. +# +# B: The operator wants to control the Krill daemon configuration themselves. +# They signal this by setting env var KRILL_MANUAL_MODE. +# +# C: The operator wants to run some other command in the container, e.g. +# krill_admin. +# +set -e +KRILL_CONF=/var/krill/data/krill.conf +KRILL_FQDN="${KRILL_FQDN:-localhost:3000}" +KRILL_AUTH_TOKEN="${KRILL_AUTH_TOKEN:-None}" +KRILL_LOG_LEVEL="${KRILL_LOG_LEVEL:-warn}" +KRILL_USE_TA="${KRILL_USE_TA:-false}" + +MAGIC="# DO NOT TOUCH, THIS LINE IS MANAGED BY DOCKER KRILL" +LOG_PREFIX="docker-krill:" + +log_warning() { + echo >&2 "${LOG_PREFIX} Warning! $*" +} + +log_info() { + echo "${LOG_PREFIX} $*" +} + +if [ "$1" == "krilld" ]; then + # Does the opreator want to use their own API token? If so they must + # supply the KRILL_AUTH_TOKEN env var. + if [ "${KRILL_AUTH_TOKEN}" == "None" ]; then + # Generate a unique hard to guess authorisation token and export it + # so that the Krill daemon uses it (unless overriden by the Krill + # daemon config file). Only do this if the operator didn't already + # supply a token when launching the Docker container. + export KRILL_AUTH_TOKEN=$(uuidgen) + fi + + # Announce the token in the Docker logs so that clients can obtain it. + log_info "Securing Krill daemon with token ${KRILL_AUTH_TOKEN}" + + log_info "Configuring ${KRILL_CONF} .." + # If the config file was persisted and the container was recreated with + # different arguments to docker run there may still be some lines in the + # config file that we added before which are now no longer correct. Remove + # any lines that we added. + if ! sed -i "/.\\+${MAGIC}/d" ${KRILL_CONF} 2>/dev/null; then + log_warning "Cannot write to ${KRILL_CONF}. You can ignore this warning if you mounted your own config file over ${KRILL_CONF}." + else + # Append to the default Krilld config file to direct clients of the + # RSYNC and RRDP endpoints to the correct FQDN. We cannot know know the + # FQDN which clients use to reach us so the operator must inform this + # script via a "-e KRILL_FQDN=some.domain.name" argument to + # "docker run". If KRILL_FQDN is not set assume that the user is + # managing the Krill configuration themselves. + cat << EOF >> ${KRILL_CONF} +rsync_base = "rsync://${KRILL_FQDN}/repo/" ${MAGIC} +service_uri = "https://${KRILL_FQDN}/" ${MAGIC} +log_level = "${KRILL_LOG_LEVEL}" ${MAGIC} +use_ta = ${KRILL_USE_TA} ${MAGIC} +EOF + + log_info "Dumping ${KRILL_CONF} config file" + cat ${KRILL_CONF} + log_info "End of dump" + fi + + +fi + +# Launch the command supplied either by the default CMD (krilld) in the +# Dockerfile or that given by the operator when invoking Docker run. Use exec +# to ensure krilld runs as PID 1 as required by Docker for proper signal +# handling. This also allows this Docker image to be used to run krill_admin +# instead of krilld. +exec "$@" \ No newline at end of file diff --git a/docker/krill.conf b/docker/krill.conf new file mode 100644 index 000000000..23c07aa68 --- /dev/null +++ b/docker/krill.conf @@ -0,0 +1,4 @@ +ip = "0.0.0.0" +port = 3000 +data_dir = "/var/krill/data" +log_type = "stderr" From 33eae6c3944e87d0c898794660aa8ad68417dad4 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 10 Sep 2019 19:03:48 +0200 Subject: [PATCH 2/2] Corrected an outdated comment. --- docker/entrypoint.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index be35b146e..7433a304a 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -11,7 +11,8 @@ # supplied by the operator. # # B: The operator wants to control the Krill daemon configuration themselves. -# They signal this by setting env var KRILL_MANUAL_MODE. +# They do this by Docker mounting their own krill.conf over the +# /var/krill/data/krill.conf path. # # C: The operator wants to run some other command in the container, e.g. # krill_admin.