Docker In Docker IN中的Docker Compose(网络问题)

时间:2019-03-19 23:55:50

标签: docker docker-compose dockerfile

我真的无法向您解释想创建一个将运行docker的docker容器有多困难,该docker容器将运行将访问我的外部docker主机的Web服务器。

所以我到目前为止所知道的:

  • 我有一个在docker外执行的dockerfile 撰写并进行测试,我可以看到它连接到了我的主机泊坞窗 守护程序!
  • 接下来,我进入docker-compose设置,我知道我必须 由于内部发生网络而出现问题 docker-compose文件。但是我有0个docker-compose网络 经验,所以我问如何将我的容器也连接到 默认网络进入该设置吗?

我的Bash脚本(入口点):

#!/bin/sh
set -e


# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
    set -- docker "$@"
fi

# if our command is a valid Docker subcommand, let's invoke it through Docker instead
# (this allows for "docker run docker ps", etc)
if docker help "$1" > /dev/null 2>&1; then
    set -- docker "$@"
fi

# if we have "--link some-docker:docker" and not DOCKER_HOST, let's set DOCKER_HOST automatically
if [ -z "$DOCKER_HOST" -a "$DOCKER_PORT_2375_TCP" ]; then
    export DOCKER_HOST='tcp://docker:2375'
fi

if [ "$1" = 'dockerd' ]; then
    cat >&2 <<-'EOW'
         Hey there!  It looks like you're trying to run a Docker daemon.
           You probably should use the "dind" image variant instead, something like:
             docker run --privileged --name some-overlay-docker -d docker:stable-dind --storage-driver=overlay
           See https://hub.docker.com/_/docker/ for more documentation and usage examples.
    EOW
    sleep 3
fi

docker version

dotnet ApiServer.dll

我的撰写文件:

version: '3.4'

services:
  apiserver:
    image: ${DOCKER_REGISTRY-}apiserver
    build:
      context: ./
      dockerfile: ./ApiServer/Dockerfile
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock

最后我的dockerfile :(应该并不需要),

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-alpine AS base

COPY /ApiServer/modprobe.sh /usr/local/bin/modprobe
COPY /ApiServer/docker-entrypoint.sh /usr/local/bin/

RUN dos2unix -u /usr/local/bin/modprobe
RUN dos2unix -u /usr/local/bin/docker-entrypoint.sh

WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-alpine AS build
WORKDIR /src
COPY ["ApiServer/ApiServer.csproj", "ApiServer/"]
COPY ["SharedLibs/SharedLibs.csproj", "SharedLibs/"]
RUN dotnet restore "ApiServer/ApiServer.csproj"
COPY . .
WORKDIR "/src/ApiServer"
RUN dotnet build "ApiServer.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "ApiServer.csproj" -c Release -o /app

FROM base AS docker
## Docker Setup
RUN apk add --no-cache \
        ca-certificates

# set up nsswitch.conf for Go's "netgo" implementation (which Docker explicitly uses)
# - https://github.com/docker/docker-ce/blob/v17.09.0-ce/components/engine/hack/make.sh#L149
# - https://github.com/golang/go/blob/go1.9.1/src/net/conf.go#L194-L275
# - docker run --rm debian:stretch grep '^hosts:' /etc/nsswitch.conf
RUN [ ! -e /etc/nsswitch.conf ] && echo 'hosts: files dns' > /etc/nsswitch.conf

ENV DOCKER_CHANNEL stable
ENV DOCKER_VERSION 18.09.3
# TODO ENV DOCKER_SHA256
# https://github.com/docker/docker-ce/blob/5b073ee2cf564edee5adca05eee574142f7627bb/components/packaging/static/hash_files !!
# (no SHA file artifacts on download.docker.com yet as of 2017-06-07 though)

RUN set -eux; \
    \
# this "case" statement is generated via "update.sh"
    apkArch="$(apk --print-arch)"; \
    case "$apkArch" in \
        x86_64) dockerArch='x86_64' ;; \
        armhf) dockerArch='armel' ;; \
        aarch64) dockerArch='aarch64' ;; \
        ppc64le) dockerArch='ppc64le' ;; \
        s390x) dockerArch='s390x' ;; \
        *) echo >&2 "error: unsupported architecture ($apkArch)"; exit 1 ;;\
    esac; \
    \
    if ! wget -O docker.tgz "https://download.docker.com/linux/static/${DOCKER_CHANNEL}/${dockerArch}/docker-${DOCKER_VERSION}.tgz"; then \
        echo >&2 "error: failed to download 'docker-${DOCKER_VERSION}' from '${DOCKER_CHANNEL}' for '${dockerArch}'"; \
        exit 1; \
    fi; \
    \
    tar --extract \
        --file docker.tgz \
        --strip-components 1 \
        --directory /usr/local/bin/ \
    ; \
    rm docker.tgz; \
    \
    dockerd --version; \
    docker --version

FROM docker AS final
WORKDIR /app
COPY --from=publish /app .

ENTRYPOINT ["../usr/local/bin/docker-entrypoint.sh"]

1 个答案:

答案 0 :(得分:0)

您的Dockerfile公开了端口 80 ,但是您没有将其映射到docker-compose.yml文件中。

尝试将docker-compose-yml文件更新为以下内容:

docker-compose-yml

version: '3.4'

services:
  apiserver:
    image: ${DOCKER_REGISTRY-}apiserver
    build:
      context: ./
      dockerfile: ./ApiServer/Dockerfile
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    ports:
      - 8080:80

端口键,会将端口从您的主机映射到容器。简化语法:

    ports:
      - <hostport>:<containerport>

使用docker-compose启动容器时,docker将为您的应用程序堆栈创建一个新的桥接网络。无法从主机访问此网络中的容器,并且网络内的容器也无法访问主机。这就是为什么需要端口映射的原因-它会将主机上的端口8080映射到容器的端口80

然后您可以使用主机上的http://localhost:8080来访问容器中公开的服务。

更新

根据您的评论,我认为您可能希望在其他主机上运行其他服务,这些服务可以从ApiServer容器内部连接到数据库,例如数据库。我猜有一个快速的解决方案,那就是将新容器连接到“主机”网络。

您可以尝试将docker-compose.yml文件更新为此:

docker-compose-yml

version: '3.4'

services:
  apiserver:
    image: ${DOCKER_REGISTRY-}apiserver
    build:
      context: ./
      dockerfile: ./ApiServer/Dockerfile
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    ports:
      - 8080:80
    network_mode: "host"

此操作的效果是,当您从容器内部解析localhost127.0.0.1时,您实际上将获得主机。但是,如果您将容器部署到一个群中,则无法使用。