我在 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.org
github.com
docker:dind
FROM docker:dind
COPY daemon.json /etc/docker/
其中daemon.json
包含:
{
"mtu": 1460
}
(1460 是与我们的 Kubernetes 集群关联的 VPC 网络的 MTU)