docker 间歇性网络超时

docker 间歇性网络超时

我在 Kubernetes 集群中运行的 docker-in-docker 应用程序遇到了网络/http 超时问题,我需要帮助来弄清楚可能发生的情况。

我在 docker 中运行一个 docker 容器(它是一个构建工具)。在最里面的容器中,docker build 挂起在执行 Dockerfile 中的此行:apk add --no-cache tzdata

控制台输出显示:fetchhttp://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz

我尝试用这个 URL 进行简单的 curl,大约 50% 的时间有效,其余时间超时。问题也仅限于 Alpine CDN URL。例如,我可以 100% 的时间从 flickr.com 下载图像。它还 100% 的时间在不同 VPC 中的不同集群中下载。因此,这个特定的 Kubernetes 堆栈和这个特定的 URL 存在一些特殊问题,导致了这个问题。我需要帮助的是如何进一步挖掘以尝试识别问题。

我已经将应用程序精简到最基本的部分,以突出问题。以下是项目结构:

项目文件结构

这是app.py:

from time import sleep

while True:
    sleep(60)

这是 Dockerfile:

FROM python:3.7-alpine3.11

RUN apk add --no-cache                                                  \
    docker

COPY entrypoint.sh /
RUN chmod 0700 /entrypoint.sh

RUN mkdir /app
WORKDIR /app/
COPY app /app/

ENTRYPOINT [ "/entrypoint.sh" ]

这是entrypoint.sh:

#!/bin/sh
set -e

echo 'Starting dockerd...'
# check if docker pid file exists (can linger from docker stop or unclean shutdown of container)
if [ -f /var/run/docker.pid ]; then
  rm -f /var/run/docker.pid
fi
mkdir -p /etc/docker
echo '{ "storage-driver": "vfs" }' > /etc/docker/daemon.json
nohup dockerd > /var/log/dockerd.log &

# The following command does not spawn execution to the background as
#     we need to leave something holding the container in run state.
echo "Starting canary app..."
exec python3 app.py

和 service.yml

apiVersion: v1
kind: List
items:
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    labels:
      run: canary
    name: canary
  spec:
    replicas: 1
    selector:
      matchLabels:
        run: canary
    template:
      metadata:
        labels:
          run: canary
      spec:
        containers:
          - image: canary
            imagePullPolicy: IfNotPresent
            name: canary
            securityContext:
              capabilities:
                add:
                  - SYS_ADMIN
              privileged: true
        dnsPolicy: ClusterFirst
- apiVersion: v1
  kind: Service
  metadata:
    name: canary
    labels:
      run: canary
  spec:
    ports:
      - port: 80
        protocol: TCP
    selector:
      run: canary
    sessionAffinity: None
    type: ClusterIP

在此处输入图片描述

答案1

该问题与 MTU 有关。我们的集群使用 Calico VXLAN 网络,其 MTU 为 1450。内部 Docker 容器没有注意到这一点,而且在路径 MTU 发现 (PMTUD) 期间似乎没有发现这一点。奇怪的是,这是 Fastly CDN 的问题,而不是我尝试过的其他服务器主机的问题,所以这是一个额外的混淆因素。当我将内部 Docker 容器的 MTU 也设置为 1450 时,问题就消失了。

答案2

我们在 CI 管道中运行 docker-in-docker 构建时遇到了非常相似的症状,该管道在 GKE 中运行。当我们尝试从(但也包括我们手动测试的其他主机,例如)apt-get下载软件包时,我们突然开始在构建 Docker 映像时出现间歇性故障。该问题的修复方式与 @Sushil 详述的方式类似,即设置内部 Docker 容器的 MTU。我们通过创建从官方映像派生的自定义 Docker 映像来实现此目的:deb.debian.orggithub.comdocker:dind

FROM docker:dind
COPY daemon.json /etc/docker/

其中daemon.json包含:

{
  "mtu": 1460
}

(1460 是与我们的 Kubernetes 集群关联的 VPC 网络的 MTU)

相关内容