Tło:
Obecnie w naszych usługach używamy Docker i Docker Compose. Udostępniliśmy konfigurację dla różnych środowisk do plików definiujących zmienne środowiskowe odczytywane przez aplikację. Na przykład prod.env
plik:
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
W ten sposób możemy po prostu użyć pliku prod.env
or test.env
podczas uruchamiania kontenera:
docker run --env-file prod.env <image>
Nasza aplikacja następnie wybiera swoją konfigurację na podstawie zmiennych środowiskowych zdefiniowanych w prod.env
.
Pytania:
- Czy istnieje sposób na zapewnienie zmiennych środowiskowych z pliku w Kubernetes (na przykład podczas definiowania poda) zamiast ich zakodowania na sztywno w następujący sposób:
apiVersion: v1 rodzaj: Pod metadane: etykiety: kontekst: docker-k8s-lab nazwa: mysql-pod nazwa: mysql-pod specyfikacja: pojemniki: - env: - nazwa: MYSQL_USER wartość: mysql - nazwa: MYSQL_PASSWORD wartość: mysql - nazwa: MYSQL_DATABASE wartość: próbka - nazwa: MYSQL_ROOT_PASSWORD wartość: supersecret image: "mysql: najnowsze" nazwa: mysql porty: - kontenerPort: 3306
- Jeśli nie jest to możliwe, jakie jest sugerowane podejście?
Secret
lub,ConfigMap
ponieważ jest to tylko tymczasowe i używane do testowania. Mam ograniczone uprawnienia w klastrze k8s. Być może uda mi się utworzyćSecret
zasób, ale nie będę mógł ich usunąć, gdy zostanie już utworzony.Odpowiedzi:
Możesz wypełnić zmienne środowiskowe kontenera za pomocą obiektów Secrets lub ConfigMaps . Używaj Secrets, gdy dane, z którymi pracujesz, są wrażliwe (np. Hasła), oraz ConfigMaps, gdy nie są.
W definicji poda określ, że kontener powinien pobierać wartości z klucza tajnego:
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 będziesz musiał określić każdą wartość ręcznie, np .:
env: - name: MYSQL_USER valueFrom: secretKeyRef: name: mysql-secret key: MYSQL_USER
(Zauważ, że
env
weź tablicę jako wartość)I powtarzanie dla każdej wartości.
Niezależnie od zastosowanego podejścia, możesz teraz zdefiniować dwa różne sekrety, jeden dla produkcji, a drugi dla programistów.
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 wdróż poprawne hasło w odpowiednim klastrze Kubernetes:
kubectl config use-context dev kubectl create -f dev-secret.yaml kubectl config use-context prod kubectl create -f prod-secret.yaml
Teraz za każdym razem, gdy Pod zostanie uruchomiony, zapełni swoje zmienne środowiskowe z wartości określonych w sekrecie.
źródło
Nowa aktualizacja Kubernetes (v1.6) pozwala na to, o co prosiłeś (lata temu).
Możesz teraz użyć
envFrom
tego w swoim pliku yaml:containers: - name: django image: image/name envFrom: - secretRef: name: prod-secrets
Tam, gdzie tajemnice rozwoju są twoim sekretem, możesz je stworzyć przez:
kubectl create secret generic prod-secrets --from-env-file=prod/env.txt`
Gdzie zawartość pliku txt to para klucz-wartość:
DB_USER=username_here DB_PASSWORD=password_here
Dokumenty wciąż są jeziorami przykładów, w tych miejscach musiałem bardzo ciężko szukać:
envFrom
- oznacza, że ta opcja jest dostępna.ConfigMap
dokumentacja pokazuje przykład, jak go używać.źródło
--from-env-file
? Użycie--from-file
wyników w jednym kluczu (nazwanym tak jak plik wejściowy) z zawartością pliku. Użycie--from-env-file
rozszerza klucze wewnątrz pliku do sekretu. Więcej informacji znajdziesz w tej dokumentacji Google .Podczas definiowania pod dla Kubernetes przy użyciu pliku YAML nie ma bezpośredniego sposobu określenia innego pliku zawierającego zmienne środowiskowe dla kontenera. Projekt Kubernetes mówi, że poprawią ten obszar w przyszłości (zobacz dokumentację Kubernetes ).
W międzyczasie sugeruję użycie narzędzia do obsługi administracyjnej i uczynienie pod YAML szablonu. Na przykład, używając Ansible, twój plik pod YAML wyglądałby tak:
plik
my-pod.yaml.template
:apiVersion: v1 kind: Pod ... spec: containers: ... env: - name: MYSQL_ROOT_PASSWORD value: {{ mysql_root_pasword }} ...
Następnie Twój Playbook Ansible 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 utworzysz zasób pod, uruchamiając na przykład:
ansible-playbook -e deploy=test my-playbook.yaml
źródło
kubectl-run
do przekazania 20 zmiennych env? dlaczego więc nie zrobić 12factor łatwiej?To działa dla mnie:
plik
env-secret.yaml
apiVersion: v1 kind: Secret metadata: name: env-secret type: Opaque stringData: .env: |- APP_NAME=Laravel APP_ENV=local
i do
deployment.yaml
lubpod.yaml
spec: ... volumeMounts: - name: foo mountPath: "/var/www/html/.env" subPath: .env volumes: - name: foo secret: secretName: env-secret ````
źródło
To stare pytanie, ale ma wielu widzów, więc dodaję odpowiedź. Najlepszym sposobem na oddzielenie konfiguracji od implementacji K8s jest użycie Helm. Każdy pakiet Helm może mieć
values.yaml
plik i możemy łatwo użyć tych wartości na wykresie Helm. Jeśli mamy topologię wieloskładnikową, możemy utworzyć pakiet parasolowy Helm, a pakiet wartości nadrzędnych może również nadpisać pliki wartości potomnych.źródło
To stare pytanie, ale pozwól, że opiszę moją odpowiedź dla przyszłych początkujących.
Możesz użyć kustomize configMapGenerator.
configMapGenerator: - name: example env: dev.env
i odnieś ten configMap / przykład w definicji poda
źródło