it-swarm.com.de

Kubernetes-Äquivalent einer env-Datei in Docker

Hintergrund:

Derzeit verwenden wir Docker und Docker Compose für unsere Dienste. Wir haben die Konfiguration für verschiedene Umgebungen in Dateien ausgelagert, die Umgebungsvariablen definieren, die von der Anwendung gelesen werden. Zum Beispiel eine prod.env-Datei:

ENV_VAR_ONE=Something Prod
ENV_VAR_TWO=Something else Prod

und eine test.env-Datei:

ENV_VAR_ONE=Something Test
ENV_VAR_TWO=Something else Test

Daher können wir beim Starten des Containers einfach die Datei prod.env oder test.env verwenden:

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

Unsere Anwendung nimmt dann ihre Konfiguration basierend auf den in prod.env definierten Umgebungsvariablen auf. 

Fragen:

  1. Gibt es eine Möglichkeit, Umgebungsvariablen aus einer Datei in Kubernetes bereitzustellen (z. B. beim Definieren eines Pods), anstatt sie wie folgt zu kodieren:
 apiVersion: v1 
 Art: Pod 
 Metadaten: 
 Etiketten: 
 Kontext: docker-k8s-lab 
 Name: mysql-pod 
 name: mysql-pod 
 spec: 
 Behälter: 
 - 
 env: 
 - 
 Name: MYSQL_USER 
 Wert: Mysql 
 - 
 Name: MYSQL_PASSWORD 
 Wert: Mysql 
 - 
 Name: MYSQL_DATABASE 
 Wert: Beispiel 
 - 
 Name: MYSQL_ROOT_PASSWORD 
 Wert: Supersecret 
 Bild: "mysql: latest" 
 Name: Mysql 
 Häfen: 
 - 
 containerPort: 3306 
  1. Wenn dies nicht möglich ist, wie lautet der vorgeschlagene Ansatz?
50
Johan

Sie können die Umgebungsvariablen eines Containers mithilfe von Secrets oder ConfigMaps auffüllen. Verwenden Sie Secrets, wenn Ihre Daten vertraulich sind (z. B. Kennwörter), und ConfigMaps, wenn dies nicht der Fall ist.

Geben Sie in Ihrer Pod-Definition an, dass der Container Werte aus einem Secret abrufen soll:

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

Beachten Sie, dass diese Syntax nur in Kubernetes 1.6 oder höher verfügbar ist. Bei einer früheren Version von Kubernetes müssen Sie jeden Wert manuell angeben, z. B .:

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

Und für jeden Wert wiederholen.

Unabhängig davon, welchen Ansatz Sie verwenden, können Sie jetzt zwei verschiedene Secrets definieren, eines für die Produktion und eines für die Entwicklung.

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

Stellen Sie das richtige Geheimnis für den richtigen Kubernetes-Cluster bereit:

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

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

Beim Starten eines Pods werden nun seine Umgebungsvariablen aus den im Secret angegebenen Werten aufgefüllt.

70
Pixel Elephant

Ein neues Update für Kubernetes (v1.6) ermöglicht, was Sie (vor Jahren) gefordert haben.

Sie können nun die Variable envFrom in Ihrer yaml-Datei verwenden:

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

Wo Entwicklungsgeheimnisse Ihr Geheimnis sind, können Sie es erstellen durch:

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

Wenn der Inhalt der TXT-Datei ein Schlüsselwert ist:

DB_USER=username_here
DB_PASSWORD=password_here

Die Dokumente sind immer noch See von Beispielen, ich musste an diesen Orten wirklich hart suchen:

11
Or Duan

Bei der Definition eines Pods für Kubernetes mithilfe einer YAML-Datei gibt es keine direkte Möglichkeit, eine andere Datei mit Umgebungsvariablen für einen Container anzugeben. Das Kubernetes-Projekt sagt, dass sie diesen Bereich in Zukunft verbessern werden (siehe Kubernetes docs ).

In der Zwischenzeit schlage ich vor, ein Provisioning-Tool zu verwenden und das Pod YAML zu einer Vorlage zu machen. Wenn Sie Ansible verwenden, sieht Ihre Pod-YAML-Datei beispielsweise so aus:

datei my-pod.yaml.template:

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

Dann kann Ihr Ansible-Spielbuch die Variable mysql_root_password an einem geeigneten Ort angeben und beim Erstellen der Ressource ersetzen. Beispiel:

datei 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

datei my-env-vars-prod.yaml:

mysql_root_password: supersecret

datei my-env-vars-test.yaml:

mysql_root_password: notsosecret

Jetzt erstellen Sie die Pod-Ressource, indem Sie beispielsweise Folgendes ausführen:

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

Dieser Kommentar zeigt, wie dies gemacht werden muss, ohne dass kubernetes config aktualisiert werden muss, wenn sich die Liste der Umgebungsvariablen ändert.

Im Wesentlichen: 1) Machen Sie ein Geheimnis mit env.sh 2) Ordnen Sie Secret als Volume Geheime Container zu.

0
Michael Cole

Das funktioniert für mich:

datei env-secret.yaml

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

und in den deployment.yaml oder pod.yaml

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