从 docker 容器写入 google-cloud-composer 中的文件

write a file from a docker container in google-cloud-composer

一些背景: 我正在使用 composer-1.3.0-airflow-1.10.0

已安装 PyPi 包docker===2.7.0

有一段时间我尝试使用 DockerOperator,但我需要从位于另一个 gcp 项目中的私有 gcr.io 注册表中拉取图像,那是一团糟。

我不会详细说明我为什么放弃这个。我切换到一个简单的 PythonOperator 用于拉取和 运行 docker 图像。操作员的运行方式如下:

def runImage(**kwargs):
    workingDir = "/app"
    imageName = "eu.gcr.io/private-registry/image"
    volume = {"/home/airflow/gcs/data/": {"bind": "/out/", "mode": "rw"}}
    userUid = os.getuid()
    command = getContainerCommand()
    client = getClient()
    print("pulling image")
    image = pullDockerImage(client, imageName)
    print("image pulled. %s", image.id)
    output = client.containers.run(
        image=imageName,
        command=command,
        volumes=volume,
        privileged=True,
        working_dir=workingDir,
        remove=True,
        read_only=False,
        user=userUid)
    print output
    return True


task = PythonOperator(
    task_id="test_pull_docker_image",
    python_callable=runImage,
    dag=dag
)

图片拉的很好。它 运行 (这已经是胜利了)。

容器将一些文件写入 /out/,我使用 rw 权限将其作为卷安装到 /home/airflow/gcs/data

添加了 working_dir, user, privileged, read_only 选项用于测试,但我认为它们不相关。

文件未创建。 直接在 pyhton 中将文件写入 /home/airflow/gcs/data 就可以了。

容器本身是编译的 C#。 在本地,如果容器无法写入文件,我会收到错误消息(如 Unhandled Exception: System.UnauthorizedAccessException: Access to the path '/out/file.txt' is denied. ---> System.IO.IOException: Permission denied

但是当我 运行 airlfow composer 中的 DAG 时,一切看起来都很好,容器输出符合预期,没有出现错误。

也许 Dockerfile 可能有用:

FROM microsoft/dotnet:2.1-sdk AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM microsoft/dotnet:2.1-sdk
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "programm.dll"]

所以问题是,

为什么不写入文件?以及如何让容器写入文件到/home/airflow/gcs/data?

所以我解决了这个问题,感谢

这里的答案分为两部分:

/home/airflow/gcsgcsfuse 卷。将此目录用于 DockerVolume 只是行不通(可以通过添加插件来工作,我为此丢失了 link :/ )

我们想在 airflow-workers 中添加一个卷,我们可以通过更新 kubectl 配置来实现: 有关如何更新配置的信息,请参阅 。 我们要添加一个主机路径:

containers:
  ...
  securityContext:
    privileged: true
    runAsUser: 0
    capabilities:
      add: 
      - SYS_ADMIN
  ...
  volumeMounts:
  - mountPath: /etc/airflow/airflow_cfg
    name: airflow-config
  - mountPath: /home/airflow/gcs
    name: gcsdir
  - mountPath: /var/run/docker.sock
    name: docker-host
  - mountPath: /bin/docker
    name: docker-app
  - mountPath: /path/you/want/as/volume
    name: mountname
  ...
  volumes:
  - configMap:
    defaultMode: 420
    name: airflow-configmap
  name: airflow-config
  - emptyDir: {}
    name: gcsdir
  - hostPath:
      path: /path/you/want/as/volume
      type: DirectoryOrCreate
    name: mountname
  - hostPath:
      path: /var/run/docker.sock
      type: ""
    name: docker-host
  - hostPath:
      path: /usr/bin/docker
      type: ""
    name: docker-app

现在我们可以在 DAG 定义中使用 volume = {"/path/you/want/as/volume": {"bind": "/out/", "mode": "rw"}}

文件将存在于 POD 中,您可以使用另一个任务将它们上传到 gcs 存储桶中。

希望能有所帮助:)