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

一些上下文:我正在使用 composer-1.3.0-airflow-1.10.0


安装的 PyPi 包 docker===2.7.0


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


我不会详细说明为什么我放弃了。我切换到一个简单的PythonOperator用于拉取和运行 docker 镜像。下面是 Operator 的工作方式:


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?


POPMUISE
浏览 160回答 1
1回答

宝慕林4294392

所以我解决了这个问题,这要归功于我的另一个问题这里的答案分为两部分:/home/airflow/gcs是一个gcsfuse卷。将这个目录用于 DockerVolume 是行不通的(可以通过添加插件来工作,我丢失了这个链接:/)我们想在气流工人中添加一个卷,我们可以通过更新 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 存储桶左右。希望它可以有所帮助:)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python