• Русский
  • Соответствие стандарту Pod Security Restricted

    Обзор функции

    Стандарт pod-security.kubernetes.io/enforce=restricted является самым строгим из Pod Security Standard, обеспечивая соблюдение современных лучших практик по усилению безопасности подов. Когда пространство имён помечено этим стандартом, все поды, создаваемые в нём, должны соответствовать жёстким требованиям безопасности.

    В этом руководстве объясняется, как настроить Tekton Pipelines для соответствия стандарту restricted, гарантируя, что все контейнеры в ваших Tasks смогут успешно запускаться в пространствах имён с ограничениями.

    Сценарии использования

    • Запуск Tekton Pipelines в пространствах имён с меткой pod-security.kubernetes.io/enforce=restricted
    • Выполнение требований организационной безопасности и соответствия
    • Повышение уровня безопасности ваших CI/CD конвейеров
    • Запуск рабочих нагрузок в строго регулируемых средах

    Предварительные требования

    • Tekton Pipelines установлен через CR TektonPipeline или TektonConfig
    • У вас есть права на изменение ресурсов TektonPipeline или TektonConfig
    • Вы можете создавать или редактировать определения Task
    • Для пользовательских образов у вас есть доступ к изменению Containerfiles и пересборке образов

    Понимание стандарта Restricted

    Стандарт pod-security.kubernetes.io/enforce=restricted требует, чтобы все три типа контейнеров в Pod соответствовали следующим требованиям безопасности контекста:

    • Обычные контейнеры (containers)
    • Init контейнеры (initContainers)
    • Эфемерные контейнеры (ephemeralContainers)

    Каждый контейнер должен иметь следующую конфигурацию securityContext:

    securityContext:
      allowPrivilegeEscalation: false
      runAsNonRoot: true
      capabilities:
        drop:
          - "ALL"
      seccompProfile:
        type: RuntimeDefault

    Разбор конфигурации:

    ПолеЗначениеНазначениеВлияние
    allowPrivilegeEscalationfalseЗапрещает процессам получать больше привилегий, чем у родительского процессаБлокирует вредоносный код от повышения привилегий через setuid бинарники или файловые возможности
    runAsNonRoottrueТребует запуск контейнеров не от root-пользователя (UID ≠ 0)Предотвращает запуск контейнеров от root, снижая риск уязвимостей выхода из контейнера
    capabilities.drop["ALL"]Удаляет все Linux capabilities из контейнераОграничивает возможности контейнера выполнять привилегированные операции (например, настройка сети, загрузка модулей ядра)
    seccompProfile.typeRuntimeDefaultПрименяет профиль seccomp по умолчанию для runtime контейнераОграничивает системные вызовы, доступные контейнеру, уменьшая поверхность атаки ядра

    Шаги

    1. Настройте Tekton для добавления securityContext в init контейнеры

    Tekton создаёт init контейнеры для каждого управляемого им Pod. Чтобы соответствовать стандарту restricted, необходимо включить автоматическое добавление требуемого securityContext к этим init контейнерам.

    Вариант A: Настройка через TektonPipeline

    Если вы управляете Tekton напрямую через CR TektonPipeline:

    apiVersion: operator.tekton.dev/v1alpha1
    kind: TektonPipeline
    spec:
      set-security-context: true

    Примените конфигурацию:

    $ kubectl patch tektonpipeline tektonpipeline \
      --type merge \
      -p '{"spec":{"set-security-context":true}}'
    
    tektonpipeline.operator.tekton.dev/tektonpipeline patched

    Вариант B: Настройка через TektonConfig

    Если вы управляете Tekton через CR TektonConfig:

    apiVersion: operator.tekton.dev/v1alpha1
    kind: TektonConfig
    spec:
      pipeline:
        set-security-context: true

    Примените конфигурацию:

    $ kubectl patch tektonconfig config \
      --type merge \
      -p '{"spec":{"pipeline":{"set-security-context":true}}}'
    
    tektonconfig.operator.tekton.dev/config patched

    Примечание: Это изменение конфигурации вступает в силу немедленно без необходимости перезапуска контроллера Tekton. Новые TaskRuns и PipelineRuns, созданные после этого изменения, автоматически будут иметь требуемый securityContext в init контейнерах.

    2. Добавьте securityContext в пользовательские определения Task

    Для пользовательских Tasks (не встроенных в платформу) необходимо явно добавить securityContext к каждому шагу.

    Пример Task с securityContext:

    apiVersion: tekton.dev/v1
    kind: Task
    metadata:
      name: custom-build-task
    spec:
      steps:
        - name: build
          image: registry.example.com/builder:latest
          securityContext:
            allowPrivilegeEscalation: false
            runAsNonRoot: true
            capabilities:
              drop:
                - "ALL"
            seccompProfile:
              type: RuntimeDefault
          script: |
            #!/bin/sh
            echo "Building application..."

    Важно: Этот шаг относится к пользовательским Tasks. Встроенные Tasks, предоставляемые платформой (за исключением buildah, см. раздел «Устранение неполадок»), совместимы с этими ограничениями безопасности, но их определения Task не содержат явных конфигураций securityContext, так как они разработаны для работы в различных контекстах безопасности, а не только в режиме restricted.

    3. Настройте образы контейнеров для запуска от не-root пользователя

    Образы контейнеров должны быть настроены на запуск от не-root пользователя. Пользователь должен быть указан с помощью числового UID, а не имени пользователя.

    В вашем Containerfile добавьте не-root пользователя и установите его по умолчанию. Пример для образов на базе Alpine:

    # Добавляем не-root пользователя с UID 65532 (синтаксис Alpine)
    RUN adduser -u 65532 -h /home/nonroot -D nonroot
    
    # Устанавливаем соответствующие права для рабочих директорий
    RUN chown -R 65532:65532 /app
    
    # Переключаемся на не-root пользователя (используем числовой UID)
    USER 65532

    Примечание: Синтаксис команды adduser зависит от базового образа. См. ссылки ниже для примеров с другими базовыми образами.

    Проверьте конфигурацию образа:

    # Проверяем, что образ запускается не от root
    $ podman run -it --rm ${registry} id
    
    uid=65532(nonroot) gid=65532(nonroot) groups=65532(nonroot)

    Подробные инструкции по настройке Containerfiles смотрите в Adjust Containerfile for Building Task-Compatible Custom Images.

    Результаты работы

    После выполнения вышеуказанных шагов:

    1. Init контейнеры: init контейнеры, создаваемые Tekton, автоматически будут соответствовать стандарту restricted
    2. Пользовательские Tasks: шаги ваших пользовательских Tasks будут иметь требуемый securityContext
    3. Образы контейнеров: образы будут запускаться от не-root пользователей с минимальными привилегиями

    Вы можете проверить соответствие, создав TaskRun в пространстве имён с ограничениями:

    # Помечаем пространство имён стандартом restricted
    $ kubectl label namespace test-ns pod-security.kubernetes.io/enforce=restricted
    
    namespace/test-ns labeled
    
    # Создаём TaskRun в ограниченном пространстве имён
    $ kubectl -n test-ns create -f taskrun.yaml
    
    taskrun.tekton.dev/example-taskrun created
    
    # Проверяем успешность TaskRun
    $ kubectl -n test-ns get taskrun
    
    NAME               SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
    example-taskrun    True        Succeeded   2m ago      1m ago

    Успешный TaskRun показывает SUCCEEDED как True и REASON как Succeeded, что означает успешный запуск всех контейнеров с требуемыми ограничениями безопасности.

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

    Для более автоматизированного подхода можно использовать инструменты принудительного соблюдения политики, такие как Kyverno, чтобы автоматически внедрять требуемый securityContext во все контейнеры. Создавая Kyverno PolicyapiVersion: kyverno.io/v1 и kind: Policy), вы можете автоматически мутировать Pods, добавляя необходимые конфигурации securityContext.

    Для дополнительной информации обратитесь к Scenario 4: Specified Namespace Security Context Enforcement.

    Этот подход устраняет необходимость ручной настройки securityContext для каждого Task, упрощая управление соответствием.

    Подробные инструкции по настройке политик Kyverno для этой цели смотрите по ссылкам:

    Устранение неполадок

    Встроенные Tasks и стандарт Restricted

    Из встроенных Tasks, предоставляемых платформой, только buildah не может работать в режиме restricted. Это связано с тем, что buildah требует повышенных привилегий для сборки контейнерных образов.

    buildah требует следующий securityContext:

    securityContext:
      # allowPrivilegeEscalation: false  # Нельзя установить в false — buildah должен повышать привилегии для использования возможности SETFCAP при установке файловых возможностей во время сборки образов; принудительное false также блокирует newuidmap/newgidmap, что приводит к fallback rootless на одиночное отображение UID/GID с предупреждениями и потенциально неправильными владельцами файлов
      runAsNonRoot: true
      capabilities:
        # drop: ["ALL"]  # Нельзя сбрасывать ВСЕ capabilities — buildah требует capability SETFCAP для установки файловых возможностей (например, cap_net_bind_service) на файлы внутри образов во время сборки
        add: ["SETFCAP"]
      # seccompProfile:
      #   type: RuntimeDefault  # Нельзя использовать RuntimeDefault — профиль seccomp по умолчанию блокирует unshare/clone(CLONE_NEWUSER)/setns, необходимые buildah, что приводит к ошибкам сборки; используйте Unconfined или кастомный профиль, разрешающий эти системные вызовы

    Решения:

    1. Используйте buildah Task в отдельном пространстве имён с режимом baseline вместо restricted (например, с меткой pod-security.kubernetes.io/enforce=baseline)
    2. Рассмотрите альтернативные методы сборки контейнерных образов с другими требованиями безопасности

    TaskRun завершается с ошибками пользователя контейнера

    Вы можете столкнуться с одной из следующих ошибок:

    • "container has runAsNonRoot and image will run as root" — в образе контейнера отсутствует директива USER в Containerfile (по умолчанию root) или явно указан USER 0 или USER root
    • "container has runAsNonRoot and image has non-numeric user" — образ контейнера использует символическое имя пользователя (например, USER appuser) вместо числового UID

    Решения:

    1. Пересоберите образ с числовым UID не-root пользователя, как описано в Шаге 3. Например, используйте USER 65532 вместо USER appuser или USER root.

    2. Укажите пользователя в securityContext Task:

      apiVersion: tekton.dev/v1
      kind: Task
      metadata:
        name: example-task
      spec:
        steps:
          - name: step1
            image: registry.example.com/myimage:latest
            securityContext:
              runAsUser: 65532
              runAsNonRoot: true
              allowPrivilegeEscalation: false
              capabilities:
                drop:
                  - "ALL"
              seccompProfile:
                type: RuntimeDefault
            script: |
              #!/bin/sh
              echo "Running as user $(id -u)"
    3. Укажите пользователя в podTemplate TaskRun:

      apiVersion: tekton.dev/v1
      kind: TaskRun
      metadata:
        name: example-taskrun
      spec:
        taskRef:
          name: example-task
        podTemplate:
          securityContext:
            runAsUser: 65532
            runAsNonRoot: true
            fsGroup: 65532

    Примечание: podTemplate.securityContext задаёт securityContext на уровне Pod, который наследуется всеми контейнерами, если не переопределён на уровне контейнера.

    Варианты 2 и 3 полезны, если вы не можете изменить образ контейнера.

    TaskRun завершается с ошибкой "Forbidden: cannot set securityContext.capabilities"

    Эта ошибка возникает, если securityContext пытается добавить capabilities при одновременном сбросе всех capabilities.

    Решение: Убедитесь, что ваш Task не добавляет capabilities. Только сбрасывайте capabilities, как показано в примерах.

    Init контейнеры завершаются с ошибками разрешений

    Если init контейнеры завершаются с ошибками разрешений после установки set-security-context: true, проверьте:

    1. Наличие соответствующих политик безопасности в пространстве имён
    2. Конфигурацию образов контейнеров, используемых Tekton, на запуск от не-root пользователя
    3. Актуальность установки Tekton

    Дополнительная информация