`docker push`到gcr.io在Kubernetes + Docker-in-docker +用户定义的docker网络

时间:2018-03-19 04:00:31

标签: docker kubernetes docker-registry google-container-registry docker-in-docker

背景:

我正在使用Drone来测试应用程序。无人机被部署到Kubernetes,并且docker(dind / docker-in-docker)容器侧面装载。

测试完成后,我再次使用无人机构建&将几个约40mb左右的码头图像推送到us.gcr.io

当Drone创建docker容器来测试我的应用程序,以及单独的容器来构建我的应用程序和图像时,它会创建一个docker网络来链接容器以构建服务,比如临时测试数据库(在CI管道中非常标准) )。

然而,当尝试推送到gcr时,Kubernetes pod网络和Docker-in-Docker的组合产生以下结果:

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"

然而,当推送到(我认为是)一个较旧的注册表版本时,它可以完美地运行。

在没有启用docker容器网络的情况下推送到gcr时,它也可以正常工作。

以下是正在运行的docker命令。显然,敏感数据已被删除。

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命令同时在8个不同的目录上运行go builddocker buildgcloud docker -- push...

所以,摘要:

Kubernetes pod + docker-in-docker + gcloud docker push导致连接中断。

我是否可以使用docker守护程序或kubernetes网络设置或某些东西来缓解这种情况?至少我想知道为什么会这样。

谢谢!

更新

这甚至不需要Kubernetes发生!

我刚尝试使用运行Ubuntu的新GCE实例,它也在那里发生。

1 个答案:

答案 0 :(得分:1)

我联系GCR支持这个问题,因为它似乎只发生在GCR上,他们告诉我,试图推送到注册表的IAM帐户实际上是GCE实例的默认服务帐户,而不是帐户我提供给我的Dockerfile。

然而,当我应该获得401 - Unauthorized时,这并没有解释“破管”和“EOF”错误。

我尝试使用google/cloud-sdk泊坞窗图片here进行同样的推送,当我在相似的环境中提供相同的密钥时,它工作正常,所以这告诉我我在gcloud上安装gcloud的方式码头图像很糟糕。

这就是我所拥有的:

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

我仍然一无所知为什么这为我做了这件事,所以如果有人有任何见解会很棒。