`docker push` к gcr.io завершается ошибкой в ​​Kubernetes + Docker-in-docker + пользовательская сеть Docker

Фон:

Я использую Drone для тестирования приложения. Дрон развернут в Kubernetes, с docker (dind / docker-in-docker) контейнер с боковой высечкой.

После завершения теста я снова использую дрон, чтобы собрать и отправить несколько изображений докера размером ~40 Мб каждый в us.gcr.io

Когда Drone создает Docker-контейнер для тестирования моего приложения и отдельный контейнер для создания моего приложения и изображений, он создает Docker-сеть для связи контейнеров с сервисами, такими как временная тестовая база данных (довольно стандартная в конвейере CI).

Тем не менее, комбинация сетей Kubernetes pod и Docker-in-Docker приводит к следующему при попытке отправки в gcr:

time="2018-03-19T03:31:12.037507241Z" level=error msg="Upload failed, retrying: net/http: HTTP/1.x transport connection broken: write tcp w.x.y.z:39662->z.y.x.w:443: write: broken pipe"
time="2018-03-19T03:31:17.208009069Z" level=error msg="Upload failed, retrying: net/http: HTTP/1.x transport connection broken: write tcp w.x.y.z:39662->z.y.x.w:443: write: broken pipe"
time="2018-03-19T03:31:17.216232506Z" level=error msg="Upload failed, retrying: net/http: HTTP/1.x transport connection broken: write tcp w.x.y.z:39662->z.y.x.w:443: write: broken pipe"
time="2018-03-19T03:31:17.407608372Z" level=error msg="Upload failed, retrying: net/http: HTTP/1.x transport connection broken: write tcp w.x.y.z:39662->z.y.x.w:443: write: broken pipe"
time="2018-03-19T03:31:17.410403394Z" level=error msg="Upload failed, retrying: net/http: HTTP/1.x transport connection broken: write tcp w.x.y.z:39662->z.y.x.w:443: write: broken pipe"
time="2018-03-19T03:31:23.432621075Z" level=error msg="Upload failed, retrying: unexpected EOF"

Однако, если нажать (что я предполагаю) на более старую версию реестра, то это работает отлично.

При нажатии на gcr, когда не включена докерная сеть, тогда он также работает отлично.

Вот команды запуска докера. Очевидно, что конфиденциальные данные были опущены.

docker network create test-network && \
docker run --network=test-network -d cockroachdb/cockroach:v1.1.2 -c /cockroach sql --insecure && \
docker run --rm -it -e GKE_CLUSTER_NAME=my-cluster-1 -e GKE_CLUSTER_ZONE=us-east1-b -e GCP_PROJECT=my-gcp-project -e DOCKER_USE_GCP=true -v /var/run/docker.sock:/var/run/docker.sock --network=test-network us.gcr.io/my-project/runner /bin/sh -c 'mkdir -p src/git.example.com/project && git clone https://user:pass!@git.example.com/project/project $GOPATH/src/git.example.com/project/project && cd $GOPATH/src/git.example.com/project/project && git checkout gcr && jules -stage deploy_docker'

jules -stage deploy_docker команда запускает go build, docker build, а потом gcloud docker -- push... на 8 разных каталогов одновременно.

Итак, резюме:

Kubernetes pod + docker-in-docker + gcloud docker push приводит к постоянно прерываемому соединению.

Есть ли что-то, что я мог бы сделать с сетевыми настройками демона docker или kubernetes или что-то, чтобы смягчить это? По крайней мере, я хочу понять, почему это происходит.

Спасибо!


Обновить:

Это даже не требует, чтобы Kubernetes случился!

Я только что попробовал это с новым экземпляром GCE, работающим на Ubuntu, и это тоже происходит там.

1 ответ

Решение

Я связался со службой поддержки GCR по этому вопросу, так как, похоже, это произошло только с GCR, и они сообщили мне, что учетная запись IAM, которая пыталась передать в реестр, на самом деле была учетной записью службы по умолчанию для экземпляров GCE, а не учетной записью, которую я предоставил. в мой Dockerfile.

Однако это не объясняло ошибки "Сломанная труба" и "EOF", когда я должен был получить 401 - Unauthorized,

Я попытался сделать то же самое с google/cloud-sdk Образ docker здесь, и он работал нормально, когда я предоставлял ему тот же ключ в аналогичной среде, так что это указывало на то, что способ установки gcloud на образ docker был плохим.

Вот что у меня было:

RUN wget https://dl.google.com/dl/cloudsdk/channels/rapid/google-cloud-sdk.tar.gz
RUN tar -xvf google-cloud-sdk.tar.gz
RUN rm google-cloud-sdk.tar.gz
RUN google-cloud-sdk/install.sh --usage-reporting=false \
  --path-update=false \
  --bash-completion=false

ENV PATH="/go/google-cloud-sdk/bin:${PATH}"
RUN gcloud components install kubectl
RUN gcloud components install docker-credential-gcr

А вот что google/cloud-sdk имел. Обновление моего Dockerfile для установки таким образом решило мою проблему.

# Install gcloud
ENV CLOUD_SDK_VERSION 193.0.0

ARG INSTALL_COMPONENTS
RUN easy_install -U pip && \
    pip install -U crcmod && \
    export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" && \
    echo "deb https://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" > /etc/apt/sources.list.d/google-cloud-sdk.list && \
    curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
    apt-get update && apt-get install -y google-cloud-sdk=${CLOUD_SDK_VERSION}-0 $INSTALL_COMPONENTS && \
    gcloud config set core/disable_usage_reporting true && \
    gcloud config set component_manager/disable_update_check true && \
    gcloud config set metrics/environment github_docker_image && \
    gcloud --version

Я до сих пор не знаю, почему это сделало это для меня, так что если у кого-то есть понимание, это было бы здорово.

Другие вопросы по тегам