Antecedentes:
Actualmente usamos Docker y Docker Compose para nuestros servicios. Hemos externalizado la configuración para diferentes entornos en archivos que definen las variables de entorno leídas por la aplicación. Por ejemplo, un prod.env
archivo:
ENV_VAR_ONE=Something Prod
ENV_VAR_TWO=Something else Prod
y un test.env
archivo:
ENV_VAR_ONE=Something Test
ENV_VAR_TWO=Something else Test
Por lo tanto, podemos simplemente usar el archivo prod.env
o test.env
al iniciar el contenedor:
docker run --env-file prod.env <image>
Luego, nuestra aplicación toma su configuración en función de las variables de entorno definidas en prod.env
.
Preguntas:
- ¿Hay alguna forma de proporcionar variables de entorno desde un archivo en Kubernetes (por ejemplo, al definir un pod) en lugar de codificarlas de esta manera?
apiVersion: v1 tipo: Pod metadatos: etiquetas: contexto: docker-k8s-lab nombre: mysql-pod nombre: mysql-pod Especificaciones: contenedores: - env: - nombre: MYSQL_USER valor: mysql - nombre: MYSQL_PASSWORD valor: mysql - nombre: MYSQL_DATABASE valor: muestra - nombre: MYSQL_ROOT_PASSWORD valor: supersecreto imagen: "mysql: último" nombre: mysql puertos: - containerPort: 3306
- Si esto no es posible, ¿cuál es el enfoque sugerido?
Secret
oConfigMap
porque esto es solo temporal y se usa para pruebas. Tengo permisos limitados en el clúster k8s. Tal vez pueda crear unSecret
recurso, pero no podré eliminarlo una vez que ya esté creado.Respuestas:
Puede completar las variables de entorno de un contenedor mediante el uso de Secrets o ConfigMaps . Use Secrets cuando los datos con los que está trabajando sean confidenciales (por ejemplo, contraseñas) y ConfigMaps cuando no lo sea.
En la definición de tu pod, especifica que el contenedor debe extraer valores de un secreto:
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
Tenga en cuenta que esta sintaxis solo está disponible en Kubernetes 1.6 o posterior. En una versión anterior de Kubernetes, deberá especificar cada valor manualmente, por ejemplo:
env: - name: MYSQL_USER valueFrom: secretKeyRef: name: mysql-secret key: MYSQL_USER
(Tenga en cuenta que
env
tome una matriz como valor)Y repitiendo por cada valor.
Independientemente del enfoque que utilice, ahora puede definir dos secretos diferentes, uno para producción y otro para desarrollo.
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 implemente el secreto correcto en el clúster de Kubernetes correcto:
kubectl config use-context dev kubectl create -f dev-secret.yaml kubectl config use-context prod kubectl create -f prod-secret.yaml
Ahora, cada vez que se inicia un Pod, completará sus variables de entorno a partir de los valores especificados en el secreto.
fuente
Una nueva actualización para Kubernetes (v1.6) permite lo que solicitó (hace años).
Ahora puede usar algo
envFrom
así en su archivo yaml:containers: - name: django image: image/name envFrom: - secretRef: name: prod-secrets
Donde los secretos de desarrollo son su secreto, puede crearlo de la siguiente manera:
kubectl create secret generic prod-secrets --from-env-file=prod/env.txt`
Donde el contenido del archivo txt es un valor-clave:
DB_USER=username_here DB_PASSWORD=password_here
Los documentos siguen siendo lagos de ejemplos, tuve que buscar muy duro en esos lugares:
envFrom
: muestra que esta opción está disponible.ConfigMap
documentos equivalentes muestran un ejemplo sobre cómo usarlo.fuente
--from-env-file
? El uso de--from-file
resultados en una clave (que lleva el nombre del archivo de entrada) con el contenido del archivo. El uso--from-env-file
expande las claves dentro del archivo en el secreto. Consulte esta documentación de Google para obtener más información.Al definir un pod para Kubernetes mediante un archivo YAML, no hay una forma directa de especificar un archivo diferente que contenga variables de entorno para un contenedor. El proyecto Kubernetes dice que mejorarán esta área en el futuro (consulte los documentos de Kubernetes ).
Mientras tanto, sugiero usar una herramienta de aprovisionamiento y hacer del pod YAML una plantilla. Por ejemplo, al usar Ansible, su archivo YAML de pod se vería así:
archivo
my-pod.yaml.template
:apiVersion: v1 kind: Pod ... spec: containers: ... env: - name: MYSQL_ROOT_PASSWORD value: {{ mysql_root_pasword }} ...
Luego, su libro de jugadas de Ansible puede especificar la variable en
mysql_root_password
algún lugar conveniente y sustituirla al crear el recurso, por ejemplo:archivo
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
archivo
my-env-vars-prod.yaml
:mysql_root_password: supersecret
archivo
my-env-vars-test.yaml
:mysql_root_password: notsosecret
Ahora crea el recurso de pod ejecutando, por ejemplo:
ansible-playbook -e deploy=test my-playbook.yaml
fuente
kubectl-run
para pasar 20 variables env? ¿Por qué entonces no hacer 12factor más fácil?Esto funciona para mi:
archivo
env-secret.yaml
apiVersion: v1 kind: Secret metadata: name: env-secret type: Opaque stringData: .env: |- APP_NAME=Laravel APP_ENV=local
y en el
deployment.yaml
opod.yaml
spec: ... volumeMounts: - name: foo mountPath: "/var/www/html/.env" subPath: .env volumes: - name: foo secret: secretName: env-secret ````
fuente
Esta es una pregunta antigua pero tiene muchos espectadores, así que agrego mi respuesta. La mejor forma de separar la configuración de la implementación de K8 es utilizando Helm. Cada paquete de Helm puede tener un
values.yaml
archivo y podemos usar fácilmente esos valores en el gráfico de Helm. Si tenemos una topología multicomponente, podemos crear un paquete Helm general y el paquete de valores padre también puede sobrescribir los archivos de valores secundarios.fuente
Esta es una pregunta antigua, pero permítanme describir mi respuesta para futuros principiantes.
Puede utilizar kustomize configMapGenerator.
configMapGenerator: - name: example env: dev.env
y consulte este configMap / example en la definición de pod
fuente