Kubernetes équivalent du fichier env dans Docker

Contexte:

Actuellement, nous utilisons Docker et Docker Compose pour nos services. Nous avons externalisé la configuration pour différents environnements dans des fichiers définissant les variables d’environnement lues par l’application. Par exemple un fichier prod.env :

 ENV_VAR_ONE=Something Prod ENV_VAR_TWO=Something else Prod 

et un fichier test.env :

 ENV_VAR_ONE=Something Test ENV_VAR_TWO=Something else Test 

Ainsi, nous pouvons simplement utiliser le fichier prod.env ou test.env lors du démarrage du conteneur:

 docker run --env-file prod.env  

Notre application reprend ensuite sa configuration en fonction des variables d’environnement définies dans prod.env .

Des questions:

  1. Existe-t-il un moyen de fournir des variables d’environnement à partir d’un fichier dans Kubernetes (par exemple lors de la définition d’un pod) au lieu de les coder en dur comme ceci:
 apiVersion: v1
 genre: Pod
 métadonnées: 
   Étiquettes: 
     contexte: docker-k8s-lab
     nom: mysql-pod
   nom: mysql-pod
 spec: 
   conteneurs: 
     - 
       env: 
         - 
           nom: MYSQL_USER
           valeur: mysql
         - 
           name: MYSQL_PASSWORD
           valeur: mysql
         - 
           name: MYSQL_DATABASE
           valeur: échantillon
         - 
           name: MYSQL_ROOT_PASSWORD
           valeur: supersecret
       image: "mysql: latest"
       nom: mysql
       ports: 
         - 
           containerPort: 3306
  1. Si ce n’est pas possible, quelle est l’approche suggérée?

Vous pouvez renseigner les variables d’environnement d’un conteneur en utilisant Secrets ou ConfigMaps . Utilisez les secrets lorsque les données avec lesquelles vous travaillez sont sensibles (par exemple, les mots de passe) et ConfigMaps lorsque ce n’est pas le cas.

Dans votre définition de pod, spécifiez que le conteneur doit extraire des valeurs d’un secret:

 apiVersion: v1 kind: Pod metadata: labels: context: docker-k8s-lab name: mysql-pod name: mysql-pod spec: containers: - image: "mysql:latest" name: mysql ports: - containerPort: 3306 envFrom: secretRef: name: mysql-secret 

Notez que cette syntaxe est uniquement disponible dans Kubernetes 1.6 ou version ultérieure. Sur une version antérieure de Kubernetes, vous devrez spécifier chaque valeur manuellement, par exemple:

 env: - name: MYSQL_USER valueFrom: secretKeyRef: name: mysql-secret key: MYSQL_USER 

Et répéter pour chaque valeur.

Quelle que soit l’approche que vous utilisez, vous pouvez maintenant définir deux secrets différents, l’un pour la production et l’autre pour le développement.

dev-secret.yaml:

 apiVersion: v1 kind: Secret metadata: name: mysql-secret type: Opaque data: MYSQL_USER: bXlzcWwK MYSQL_PASSWORD: bXlzcWwK MYSQL_DATABASE: c2FtcGxlCg== MYSQL_ROOT_PASSWORD: c3VwZXJzZWNyZXQK 

prod-secret.yaml:

 apiVersion: v1 kind: Secret metadata: name: mysql-secret type: Opaque data: MYSQL_USER: am9obgo= MYSQL_PASSWORD: c2VjdXJlCg== MYSQL_DATABASE: cHJvZC1kYgo= MYSQL_ROOT_PASSWORD: cm9vdHkK 

Et déployez le secret correct sur le cluster Kubernetes correct:

 kubectl config use-context dev kubectl create -f dev-secret.yaml kubectl config use-context prod kubectl create -f prod-secret.yaml 

Désormais, à chaque démarrage d’un pod, ses variables d’environnement seront renseignées à partir des valeurs spécifiées dans le secret.

Lors de la définition d’un conteneur pour Kubernetes à l’aide d’un fichier YAML, il n’existe aucun moyen direct de spécifier un fichier différent contenant des variables d’environnement pour un conteneur. Le projet Kubernetes indique qu’il améliorera ce domaine à l’avenir (voir Kubernetes docs ).

En attendant, je suggère d’utiliser un outil d’approvisionnement et de faire du pod YAML un modèle. Par exemple, en utilisant Ansible, le fichier YAML de votre pod ressemblerait à ceci:

fichier my-pod.yaml.template :

 apiVersion: v1 kind: Pod ... spec: containers: ... env: - name: MYSQL_ROOT_PASSWORD value: {{ mysql_root_pasword }} ... 

Ensuite, votre playbook Ansible peut spécifier la variable mysql_root_password quelque part et le remplacer lors de la création de la ressource, par exemple:

fichier my-playbook.yaml :

 - hosts: my_hosts vars_files: - my-env-vars-{{ deploy_to }}.yaml tasks: - name: create pod YAML from template template: src=my-pod.yaml.template dst=my-pod.yaml - name: create pod in Kubernetes command: kubectl create -f my-pod.yaml 

fichier my-env-vars-prod.yaml :

 mysql_root_password: supersecret 

fichier my-env-vars-test.yaml :

 mysql_root_password: notsosecret 

Vous créez maintenant la ressource pod en exécutant, par exemple:

 ansible-playbook -e deploy=test my-playbook.yaml 

Une nouvelle mise à jour pour Kubernetes (v1.6) permet ce que vous avez demandé (il y a des années).

Vous pouvez maintenant utiliser envFrom comme ceci dans votre fichier yaml:

  containers: - name: django image: image/name envFrom: - secretRef: name: prod-secrets 

Si le secret du développement est votre secret, vous pouvez le créer en:

 kubectl create secret generic prod-secrets --from-file=prod/env.txt` 

Où le contenu du fichier txt est une valeur-clé:

 DB_USER=username_here DB_PASSWORD=password_here 

Les docs sont encore des lacs d’exemples, j’ai dû chercher très fort sur ces lieux:

  • Secrets docs , recherchez envFrom – indique que cette option est disponible.
  • Les documents ConfigMap équivalents montrent un exemple d’utilisation.

Ce commentaire montre comment faire sans avoir à mettre à jour la configuration de kubernetes lorsque la liste des variables d’environnement change.

Essentiellement: 1) Créer un secret avec env.sh 2) env.sh secret dans le conteneur au volume 3) Le script de démarrage du conteneur exécute env.sh puis l’application.