web-dev-qa-db-fra.com

Equivalent Kubernetes du fichier env dans Docker

Contexte:

Nous utilisons actuellement Docker et Docker Compose pour nos services. Nous avons externalisé la configuration de 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 <image>

Notre application sélectionne 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 de la manière suivante:
 apiVersion: v1 
 type: Pod 
 métadonnées: 
 Étiquettes: 
 contexte: docker-k8s-lab 
 nom: mysql-pod 
 nom: mysql-pod 
 spec: 
 conteneurs: 
 - 
 env: 
 - 
 nom: MYSQL_USER 
 valeur: mysql 
 - 
 nom: MYSQL_PASSWORD 
 valeur: mysql 
 - 
 nom: MYSQL_DATABASE 
 valeur: échantillon 
 - 
 nom: MYSQL_ROOT_PASSWORD 
 valeur: supersecret 
 image: "mysql: latest" 
 nom: mysql 
 ports: 
 - 
 containerPort: 3306 
  1. Si ce n'est pas possible, quelle est l'approche proposée?
50
Johan

Vous pouvez renseigner les variables d'environnement d'un conteneur en utilisant Secrets ou ConfigMaps . Utilisez Secrets lorsque les données que vous utilisez sont sensibles (par exemple, les mots de passe) et ConfigMaps dans le cas contraire.

Dans la définition de votre pod, spécifiez que le conteneur doit extraire les 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 n'est disponible que 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 en répétant pour chaque valeur.

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

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 approprié:

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 pod démarrera et renseignera ses variables d'environnement à partir des valeurs spécifiées dans le secret.

70
Pixel Elephant

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

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

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

Où secret-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 exemples, il a fallu que je fouille vraiment dans ces endroits:

11
Or Duan

Lors de la définition d'un pod pour Kubernetes à l'aide d'un fichier YAML, il n'existe aucun moyen direct de spécifier un autre fichier contenant des variables d'environnement pour un conteneur. Le projet Kubernetes prévoit d'améliorer ce domaine à l'avenir (voir Documents Kubernetes ).

En attendant, je suggère d'utiliser un outil de provisioning et de transformer le pod YAML en modèle. Par exemple, en utilisant Ansible, le fichier YAML de votre pod ressemble à ceci:

fichier my-pod.yaml.template:

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

Ensuite, votre manuel Ansible peut spécifier la variable mysql_root_password à un endroit pratique, et la 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

Maintenant, vous créez la ressource pod en exécutant, par exemple:

ansible-playbook -e deploy=test my-playbook.yaml
10
Spencer Brown

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

Essentiellement: 1) Créez un secret avec env.sh 2) Mappez le secret dans un conteneur en tant que volume 3) Le script de démarrage du conteneur exécute env.sh, puis app.

0
Michael Cole

Cela fonctionne pour moi:

fichier env-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: env-secret
type: Opaque
stringData:
  .env: |-
    APP_NAME=Laravel
    APP_ENV=local

et dans le deployment.yaml ou pod.yaml

spec:
  ...
        volumeMounts:
        - name: foo
          mountPath: "/var/www/html/.env"
          subPath: .env
      volumes:
      - name: foo
        secret:
          secretName: env-secret
````
0
madwyatt