繁体   English   中英

在 Docker 中的 Docker 上运行 webserver

[英]Run webserver on Docker in Docker

我有以下 Dockerfile:

FROM ubuntu:bionic

RUN apt-get update
RUN apt-get -y install curl
RUN apt-get install sudo

# Install Miniconda
ENV PATH="/root/miniconda3/bin:${PATH}"
ARG PATH="/root/miniconda3/bin:${PATH}"

RUN apt-get install -y wget && rm -rf /var/lib/apt/lists/*

RUN wget \
    https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \
    && mkdir /root/.conda \
    && bash Miniconda3-latest-Linux-x86_64.sh -b \
    && rm -f Miniconda3-latest-Linux-x86_64.sh 
RUN conda --version

## Install Docker
RUN sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    lsb-release
RUN sudo apt-get install gnupg

RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
RUN echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

RUN sudo apt-get update
RUN sudo apt-get install docker-ce docker-ce-cli containerd.io -y
RUN pip install gevent

WORKDIR /mnt

我运行该图像:

docker run -v /some/dir:/mnt \
    -v /var/run/docker.sock:/var/run/docker.sock -it <image_tag> /bin/bash

一旦进入图像,我会:

docker run -d -p 8501:8501 -v /path/to/model:/models tensorflow/serving 

但是当我尝试这样做时

curl -v http://localhost:8501/v1/models/model

我得到:

curl: (7) Failed to connect to localhost port 8501: Connection refused

那么我应该如何运行这两个容器才能对其中一个运行curl呢?

这与两个容器需要相互通信的任何其他设置的工作方式相同:它们都需要在同一个(非默认)Docker 网络上,并且一个可以使用另一个的docker run --name as a ZED5F2BDECBD4BD349D09466 . 一个容器启动另一个容器并不重要。

更广泛地说,这与 Docker 守护进程位于“其他地方”的任何其他设置的工作方式相同; 也许您已将$DOCKER_HOST设置为指向在 VM 中运行的 Docker,或者完成了在远程主机上使用双向 TLS 身份验证设置 Docker 的工作。 docker run -v选项指的是运行 Docker 守护程序的主机系统路径; docker run -p选项在运行 Docker 守护程序的主机上发布端口。 在您的情况下,您正在容器的网络空间中调用localhost ,但这与 Docker 守护程序的网络空间不同,因此您无法通过这种方式访问其他容器。

由于您需要了解有关主机系统环境的许多详细信息,因此您需要将这些信息传递给启动容器,可能作为环境变量。 使用Python Docker 客户端库,例如:

import os
import docker
import requests

if __name__ == '__main__':
  shared_host_path = os.environ['SHARED_HOST_PATH']
  docker_network = os.environ['DOCKER_NETWORK']
  client = docker.from_env()
  container = client.containers.run('tensorflow/serving',
    detach=True,
    network=docker_network,
    name='tensorflow',
    volumes={shared_host_path: {'bind': '/models'}}
  )
  requests.get('http://tensorflow:8501/v1/models/model')

启动容器时,您必须将这些详细信息传递到容器中:

sudo docker network create some-network
sudo docker run -d \
  --net some-network \
  -e DOCKER_NETWORK=some-network \
  -e SHARED_HOST_PATH=/path/to/model \
  -v /path/to/model:/mnt \
  -v /var/run/docker.sock:/var/run/docker.sock \
  your-image

这设置起来很尴尬,它是非常特定于 Docker 的(它在 Kubernetes 或其他编排器中不起作用),并且它需要管理员权限(任何可以访问 Docker 套接字的人都可以轻松地启动主机)。 我发现这种方法对某些类型的集成测试很有用。 更典型的模式是创建一个可以通过 HTTP 或作业队列接受请求的长时间运行的进程,以及可以向其发送请求的第二个进程。 您可以在没有 Docker 的情况下构建和测试它,然后当您想在容器中运行它时,您可以使用普通的 Docker 网络,无需任何特殊权限或复杂设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM