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:
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
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.
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:
envFrom
- indique que cette option est disponible.ConfigMap
docs montre un exemple d'utilisation.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
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.
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
````