通过Dragonfly拉取镜像
操作场景
随着企业业务的不断扩展,企业应用中容器集群的规模也会随之不断增长。当容器集群达到一定的规模时集群中容器镜像的分发将面临挑战,首先面临压力的是swr服务或者后端存储的带宽。在一些较大的集群中,可能有成百上千个节点同时拉取一个镜像,带宽压力不容小觑。
解决这个问题的方法有很多,比如划分集群、增加缓存和负载均衡等,但较好的解决方法是采用P2P镜像分发技术,把镜像数据存储在P2P网络集群中,拉取时从多个P2P节点拉取。P2P镜像分发技术也有多种,如 Kraken,BitTorrent,Dragonfly等。本文以Dragonfly为例,在CCE集群上部署Dragonfly,验证通过代理方式从Dragonfly拉取镜像的能力,Dragonfly的其他功能或配置请参考文末给出的文档。
部署结构如下:
Dragonfly简介
架构简介
Dragonfly组件可分为四类:Manager、Scheduler、Seed Peer 和 Peer,具体见下图。
- Manager:维护各个P2P集群之间的关系,主要提供动态配置管理、数据收集等功能。同时包含一个前端控制台,方便用户可视化地操作和管理集群。
- Scheduler:为下载节点选择最佳的下载父节点。在适当的时候,触发SeedPeer进行回源下载。
- Seed Peer:提供上传、下载、分发镜像块功能,可以作为P2P网络中的根节点,允许Scheduler主动发起回源。
- Peer:提供上传、下载、p2p分发等功能。
镜像拉取
- 下载镜像,下载请求会通过 Peer HTTP Proxy 代理到 Dragonfly,Peer 会先将 Task 注册到 Scheduler,Scheduler 会检查 Task 的元数据,判断该 Task 是否在 P2P 集群中首次下载。
- 如果是首次下载,则会触发 Seed Peer 回源下载,并根据 Piece 级别进行 Task 的切分。注册成功后,Scheduler根据 Piece 级别将 Seedpeer调度给Peer进行流式传输。当一个 Piece 下载成功后,会将Piece的元数据上报给 Scheduler,以便下次调度,Piece会在多个peer内分发。
- 如果是非首次下载,Scheduler 会调度其他一组最优Peer进行下载。代理Peer会从不同的 Peer下载Piece,然后拼接并返回整个文件,P2P下载完成。
前提条件
- 已存在CCE集群且该集群下划分有节点池,把dragonfly安装到该节点池内的node上。下文中以CCE集群的test-dragonfly-nodepool节点池为例进行安装。
- 在CCE集群的某一台node节点上已安装helm工具。
部署Dragonfly组件
- 下载并解压Dragonlfy的helm-chart包到CCE集群中已安装helm工具的节点上。
- 修改dragonfly/values.yaml中的storageClass参数的value值为“csi-disk”;
修改nodeSelector的值为dragonfly节点池的标签cce.cloud.com/cce-nodepool: "test-dragonfly-nodepool",该标签是节点池创建成功后自动根据生成的,请将test-dragonfly-nodepool修改为您的节点池名称。该配置是为了把dragonfly组件都部署在dragonfly节点池,与业务节点池进行隔离。
- 开始安装Dragonfly
- 进入helm-chart包解压后的dragonfly目录执行安装命令。
helm install --wait --create-namespace --namespace dragonfly-system dragonfly .
如果安装失败请先卸载然后再次安装。卸载后需要清理您的集群的dragonfly相关pvc,否则会影响下次重装Dragonfly。卸载命令如下:
helm uninstall --namespace dragonfly-system dragonfly
- 回显如下表示部署成功。此时Dragonfly全部组件已经成功运行。安装过程耗时几分钟,请您耐心等待。
上图dragonfly-client即架构图中的peer,dragonfly-seed-client即架构图中的seed peer。
部署完成之后还会创建出来一些服务,如dragonfly-manager、dragon-mysql等,其中dragonfly-manager是用户的Console界面,需要暴露出来给用户访问。
- pod都运行起来后,在您的集群里需要为守护进程集下的名称为dragonfly-client的工作负载创建一个负载均衡类型的服务,容器端口和服务端口均配置为4001,即转发到dragonfly-client pod的4001的端口,请记录该负载均衡类型服务的访问地址列的负载均衡私有IP的值,如下图中的192.168.0.177:4001,该地址将用于后续Docker或者Containerd容器引擎客户端的代理端地址。
- 进入helm-chart包解压后的dragonfly目录执行安装命令。
- 登录CCE云容器引擎控制台,进入您的集群,单击左侧菜单栏的“服务”,更新dragonfly-manager服务的访问类型为节点访问(NodePort),使其可以通过外部访问。
访问其8080映射地址的node-ip:node-port。
用户名、密码默认 root/dragonfly,通过控制台可以查看各个组件和任务信息。
至此Dragonfly已经部署完成并通过elb类型的service暴露了Dragonfly-client的4001端口作为http代理端口
验证通过Dragonfly组件拉取镜像
上文已经搭建了Dragonfly集群并通过elb暴露了Dragonfly-client代理服务(上文样例中为192.168.0.177:4001),接下来通过该地址把Containerd容器引擎客户端以及Docker容器引擎客户端的流量接入Dragonfly。
- 配置Containerd容器引擎客户端以HTTP_PROXY的方式接入Dragonfly。
配置 Proxy 时要特别注意NO_PROXY的配置,建议除了拉取镜像之外的请求均配置到NO_PROXY里面。避免出现网络访问异常甚至业务异常。
- 编辑/etc/systemd/system/containerd.service.d/http-proxy.conf文件,如果/etc/systemd/system/containerd.service.d/目录不存在则手工创建。
vim /etc/systemd/system/containerd.service.d/http-proxy.conf
- 拷贝下面的内容到http-proxy.conf文件中,请将192.168.0.177:4001修改为您步骤3记录的地址。 http代理将拉取镜像的流量接入Dragonfly。
[Service] Environment="HTTP_PROXY=http://192.168.0.177:4001" Environment="HTTPS_PROXY=http://192.168.0.177:4001" Environment="NO_PROXY=localhost,127.0.0.1,127.0.0.0/8,.cluster.local,.svc"
- 编辑/etc/systemd/system/containerd.service.d/http-proxy.conf文件,如果/etc/systemd/system/containerd.service.d/目录不存在则手工创建。
- 配置忽略证书校验。
- 如果Dragonfly未配置https的证书,需要编辑Containerd配置文件config.toml,让Containerd忽略证书验证。
vim /etc/containerd/config.toml
拷贝下面的内容到config.toml文件中。请将test-uvpv1j.swr-pro.myhuaweicloud.com/library/busybox:latest替换为您的目标镜像的地址。
[plugins."io.containerd.grpc.v1.cri".registry.configs] [plugins."io.containerd.grpc.v1.cri".registry.configs."test-uvpv1j.swr-pro.myhuaweicloud.com".tls] insecure_skip_verify = true
- 如果Dragonfly已经配置有效https证书可不用做此步骤。
- 如果Dragonfly未配置https的证书,需要编辑Containerd配置文件config.toml,让Containerd忽略证书验证。
- 重启Containerd服务并拉取镜像。
systemctl daemon-reload && systemctl restart containerd.service crictl -debug pull test-uvpv1j.swr-pro.myhuaweicloud.com/library/mysql:8.0.36-debian-12-r10
请将crictl -debug pull命令中的test-uvpv1j.swr-pro.myhuaweicloud.com/library/busybox:latest替换为您的目标镜像的地址。
如果反复拉取镜像验证,需要先把本地已拉取的镜像清理掉,如果本地已存在要拉取的镜像则不会再次去拉取。
crictl rmi test-uvpv1j.swr-pro.myhuaweicloud.com/library/mysql:8.0.36-debian-12-r10
- 登录CCE云容器引擎控制台,进入您的集群,依次单击“工作负载-守护进程集”,查看dragonfly-client工作负载的更多列的“日志”,可以看到如下镜像拉取信息,表示通过Dragonfly拉取镜像成功。
- 配置Docker容器引擎客户端以HTTP_PROXY的方式接入Dragonfly。
配置 Proxy 时要特别注意NO_PROXY的配置,建议除了拉取镜像之外的请求均配置到NO_PROXY里面。避免出现网络访问异常甚至业务异常。
- 编辑/etc/systemd/system/docker.service.d/http-proxy.conf文件,如果/etc/systemd/system/docker.service.d/目录不存在则手工创建。
vim /etc/systemd/system/docker.service.d/http-proxy.conf
- 拷贝下面的内容到http-proxy.conf文件中,请将192.168.0.177:4001修改为您步骤3记录的地址。 http代理将拉取镜像的流量接入Dragonfly。
[Service] Environment="HTTP_PROXY=http://192.168.0.177:4001" Environment="HTTPS_PROXY=http://192.168.0.177:4001" Environment="NO_PROXY=localhost,127.0.0.1,127.0.0.0/8,.cluster.local,.svc"
- 编辑/etc/systemd/system/docker.service.d/http-proxy.conf文件,如果/etc/systemd/system/docker.service.d/目录不存在则手工创建。
- 配置忽略证书校验。
- 如果Dragonfly已经配置有效https证书可不用做此步骤。
- 重启服务拉取镜像。
systemctl daemon-reload && systemctl restart docker.service docker pull test-uvpv1j.swr-pro.myhuaweicloud.com/library/busybox:latest
请将docker pull命令中的test-uvpv1j.swr-pro.myhuaweicloud.com/library/busybox:latest替换为您的目标镜像的地址。
如果反复拉取镜像验证,需要先把本地已拉取的镜像清理掉,如果本地已存在要拉取的镜像则不会再次去拉取。
docker rmi test-uvpv1j.swr-pro.myhuaweicloud.com/library/busybox:latest
- 登录CCE云容器引擎控制台,进入您的集群,依次单击“工作负载-守护进程集”,查看dragonfly-client工作负载的更多列的“日志”,可以看到如下镜像拉取信息,表示通过Dragonfly拉取镜像成功。
了解更多