Odpowiednik Kubernetes pliku env w Dockerze

Background:

Obecnie używamy Dockera i Docker Compose do naszych usług. Uzewnętrzniliśmy konfigurację dla różnych środowisk do plików definiujących zmienne środowiskowe odczytywane przez aplikację. Na przykład plik prod.env:

ENV_VAR_ONE=Something Prod
ENV_VAR_TWO=Something else Prod

I test.env plik:

ENV_VAR_ONE=Something Test
ENV_VAR_TWO=Something else Test

Możemy więc po prostu użyć pliku prod.env lub test.env podczas uruchamiania kontenera:

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

Nasza aplikacja następnie pobiera swoją konfigurację w oparciu o środowisko zmienne zdefiniowane w prod.env.

Pytania:

  1. czy istnieje sposób na dostarczenie zmiennych środowiskowych z pliku w Kubernetes (na przykład podczas definiowania pod) zamiast kodowania ich na twardo w następujący sposób:
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. jeśli nie jest to możliwe, Jakie jest sugerowane podejście?
Author: Johan, 2015-11-02

4 answers

Można wypełniać zmienne środowiskowe kontenera za pomocą Secrets lub ConfigMaps. Używaj tajemnic, gdy dane, z którymi pracujesz, są wrażliwe (np. hasła), a Configmapy, gdy nie są.

W definicji Pod określ, że kontener powinien pobierać wartości z tajemnicy:

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

Zauważ, że ta składnia jest dostępna tylko w Kubernetes 1.6 lub nowszym. We wcześniejszej wersji Kubernetes trzeba będzie ręcznie określić każdą wartość, np.:

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

I powtarzanie dla każdej wartości.

Niezależnie od tego, jakiego podejścia użyjesz, możesz teraz zdefiniować dwa różne sekrety, jeden dla produkcji i jeden dla dev.

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
I wdrożyć poprawny sekret do poprawnego klastra Kubernetes:
kubectl config use-context dev
kubectl create -f dev-secret.yaml

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

Teraz, gdy Pod się uruchomi, wypełni swoje zmienne środowiskowe z wartości określonych w sekrecie.

 60
Author: Pixel Elephant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-19 16:45:49

Podczas definiowania pod Dla Kubernetes za pomocą pliku YAML, nie ma bezpośredniego sposobu na określenie innego pliku zawierającego zmienne środowiskowe dla kontenera. Projekt Kubernetes mówi, że poprawi ten obszar w przyszłości(Zobacz Kubernetes docs ).

W międzyczasie proponuję użyć narzędzia aprowizacyjnego i zrobić z pod YAML szablon. Na przykład, używając Ansible Twój plik pod YAML będzie wyglądał następująco:

Plik my-pod.yaml.template:

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

Then your Ansible playbook może określić zmienną mysql_root_password w dogodnym miejscu i zastąpić ją podczas tworzenia zasobu, na przykład:

Plik 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

Plik my-env-vars-prod.yaml:

mysql_root_password: supersecret

Plik my-env-vars-test.yaml:

mysql_root_password: notsosecret

Teraz tworzysz zasób pod uruchamiając, na przykład:

ansible-playbook -e deploy=test my-playbook.yaml
 9
Author: Spencer Brown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-03 22:10:25

Nowa aktualizacja Kubernetes (v1.6) pozwala na to,o co prosiłeś (lata temu).

Możesz teraz użyć envFrom w ten sposób w swoim pliku yaml:

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

Gdzie development-secrets jest Twoim sekretem, możesz go utworzyć przez:

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

Gdzie zawartość pliku txt jest wartością klucza:

DB_USER=username_here
DB_PASSWORD=password_here

Docs to wciąż mnóstwo przykładów, musiałem szukać naprawdę ciężko w tych miejscach:

 8
Author: Or Duan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-05 09:57:08

Ten komentarz pokazuje, jak to zrobić bez konieczności aktualizacji kubernetes config, gdy zmieni się lista zmiennych środowiskowych.

Zasadniczo: 1) Make a secret with env.sh 2) Mapuj sekret do pojemnika jako objętość 3) uruchamia się skrypt startowy kontenera env.sh następnie app.

 0
Author: Michael Cole,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-20 18:57:47