Docker In Docker IN Docker Compose (проблемы с сетью) - PullRequest
1 голос
/ 20 марта 2019

Я буквально не могу объяснить вам, как трудно обернуть голову желанием создать докер-контейнер, на котором будет работать докер, на котором будет работать мой веб-сервер, который будет иметь доступ к моему внешнему хосту докера.

Итак, что я знаю до сих пор:

  • У меня есть dockerfile, который при исполнении вне docker создает и тестирует с ним, и я вижу, что он подключается к моему демону docker хоста!
  • Затем я перехожу к настройке docker-compose и понимаю, что у меня должна быть проблема из-за сетевого взаимодействия внутри файлов docker-compose.Но у меня есть опыт работы с сетью Docker-compose, поэтому я спрашиваю, как я также могу подключить свой контейнер к сети по умолчанию один раз в этой настройке?

My Bash Script (Entrypoint):

#!/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 голосов
/ 20 марта 2019

Ваш 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, как база данных.Я полагаю, что есть одно быстрое решение: подключить новый контейнер к сети "host".

Вы можете попробовать обновить файл 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"

Эффект этого состоит в том, что когда вы решаете localhost и 127.0.0.1 изнутри вашего контейнера - вы фактически получаете хост-машину.Это не сработает, если вы развернете свой контейнер в рой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...