Containers et configuration 

De la promesse au concret avec git et confd


Alexandre Garnier ( zigarn)

Présentation aimablement prêtée
par Christophe Furmaniak

Ice Breaker

Ou speaker warmup ?

  • Qui utilise docker régulièrement ?
  • En production ?
  • Avec un orchestrateur ?

Docker, la promesse

Elle est pas belle ma matrice ?

Docker, la réponse

YEAH !!! Des containers partout !

Containers ou Conteneurs ?

La réalité

  • Oui, les containers (ou plutôt les images) sont un moyen pratique (voire élégant ?) de packager vos apps
  • Mais ⇒ Tous vos environnements (runtime) ne sont pas égaux !
  • Qu'en est-il de votre configuration (runtime) ?
  • Combien d'environnements devez-vous gérer au fait ?
    • Dev, ..., QA, ..., Prod
  • Combien d'équipes (en terme de responsabilités/droits d'accès [RBAC]) ?

Les containers ne sont pas (au premier abord) le facilitateur pour vos problématiques de configuration d'environnement

Configuration ?

De quoi parle-t-on au fait ?

  • Fichiers de configuration "human readable"
    • "server.conf" et compagnie
    • text/yaml/json/toml/xml/properties
  • Fichiers binaires (ou presque)
    • Certificats
    • Ce qui a un rapport avec le chiffrement
  • Vos secrets !

Tout ce qui permet à vos apps d'intéragir avec leur écosystème !

Problématiques de configuration

En rapport avec les containers... ou pas

  • Comment apporter la configuration dans vos containers ?
  • Comment générer la configuration pour vos containers ?
  • Comment gérer sa configuration ?
    • Historique, versions
    • RBAC
    • Comment partager des bouts de configuration entre applications et/ou entre environnements ?

Plateformes Docker ?

De nos jours ?

  • Docker tout seul ⇒ "Pet docker"
  • Docker à fond ⇒ "Cattle docker"
    ⇒ Orchestration FTW !
    (Swarm, Kubernetes, DC/OS Mesos+Marathon, Openshift, Rancher, Nomad, Titus, Deis, Tectonic, Mantl, Kontena, ...)

L'appli pour la démo

Un super guestbook

  • Front : AngularJs + nginx
  • Gateway : springboot
  • Filtre : springboot
  • Service  de stockage: springboot
  • Couche de stockage : redis

Frontend → Gateway ↔ Filter Service

↳ Storage Service → Redis

Configuration dans les conteneurs

Solution #0 : variables d'environnement

Apporter la configuration par le biais de variables d'environnement

  • 1 Image qui package votre app
  • La partie configuration dynamique est exposée à votre app par des variables d'env
    • Ça ne fonctionne pas pour les "fichiers binaires"
    • Dans la vraie vie on apporte souvent beaucoup de variables : ça peut vite devenir douloureux
    • Problème de séparation des responsabilités

Configuration dans les conteneurs

Solution #0 : variables d'environnement


docker run -t -d \
  -w /home/user/dev/work-dir \
  -v /home/user/dev/work-dir:/work:rw \
  -e ******** -e ******** -e ******** -e ******** -e ******** \
  -e ******** -e ******** -e ******** -e ******** -e ******** \
  -e ******** -e ******** -e ******** -e ******** -e ******** \
  -e ******** -e ******** -e ******** -e ******** -e ******** \
  -e ******** -e ******** -e ******** -e ******** -e ******** \
  -e ******** -e ******** -e ******** -e ******** -e ******** \
  -e ******** -e ******** -e ******** -e ******** -e ******** \
  -e ******** -e ******** -e ******** -e ******** -e ******** \
  -e ******** -e ******** -e ******** -e ******** -e ******** \
  mycompany/myimage:v1.0.2
					

Démo

Solution #0

Configuration dans les conteneurs

Solution #1 : images "tout-en-un"

Intégrez votre app et sa configuration dans la même image

  1. 1 image qui embarque votre app
  2. ajout de la configuration "au dessus"
    FROM myapp:1.3.2myapp-prod:1.3.2

PAS BIEN !!

  • Ce ne sera pas la même image sur tous les envs
  • Vous devrez tout reconstruire à chaque nouvelle version (même si la conf ne change pas)

Démo

Solution #1

Configuration dans les conteneurs

Solution #2 : configuration sur le "host" docker

Fournissez la config par le biais des volumes "mappés" sur le host docker


docker run -v /data/env/prod:/data ...
					

PAS BIEN !!

Êtes vous sur de vouloir préférer les animaux de compagnie au bétail ?

Démo

Solution #2

Configuration dans les conteneurs

Solution #3 : data containers

Créez des containers dédiés pour la configuration

  1. 1 image pour votre application
  2. 1 image pour chaque environnement
  3. Les 2 containers résultant assemblés par le biais du --volumes-from (ou équivalent)

Démo

Solution #3

Configuration dans les conteneurs

Solution #4 : configuration distante

Utilisons un service de configuration

  1. 1 image pour votre application
  2. 1 (ou plusieurs) services/serveurs hébergeant votre configuration distante
    • Netflix Archaius (#link)
      • Java uniquement 😞
    • Spring Cloud Config (#link)
      • Super méga cool pour les apps Spring(boot)
      • Besoin d'introduire du code pour l'utiliser dans d'autres apps java ou autres langages

Configuration dans les conteneurs

Solution #4 : configuration distante

  • OK pour le "même image quelque soit l'env"
  • Points négatifs
    • Potentiellement très intrusif
      • La plupart du temps : NO-GO pour les applis "anciennes" car trop de modifs
    • Attention : désormais ces serveurs/services de configuration distante sont un nouveau composant de votre appli

Pas de démo

Solution #4

Configuration dans les conteneurs

Solution #5 : solution native orchestrateur

Swarm configs et secrets

  1. 1 image pour votre appli
  2. Des configs et secrets pour stocker vos valeurs d'environnement
    • Les configs et secrets sont stockés au niveau cluster Swarm
    • Permettent de peupler des fichiers :
      • /{config-name} pour les configs (ou autre via target)
      • /run/secrets/{secret-name} pour les secrets

Configuration dans les conteneurs

Solution #5 : solution native orchestrateur

Kubernetes (et dérivés) ConfigMaps

  1. 1 image pour votre appli
  2. Des objets "ConfigMap" pour stocker vos valeurs d'environnement
    • Les ConfigMap sont stockés au niveau cluster Kubernetes
    • Peuvent-être utilisés pour
      • Peupler des vars d'env
      • Enrichir les "commandes" des containers
      • Peupler des fichiers

Démo

Solution #5

Gestion de la configuration

Avant de présenter la config au container

Nous avons besoin :

  • De tracer son historique
  • De pouvoir s'appuyer sur des modèles pour la partager plus facilement entre les environnements
  • RBAC / Gestion des droits
  • De pouvoir partager des éléments de config
    • Entre les environnements
    • Entre les applications

Gestion de la configuration

Proposition

  • Git pour la gestion de l'historique et des droits
  • Confd pour les modèles
  • Une structure de répertoires hierarchisée pour le partage d'éléments

Note : Un dépôt git peut contenir la configuration d'une ou plusieurs applications

Confd ?

confd-data-container-generator

Workflow

Confd avec la source de valeurs "env"

Les utilisateurs collaborent sur la configuration par le biais de git et de la structure hiérarchisée


├── data
│   ├── dev-local (rep)
│   ├── acc-1 (rep)
│   ├── prod (rep)
│   └── common (rep)
└── dictionaries
    ├── dev-local (rep)
    ├── acc-1 (rep)
    ├── prod (rep)
    └── common.dict (fic)
					

Workflow

Confd avec la source de valeurs "env"

Les tags Git permettent de figer
une "version pour un env"

  • v0.2.3_dev-local
  • v0.2.4_acc-1
  • v0.2.4_dev-local
  • v0.2.4_prod
  • v0.2.5_acc-1

Workflow

Confd avec la source de valeurs "env"

Les images des apps embarquent les modèles de fichier


└── src
    ├── main
    │   ├── confd
    │   │   ├── conf.d
    │   │   └── templates
    │   ├── java
    │   │   └── net
    │   ├── resources
    │   └── scripts
    └── test
        └── java
            └── net
					

Workflow

Exemple de template


filter:
  sanitize:
    url: /api/v1/filter/sanitize
guestbook:
  messages:
    url: /api/v1/guestbook/messages
info:
  custom:
    env: {{ getv "/guestbook/shared/info/custom/env" }}
    message: {{ getv "/guestbook/filter/info/custom/message" }}
					

Workflow

Confd avec la source de valeurs "env"

Les images de configuration embarquent les fichiers bruts et les valeurs pour les modèles sous la forme de vars d'environnement


└── config
    ├── dictionnaries
    │   └── env.sh
    └── data
        ├── dummy.txt
        └── filterDefinition.properties
					

Workflow

Confd avec la source de valeurs "env"

Containers d’application :

  • Démarrés avec les volumes des containers de config
  • Lancement d’un wrapper qui :
    • Génère la config en assemblant :
      • Les modèles présent dans le container d'appli
      • Les valeurs présentes dans le container de configuration
    • Démarre l'appli qui utilise la config générée et les fichiers bruts

Démo

Croisons les doigts

Remarques

Coupure introspection

  • Compatible avec
    • Solution#3/data-containers
    • Solution#5/Solution orchestrateur
  • Ça marche aussi avec des applications qui ne sont pas dans des containers !!!

Opportunités

Étapes suivantes pour confd-data-container-generator

  • Proposer de prendre en compte les sources Consul et Etcd
    • La version de la configuration sera intégrée dans la définition du namespace côté consul et etcd
/config/dict/prod/v1.3.1/guestbook/...

Opportunités

Étapes suivantes

  • Plus d'outils
    • Diff entre environnements ( dépôt, démo)
    • Comparer une clé+valeur sur tous les environnements (idem)
    • Lister les clés inutilisées dans les dict
    • Appli Web facilitant la contribution à la configuration d'utilisateurs moins techniques
  • (Bientôt sur nodevops)

Liens

Servez-vous

Merci

Des questions ?