阿里蜻蜓 dragonfly p2p 镜像分发功能测试

说明

如果说微服务和容器是最佳拍档,那么模块多实例是肯定少不了。假如没有使用类似 Google jib 等手段进行镜像分层(利用镜像缓存),势必会造成:

  1. 带宽浪费: 尤其是公网带宽,如果是自建 harbor,那么会容易导致单节点网卡被打满,如果用了 harbor 联邦,又会导致数据同步等运维问题。
  2. 集群拉起慢:镜像下载慢,必然会导致服务拉起慢。
    Dragonfly 是阿里巴巴自研并开源的一款基于 P2P 协议的文件分发系统。除了使用 dfget 进行文件下载外,还支持通过 dfdaemon 调用 dfget 进行 docker 镜像下载。

对于 dfdaemon 放置方案

方案                                  优点                   缺点
通过 daemonset 部署到所有节点            简单                   新节点启动,其 dfdaemon 自身还无法启动,无法提供代理功能,出现鸡和蛋的问题
通过 daemonset 部署到已有部分节点      资源复用                 拉取镜像需要消耗这些节点大量的流量和资源,对这些节点上的应用产生影响
通过 docker 在新节点初始化时部署        解决鸡和蛋的问题         会造成管理复杂性,这部分容器不受 kubernetes 管理
通过二进制在新节点初始化时部署         资源复用                 增加了节点初始化时间,随着节点增加,复杂度线性增长
通过额外节点 docker 部署                隔离效果好,复杂度固定   增加了成本

吐槽

Dragonfly 的一些资料除了网上早几年的宣传文档,几乎没找到近期的一些实战资料(不禁怀疑真的有生产用户在用?)。另外官方文档简陋的几页,都年久失修,简直就是 TMD 的垃圾中的战斗机(致敬满满铜臭的阿里)。

安装

步骤 1:部署 Dragonfly 集群管理器(Cluster Manager)服务端 Supernode

打印默认配置:
参考:https://github.com/dragonflyoss/Dragonfly/blob/master/docs/config/supernode_config_template.yml

# docker run --rm -it dragonflyoss/supernode:1.0.6 config default

启动 supernode 容器:
备注:我这里时间设置都尽量调大了,为了尽可能多的使用 cache
--advertise-ip 是 supernode 所在宿主机的 IP,必须是客户端能够连通的,如果不设置,有可能会导致 client 无法连接 supernode,届时 docker pull 会走 clinet 的网络,从真实的 registry 直接下载镜像
--pool-size 是核心池大小。当请求启动下载任务时,超级节点将构造一个线程并发池,以下载源文件片段并写入指定的存储。通过 HTTP 标头中设置的 range 属性将源文件下载分成多个部分。
--max-bandwidth 是超级节点可以使用的网络带宽
--system-bandwidth 是为系统软件保留的网络带宽
--fail-access-interval 是访问 URL 失败后的时间间隔。如果无法从源下载任务,则自上次失败以来的时间内将不会重试该任务。
--gc-initial-delay 从启动到第一次执行 GC 的延迟时间
--gc-meta-interval 执行 GC 元数据的间隔时间
--task-expire-time 当未在 task-expire-time 内访问任务时,该任务将被视为过期
--peer-gc-delay 对等方报告脱机之后执行 GC 的延迟时间

# mkdir -p /opt/dragonfly
# cat > /opt/dragonfly/supernode.yml <<EOF
base:
  cdnPattern: local
  listenPort: 8002
  downloadPort: 8001
  homeDir: /home/admin/supernode
  schedulerCorePoolSize: 100
  downloadpath: /home/admin/supernode/repo/download
  peerUpLimit: 5
  peerDownLimit: 5
  # 当 dfget 节点开始扮演对等方的角色时,它将为其他对等方提供服务。如果在为对等方提供服务时遇到问题,其自故障将增加 1。当故障限制达到 eliminationLimit 时,对等方会将自己隔离为不健康状态。然后,此 dfget 将不再被其他对等方调用
  eliminationLimit: 5
  # 是在 dfget 客户端在超级节点中设置的故障计数限制。当 dfget 客户端加入由超级节点构建的对等网络时,超级节点将命令对等方开始分发任务。当 dfget 客户端未能完成分发任务时,客户端的失败计数将增加 1。当客户端的失败计数达到 failureCountLimit 时,dfget 客户端将被移至超级节点的黑名单以停止作为对等方角色。
  failureCountLimit: 5
  linkLimit: 20MB
  systemReservedBandwidth: 20MB
  maxBandwidth: 200MB
  enableProfiler: false
  debug: true
  # supernode 地址
  advertiseIP: "10.64.57.72"
  failAccessInterval: 1m
  gcInitialDelay: 5m
  gcMetaInterval: 24h
  taskExpireTime: 30m
  peerGCDelay: 24h
  # 执行磁盘 GC 的间隔时间
  gcDiskInterval: 5m
  # 如果可用磁盘空间大于 YoungGCThreshold 不需要 GC 磁盘
  youngGCThreshold: 10GB
  # 如果可用磁盘空间小于 FullGCThreshold,超级节点应 gc 所有未使用的任务文件
  fullGCThreshold: 5GB
  # 访问任务文件的时间间隔的阈值
  IntervalThreshold: 2h0m0s
  cleanratio: 1
  logConfig:
    maxSize: 0
    maxBackups: 0
    path: ""
plugins: {}
storages: {}
EOF
# docker run --name supernode \
             -d \
             --restart=always \
             -p 8001:8001 \
             -p 8002:8002 \
             -v /opt/dragonfly/supernode:/home/admin/supernode \
             -v /opt/dragonfly/supernode.yml:/etc/dragonfly/supernode.yml:ro \
             dragonflyoss/supernode:1.0.6 \
             --config /etc/dragonfly/supernode.yml
# docker exec -it supernode netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:8001            0.0.0.0:*               LISTEN      7/nginx: master pro
tcp        0      0 :::8002                 :::*                    LISTEN      8/supernode

查看目录:
注意:repo 目录是用来做临时源缓存的

# docker exec -it supernode ls -l /home/admin/supernode/
total 0
drwxr--r--    2 root     root            20 Dec  2 07:05 logs
drwxr-xr-x    2 root     root             6 Dec  2 07:05 repo

查看日志:

# docker logs -f supernode 
time="2020-12-02T07:05:11Z" level=debug msg="use log file /home/admin/supernode/logs/app.log"

# docker exec -it supernode tail -f /home/admin/supernode/logs/app.log
  cleanratio: 1
  logConfig:
    maxSize: 0
    maxBackups: 0
    path: ""
plugins: {}
storages: {}

2020-12-02 07:05:11.455 INFO sign:8 : start to run supernode
2020-12-02 07:05:11.465 DEBU sign:8 : start the gc job

步骤 2:部署 Dragonfly 客户端 dfclient

打印默认配置:
参考:https://github.com/dragonflyoss/Dragonfly/blob/master/docs/config/dfdaemon_config_template.yml

# docker run --rm -it dragonflyoss/dfclient:1.0.6 config default  

注意:该镜像中包含 dfdaemon 和 dfget
注意:dfdaemon 仅用于拉取镜像。dfdaemon 扮演代理角色,拦截容器引擎的镜像下载请求并重定向到 dfget 中。
注意:--node 指定 supernodes 地址,支持多个地址如:nodeIp1,nodeIp2
注意:--registry 指定镜像仓库地址,https://index.docker.io 为官方镜像仓库,您也可以设置为其他仓库地址,也可以写加速器地址。
注意:--workHome 测试无法改变 /root/.small-dragonfly 目录

# mkdir -p /opt/dragonfly
# cat > /opt/dragonfly/dfdaemon.yml <<EOF
# 配置注册表的镜像,从自己的私有仓库下拉,拉不到就去 docker hub 拉,再拉不到报错
registry_mirror:
  remote: https://harbor.sit.hupu.io 
  certs: null
  insecure: false
  direct: false

# 透明代理的规则列表。如果未提供任何规则,则将直接代理所有请求。请求将使用第一个匹配规则进行代理
proxies: []
## proxy all http image layer download requests with dfget
#- regx: blobs/sha256.*
## change http requests to some-registry to https and proxy them with dfget
#- regx: some-registry/
#  use_https: true
## proxy requests directly, without dfget
#- regx: no-proxy-reg
#  direct: true

# dfdaemon 应当劫持其 https 请求的主机列表。如果网址与代理规则匹配,则 DFdaemon 将能够使用 dfget 代理来自它们的请求。将使用第一个匹配的规则。
hijack_https: null
  ## key pair used to hijack https requests
  #cert: df.crt
  #key: df.key
  #hosts:
  #   - regx: mirror.aliyuncs.com:443  # regexp to match request hosts
  #     # whether to ignore https certificate errors
  #     insecure: false
  #     # optional certificates if the host uses self-signed certificates
  #     certs: []
port: 65001
hostIp: 127.0.0.1
certpem: ""
keypem: ""
verbose: false
maxprocs: 4
# --node        指定 supernodes
# --expiretime:缓存的文件不被任何进程访问持续时间(默认 3 分钟)
# --alivetime:上载器在任何期间都无法访问任何上载请求的有效持续时间,在此期间上载器将自动退出(默认值为 5m0s)
#dfget_flags: ["--node", "192.168.33.21", "--verbose", "--ip", "192.168.33.23", "--port", "15001", "--expiretime", "3m0s", "--alivetime", "5m0s", "-f", "filterParam1&filterParam2"]
dfget_flags: ["--expiretime", "24h", "--alivetime", "1h"]
# 这里指定多个 supernode 节点
supernodes:
- 10.64.56.175:8002
- 10.64.56.176:8002
ratelimit: 200MB
workHome: /root/.small-dragonfly
localrepo: /root/.small-dragonfly/dfdaemon/data
dfpath: /opt/dragonfly/df-client/dfget
logConfig:
  maxSize: 0
  maxBackups: 0
  path: ""
localIP: ""
peerPort: 0
streamMode: false
EOF
# docker run --name dfclient \
             -d \
             --restart=always \
             -p 65001:65001 \
             -v /opt/dragonfly/.small-dragonfly:/root/.small-dragonfly \
             -v /opt/dragonfly/dfdaemon.yml:/etc/dragonfly/dfdaemon.yml:ro \
             dragonflyoss/dfclient:1.0.6 \
             --config /etc/dragonfly/dfdaemon.yml
# docker logs -f dfclient
# docker exec -it dfclient tail -f /root/.small-dragonfly/logs/dfdaemon.log

备注:如果要使用二进制部署:

# wget https://github.com/dragonflyoss/Dragonfly/releases/download/v1.0.6/Dragonfly_1.0.6_linux_amd64.tar.gz
# tar -zxf Dragonfly_1.0.6_linux_amd64.tar.gz
# mv Dragonfly_1.0.6_linux_amd64/{supernode,dfget,dfdaemon} /usr/local/bin/
# rm -rf Dragonfly_1.0.6_linux_amd64/

# vi /etc/dragonfly/dfdaemon.yml
# 注意修改 dfget 路径
dfpath: /usr/local/bin/dfget

# cat > /usr/lib/systemd/system/dfdaemon.service <<EOF
[Unit]
Description=dfdaemon server
Documentation=https://github.com/dragonflyoss/Dragonfly
After=network.target

[Service]
ExecStart=/usr/local/bin/dfdaemon --config /etc/dragonfly/dfdaemon.yml

Type=simple
Restart=always
RestartSec=5
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target
EOF

# systemctl enable dfdaemon.service --now

步骤 3:修改 Docker Daemon 配置

我们需要修改 Docker Daemon 配置,通过 mirror 方式来使用 Dragonfly 进行镜像的拉取。即让 docker engine 走 dfdaemon
注意:如果是本机代理用 127.0.0.1 即可,如果额外部署 dfdaemon 节点的话,需要用 LB 去负载均衡,这里就要换成 LB 地址

# vi /etc/docker/daemon.json
{
  "registry-mirrors": ["http://127.0.0.1:65001"]
}

重启 Docker Daemon:

# systemctl restart docker

步骤 4:拉取镜像

通过以上步骤我们即完成了 Dragonfly 服务端与客户端的部署,并且设置了 Docker Daemon 通过 Dragonfly 来拉取 harbor 镜像。
注意:不要在 imageName 中包含映像库 URL,因为在启动 dfdaemon 时已使用注册表参数指定了库 URL

直接走公网下载:

# docker pull grafana/grafana:7.3.4

直接走 harbor 下载:

# docker pull harbor.sit.hupu.io/k8s/grafana:7.3.2

走 dragonfly 下载:
注意:当 dfdaemon 都挂掉了,那么这里就无法拉取了,会报错的
注意:首先去 harbor 拉取,如果 harbor 没有就去 docker hub 拉取,如果再没有就报错

# docker pull k8s/grafana:7.3.1

查看镜像:

# docker images |grep grafana
grafana/grafana                  7.3.4               651ff2dc930f        2 weeks ago         187MB
harbor.sit.hupu.io/k8s/grafana   7.3.2               68f75fcab5a9        3 weeks ago         186MB
k8s/grafana                      7.3.1               900b03b57e41        5 weeks ago         186MB

步骤 5:验证

您可以通过执行以下命令,检验 alpine 镜像是否通过 Dragonfly 来传输完成。

# docker exec dfclient grep 'downloading piece' /root/.small-dragonfly/logs/dfclient.log
...
2020-12-02 06:46:45.790 INFO sign:126-1606891605.701 : downloading piece:{"taskID":"3dad6a545f6d13baf8708306d6ae7dda0d4b45e14b2172cd9e0b4f4d0a249b8e","superNode":"10.64.57.72:8002","dstCid":"","range":"","result":502,"status":700,"pieceSize":0,"pieceNum":0}

另外还可以查看其他日志:

# docker exec -it dfclient ls -la /root/.small-dragonfly/logs
total 532
drwxr--r--    2 root     root            63 Dec  2 07:11 .
drwxr-xr-x    6 root     root            54 Dec  2 07:11 ..
-rw-r--r--    1 root     root        277869 Dec  2 07:12 dfclient.log
-rw-r--r--    1 root     root         14482 Dec  2 07:13 dfdaemon.log
-rw-r--r--    1 root     root          2259 Dec  2 07:12 dfserver.log

# docker exec dfclient cat /root/.small-dragonfly/logs/dfdaemon.log
2020-12-02 06:46:44.904 INFO sign:1 : start download url:https://harbor.sit.hupu.io/v2/base/openjdk/blobs/sha256:53301c1d4ea328b37c7cf0577a15b083d175a88e1375632a8ac6532e820a9332 to 98907c7d-6f41-46f9-b111-7a4a8cf1af9d in repo
2020-12-02 06:46:44.904 DEBU sign:1 : round trip with dfget: https://harbor.sit.hupu.io/v2/base/openjdk/blobs/sha256:b205ed23b4294eb568169e43e158008ab7c43c32ad78b8c7a492448a7bbd371b

查看目录:

# docker exec -it dfclient ls -la /root/.small-dragonfly/
total 4
drwxr-xr-x    6 root     root            54 Dec  2 07:11 .
drwx------    1 root     root            30 Dec  2 07:09 ..
drwxr-xr-x    2 root     root          4096 Dec  2 07:12 data
drwxr-xr-x    3 root     root            17 Dec  2 07:09 dfdaemon
drwxr--r--    2 root     root            63 Dec  2 07:11 logs
drwxr-xr-x    2 root     root            22 Dec  2 07:11 meta

发现拉取的数据:

# docker exec -it dfclient ls -la /root/.small-dragonfly/meta
total 4
drwxr-xr-x    2 root     root            22 Dec  2 07:11 .
drwxr-xr-x    6 root     root            54 Dec  2 07:11 ..
-rwxr-xr-x    1 root     root            21 Dec  2 07:11 host.meta

# docker exec -it dfclient ls -la /root/.small-dragonfly/data
total 256108
drwxr-xr-x    2 root     root          4096 Dec  2 07:12 .
drwxr-xr-x    6 root     root            54 Dec  2 07:11 ..
-rwxr-xr-x    1 root     root         30210 Dec  2 07:11 1f1b8628-743f-4d86-b6e6-daa039563005-86-1606893114.657.service
-rwxr-xr-x    1 root     root           916 Dec  2 07:12 21102506-36cd-431c-89ca-5b192bd38e92-226-1606893129.060.service
-rwxr-xr-x    1 root     root         11669 Dec  2 07:11 2e0ac47e-5a01-481e-be61-45e3bff18bfd-40-1606893114.210.service
-rwxr-xr-x    1 root     root       5779438 Dec  2 07:11 364e003e-0431-4123-8fcd-95d1f3d8adc5-113-1606893118.230.service
-rwxr-xr-x    1 root     root      12401014 Dec  2 07:12 39f690e5-3e86-44f2-bc5f-5b6e9cebcac5-171-1606893122.577.service
-rwxr-xr-x    1 root     root           541 Dec  2 07:12 3bfc69a4-1312-4590-9b9a-eed9243bf477-180-1606893122.861.service
-rwxr-xr-x    1 root     root        960596 Dec  2 07:11 40bb4cdd-74b6-4664-ac96-01fcd9cf5386-95-1606893114.949.service
-rwxr-xr-x    1 root     root           540 Dec  2 07:12 4f650c4d-1dae-4320-a4fb-be5bdde8cde5-163-1606893122.237.service
-rwxr-xr-x    1 root     root           200 Dec  2 07:12 6ec2527a-1962-4f9e-8eed-9d9e49599e78-153-1606893121.884.service
-rwxr-xr-x    1 root     root      18013716 Dec  2 07:12 73dbede6-d852-48be-ab0d-2e1c3fd485e5-103-1606893115.691.service
-rwxr-xr-x    1 root     root         57784 Dec  2 07:12 78ea94a9-c56b-4222-b078-41d8205d94a2-122-1606893120.421.service
-rwxr-xr-x    1 root     root      73361858 Dec  2 07:11 85f2cebd-030e-4ed1-8cdd-af91536b9dd5-47-1606893114.232.service
-rwxr-xr-x    1 root     root      43395889 Dec  2 07:11 89aa7794-2e25-47e8-ae5a-175d59b42a19-45-1606893114.223.service
-rwxr-xr-x    1 root     root     104078240 Dec  2 07:12 9f374057-72ef-4c23-b637-5cd23546a68a-143-1606893121.682.service
-rwxr-xr-x    1 root     root         56984 Dec  2 07:12 bfd1e2fc-60e6-4f44-8ca9-7160b0388152-130-1606893120.808.service
-rwxr-xr-x    1 root     root       4047182 Dec  2 07:12 c1d46b63-9c6b-4f63-a224-f963aa950c9f-139-1606893121.689.service
-rwxr-xr-x    1 root     root           590 Dec  2 07:12 cfdc0a72-f543-4060-b337-e1570b6646e3-199-1606893124.507.service
-rwxr-xr-x    1 root     root           412 Dec  2 07:11 da69371b-810e-41e9-84b8-a2b9c8ca3299-55-1606893114.207.service
-rwxr-xr-x    1 root     root           512 Dec  2 07:12 df8b81da-e052-41ef-bbc2-451d6ce13964-189-1606893123.371.service
-rwxr-xr-x    1 root     root           590 Dec  2 07:12 e0ee3ef4-7e0c-41a6-8e39-99c74b8df5aa-209-1606893127.091.service
-rwxr-xr-x    1 root     root           436 Dec  2 07:12 e22b5706-3ba4-470b-87bb-ecb158f8be62-214-1606893127.138.service

步骤 6:k8s 上验证

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: flog
  name: flog
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 4
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: flog
  strategy:
    type: Recreate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: flog
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - flog
              topologyKey: kubernetes.io/hostname
            weight: 100
      containers:
      - args:
        - -t
        - stdout
        - -n
        - "100000000000"
        - -l
        # 注意:image 无需带上 registry 地址和端口
        image: k8s/flog:latest
        imagePullPolicy: IfNotPresent
        name: flog
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

# kubectl apply -f flog.yaml

排错

错误 1:

# docker pull base/openjdk:v1.8
Error response from daemon: pull access denied for base/openjdk, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

解决:
需要指定 mirror 的仓库

registry_mirror:
  remote: https://harbor.sit.hupu.io 
  certs: null
  insecure: false
  direct: false

或:

--registry https://harbor.sit.hupu.io

错误2:

通过一个 daemonset 启动 2 GB 镜像(节点 200 台),然后蜻蜓 dfdaemon 就全挂了

# docker exec -it dfclient tail -f /root/.small-dragonfly/logs/dfdaemon.log
2020-12-24 03:48:42.019 ERRO sign:1 : download fail: dfget fail(exit status 2):exit status 2
2020-12-24 03:48:42.019 ERRO sign:1 : download fail: dfget fail(signal: killed):signal: killed
2020-12-24 03:48:42.019 ERRO sign:1 : download fail: dfget fail(exit status 80):exit status 80

解决:
架构:
nodes -> SLB -> dfdaemons -> supernodes -> harbor
阿里群里 2个大佬说目前 dfdaemon 目前只支持本地代理,2.0 架构会支持上面的部署模式。
但是不对,因为早上我刚开始用 ds 启动 grafana(200 个 grafana) 是正常的,grafana 镜像应该比较小。然后换成我自己特地弄的 2 个大镜像(单个 1.6G)就不行了。真心不靠谱啊。
又有大佬说:理论上 1.0 的就算这样使用,也是可以下载文件的,看上去应该是 dfget 有问题,下载不了文件导致的。这个还比较中肯。

查看发现 load 太高了,iowait 也很高,内存 8G 也用光了

# top
top - 12:12:23 up 1 day, 18:11,  1 user,  load average: 829.77, 905.13, 868.60
Tasks: 296 total,   1 running, 270 sleeping,   0 stopped,  25 zombie
%Cpu(s):  1.8 us,  4.6 sy,  0.0 ni,  0.0 id, 93.4 wa,  0.0 hi,  0.2 si,  0.0 st
KiB Mem :  7733220 total,   101964 free,  7292648 used,   338608 buff/cache
KiB Swap:        0 total,        0 free,        0 used.    63700 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND           
16499 root      20   0  134868  25764      0 S   5.4  0.3   1:18.02 dfget             
27092 root      20   0  185408  42756   1500 S   5.1  0.6   0:02.09 dfget             
28461 root      20   0  238580  96816      0 S   4.9  1.3   3:09.05 dfdaemon          
 3331 root      20   0  130176  17396      0 S   3.4  0.2   0:47.88 dfget             
25958 root      20   0  117940  47708   1124 S   3.3  0.6   0:02.20 dfget             
 3692 root      20   0  116684  40892      0 S   3.0  0.5   7:07.46 node_exporter     
21333 root      20   0  123460  18336      0 D   2.5  0.2   0:12.52 dfget             
26251 root      20   0  117848   8412    764 S   2.5  0.1   0:04.54 dfget             
25564 root      20   0  125208  16356      0 D   2.3  0.2   0:04.60 dfget             
 9414 root      20   0  134316  20448      0 S   2.1  0.3   0:55.74 dfget             
55887 root      20   0  212824  30608      0 S   1.5  0.4   1:55.30 dfget             
  465 root       0 -20       0      0      0 S   1.3  0.0   0:10.58 kworker/3:1H      
26240 root      20   0  185592  52772   1772 S   1.0  0.7   0:04.50 dfget             
 3379 root      20   0 1226372  12980   1104 S   0.7  0.2   5:24.39 /usr/local/clou   
26252 root      20   0  253520 101456   1668 D   0.7  1.3   0:03.31 dfget             
27865 root      20   0  117756  67168    880 S   0.7  0.9   0:02.94 dfget             
27888 root      20   0  185500  88564   1672 S   0.7  1.1   0:00.88 dfget             
28938 root      20   0  118032  35352   2488 S   0.7  0.5   0:00.65 dfget             
27656 root      20   0  117848  62964    576 S   0.5  0.8   0:01.02 dfget             
46168 root      10 -10  137704  10388      0 S   0.5  0.1   3:13.82 AliYunDun         
    2 root      20   0       0      0      0 D   0.3  0.0   0:03.46 kthreadd          
    3 root      20   0       0      0      0 S   0.3  0.0   0:12.40 ksoftirqd/0       
26227 root      20   0  185776 102396   1352 S   0.3  1.3   0:07.07 dfget             
26286 root      20   0  117848  58804    768 S   0.3  0.8   0:01.76 dfget             
27074 root      20   0  117848  21228    868 S   0.3  0.3   0:04.37 dfget             
27461 root      20   0  117848  21168   1152 S   0.3  0.3   0:01.76 dfget             
27577 root      20   0  117940  25304   1084 S   0.3  0.3   0:00.72 dfget             
27777 root      20   0  185868  81376   1184 S   0.3  1.1   0:02.01 dfget             
27823 root      20   0  185500  79720    700 S   0.3  1.0   0:00.90 dfget             
27881 root      20   0  118032  24388   1600 S   0.3  0.3   0:02.43 dfget             
# iostat -x 1
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.70    0.00    5.44   88.86    0.00    0.00

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
vda               0.00     0.00    0.00    2.00     0.00     8.00     8.00     0.00    0.00    0.00    0.00   0.00   0.00
vdb             207.00     0.00  114.00  520.00 21776.00 95992.00   371.51   119.03  414.62  242.16  452.43   1.47  93.00

dfget 进程很多:

# ps -elf|grep dfget|wc -l
339

查看发现 OOM:

[Thu Dec 24 12:23:09 2020] kthreadd invoked oom-killer: gfp_mask=0x3000d0, order=2, oom_score_adj=0
[Thu Dec 24 12:23:09 2020] kthreadd cpuset=/ mems_allowed=0
[Thu Dec 24 12:23:09 2020] CPU: 0 PID: 2 Comm: kthreadd Tainted: G           OE  ------------ T 3.10.0-957.21.3.el7.x86_64 #1
[Thu Dec 24 12:23:09 2020] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS 8c24b4c 04/01/2014
[Thu Dec 24 12:23:09 2020] Call Trace:
[Thu Dec 24 12:23:09 2020]  [<ffffffffa4963107>] dump_stack+0x19/0x1b
[Thu Dec 24 12:23:09 2020]  [<ffffffffa495db2a>] dump_header+0x90/0x229
[Thu Dec 24 12:23:09 2020]  [<ffffffffa4301292>] ? ktime_get_ts64+0x52/0xf0
[Thu Dec 24 12:23:09 2020]  [<ffffffffa43584df>] ? delayacct_end+0x8f/0xb0
[Thu Dec 24 12:23:09 2020]  [<ffffffffa43ba834>] oom_kill_process+0x254/0x3d0
[Thu Dec 24 12:23:09 2020]  [<ffffffffa43ba2dd>] ? oom_unkillable_task+0xcd/0x120
[Thu Dec 24 12:23:09 2020]  [<ffffffffa43ba386>] ? find_lock_task_mm+0x56/0xc0
[Thu Dec 24 12:23:09 2020]  [<ffffffffa43bb076>] out_of_memory+0x4b6/0x4f0
[Thu Dec 24 12:23:09 2020]  [<ffffffffa495e62e>] __alloc_pages_slowpath+0x5d6/0x724
[Thu Dec 24 12:23:09 2020]  [<ffffffffa43c1454>] __alloc_pages_nodemask+0x404/0x420
[Thu Dec 24 12:23:09 2020]  [<ffffffffa42c1cd0>] ? insert_kthread_work+0x40/0x40
[Thu Dec 24 12:23:09 2020]  [<ffffffffa4294dfd>] copy_process+0x1dd/0x1a40
[Thu Dec 24 12:23:09 2020]  [<ffffffffa4296811>] do_fork+0x91/0x320
[Thu Dec 24 12:23:09 2020]  [<ffffffffa4296ac6>] kernel_thread+0x26/0x30
[Thu Dec 24 12:23:09 2020]  [<ffffffffa42c2761>] kthreadd+0x2c1/0x300
[Thu Dec 24 12:23:09 2020]  [<ffffffffa42c24a0>] ? kthread_create_on_cpu+0x60/0x60
[Thu Dec 24 12:23:09 2020]  [<ffffffffa4975c37>] ret_from_fork_nospec_begin+0x21/0x21
[Thu Dec 24 12:23:09 2020]  [<ffffffffa42c24a0>] ? kthread_create_on_cpu+0x60/0x60
[Thu Dec 24 12:23:09 2020] Mem-Info:
[Thu Dec 24 12:23:09 2020] active_anon:1689377 inactive_anon:174 isolated_anon:0
 active_file:1285 inactive_file:2791 isolated_file:245
 unevictable:0 dirty:0 writeback:147 unstable:0
 slab_reclaimable:11342 slab_unreclaimable:35879
 mapped:334 shmem:254 pagetables:8860 bounce:0
 free:25505 free_pcp:0 free_cma:0
[Thu Dec 24 12:23:09 2020] Node 0 DMA free:15908kB min:136kB low:168kB high:204kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
[Thu Dec 24 12:23:09 2020] lowmem_reserve[]: 0 2795 7533 7533
[Thu Dec 24 12:23:09 2020] Node 0 DMA32 free:43740kB min:25024kB low:31280kB high:37536kB active_anon:2495316kB inactive_anon:184kB active_file:2308kB inactive_file:7212kB unevictable:0kB isolated(anon):0kB isolated(file):1184kB present:3111608kB managed:2865384kB mlocked:0kB dirty:164kB writeback:376kB mapped:784kB shmem:284kB slab_reclaimable:19756kB slab_unreclaimable:47628kB kernel_stack:44064kB pagetables:10072kB unstable:0kB bounce:0kB free_pcp:408kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:3153 all_unreclaimable? no
[Thu Dec 24 12:23:09 2020] lowmem_reserve[]: 0 0 4738 4738
[Thu Dec 24 12:23:09 2020] Node 0 Normal free:42300kB min:42416kB low:53020kB high:63624kB active_anon:4262192kB inactive_anon:512kB active_file:3348kB inactive_file:5520kB unevictable:0kB isolated(anon):0kB isolated(file):496kB present:4980736kB managed:4851916kB mlocked:0kB dirty:40kB writeback:212kB mapped:1028kB shmem:732kB slab_reclaimable:25612kB slab_unreclaimable:95888kB kernel_stack:35232kB pagetables:25368kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:1787 all_unreclaimable? no
[Thu Dec 24 12:23:09 2020] lowmem_reserve[]: 0 0 0 0
[Thu Dec 24 12:23:09 2020] Node 0 DMA: 1*4kB (U) 0*8kB 0*16kB 1*32kB (U) 2*64kB (U) 1*128kB (U) 1*256kB (U) 0*512kB 1*1024kB (U) 1*2048kB (M) 3*4096kB (M) = 15908kB
[Thu Dec 24 12:23:09 2020] Node 0 DMA32: 11064*4kB (UM) 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 44256kB
[Thu Dec 24 12:23:09 2020] Node 0 Normal: 1723*4kB (UEM) 4480*8kB (UEM) 4*16kB (UM) 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 42796kB
[Thu Dec 24 12:23:09 2020] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=1048576kB
[Thu Dec 24 12:23:09 2020] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
[Thu Dec 24 12:23:09 2020] 3797 total pagecache pages
[Thu Dec 24 12:23:09 2020] 0 pages in swap cache
[Thu Dec 24 12:23:09 2020] Swap cache stats: add 0, delete 0, find 0/0
[Thu Dec 24 12:23:09 2020] Free swap  = 0kB
[Thu Dec 24 12:23:09 2020] Total swap = 0kB
[Thu Dec 24 12:23:09 2020] 2027084 pages RAM
[Thu Dec 24 12:23:09 2020] 0 pages HighMem/MovableOnly
[Thu Dec 24 12:23:09 2020] 93782 pages reserved
[Thu Dec 24 12:23:09 2020] [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
[Thu Dec 24 12:23:09 2020] [  505]     0   505    11115      139      23        0         -1000 systemd-udevd
[Thu Dec 24 12:23:09 2020] [  757]     0   757     6653      140      19        0             0 systemd-logind
[Thu Dec 24 12:23:09 2020] [  762]   999   762   153083     2192      62        0             0 polkitd
[Thu Dec 24 12:23:09 2020] [  763]    81   763    14883      441      33        0          -900 dbus-daemon
[Thu Dec 24 12:23:09 2020] [  771]   998   771    29446      130      28        0             0 chronyd
[Thu Dec 24 12:23:09 2020] [  816]     0   816    31579      166      19        0             0 crond
[Thu Dec 24 12:23:09 2020] [  819]     0   819     6476       51      19        0             0 atd
[Thu Dec 24 12:23:09 2020] [  828]     0   828    27526       32      11        0             0 agetty
[Thu Dec 24 12:23:09 2020] [  829]     0   829    27526       33       9        0             0 agetty
[Thu Dec 24 12:23:09 2020] [ 1025]     0  1025    25710      514      49        0             0 dhclient
[Thu Dec 24 12:23:09 2020] [ 1086]     0  1086   143480     2768      98        0             0 tuned
[Thu Dec 24 12:23:09 2020] [ 1339]     0  1339     4451      120      13        0             0 assist_daemon
[Thu Dec 24 12:23:09 2020] [ 1372]     0  1372    10534      190      13        0             0 aliyun-service
[Thu Dec 24 12:23:09 2020] [ 3621]     0  3621     5632       91      15        0             0 argusagent
[Thu Dec 24 12:23:09 2020] [ 3623]     0  3623   288161     3274      57        0             0 /usr/local/clou
[Thu Dec 24 12:23:09 2020] [ 3731]   997  3731    19740      202      37        0             0 zabbix_agentd
[Thu Dec 24 12:23:09 2020] [ 3732]   997  3732    19765      318      37        0             0 zabbix_agentd
[Thu Dec 24 12:23:09 2020] [ 3733]   997  3733    19740      228      38        0             0 zabbix_agentd
[Thu Dec 24 12:23:09 2020] [ 3734]   997  3734    19740      228      38        0             0 zabbix_agentd
[Thu Dec 24 12:23:09 2020] [ 3735]   997  3735    19740      228      38        0             0 zabbix_agentd
[Thu Dec 24 12:23:09 2020] [ 3736]   997  3736    20848      309      42        0             0 zabbix_agentd
[Thu Dec 24 12:23:09 2020] [ 3973]     0  3973    29123    11172      33        0             0 node_exporter
[Thu Dec 24 12:23:09 2020] [ 4012]     0  4012   109224      148      27        0             0 AliSecGuard
[Thu Dec 24 12:23:09 2020] [ 4762]     0  4762    28216      258      57        0         -1000 sshd
[Thu Dec 24 12:23:09 2020] [ 6035]     0  6035    13881      114      27        0         -1000 auditd
[Thu Dec 24 12:23:09 2020] [ 7333]     0  7333   185371     8005      67        0          -999 containerd
[Thu Dec 24 12:23:09 2020] [ 8114]     0  8114   191483    14776     116        0         -1000 dockerd
[Thu Dec 24 12:23:09 2020] [21528]     0 21528    96053     1291      62        0             0 rsyslogd
[Thu Dec 24 12:23:09 2020] [31410]     0 31410    54259     1829      18        0         -1000 docker-proxy
[Thu Dec 24 12:23:09 2020] [31425]     0 31425    28343     2055      13        0          -998 containerd-shim
[Thu Dec 24 12:23:09 2020] [31445]     0 31445    60469    23040      96        0             0 dfdaemon
[Thu Dec 24 12:23:09 2020] [49106]     0 49106     8133      360      21        0             0 AliYunDunUpdate
[Thu Dec 24 12:23:09 2020] [49133]     0 49133    34587     2763      67        0             0 AliYunDun
[Thu Dec 24 12:23:09 2020] [58651]     0 58651    39180      331      79        0             0 sshd
[Thu Dec 24 12:23:09 2020] [58653]  1002 58653    39180      341      76        0             0 sshd
[Thu Dec 24 12:23:09 2020] [58654]  1002 58654    28991      235      13        0             0 bash
[Thu Dec 24 12:23:09 2020] [58685]     0 58685    60294      293      73        0             0 sudo
[Thu Dec 24 12:23:09 2020] [58686]     0 58686    47944      146      49        0             0 su
[Thu Dec 24 12:23:09 2020] [58687]     0 58687    29023      258      13        0             0 bash
[Thu Dec 24 12:23:09 2020] [ 9952]     0  9952    30543     2953      26        0             0 dfget
[Thu Dec 24 12:23:09 2020] [11576]     0 11576    30060     1638      22        0             0 dfget
[Thu Dec 24 12:23:09 2020] [13986]     0 13986    33625     6044      44        0             0 dfget
[Thu Dec 24 12:23:09 2020] [14617]     0 14617    29462     1883      18        0             0 dfget
[Thu Dec 24 12:23:09 2020] [16105]     0 16105    35097     6758      52        0             0 dfget
...
[Thu Dec 24 12:23:09 2020] [42344]     0 42344    29393     1261      19        0             0 dfget
[Thu Dec 24 12:23:09 2020] [42345]     0 42345    29324     1516      18        0             0 dfget
[Thu Dec 24 12:23:09 2020] [42346]     0 42346    29347     1457      19        0             0 dfget
[Thu Dec 24 12:23:09 2020] [42560]     0 42560    57650     1292      26        0          -998 runc
[Thu Dec 24 12:23:09 2020] [42779]     0 42779    29324     1279      17        0             0 dfget
[Thu Dec 24 12:23:09 2020] [42961]   997 42961    20848      266      44        0             0 zabbix_agentd
[Thu Dec 24 12:23:09 2020] [42977]     0 42977    41388      209      37        0             0 crond
[Thu Dec 24 12:23:09 2020] [43068]     0 43068    29324     1472      18        0             0 dfget
[Thu Dec 24 12:23:09 2020] Out of memory: Kill process 35174 (dfget) score 14 or sacrifice child
[Thu Dec 24 12:23:09 2020] Killed process 35174 (dfget) total-vm:185500kB, anon-rss:109556kB, file-rss:0kB, shmem-rss:0kB

查看日志发现一些节点回源通信错误,换成 --net=host 试试,可惜问题也无法解决。

大佬说明:
一般 dfclient 都是节点粒度的,镜像的下载都是一对一的,只会启动一个 dfget 去下载,然后你现在的这个模式,变成了多对多,启动了几百个 dfget 去下载,小文件还好,大文件就爆了,我看你设置的 down limit 是 50,这样每个 dfget 占用的内存就可能会达到 15 * 50M 的,几百个 dfget 一起下载,多半就跪了。就算改小了,这里还是可能有问题的,dfclient 没有针对大量的请求做优化,还是会有崩掉的可能。
后面会上线一个 seed 的功能,应该可以满足你这个需求的,不会有那么多的 dfget 了,是单进程的

后续

换方案,每个节点使用二进制部署,然后本地代理,使用 10 个 daemonset(15 个节点),最终部分镜像下载成功,部分就一直无法下载了,惨不忍睹,真不知道阿里内部说严重依靠dragonfly做镜像分发是否是真的,或者说开源出来的版本完全就是个摆设?只能用于少量的镜像分发,对应大量的镜像直接挂,那要它何用?

kubectl delete -f grafana-dragonfly.yaml -f grafana-dragonfly0.yaml -f grafana-dragonfly1.yaml -f grafana-dragonfly2.yaml -f grafana-dragonfly3.yaml -f grafana-dragonfly4.yaml -f grafana-dragonfly5.yaml -f grafana-dragonfly6.yaml -f grafana-dragonfly7.yaml -f grafana-dragonfly8.yaml -f grafana-dragonfly9.yaml 
snap_screen_20201225175017.png

结论

测试了几天,目前发现 dragonfly 无法应对量数据分发场景,且有一些性能问题,换了两组方案都无法成功 pull。
看看就好,生产慎重。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容