• Русский
  • Понимание переменных окружения

    Содержание

    Overview

    Переменные окружения в Kubernetes — это пары ключ-значение, которые предоставляют конфигурационные данные контейнерам во время выполнения. Они обеспечивают гибкий и безопасный способ внедрения конфигурационной информации, секретов и параметров выполнения в ваши приложения без необходимости изменять образы контейнеров или код приложения.

    Core Concepts

    Что такое переменные окружения?

    Переменные окружения — это:

    • пары ключ-значение, доступные процессам, работающим внутри контейнеров
    • механизм конфигурации во время выполнения, не требующий пересборки образов
    • стандартный способ передачи конфигурационных данных приложениям
    • доступные через стандартные API операционной системы на любом языке программирования

    Источники переменных окружения в Kubernetes

    Kubernetes поддерживает несколько источников переменных окружения:

    Тип источникаОписаниеСценарий использования
    Статические значенияПрямые пары ключ-значениеПростая конфигурация
    ConfigMapСсылка на ключи ConfigMapНеконфиденциальная конфигурация
    SecretСсылка на ключи SecretКонфиденциальные данные (пароли, токены)
    Field ReferenceМетаданные Pod/ContainerДинамическая информация во время выполнения
    Resource ReferenceЗапросы/лимиты ресурсовКонфигурация с учётом ресурсов

    Приоритет переменных окружения

    Переменные окружения переопределяют конфигурацию в следующем порядке:

    1. Kubernetes env (наивысший приоритет)
    2. Ссылки на ConfigMaps/Secrets
    3. Инструкции ENV в Dockerfile
    4. Значения по умолчанию приложения (наименьший приоритет)

    Use Cases and Scenarios

    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 Examples and Practical Usage

    Использование 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

    Best Practices

    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"             # Ограничивайте количество повторных попыток