【问题标题】:write a file from a docker container in google-cloud-composer从 google-cloud-composer 中的 docker 容器写入文件
【发布时间】:2018-11-14 16:29:06
【问题描述】:

一些上下文: 我正在使用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/,我将其作为卷安装到/home/airflow/gcs/data,并具有rw 权限。

添加了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写文件?

【问题讨论】:

    标签: python docker airflow google-cloud-composer dockerpy


    【解决方案1】:

    感谢my other question,我解决了这个问题

    这里的答案分为两部分:

    /home/airflow/gcs 是一个gcsfuse 卷。为 DockerVolume 使用这个目录是行不通的(可以通过添加插件来工作,我丢失了这个链接:/)

    我们想在气流工作者中添加一个卷,我们可以通过更新 kubectl 配置来实现: 请参阅this question 了解如何更新配置。 我们要添加一个hostPath:

    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 存储桶中。

    希望能有所帮助:)

    【讨论】:

      猜你喜欢
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-12
      • 2021-12-28
      • 1970-01-01
      • 2016-06-12
      相关资源
      最近更新 更多