⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Stocker les données de configuration en utilisant Docker Configs

À propos des configs

Les configs des services Docker swarm vous permettent de stocker des informations non sensibles, comme les fichiers de configuration, en dehors de l'image ou des conteneurs en cours d'exécution d'un service. Cela vous permet de garder vos images aussi génériques que possible, sans avoir besoin de lier par montage des fichiers de configuration dans les conteneurs ou utiliser des variables d'environnement.

Les configs fonctionnent de manière similaire aux secrets, sauf qu'elles ne sont pas chiffrées au repos et sont montées directement dans le système de fichiers du conteneur sans l'utilisation de disques RAM. Les configs peuvent être ajoutées ou supprimées d'un service à tout moment, et les services peuvent partager une config. Vous pouvez même utiliser les configs en conjonction avec des variables d'environnement ou des étiquettes, pour une flexibilité maximale. Les valeurs de config peuvent être des chaînes génériques ou du contenu binaire (jusqu'à 500 ko de taille).

Note

Les configs Docker ne sont disponibles que pour les services swarm, pas pour les conteneurs autonomes. Pour utiliser cette fonctionnalité, considérez adapter votre conteneur pour qu'il fonctionne comme un service avec une échelle de 1.

Les configs sont supportées sur les services Linux et Windows.

Support Windows

Docker inclut le support des configs sur les conteneurs Windows, mais il y a des différences dans les implémentations, qui sont signalées dans les exemples ci-dessous. Gardez à l'esprit les différences notables suivantes :

  • Les fichiers de config avec des cibles personnalisées ne sont pas directement liés par montage dans les conteneurs Windows, car Windows ne supporte pas les montages de liaison de fichiers non-répertoires. Au lieu de cela, les configs pour un conteneur sont toutes montées dans C:\ProgramData\Docker\internal\configs (un détail d'implémentation sur lequel les applications ne devraient pas compter) dans le conteneur. Des liens symboliques sont utilisés pour pointer de là vers la cible désirée de la config dans le conteneur. La cible par défaut est C:\ProgramData\Docker\configs.

  • Lors de la création d'un service qui utilise des conteneurs Windows, les options pour spécifier UID, GID et mode ne sont pas supportées pour les configs. Les configs ne sont actuellement accessibles que par les administrateurs et les utilisateurs avec un accès system dans le conteneur.

  • Sur Windows, créez ou mettez à jour un service en utilisant --credential-spec avec le format config://<config-name>. Cela passe le fichier d'identifiants gMSA directement aux nœuds avant qu'un conteneur démarre. Aucun identifiant gMSA n'est écrit sur le disque sur les nœuds travailleurs. Pour plus d'informations, référez-vous à Déployer des services dans un swarm.

Comment Docker gère les configs

Lorsque vous ajoutez une config au swarm, Docker envoie la config au gestionnaire swarm via une connexion TLS mutuelle. La config est stockée dans le log Raft, qui est chiffré. L'ensemble du log Raft est répliqué à travers les autres gestionnaires, assurant les mêmes garanties de haute disponibilité pour les configs que pour le reste des données de gestion swarm.

Lorsque vous accordez à un service nouvellement créé ou en cours d'exécution l'accès à une config, la config est montée comme un fichier dans le conteneur. L'emplacement du point de montage dans le conteneur par défaut est /<config-name> dans les conteneurs Linux. Dans les conteneurs Windows, les configs sont toutes montées dans C:\ProgramData\Docker\configs et des liens symboliques sont créés vers l'emplacement désiré, qui par défaut est C:\<config-name>.

Vous pouvez définir la propriété (uid et gid) pour la config, en utilisant soit l' ID numérique ou le nom de l'utilisateur ou du groupe. Vous pouvez également spécifier les permissions de fichier (mode). Ces paramètres sont ignorés pour les conteneurs Windows.

  • Si non définie, la config appartient à l'utilisateur exécutant la commande du conteneur (souvent root) et au groupe par défaut de cet utilisateur (aussi souvent root).
  • Si non définie, la config a des permissions lisibles par tous (mode 0444), sauf si un umask est défini dans le conteneur, auquel cas le mode est impacté par cette valeur umask.

Vous pouvez mettre à jour un service pour lui accorder l'accès à des configs supplémentaires ou révoquer son accès à une config donnée à tout moment.

Un nœud n'a accès aux configs que si le nœud est un gestionnaire swarm ou s'il exécute des tâches de service auxquelles l'accès à la config a été accordé. Lorsqu'une tâche de conteneur s'arrête, les configs partagées avec elle sont démontées du système de fichiers en mémoire pour ce conteneur et supprimées de la mémoire du nœud.

Si un nœud perd la connectivité avec le swarm pendant qu'il exécute un conteneur de tâche avec accès à une config, le conteneur de tâche a toujours accès à ses configs, mais ne peut pas recevoir de mises à jour jusqu'à ce que le nœud se reconnecte au swarm.

Vous pouvez ajouter ou inspecter une config individuelle à tout moment, ou lister toutes les configs. Vous ne pouvez pas supprimer une config qu'un service en cours d'exécution utilise. Voir Faire tourner une config pour une façon de supprimer une config sans perturber les services en cours d'exécution.

Pour mettre à jour ou revenir en arrière sur les configs plus facilement, considérez ajouter un numéro de version ou une date au nom de la config. Ceci est facilité par la capacité de contrôler le point de montage de la config dans un conteneur donné.

Pour mettre à jour une pile, apportez des modifications à votre fichier Compose, puis relancez docker stack deploy -c <nouveau-fichier-compose> <nom-pile>. Si vous utilisez une nouvelle config dans ce fichier, vos services commencent à les utiliser. Gardez à l'esprit que les configurations sont immutables, donc vous ne pouvez pas changer le fichier pour un service existant. Au lieu de cela, vous créez une nouvelle config pour utiliser un fichier différent.

Vous pouvez exécuter docker stack rm pour arrêter l'application et démonter la pile. Cela supprime toute config qui a été créée par docker stack deploy avec le même nom de pile . Cela supprime toutes les configs, y compris celles non référencées par les services et celles restantes après un docker service update --config-rm.

En savoir plus sur les commandes docker config

Utilisez ces liens pour lire à propos de commandes spécifiques, ou continuez vers l' exemple sur l'utilisation des configs avec un service.

Exemples

Cette section inclut des exemples gradués qui illustrent comment utiliser les configs Docker.

Note

Ces exemples utilisent un swarm à moteur unique et des services non mis à l'échelle pour la simplicité. Les exemples utilisent des conteneurs Linux, mais les conteneurs Windows supportent également les configs.

Définir et utiliser les configs dans les fichiers compose

La commande docker stack supporte la définition de configs dans un fichier Compose. Cependant, la clé configs n'est pas supportée pour docker compose. Voir la référence du fichier Compose pour les détails.

Exemple simple : Commencer avec les configs

Cet exemple simple montre comment les configs fonctionnent en quelques commandes seulement. Pour un exemple du monde réel, continuez vers Exemple avancé : Utiliser les configs avec un service Nginx.

  1. Ajoutez une config à Docker. La commande docker config create lit l'entrée standard car le dernier argument, qui représente le fichier à partir duquel lire la config, est défini à -.

    $ echo "This is a config" | docker config create my-config -
    
  2. Créez un service redis et accordez-lui l'accès à la config. Par défaut, le conteneur peut accéder à la config à /my-config, mais vous pouvez personnaliser le nom de fichier sur le conteneur en utilisant l'option target.

    $ docker service create --name redis --config my-config redis:alpine
    
  3. Vérifiez que la tâche fonctionne sans problèmes en utilisant docker service ps. Si tout fonctionne, la sortie ressemble à ceci :

    $ docker service ps redis
    
    ID            NAME     IMAGE         NODE              DESIRED STATE  CURRENT STATE          ERROR  PORTS
    bkna6bpn8r1a  redis.1  redis:alpine  ip-172-31-46-109  Running        Running 8 seconds ago
    
  4. Obtenez l'ID du conteneur de tâche du service redis en utilisant docker ps, afin que vous puissiez utiliser docker container exec pour vous connecter au conteneur et lire le contenu du fichier de données de config, qui par défaut est lisible par tous et a le même nom que le nom de la config. La première commande ci-dessous illustre comment trouver l'ID du conteneur, et les deuxième et troisième commandes utilisent la complétion shell pour faire cela automatiquement.

    $ docker ps --filter name=redis -q
    
    5cb1c2348a59
    
    $ docker container exec $(docker ps --filter name=redis -q) ls -l /my-config
    
    -r--r--r--    1 root     root            12 Jun  5 20:49 my-config
    
    $ docker container exec $(docker ps --filter name=redis -q) cat /my-config
    
    This is a config
    
  5. Essayez de supprimer la config. La suppression échoue car le service redis est en cours d'exécution et a accès à la config.

    $ docker config ls
    
    ID                          NAME                CREATED             UPDATED
    fzwcfuqjkvo5foqu7ts7ls578   hello               31 minutes ago      31 minutes ago
    
    
    $ docker config rm my-config
    
    Error response from daemon: rpc error: code = 3 desc = config 'my-config' is
    in use by the following service: redis
    
  6. Supprimez l'accès à la config du service redis en cours d'exécution en mettant à jour le service.

    $ docker service update --config-rm my-config redis
    
  7. Répétez les étapes 3 et 4 à nouveau, vérifiant que le service n'a plus accès à la config. L'ID du conteneur est différent, car la commande service update redéploie le service.

    $ docker container exec -it $(docker ps --filter name=redis -q) cat /my-config
    
    cat: can't open '/my-config': No such file or directory
  8. Arrêtez et supprimez le service, et supprimez la config de Docker.

    $ docker service rm redis
    
    $ docker config rm my-config
    

Exemple simple : Utiliser les configs dans un service Windows

C'est un exemple très simple qui montre comment utiliser les configs avec un service Microsoft IIS en cours d'exécution sur Docker pour Windows sur Microsoft Windows 10. C'est un exemple naïf qui stocke la page web dans une config.

Cet exemple suppose que vous avez PowerShell installé.

  1. Enregistrez le suivant dans un nouveau fichier index.html.

    <html lang="en">
      <head><title>Hello Docker</title></head>
      <body>
        <p>Hello Docker! You have deployed a HTML page.</p>
      </body>
    </html>
  2. Si vous ne l'avez pas déjà fait, initialisez ou rejoignez le swarm.

    docker swarm init
  3. Enregistrez le fichier index.html en tant que config swarm nommée homepage.

    docker config create homepage index.html
  4. Créez un service IIS et accordez-lui l'accès à la config homepage.

    docker service create
        --name my-iis
        --publish published=8000,target=8000
        --config src=homepage,target="\inetpub\wwwroot\index.html"
        microsoft/iis:nanoserver
  5. Accédez au service IIS à http://localhost:8000/. Il devrait servir le contenu HTML de la première étape.

  6. Supprimez le service et la config.

    docker service rm my-iis
    
    docker config rm homepage

Exemple : Utiliser une config templée

Pour créer une configuration dans laquelle le contenu sera généré en utilisant un moteur de template, utilisez le paramètre --template-driver et spécifiez le nom du moteur comme argument. Le template sera rendu lorsque le conteneur est créé.

  1. Enregistrez le suivant dans un nouveau fichier index.html.tmpl.

    <html lang="en">
      <head><title>Hello Docker</title></head>
      <body>
        <p>Hello {{ env "HELLO" }}! I'm service {{ .Service.Name }}.</p>
      </body>
    </html>
  2. Enregistrez le fichier index.html.tmpl en tant que config swarm nommée homepage. Fournissez le paramètre --template-driver et spécifiez golang comme moteur de template.

    $ docker config create --template-driver golang homepage index.html.tmpl
    
  3. Créez un service qui exécute Nginx et a accès à la variable d'environnement HELLO et à la config.

    $ docker service create \
         --name hello-template \
         --env HELLO="Docker" \
         --config source=homepage,target=/usr/share/nginx/html/index.html \
         --publish published=3000,target=80 \
         nginx:alpine
    
  4. Vérifiez que le service est opérationnel : vous pouvez accéder au serveur Nginx, et que la sortie correcte est servie.

    $ curl http://0.0.0.0:3000
    
    <html lang="en">
      <head><title>Hello Docker</title></head>
      <body>
        <p>Hello Docker! I'm service hello-template.</p>
      </body>
    </html>
    

Exemple avancé : Utiliser les configs avec un service Nginx

Cet exemple est divisé en deux parties. La première partie est tout à propos de générer le certificat de site et ne concerne pas directement les configs Docker du tout, mais elle met en place la deuxième partie, où vous stockez et utilisez le certificat de site comme une série de secrets et la configuration Nginx comme une config. L'exemple montre comment définir des options sur la config, comme l' emplacement cible dans le conteneur et les permissions de fichier (mode).

Générer le certificat de site

Générez une autorité de certification racine et un certificat TLS et clé pour votre site. Pour les sites de production, vous pouvez vouloir utiliser un service tel que Let's Encrypt pour générer le certificat et la clé TLS, mais cet exemple utilise des outils en ligne de commande. Cette étape est un peu compliquée, mais est uniquement une étape de configuration pour que vous ayez quelque chose à stocker comme secret Docker. Si vous voulez sauter ces sous-étapes, vous pouvez utiliser Let's Encrypt pour générer la clé et le certificat du site, nommez les fichiers site.key et site.crt, et passez à Configurer le conteneur Nginx.

  1. Générez une clé racine.

    $ openssl genrsa -out "root-ca.key" 4096
    
  2. Générez un CSR à l'aide de la clé racine.

    $ openssl req \
              -new -key "root-ca.key" \
              -out "root-ca.csr" -sha256 \
              -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA'
    
  3. Configurez l'autorité de certification racine. Modifiez un nouveau fichier appelé root-ca.cnf et collez le contenu suivant dans le fichier. Cela contraint l'autorité de certification racine à signer uniquement des certificats de feuille et non des CAs intermédiaires.

    [root_ca]
    basicConstraints = critical,CA:TRUE,pathlen:1
    keyUsage = critical, nonRepudiation, cRLSign, keyCertSign
    subjectKeyIdentifier=hash
  4. Signez le certificat.

    $ openssl x509 -req -days 3650 -in "root-ca.csr" \
                   -signkey "root-ca.key" -sha256 -out "root-ca.crt" \
                   -extfile "root-ca.cnf" -extensions \
                   root_ca
    
  5. Générez la clé du site.

    $ openssl genrsa -out "site.key" 4096
    
  6. Générez le certificat du site et signez-le avec la clé du site.

    $ openssl req -new -key "site.key" -out "site.csr" -sha256 \
              -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'
    
  7. Configurez le certificat du site. Modifiez un nouveau fichier appelé site.cnf et collez le contenu suivant dans le fichier. Cela contraint le certificat du site pour qu'il puisse uniquement être utilisé pour authentifier un serveur et ne peut pas être utilisé pour signer des certificats.

    [server]
    authorityKeyIdentifier=keyid,issuer
    basicConstraints = critical,CA:FALSE
    extendedKeyUsage=serverAuth
    keyUsage = critical, digitalSignature, keyEncipherment
    subjectAltName = DNS:localhost, IP:127.0.0.1
    subjectKeyIdentifier=hash
  8. Signez le certificat du site.

    $ openssl x509 -req -days 750 -in "site.csr" -sha256 \
        -CA "root-ca.crt" -CAkey "root-ca.key" -CAcreateserial \
        -out "site.crt" -extfile "site.cnf" -extensions server
    
  9. Les fichiers site.csr et site.cnf ne sont pas nécessaires au service Nginx, mais vous en avez besoin si vous voulez générer un nouveau certificat de site. Protégez le fichier root-ca.key.

Configurer le conteneur Nginx

  1. Produisez une configuration Nginx très basique qui sert des fichiers statiques sur HTTPS. Le certificat et la clé sont stockés comme secrets Docker pour qu'ils puissent être tournés facilement.

    Dans le répertoire actuel, créez un nouveau fichier appelé site.conf avec le contenu suivant :

    server {
        listen                443 ssl;
        server_name           localhost;
        ssl_certificate       /run/secrets/site.crt;
        ssl_certificate_key   /run/secrets/site.key;
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
    }
  2. Créez deux secrets, représentant la clé et le certificat. Vous pouvez stocker n'importe quel fichier comme secret tant que sa taille est inférieure à 500 KB. Cela vous permet de découpler la clé et le certificat des services qui les utilisent. Dans ces exemples, le nom du secret et le nom du fichier sont les mêmes.

    $ docker secret create site.key site.key
    
    $ docker secret create site.crt site.crt
    
  3. Enregistrez le fichier site.conf dans une Docker config. Le premier paramètre est le nom de la config, et le second paramètre est le fichier à lire à partir de.

    $ docker config create site.conf site.conf
    

    Listez les configs :

    $ docker config ls
    
    ID                          NAME                CREATED             UPDATED
    4ory233120ccg7biwvy11gl5z   site.conf           4 seconds ago       4 seconds ago
    
  4. Créez un service qui exécute Nginx et a accès aux deux secrets et à la config. Définissez le mode sur 0440 pour que le fichier ne soit lisible que par son propriétaire et le groupe de ce propriétaire, et non par le monde.

    $ docker service create \
         --name nginx \
         --secret site.key \
         --secret site.crt \
         --config source=site.conf,target=/etc/nginx/conf.d/site.conf,mode=0440 \
         --publish published=3000,target=443 \
         nginx:latest \
         sh -c "exec nginx -g 'daemon off;'"
    

    Dans les conteneurs en cours d'exécution, les trois fichiers suivants existent maintenant :

    • /run/secrets/site.key
    • /run/secrets/site.crt
    • /etc/nginx/conf.d/site.conf
  5. Vérifiez que le service Nginx est en cours d'exécution.

    $ docker service ls
    
    ID            NAME   MODE        REPLICAS  IMAGE
    zeskcec62q24  nginx  replicated  1/1       nginx:latest
    
    $ docker service ps nginx
    
    NAME                  IMAGE         NODE  DESIRED STATE  CURRENT STATE          ERROR  PORTS
    nginx.1.9ls3yo9ugcls  nginx:latest  moby  Running        Running 3 minutes ago
    
  6. Vérifiez que le service est opérationnel : vous pouvez accéder au serveur Nginx, et que le certificat TLS correct est utilisé.

    $ curl --cacert root-ca.crt https://0.0.0.0:3000
    
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support, refer to
    <a href="https://nginx.org">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="https://www.nginx.com">www.nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    
    $ openssl s_client -connect 0.0.0.0:3000 -CAfile root-ca.crt
    
    CONNECTED(00000003)
    depth=1 /C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA
    verify return:1
    depth=0 /C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost
    verify return:1
    ---
    Certificate chain
     0 s:/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost
       i:/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----
    subject=/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost
    issuer=/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 1663 bytes and written 712 bytes
    ---
    New, TLSv1/SSLv3, Cipher is AES256-SHA
    Server public key is 4096 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    SSL-Session:
        Protocol  : TLSv1
        Cipher    : AES256-SHA
        Session-ID: A1A8BF35549C5715648A12FD7B7E3D861539316B03440187D9DA6C2E48822853
        Session-ID-ctx:
        Master-Key: F39D1B12274BA16D3A906F390A61438221E381952E9E1E05D3DD784F0135FB81353DA38C6D5C021CB926E844DFC49FC4
        Key-Arg   : None
        Start Time: 1481685096
        Timeout   : 300 (sec)
        Verify return code: 0 (ok)
    
  7. Sauf si vous allez continuer à l'exemple suivant, nettoyez après avoir exécuté cet exemple en supprimant le service nginx et les secrets et configs stockés.

    $ docker service rm nginx
    
    $ docker secret rm site.crt site.key
    
    $ docker config rm site.conf
    

Vous avez maintenant configuré un service Nginx avec sa configuration découplée de son image. Vous pourriez exécuter plusieurs sites avec exactement la même image mais des configurations séparées, sans avoir besoin de construire une image personnalisée.

Exemple : Rotate a config

Pour tournér une config, vous d'abord enregistrez une nouvelle config avec un nom différent que celui qui est actuellement en cours d'utilisation. Vous redéployez ensuite le service, en supprimant l'ancienne config et en ajoutant la nouvelle config au même point de montage dans le conteneur. Cet exemple se base sur le précédent en tournant le fichier de configuration site.conf de la partie précédente.

  1. Modifiez le fichier site.conf localement. Ajoutez index.php à la ligne index, et enregistrez le fichier.

    server {
        listen                443 ssl;
        server_name           localhost;
        ssl_certificate       /run/secrets/site.crt;
        ssl_certificate_key   /run/secrets/site.key;
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm index.php;
        }
    }
  2. Créez une nouvelle Docker config en utilisant le nouveau site.conf, appelé site-v2.conf.

    $ docker config create site-v2.conf site.conf
  3. Mettez à jour le service nginx pour utiliser la nouvelle config au lieu de l'ancienne.

    $ docker service update \
      --config-rm site.conf \
      --config-add source=site-v2.conf,target=/etc/nginx/conf.d/site.conf,mode=0440 \
      nginx
    
  4. Vérifiez que le service nginx est entièrement redéployé, en utilisant docker service ps nginx. Lorsqu'il est, vous pouvez supprimer l'ancienne site.conf config.

    $ docker config rm site.conf
    
  5. Pour nettoyer, vous pouvez supprimer le service nginx, ainsi que les secrets et configs.

    $ docker service rm nginx
    
    $ docker secret rm site.crt site.key
    
    $ docker config rm site-v2.conf
    

Vous avez maintenant mis à jour le service nginx sans avoir besoin de reconstruire son image.