Dfdaemon 配合 Caddy 搭建 Container Registry 镜像

在国内,有许多免费的 Docker Hub 镜像可以使用。例如腾讯云提供的镜像地址

  • https://mirror.ccs.tencentyun.com

但对于 ghcr.iogcr.io 这些仓库,则很少有提供。所以便想着要不自己做镜像。一开始,是想用 Docker 提供的 registry 来做镜像服务。但发现,每针对一个仓库,便需要新启一个 registry,不免有些浪费,后来找到了 Dfdaemon,这个可以同时对多个仓库提供镜像。

这是我使用的配置,只保留了用于镜像服务的功能

# 当 daemon 退出是, 是否保存缓存数据。
# 保留缓存数据在升级 daemon 的时候比较有用。
# 默认为 false。
keepStorage: true

# Peer task 存储选项。
storage:
  # Task data 过期时间。
  # 超过指定时间没有访问之后,缓存数据将会被清理。
  taskExpireTime: 720h
  # storage strategy when process task data
  # io.d7y.storage.v2.simple : download file to data directory first, then copy to output path, this is default action
  #                           the download file in date directory will be the peer data for uploading to other peers
  # io.d7y.storage.v2.advance: download file directly to output path with postfix, hard link to final output,
  #                            avoid copy to output path, fast than simple strategy, but:
  #                            the output file with postfix will be the peer data for uploading to other peers
  #                            when user delete or change this file, this peer data will be corrupted
  # default is io.d7y.storage.v2.simple
  strategy: io.d7y.storage.v2.simple
  # 磁盘 GC 阈值,缓存数据超过阈值后,最旧的缓存数据将会被清理。
  diskGCThreshold: 10Gi
  # 磁盘利用率 GC 阈值,磁盘利用率超过阈值后,最旧的缓存数据将会被清理。
  # 例如, diskGCThresholdPercent=80, 当磁盘利用率超过 80% 的时候,会进行清理最旧的缓存数据。
  diskGCThresholdPercent: 80
  # 相同 task id 的 peer task 是否复用缓存。
  multiplex: true

# 代理服务详细选项。
proxy:
  # 哈希 URL 的时候的过滤选项。
  # 例如:defaultFilter: "Expires&Signature&ns":
  #  http://localhost/xyz?Expires=111&Signature=222&ns=docker.io and http://localhost/xyz?Expires=333&Signature=999&ns=docker.io
  # 是相同的 task, 也可以通过代理增加 X-Dragonfly-Filter Header 覆盖默认的 Filter。
  defaultFilter: "Expires&Signature&ns"
  tcpListen:
    # 监听的网络命名空间, 例如:/proc/1/ns/net。
    # 主要用在部署 kubernetes 中的时候,daemon 不使用 host network 时,监听宿主机的端口。
    # 仅支持 Linux。
    # namespace: ''
    # 监听地址。
    listen: 0.0.0.0
    # 监听端口。
    port: 65001
  registryMirror:
    # 开启时,使用 header 里的 "X-Dragonfly-Registry" 替换 url 里的 host。
    dynamic: true
    # 镜像中心地址。
    url: https://index.docker.io

然后使用 docker compose 启动

version: "3"

services:
  k8s:
    image: dragonflyoss/dfdaemon
    restart: always
    ports:
      - "127.0.0.1:9039:65001"
    volumes:
      - ./dfget.yaml:/etc/dragonfly/dfget.yaml:ro
      - ./dragonfly_data:/var/lib/dragonfly
      - ./dragonfly_cache:/var/cache/dragonfly

Dfdaemon 的上有仓库可以用 http header 的 X-Dragonfly-Registry 字段动态修改,所以配合 http 的反向代理可以为不同的入口地址,配置不同的仓库镜像,这里我使用了 Caddy

mirrors.example.com {
  handle_path /k8s/* {
    reverse_proxy {
      to http://127.0.0.1:9039
      header_up X-Dragonfly-Registry "https://k8s.gcr.io"
    }
  }

  handle_path /docker/* {
    reverse_proxy {
      to http://127.0.0.1:9039
      header_up X-Dragonfly-Registry "https://mirror.gcr.io"
    }
  }

  handle_path /ghcr/* {
    reverse_proxy {
      to http://127.0.0.1:9039
      header_up X-Dragonfly-Registry "https://ghcr.io"
    }
  }
}

这样就有了三个镜像仓库

  • https://mirrors.example.com/k8s -> https://k8s.gcr.io
  • https://mirrors.example.com/docker -> https://mirror.gcr.io
  • https://mirrors.example.com/ghcr -> https://ghcr.io

然后配置 containerd ,例如配置 ghcr.io 镜像,在 /etc/containerd/certs.d 目录下新建 ghcr.io 目录,该目录下新建 hosts.toml

server = "https://ghcr.io"

[host."https://mirrors.cr.zhtto.top/ghcr"]
  capabilities = ["pull", "resolve"]

验证

ctr --debug images pull 镜像 --hosts-dir "/etc/containerd/certs.d"