32

Background:kubernetes equivalente di ENV-file in Docker

Attualmente stiamo usando Docker Docker e Compose per i nostri servizi. Abbiamo esternalizzato la configurazione per diversi ambienti in file che definiscono le variabili di ambiente lette dall'applicazione. Per esempio un file prod.env:

ENV_VAR_ONE=Something Prod 
ENV_VAR_TWO=Something else Prod 

e un file test.env:

ENV_VAR_ONE=Something Test 
ENV_VAR_TWO=Something else Test 

Così si possono semplicemente utilizzare il file prod.env o test.env quando si avvia il contenitore:

docker run --env-file prod.env <image> 

La nostra applicazione poi riprende la sua configurazione in base alle variabili di ambiente definite in prod.env.

Domande:

  1. C'è un modo per fornire le variabili di ambiente da un file a kubernetes (ad esempio quando si definisce un baccello) invece di hardcoding in questo modo:
 
apiVersion: v1 
kind: Pod 
metadata: 
    labels: 
    context: docker-k8s-lab 
    name: mysql-pod 
    name: mysql-pod 
spec: 
    containers: 
    - 
     env: 
     - 
      name: MYSQL_USER 
      value: mysql 
     - 
      name: MYSQL_PASSWORD 
      value: mysql 
     - 
      name: MYSQL_DATABASE 
      value: sample 
     - 
      name: MYSQL_ROOT_PASSWORD 
      value: supersecret 
     image: "mysql:latest" 
     name: mysql 
     ports: 
     - 
      containerPort: 3306 
  1. Se ciò non è possibile, qual è l'approccio suggerito?

risposta

45

È possibile popolare le variabili di ambiente del contenitore attraverso l'uso di Secrets oppure ConfigMaps.Usa i segreti quando i dati con cui stai lavorando sono sensibili (ad es. Password) e ConfigMaps quando non lo sono.

nella definizione Pod specificare che il contenitore dovrebbe tirare i valori da un segreto:

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 

Si noti che questa sintassi è disponibile solo in kubernetes 1.6 o versioni successive. Su una versione precedente di kubernetes si dovrà specificare ogni valore manualmente, ad es .:

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

e ripetendo per ogni valore.

Qualsiasi approccio tu usi, ora puoi definire due diversi Secreti, uno per la produzione e uno per lo sviluppo.

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 

e distribuire il corretto segreto per il corretto kubernetes cluster:

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

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

Ora ogni volta un Pod inizia a popolare le sue variabili d'ambiente dai valori specificati nel Segreto.

+3

Questo è il mio approccio attuale, tuttavia ho 3 diversi pod che usano lo stesso elenco di segreti esposti come EnvVars. È possibile definirli una volta e esporli ai 3 pod? –

+1

Non che io sappia. –

+2

che sarebbe così bello ... sembra assegnare il boilerplate per ottenere i vv env in container. @PixelElephant – AndrewMcLagan

9

Quando si definisce un pod per Kubernetes utilizzando un file YAML, non esiste un modo diretto per specificare un file diverso contenente le variabili di ambiente per un contenitore. Il progetto Kubernetes dice che miglioreranno quest'area in futuro (vedi Kubernetes docs).

Nel frattempo, suggerisco di utilizzare uno strumento di provisioning e di rendere il pod YAML un modello. Ad esempio, utilizzando Ansible il file YAML pod sarà simile:

file di my-pod.yaml.template:

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

Allora il vostro playbook Ansible può specificare la variabile mysql_root_password un posto comodo, e sostituirlo durante la creazione della risorsa, ad esempio:

file di 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 

file di my-env-vars-prod.yaml:

mysql_root_password: supersecret 

file di my-env-vars-test.yaml:

Ora si crea la risorsa pod eseguendo, per esempio:

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

Idealmente dovresti essere in grado di definire un Segreto (o gli eventuali oggetti di configurazione che avremo) e averli iniettati come oggetti. Sfortunatamente quel lavoro non è ancora finito, quindi voterò per questo. –

+0

Si tratta di lavori in corso o sulla cartina stradale? – Johan

+0

Se utilizzi l'ansible, abbiamo un ruolo comune da implementare su kubernetes: https://github.com/ansibl8s/k8s-common. Quindi è molto facile preparare nuove applicazioni, vedere esempi su come usarlo in altri pronti contro termine: https://github.com/ansibl8s – ant31

0

This comment mostra come eseguire questa operazione senza dover aggiornare la configurazione di kubernetes quando l'elenco delle variabili di ambiente cambia.

In sostanza: 1) Fai un segreto con env.sh 2) Mappa segreto nel contenitore come il volume 3) script di avvio del contenitore viene eseguito env.sh poi app.

6

Un nuovo aggiornamento per Kubernetes (v1.6) consente ciò che hai chiesto (anni fa).

È ora possibile utilizzare la envFrom come questo nel file YAML:

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

dove lo sviluppo-segreti è il tuo segreto, lo si può creare da:

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

Dove il contenuto del file txt è un valore-chiave:

I documenti sono ancora laghi di esempi, I doveva cercare davvero difficile in quei luoghi:

+0

Puoi condividere la documentazione di Kubernetes su questo ? –

+0

@ArtemDolobanko Modificato, tenere presente che questo è ancora nuovo e laghi di documenti, è possibile trovare molte discussioni sul tracker di problemi di Github se si desidera maggiori dettagli. –

Problemi correlati