Понимание переменных окружения
Содержание
Overview
Переменные окружения в Kubernetes — это пары ключ-значение, которые предоставляют конфигурационные данные контейнерам во время выполнения. Они обеспечивают гибкий и безопасный способ внедрения конфигурационной информации, секретов и параметров выполнения в ваши приложения без необходимости изменять образы контейнеров или код приложения.
Core Concepts
Что такое переменные окружения?
Переменные окружения — это:
- пары ключ-значение, доступные процессам, работающим внутри контейнеров
- механизм конфигурации во время выполнения, не требующий пересборки образа
- стандартный способ передачи конфигурационных данных в приложения
- доступные через стандартные API операционной системы на любом языке программирования
Источники переменных окружения в Kubernetes
Kubernetes поддерживает несколько источников переменных окружения:
Тип источника | Описание | Сценарий использования |
---|
Статические значения | Прямые пары ключ-значение | Простая конфигурация |
ConfigMap | Ссылка на ключи ConfigMap | Неконфиденциальная конфигурация |
Secret | Ссылка на ключи Secret | Конфиденциальные данные (пароли, токены) |
Field Reference | Метаданные Pod/Container | Динамическая информация во время выполнения |
Resource Reference | Запросы/лимиты ресурсов | Конфигурация с учётом ресурсов |
Приоритет переменных окружения
Переменные окружения переопределяют конфигурацию в следующем порядке:
- Kubernetes env (наивысший приоритет)
- Ссылки на ConfigMaps/Secrets
- Инструкции ENV в Dockerfile
- Значения по умолчанию в приложении (наименьший приоритет)
Сценарии использования
1. Конфигурация приложения
Базовые настройки приложения:
apiVersion: v1
kind: Pod
spec:
containers:
- name: web-app
image: myapp:latest
env:
- name: PORT
value: "8080"
- name: LOG_LEVEL
value: "info"
- name: ENVIRONMENT
value: "production"
- name: MAX_CONNECTIONS
value: "100"
2. Конфигурация базы данных
Настройки подключения к базе данных с использованием ConfigMaps и Secrets:
apiVersion: v1
kind: ConfigMap
metadata:
name: db-config
data:
DB_HOST: "postgres.example.com"
DB_PORT: "5432"
DB_NAME: "myapp"
DB_POOL_SIZE: "10"
---
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
DB_USER: bXl1c2Vy # base64 encoded "myuser"
DB_PASSWORD: bXlwYXNzd29yZA== # base64 encoded "mypassword"
---
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
env:
# Из ConfigMap
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: db-config
key: DB_HOST
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: db-config
key: DB_PORT
- name: DB_NAME
valueFrom:
configMapKeyRef:
name: db-config
key: DB_NAME
# Из Secret
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-secret
key: DB_USER
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
3. Динамическая информация во время выполнения
Доступ к метаданным Pod и Node:
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
env:
# Информация о Pod
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
# Информация о ресурсах
- name: CPU_REQUEST
valueFrom:
resourceFieldRef:
resource: requests.cpu
- name: MEMORY_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
4. Конфигурация для разных сред
Различные конфигурации для разных сред:
# Среда разработки
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-dev
data:
DEBUG: "true"
LOG_LEVEL: "debug"
CACHE_TTL: "60"
RATE_LIMIT: "1000"
---
# Производственная среда
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-prod
data:
DEBUG: "false"
LOG_LEVEL: "warn"
CACHE_TTL: "3600"
RATE_LIMIT: "100"
---
# Деплой с использованием конфигурации для конкретной среды
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
spec:
containers:
- name: app
image: myapp:latest
envFrom:
- configMapRef:
name: app-config-prod # Для разработки заменить на app-config-dev
Примеры CLI и практическое использование
Использование kubectl run
# Установка переменных окружения напрямую
kubectl run myapp --image=nginx --env="PORT=8080" --env="DEBUG=true"
# Несколько переменных окружения
kubectl run webapp --image=myapp:latest \
--env="DATABASE_URL=postgresql://localhost:5432/mydb" \
--env="REDIS_URL=redis://localhost:6379" \
--env="LOG_LEVEL=info"
# Интерактивный pod с переменными окружения
kubectl run debug --image=ubuntu:20.04 -it --rm \
--env="TEST_VAR=hello" \
--env="ANOTHER_VAR=world" \
-- /bin/bash
Использование kubectl create
# Создание ConfigMap из литеральных значений
kubectl create configmap app-config \
--from-literal=DATABASE_HOST=postgres.example.com \
--from-literal=DATABASE_PORT=5432 \
--from-literal=CACHE_SIZE=256MB
# Создание ConfigMap из файла
echo "DEBUG=true" > app.env
echo "LOG_LEVEL=debug" >> app.env
kubectl create configmap app-env --from-env-file=app.env
# Создание Secret для конфиденциальных данных
kubectl create secret generic db-secret \
--from-literal=username=myuser \
--from-literal=password=mypassword
Сложные примеры переменных окружения
Микросервисы с обнаружением сервисов
apiVersion: v1
kind: ConfigMap
metadata:
name: service-config
data:
USER_SERVICE_URL: "http://user-service:8080"
ORDER_SERVICE_URL: "http://order-service:8080"
PAYMENT_SERVICE_URL: "http://payment-service:8080"
NOTIFICATION_SERVICE_URL: "http://notification-service:8080"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
spec:
template:
spec:
containers:
- name: gateway
image: api-gateway:latest
env:
- name: PORT
value: "8080"
- name: ENVIRONMENT
value: "production"
envFrom:
- configMapRef:
name: service-config
- secretRef:
name: api-keys
Pod с несколькими контейнерами и общей конфигурацией
apiVersion: v1
kind: Pod
metadata:
name: multi-container-app
spec:
containers:
# Основное приложение
- name: app
image: myapp:latest
env:
- name: ROLE
value: "primary"
- name: SHARED_SECRET
valueFrom:
secretKeyRef:
name: shared-secret
key: token
envFrom:
- configMapRef:
name: shared-config
# Sidecar контейнер
- name: sidecar
image: sidecar:latest
env:
- name: ROLE
value: "sidecar"
- name: MAIN_APP_URL
value: "http://localhost:8080"
- name: SHARED_SECRET
valueFrom:
secretKeyRef:
name: shared-secret
key: token
envFrom:
- configMapRef:
name: shared-config
Лучшие практики
1. Лучшие практики безопасности
# ✅ Используйте Secrets для конфиденциальных данных
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
api-key: <base64-encoded-value>
database-password: <base64-encoded-value>
---
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
env:
# ✅ Ссылка на секреты
- name: API_KEY
valueFrom:
secretKeyRef:
name: app-secrets
key: api-key
# ❌ Избегайте хардкода конфиденциальных данных
# - name: API_KEY
# value: "secret-api-key-123"
2. Организация конфигурации
# ✅ Организуйте конфигурацию по назначению
apiVersion: v1
kind: ConfigMap
metadata:
name: database-config
data:
DB_HOST: "postgres.example.com"
DB_PORT: "5432"
DB_POOL_SIZE: "10"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cache-config
data:
REDIS_HOST: "redis.example.com"
REDIS_PORT: "6379"
CACHE_TTL: "3600"
---
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
envFrom:
- configMapRef:
name: database-config
- configMapRef:
name: cache-config
3. Именование переменных окружения
# ✅ Используйте единообразные соглашения об именах
env:
- name: DATABASE_HOST # Чёткие, описательные имена
value: "postgres.example.com"
- name: DATABASE_PORT # Используйте подчёркивания для разделения
value: "5432"
- name: LOG_LEVEL # Используйте заглавные буквы для переменных окружения
value: "info"
- name: FEATURE_FLAG_NEW_UI # Префикс для связанных переменных
value: "true"
# ❌ Избегайте неясных или непоследовательных имён
# - name: db # Слишком короткое
# - name: databaseHost # Несогласованный стиль написания
# - name: log-level # Несогласованный разделитель
4. Значения по умолчанию и валидация
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
env:
- name: PORT
value: "8080" # Предоставляйте разумные значения по умолчанию
- name: LOG_LEVEL
value: "info" # Безопасные значения по умолчанию
- name: TIMEOUT_SECONDS
value: "30" # Указывайте единицы измерения в именах
- name: MAX_RETRIES
value: "3" # Ограничивайте количество повторных попыток