首页 > 解决方案 > Airflow 中的 KubernetesPodOperator 特权 security_context

问题描述

我在 Google 的 Cloud Composer 上运行 Airflow。我正在使用KubernetesPodOperator并想通过 gcsfuse 将 google 存储桶安装到 pod 中的目录。似乎要做到这一点,我需要按照此处指定的方式为 k8s 提供特权安全上下文。似乎气流最近将 security_context 参数添加到 KubernetesPodOperator。我在运算符中指定的安全上下文是:

security_context = {
  'securityContext': {
    'privileged': True,
    'capabilities':
      {'add': ['SYS_ADMIN']}
  }
}

当我尝试airflow test dag_id task_id date在气流工作器中运行时,吊舱启动,并且当代码尝试通过 gcsfuse 安装存储桶时,它会抛出错误"fusermount: fuse device not found, try 'modprobe fuse' first"。这使得 security_context 似乎不起作用(例如)。

我是否误解了运算符中的 security_context 参数和/或我的 securityContext 字典定义无效?

标签: kubernetesgoogle-kubernetes-engineairflowgoogle-cloud-composer

解决方案


KubernetesPodOperator的security_contextkwarg 设置 pod 的安全上下文,而不是 pod 中的特定容器,因此它仅支持PodSecurityContext. 由于您指定的参数对于 pod 的安全上下文无效,因此它们将被丢弃。

privilegedcapabilities属性仅作为容器的一部分有效,SecurityContext这意味着您需要以某种方式在 pod 的容器规范中设置它们。您可以通过自己定义整个 pod 规范来做到这一点(而不是让操作员为您生成它)。使用 KubernetesPodOperator,您可以设置full_pod_specpod_template_file指定 Kubernetes API Python 对象,或指向 YAML 对象的路径,然后将其用于生成 pod。使用前者的示例:

from airflow.contrib.operators.kubernetes_pod_operator import KubernetesPodOperator
import kubernetes.client.models as k8s

pod = k8s.V1Pod()
pod.spec = k8s.V1PodSpec()
pod.spec.containers = [
    k8s.V1Container(
      ...,
      security_context={
          'privileged': True,
          'capabilities': {'add': ['SYS_ADMIN']}
      }
    )
]

# Equivalent to setting security_context from the operator
pod.spec.security_context = {}

t1 = KubernetesPodOperator(..., full_pod_spec=pod)

如果您想pod_template_file与 Cloud Composer 一起使用,您可以将 pod YAML 上传到 GCS 并将其设置为映射的存储路径之一(例如/home/airflow/gcs/dags/my-pod.yaml,如果您将其放在 DAGs 目录中。

阅读airflow.providers.google.cloudKubernetesPodOperator 的版本,有可能full_pod_spec在较新版本的 operator 中出现问题。但是,它应该适用于旧的 contrib 版本。


推荐阅读