6 votes

Définition de la variable d'environnement du docker à partir du secret de construction

Existe-t-il un moyen de définir des variables d'environnement à partir du nouveau docker ? améliorations de la construction ?

J'ai essayé

RUN --mount=type=secret,id=secret export SECRET=`/run/secrets/secret
RUN --mount=type=secret,id=secret ENV SECRET=`/run/secrets/secret

Les deux ne fonctionnent pas. Ou est-ce que le fait de définir des secrets sur des variables d'environnement dans le dockerfile est mauvais ? Puisque l'exécution de docker history à la var env étant définie en texte clair. Si c'est le cas, quelle est la meilleure façon de définir la variable env la plus sécurisée possible ?

4voto

BMitch Points 3744

Pour définir une variable à partir d'un secret, vous pouvez utiliser la fonction $(cat /filename) syntaxe dans le shell. Cela affecte l'interpréteur de commandes à l'intérieur de cette seule étape, de sorte que toutes vos utilisations de cette variable doivent se faire à l'intérieur de la même étape. Vous ne pouvez pas extraire une variable d'une étape RUN vers une étape ENV. Si vous avez besoin qu'elle persiste dans d'autres étapes RUN, vous devrez écrire la variable dans le système de fichiers et l'inclure dans l'image, ce qui n'est pas souhaitable (au lieu de cela, il suffit de monter le secret une deuxième fois dans l'étape RUN ultérieure).

Voici un exemple de travail, vous pouvez également exporter ce secret avec export secret_var :

$ cat df.secret
FROM busybox
RUN --mount=type=secret,id=secret \
    secret_var="$(cat /run/secrets/secret)" \
 && echo ${secret_var}

$ cat secret.txt
my_secret

$ docker build --progress=plain --secret id=secret,src=$(pwd)/secret.txt -f df.secret .
#1 [internal] load build definition from df.secret
#1 sha256:85a18e77d3e60159b744d6ee3d96908a6fed0bd4f6a46d038e2aa0201a1028de
#1 DONE 0.0s

#1 [internal] load build definition from df.secret
#1 sha256:85a18e77d3e60159b744d6ee3d96908a6fed0bd4f6a46d038e2aa0201a1028de
#1 transferring dockerfile: 152B done
#1 DONE 0.0s

#2 [internal] load .dockerignore
#2 sha256:a5a676bca3eaa2c757a3ae40d8d5d5e91b980822056c5b3b6c5b3169fc65f0f1
#2 transferring context: 49B done
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/busybox:latest
#3 sha256:da853382a7535e068feae4d80bdd0ad2567df3d5cd484fd68f919294d091b053
#3 DONE 0.0s

#5 [1/2] FROM docker.io/library/busybox
#5 sha256:08a03f3ffe5fba421a6403c31e153425ced631d108868f30e04985f99d69326e
#5 DONE 0.0s

#4 [2/2] RUN --mount=type=secret,id=secret     secret=$(cat /run/secrets/secret)  && echo ${secret}
#4 sha256:6ef91a8a7daf012253f58dba292a0bd86af1d1a33a90838b6a99aba5abd4cfaf
#4 0.587 my_secret
#4 DONE 0.7s

#6 exporting to image
#6 sha256:e8c613e07b0b7ff33893b694f7759a10d42e180f2b4dc349fb57dc6b71dcab00
#6 exporting layers 0.0s done
#6 writing image sha256:a52db3458ad88481406cd60627e2ed6f55b6720c1614f65fa8f453247a9aa4de done
#6 DONE 0.0s

Notez la ligne #4 0.587 my_secret montrant que le secret est sorti.

-1voto

Elliott de Launay Points 731

Dans vos exemples, les variables d'environnement sont définies à partir de secrets, mais uniquement pour ce processus.

Si vous voulez que les variables d'environnement d'exécution soient définies à partir des secrets, vous devrez soit monter un volume contenant les secrets, soit passer les secrets via docker-compose, dans les deux cas, puis utiliser un point d'entrée script pour définir les secrets en fonction des emplacements des secrets.

Remarque : les fichiers secrets devront être accessibles à toute personne ou service qui exécutera le fichier docker.

Ajouter un point d'entrée script à votre Dockerfile

Dockerfile :

FROM alpine

# Bash is needed for the script to set env_vars based on secrets
RUN apk upgrade --update-cache --available && \
    apk add bash \
    && rm -rf /var/cache/apk/*

# Adding entrypoint script to image
COPY ./docker_entrypoint /usr/local/bin/docker_entrypoint
RUN chmod +x /usr/local/bin/docker_entrypoint

ENTRYPOINT [ "docker_entrypoint"]

CMD ["printenv"]

Ce script va chercher une variable d'environnement au format ENVAR_FILE pour trouver le chemin de l'endroit où le secret est stocké - exporter le secret vers une variable d'environnement sans l'option _FILE et ensuite appeler la commande restante.

docker_entrypoint :

#!/usr/bin/env bash

set -e

file_env() {
    local var="$1"
    local fileVar="${var}_FILE"
    local def="${2:-}"

    if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
        echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
        exit 1
    fi
    local val="$def"
    if [ "${!var:-}" ]; then
        val="${!var}"
    elif [ "${!fileVar:-}" ]; then
        val="$(< "${!fileVar}")"
    fi
    export "$var"="$val"
    unset "$fileVar"
}

# Explicitly list the environment variables you want to
# set from secrets
file_env "ENVAR1"
file_env "ENVAR2"

exec "$@"

Maintenant, vous pourriez passer des variables d'environnement du format ENVAR_FILE=/mnt/path/to/secret - et le point d'entrée ci-dessus script lira le contenu de ce fichier et générera les variables ENVAR=quelque soit votreSecretIs

Un exemple utilisant docker-compose :

services:
  someService:
    image: <imageFromDockerFileAbove>
    environment: 
      - ENVAR1_FILE=/run/secrets/envar1
      - ENVAR2_FILE=/run/secrets/envar2
    secrets:
      - envar1
      - envar2
secrets:
  envar1:
    file: /pth/to/secret
  envar2:
    file: /pth/to/secret

Sortie attendue :

someService_1  | HOSTNAME=<containerID>
someService_1  | ENVAR1=mysecret1
someService_1  | ENVAR2=mysecret2
someService_1  | PWD=/
someService_1  | HOME=/root
someService_1  | SHLVL=0
someService_1  | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Et

docker inspect --format='{{json .Config.Env}}' <containerID>

retours :

["ENVAR1_FILE=/run/secrets/envar1","ENVAR2_FILE=/run/secrets/envar2","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X