Какая связь между развертыванием и ConfigMap? - PullRequest
2 голосов
/ 06 марта 2019

Мне интересно, как ConfigMap и Deployment работают в kubernetes.

Я хотел использовать значения в ConfigMap в качестве аргументов для моих модулей развертывания. Я пробовал это с разными изображениями и обнаружил разное поведение при передаче значения ConfigMap в качестве аргументов команды между контейнерами, которые используют sh в качестве точки входа, и другими командами в качестве точки входа.

Вот пример конфигурации, чтобы лучше проиллюстрировать мой случай:

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-envs
data:
  key: "value"
  BUCKET_NAME: "gs://bucket-name/"
  OUTPUT_PATH: "/data"

deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
spec:
  template:
    containers:
    - name: firstContainer
      image: busybox
      command: ["sh"]
      args: 
      - c
      - |
        echo $key
        echo ${BUCKET_NAME}
        echo $(OUTPUT_PATH)
      envFrom:
      - configMapRef:
          name: app-envs
    - name: secondContainer
      image: someImage
      args: [ "cmd", "${BUCKET_NAME}", "${OUTPUT_DATA}", "${key}" ] 
      envFrom:
      - configMapRef:
          name: app-envs
    - name: thirdContainer
      image: someImage
      args: [ "cmd", "$(BUCKET_NAME)", "$(OUTPUT_DATA)", "$(key)" ] 
      envFrom:
      - configMapRef:
          name: app-envs

someImage - это изображение докера, в котором в качестве точки входа используется определенный сценарий bash, который печатает значения среды.


firstContainer и thirdContainer способны правильно печатать все значения ConfigMap, то есть все value, gs://bucket-name/ и /data принимаются в качестве входных аргументов.

Однако secondContainer не может правильно распечатать эти значения. Я попытался повторить полученные аргументы, и оказалось, что он получает:

${BUCKET_NAME}, ${OUTPUT_DATA} и ${key} буквально в качестве ввода аргументы вместо фактических значений из ConfigMaps.

Итак, после наблюдения вышеуказанного поведения, вот мои вопросы:

  1. Какая связь между развертыванием и ConfigMap? Есть какой-то порядок, который определяет, как создаются ресурсы в модуле / развертывании k8s (например, загружается ли сначала ConfigMap, затем volumeMounts, а затем контейнер или какой-либо вид заказов)?

  2. В чем разница между ${} и $()? Почему значения ConfigMap принимаются в виде буквенных строк при использовании ${} для контейнера с точкой входа, отличной от bash или sh?

Спасибо. Буду признателен за вашу помощь.

1 Ответ

2 голосов
/ 06 марта 2019

Кубернетес понимает только прямые ссылки на переменные окружения в скобках $(VAR); см., например, примечание в Определение команды и аргументов для контейнера .

args: [ "cmd", "$(BUCKET_NAME)", "$(OUTPUT_DATA)", "$(key)" ] 

Сам Kubernetes знает, что такое переменные среды, и выполняет подстановку, поэтому контейнер запускается как cmd gs://bucket-name/ /data key.

command: ["sh"]
args: 
- c
- |
  echo $key
  echo ${BUCKET_NAME}
  echo $(OUTPUT_PATH)

Kubernetes расширяет $(OUTPUT_PATH), но не понимает никакой другой формы скобок, поэтому другие строки отправляются как есть. Поскольку вы явно запускаете это через оболочку, то и $key, и ${BUCKET_NAME} являются стандартными расширениями переменных оболочки, поэтому оболочка расширяет эти значения.

args: [ "cmd", "${BUCKET_NAME}", "${OUTPUT_DATA}", "${key}" ] 

Кубернетес не раскрывает вещи в фигурных скобках, и нет оболочки или чего-либо еще, чтобы расширять эти переменные, поэтому строки переменных (а не их содержимое) передаются как есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...