Uso de variables de entorno en la especificación de implementación de Kubernetes

18

Actualmente uso una especificación de Kubernetes Deployment.yamlpara implementar un servicio. La especificación incluye una referencia literal a una dirección IP específica (marcada como se <static-ip-address>muestra a continuación):

spec:
  type: LoadBalancer
  loadBalancerIP: <static-ip-address>

Me preocupa insertar información como contraseñas o direcciones IP en repositorios remotos de Git. ¿Puedo evitar esto, por ejemplo, haciendo uso de variables de entorno, por ejemplo, con una especificación de implementación y una implementación real aproximadamente de la siguiente manera:

spec:
   type: LoadBalancer
   loadBalancerIP: ${SERVICE_ADDRESS}

y

export SERVICE_ADDRESS=<static-ip-address>
kubectl create -f Deployment.yaml

Obviamente, esta sintaxis específica aún no funciona. ¿Pero es posible algo así y, si es así, cómo?

Prefiero no confiar en una herramienta de aprovisionamiento separada . Los secretos s ConfigMapparecen prometedores, pero aparentemente no se pueden consumir de una manera que se adapte a este propósito. Si pudiera hacer referencia directa a una dirección IP estática que se definió con gcloud compute addresses create service-addresseso sería lo mejor.

Drux
fuente

Respuestas:

27

Una solución mucho más fácil / limpia: envsubst

En deploy.yml:

LoadbalancerIP: $LBIP

Luego, simplemente cree su env var y ejecute kubectl de esta manera:

export LBIP="1.2.3.4"
envsubst < deploy.yml | kubectl apply -f -

Simplemente coloca variables Bash regulares en el archivo que quieras usar, en este caso el manifiesto YAML, y luego has leído ese archivo. Producirá el archivo con las variables de entorno reemplazadas por sus valores. También puede usarlo para crear nuevos archivos como este:

envsubst < input.yml > output.yml

envsubstestá disponible en, por ejemplo, el gettextpaquete Ubuntu / Debian .

Jan Grewe
fuente
2
+1 para envsubst. no sabía sobre esto hasta ahora
user1129682
1
No es más fácil / más limpio, ya que requiere una herramienta separada, que no está instalada por defecto en todos los sistemas (por ejemplo, Mac)
Ivan
@Ivan Su pregunta fue "¿Pero es posible algo así y, de ser así, cómo?", Y esa es la respuesta a su pregunta. La pregunta no era "¿Cómo puedo hacer esto con las herramientas disponibles en cada sistema operativo de forma predeterminada?". Y sí, es 1) más fácil Y 2) más limpio que usar sed. Según su definición, la solución propuesta con sedtampoco sería más fácil / limpia, ya que no está sedinstalada en las máquinas con Windows de forma predeterminada.
Jan Grewe
No está claro en absoluto que estuvieras comparando con la opción "sed".
Ivan
2

No había otra solución gratamente simple: Tengo una dirección de Google Compute my-addressdefinido, y al parecer lo puedo usar en la especificación del servicio, así: loadBalancerIP: my-address.

Con esto como fuente "externa" para direcciones IP y secretos para contraseñas, ya no hay necesidad de una herramienta de aprovisionamiento (o plantillas) para mi caso de uso simple (dentro de un entorno GKE).

OBSOLETO AHORA:sed Después de todo, he decidido usar una especie de herramienta de aprovisionamiento, a saber, "incorporada" .

Mi Deployment.yamlahora contiene una "variable de plantilla", por ejemplo, en

loadBalancerIP: $$EXTERNAL_IP

y despliegue el servicio con, digamos, 1.2.3.4 como dirección IP externa con

cat Deployment.yaml | sed s/\$\$EXTERNAL_IP/1.2.3.4/ | kubectl create -f -
Drux
fuente
1
El enfoque de Jan Grewe es más genérico y puede aplicarse a cualquier número de variables. Sugeriría aceptar su respuesta en lugar de aceptar la suya que es menos genérica y debe ajustarse para cada variable adicional.
TekTimmy
0

Puede escribir un preprocesador simple para realizar una sustitución de variables en sus archivos yaml (o puede usar jsonnet para lograr lo mismo en los archivos de configuración json).

Existe cierta discusión sobre agregar plantillas directamente a la configuración de Kubernetes, pero aún no está implementado o disponible.

Robert Bailey
fuente
Sí, pero jsonnet es una herramienta de suministro como se menciona en la pregunta.
Drux
1
Si está buscando algo integrado, entonces seguir el problema al que me vinculé es su mejor opción en este momento.
Robert Bailey
0

Hasta que las plantillas estén disponibles, la forma más fácil de hacerlo es ejecutar un trabajo que use la API de Kubernetes para actualizar el servicio. Un script de shell corto en una imagen basada en alpino, junto con un secreto (que contiene la dirección IP) y un mapa de configuración (que contiene la plantilla), debería ser lo suficientemente simple. La parte difícil es usar correctamente las funciones de autenticación y autorización del apiserver.

/programming/30690186/how-do-i-access-the-kubernetes-api-from-within-a-pod-container da un ejemplo de acceso a la API. Obviamente, querrás PUBLICAR en / api / v1 / namespaces / default / services en lugar de GET en ese ejemplo.

Aecolley
fuente
Suena interesante, pero ¿puedes explicar un poco más? ¿Podría dar o señalar un ejemplo de un script de shell adecuado?
Drux