Задний план:
В настоящее время мы используем Docker и Docker Compose для наших сервисов. Мы перенесли конфигурацию для различных сред в файлы, которые определяют переменные среды, считываемые приложением. Например prod.env
файл:
ENV_VAR_ONE=Something Prod
ENV_VAR_TWO=Something else Prod
и test.env
файл:
ENV_VAR_ONE=Something Test
ENV_VAR_TWO=Something else Test
Таким образом, мы можем просто использовать файл prod.env
или test.env
при запуске контейнера:
docker run --env-file prod.env <image>
Затем наше приложение подбирает свою конфигурацию на основе переменных среды, определенных в prod.env
.
Вопросов:
- Есть ли способ предоставить переменные среды из файла в Kubernetes (например, при определении пода) вместо их жесткого кодирования следующим образом:
apiVersion: v1 вид: Стручок метаданные: ярлыки: контекст: docker-k8s-lab имя: mysql-pod имя: mysql-pod спецификации: контейнеры: - env: - имя: MYSQL_USER значение: mysql - имя: MYSQL_PASSWORD значение: mysql - имя: MYSQL_DATABASE значение: образец - имя: MYSQL_ROOT_PASSWORD значение: supersecret изображение: "mysql: latest" имя: mysql порты: - containerPort: 3306
- Если это невозможно, каков предлагаемый подход?
Secret
или,ConfigMap
потому что это временно и используется для тестирования. У меня ограниченные права доступа в кластере k8s. Возможно, я смогу создатьSecret
ресурс, но я не смогу удалить его, когда он уже будет создан.Ответы:
Вы можете заполнить переменные среды контейнера с помощью Secrets или ConfigMaps . Используйте секреты, если данные, с которыми вы работаете, являются конфиденциальными (например, пароли), и ConfigMaps, когда это не так.
В определении вашего Pod укажите, что контейнер должен извлекать значения из секрета:
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
Обратите внимание, что этот синтаксис доступен только в Kubernetes 1.6 или новее. В более ранней версии Kubernetes вам нужно будет указать каждое значение вручную, например:
env: - name: MYSQL_USER valueFrom: secretKeyRef: name: mysql-secret key: MYSQL_USER
(Обратите внимание, что
env
в качестве значения принимайте массив)И повторение для каждого значения.
Какой бы подход вы ни использовали, теперь вы можете определить два разных секрета: один для продакшена и один для разработчиков.
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
И разверните правильный секрет в правильном кластере Kubernetes:
kubectl config use-context dev kubectl create -f dev-secret.yaml kubectl config use-context prod kubectl create -f prod-secret.yaml
Теперь всякий раз, когда Pod запускается, он заполняет свои переменные среды значениями, указанными в Secret.
источник
Новое обновление для Kubernetes (v1.6) позволяет то, о чем вы просили (много лет назад).
Теперь вы можете использовать
envFrom
это в своем файле yaml:containers: - name: django image: image/name envFrom: - secretRef: name: prod-secrets
Если секреты разработки - это ваш секрет, вы можете создать его:
kubectl create secret generic prod-secrets --from-env-file=prod/env.txt`
Где содержимое файла txt - это пара "ключ-значение":
DB_USER=username_here DB_PASSWORD=password_here
Документы по-прежнему представляют собой горы примеров, мне пришлось очень много искать в этих местах:
envFrom
- показывает, что эта опция доступна.ConfigMap
документах показан пример того, как его использовать.источник
--from-env-file
? Использование--from-file
приводит к одному ключу (названному в честь входного файла) с содержимым файла. Использование--from-env-file
расширяет ключи внутри файла в секрет. См. Эту документацию Google для получения дополнительной информации.При определении пода для Kubernetes с помощью файла YAML нет прямого способа указать другой файл, содержащий переменные среды для контейнера. В проекте Kubernetes говорится, что они улучшат эту область в будущем (см. Документы Kubernetes ).
А пока я предлагаю использовать инструмент подготовки и сделать модуль YAML шаблоном. Например, при использовании Ansible ваш YAML-файл пода будет выглядеть так:
файл
my-pod.yaml.template
:apiVersion: v1 kind: Pod ... spec: containers: ... env: - name: MYSQL_ROOT_PASSWORD value: {{ mysql_root_pasword }} ...
Затем в вашем сценарии Ansible можно указать переменную в
mysql_root_password
удобном месте и заменить ее при создании ресурса, например:файл
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
файл
my-env-vars-prod.yaml
:mysql_root_password: supersecret
файл
my-env-vars-test.yaml
:mysql_root_password: notsosecret
Теперь вы создаете ресурс модуля, запустив, например:
ansible-playbook -e deploy=test my-playbook.yaml
источник
kubectl-run
для передачи 20 переменных env ??? почему тогда не сделать 12factor проще ??Это работает для меня:
файл
env-secret.yaml
apiVersion: v1 kind: Secret metadata: name: env-secret type: Opaque stringData: .env: |- APP_NAME=Laravel APP_ENV=local
и в
deployment.yaml
илиpod.yaml
spec: ... volumeMounts: - name: foo mountPath: "/var/www/html/.env" subPath: .env volumes: - name: foo secret: secretName: env-secret ````
источник
Это старый вопрос, но у него много зрителей, поэтому я добавляю свой ответ. Лучший способ отделить конфигурацию от реализации K8s - использовать Helm. Каждый пакет Helm может иметь
values.yaml
файл, и мы можем легко использовать эти значения в диаграмме Helm. Если у нас есть многокомпонентная топология, мы можем создать зонтичный пакет Helm, а пакет родительских значений также может перезаписать дочерние файлы значений.источник
Это старый вопрос, но позвольте мне описать свой ответ для будущего новичка.
Вы можете настроить configMapGenerator.
configMapGenerator: - name: example env: dev.env
и ссылайтесь на этот configMap / example в определении пода
источник
Я уже 2 часа разбивал себе голову по этому поводу. Я нашел в документации очень простое решение, чтобы минимизировать мою (и, надеюсь, вашу) боль.
Держите
env.prod
,env.dev
как у вас есть.Используйте сценарий oneliner, чтобы импортировать их в yaml:
kubectl create configmap my-dev-config --from-env-file=env.dev
kubectl create configmap my-prod-config --from-env-file=env.prod
Вы можете увидеть результат (для мгновенного удовлетворения):
# You can also save this to disk kubectl get configmap my-dev-config -o yaml
Как Rubyist, я лично считаю это решение DRYest, так как у вас есть одна точка для обслуживания (файл ENV bash, который совместим с библиотеками Python / Ruby, ..), а затем вы YAMLize его за одно выполнение.
Обратите внимание, что вам нужно содержать файл ENV в чистоте (у меня есть много комментариев, которые мешали этому сработать, поэтому пришлось добавить
cat config.original | egrep -v "^#" | tee config.cleaned
), но это не меняет существенно сложность.Все это задокументировано здесь
источник