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).
NoteLes 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 estC:\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 formatconfig://<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 souventroot
). - Si non définie, la config a des permissions lisibles par tous (mode
0444
), sauf si unumask
est défini dans le conteneur, auquel cas le mode est impacté par cette valeurumask
.
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.
NoteCes 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.
-
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 -
-
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'optiontarget
.$ docker service create --name redis --config my-config redis:alpine
-
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
-
Obtenez l'ID du conteneur de tâche du service
redis
en utilisantdocker ps
, afin que vous puissiez utiliserdocker 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
-
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
-
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
-
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
-
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é.
-
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>
-
Si vous ne l'avez pas déjà fait, initialisez ou rejoignez le swarm.
docker swarm init
-
Enregistrez le fichier
index.html
en tant que config swarm nomméehomepage
.docker config create homepage index.html
-
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
-
Accédez au service IIS à
http://localhost:8000/
. Il devrait servir le contenu HTML de la première étape. -
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éé.
-
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>
-
Enregistrez le fichier
index.html.tmpl
en tant que config swarm nomméehomepage
. Fournissez le paramètre--template-driver
et spécifiezgolang
comme moteur de template.$ docker config create --template-driver golang homepage index.html.tmpl
-
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
-
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.
-
Générez une clé racine.
$ openssl genrsa -out "root-ca.key" 4096
-
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'
-
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
-
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
-
Générez la clé du site.
$ openssl genrsa -out "site.key" 4096
-
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'
-
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
-
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
-
Les fichiers
site.csr
etsite.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 fichierroot-ca.key
.
Configurer le conteneur Nginx
-
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; } }
-
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
-
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
-
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
-
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
-
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)
-
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.
-
Modifiez le fichier
site.conf
localement. Ajoutezindex.php
à la ligneindex
, 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; } }
-
Créez une nouvelle Docker config en utilisant le nouveau
site.conf
, appelésite-v2.conf
.$ docker config create site-v2.conf site.conf
-
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
-
Vérifiez que le service
nginx
est entièrement redéployé, en utilisantdocker service ps nginx
. Lorsqu'il est, vous pouvez supprimer l'anciennesite.conf
config.$ docker config rm site.conf
-
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.