如何在运行时从正在运行的容器中加载和运行容器
我正在研究可在Google Container Engine(Kubernetes)上运行的计算框架。
所需的行为是,用户将提供一个容器来执行(这是用户有效载荷,我们可以这样做,因为用户很less和可信)。 用户容器将被预先上传到registry中。
当框架运行时,它会启动一些工作者(每个工作人员在一个容器中,监听一个芹菜队列),一个主节点将加载一堆parameter passing给工作人员(通过芹菜/ rabbitmq)。
当一个工人运行时,它会执行3件事(对于每个工作项目):
-
SET UP
:工作人员将从谷歌云存储和其他地方复制文件和configuration。 这些文件将被放置在一个容器中。 -
EXECUTION
:工作人员应该从registry中下载用户容器并运行它。 我也想从容器的进程中捕获stdout
和stderr
,如果可能的话添加一个截止date(如果容器在X秒内没有完成执行,暂停)。 用户容器将生成结果作为卷目录中的文件。 -
CLEAN UP and REPORTING
:主机窗格会将用户容器生成的一些工件复制回谷歌云。 其他结果将被报告给专有应用程序。
我希望框架对用户是不可见的(因为我们不想与他们共享凭证并阻止他们拥有任何任务pipe理逻辑)。
由于主机本身就是一个容器,所以还没有find一个好方法来实现这个(在另一个容器中运行的脚本中拉取并运行一个容器)。
这可能在Kubernetes中实现吗? 是否有任何文件或项目做类似的事情? 而且,这种方法有没有陷阱?
谢谢!
最终解决如下:
首先,我创build了一个定义如下(片段)的工作:
apiVersion: batch/v1 kind: Job metadata: name: item-001 spec: template: metadata: name: item-xxx spec: containers: - name: worker image: gcr.io/<something>/worker volumeMounts: - mountPath: /var/run/docker.sock name: docker-socket-mount - mountPath: /workspace name: workspace volumes: - name: docker-socket-mount hostPath: path: /var/run/docker.sock - name: workspace hostPath: path: /home/workspace
有2个挂载,第一个docker-socket-mount
挂载/var/run/docker.sock
到容器中,所以我可以从里面使用Docker,第二个挂载一个卷,它将在主机和客人容器workspace
。
worker
运行一个类似于这样的脚本:
#!/usr/bin/env bash IMAGE=gcr.io/some/guest/image # ... gsutil -m cp -r gs://some/files/I/need/* /workspace # ... export DOCKER_API_VERSION=1.23 gcloud docker -- pull ${IMAGE} docker run -v /home/workspace:/workspace ${IMAGE} # ...
Docker套接字可用,安装Docker客户端并正常调用它已经足够了。 诀窍是从/home/workspace
挂载guest镜像,如从kubernetes节点看到的,而不是从主机映像( /workspace
)看到的。 下载到/workspace
的文件现在也在客人容器上可用。
最后, Dockerfile
看起来像这样:
FROM ubuntu:14.04 # ... # Install Docker RUN curl -fsSL https://get.docker.com/ | sh # Install Google Cloud SDK ADD xxx.json /home/keys/xxx.json RUN curl https://sdk.cloud.google.com > /tmp/gcloud.sh RUN bash /tmp/gcloud.sh --disable-prompts --install-dir=/home/tools/ RUN /home/tools/google-cloud-sdk/bin/gcloud auth activate-service-account name@my-project.iam.gserviceaccount.com --key-file=/home/keys/xxx.json RUN /home/tools/google-cloud-sdk/bin/gcloud config set project my-project # ...