使用P2P加速

P2P加速利用计算节点的内网带宽资源,在节点之间分发镜像。P2P加速功能可以提升镜像拉取速度,减少应用部署时间。当大规模容器集群批量下载镜像时,您可以使用P2P加速功能提升镜像拉取速度。本文介绍如何使用P2P加速功能提升镜像拉取速度。

背景信息

当大规模容器集群批量下载镜像时,容器镜像存储的网络带宽会成为性能瓶颈,导致镜像拉取缓慢。P2P加速功能可以利用您计算节点的带宽资源,进行节点之间的镜像分发,以减少对容器镜像存储的压力,可以大幅提升镜像拉取速度,减少应用部署时间。经过测试,1000节点规模下拉取1 GB大小的镜像,相比普通镜像拉取方式(以带宽为10 Gbps为例),P2P加速方式可以减少95%以上的镜像拉取时间。此外,新版的P2P加速方案相较于旧版的P2P有30%~50%的性能提升。

您可以在以下场景使用P2P加速功能。

  • ACK集群

  • IDC或其他云厂商集群

前提条件

安装P2P加速套件。

启用P2P加速

您可以通过添加标签的方式启用P2P加速,可以为应用负载添加P2P加速标签,例如Pod、Deployment等。也可以为ACK集群的命名空间设置P2P加速标签。为命名空间设置P2P加速标签后,该命名空间内的所有符合加速条件的应用负载都会启用P2P加速,无需再修改应用负载的YAML文件。根据实际情况选择任一方式添加P2P加速标签。

说明

标签的名称为k8s.aliyun.com/image-accelerate-mode,值为p2p

  • 为应用负载添加P2P加速标签。

    以下以Deployment为例设置标签。执行以下命令,为Deployment设置标签。

    kubectl edit deploy <Deployment名称>

    在Deployment文件中添加标签k8s.aliyun.com/image-accelerate-mode: p2p

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: test
      labels:
        app: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            # enable P2P
            k8s.aliyun.com/image-accelerate-mode: p2p
            app: nginx
        spec:
          # your ACR instacne image pull secret
          imagePullSecrets:
          - name: test-registry
          containers:
          # your ACR instacne image
          - image: test-registry-vpc.cn-hangzhou.cr.aliyuncs.com/docker-builder/nginx:latest
            name: test
            command: ["sleep", "3600"]
  • 为命名空间添加P2P加速标签

    • 通过控制台添加P2P加速标签。

      1. 登录容器服务管理控制台

      2. 在控制台左侧导航栏中,单击集群

      3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情

      4. 在集群管理页面单击命名空间与配额

      5. 命名空间页面单击目标命名空间操作列的编辑

      6. 编辑命名空间对话框中设置标签变量名称k8s.aliyun.com/image-accelerate-mode标签变量值p2p,然后单击确定

    • 通过命令行添加P2P加速标签。

      kubectl label namespaces <your-namespace> k8s.aliyun.com/image-accelerate-mode=p2p

验证P2P加速

启用P2P加速后,P2P组件会自动为Pod注入P2P相关annotation、P2P加速镜像地址以及对应的镜像拉取凭证。

重要

P2P镜像拉取凭证与您原先配置的非P2P镜像地址拉取凭证仅镜像仓库域名不一样,其他凭证信息一致。因此,若您原先镜像拉取凭证用户信息配置错误,也会导致P2P镜像拉取失败。

执行以下命令,查看Pod。

kubectl get po <Pod的名称> -oyaml

预期输出:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    # inject p2p-annotations automatically
    k8s.aliyun.com/image-accelerate-mode: p2p
    k8s.aliyun.com/p2p-config: '...'
spec:
  containers:
   # inject image to p2p endpoint
   - image: test-registry-vpc.distributed.cn-hangzhou.cr.aliyuncs.com:65001/docker-builder/nginx:latest
  imagePullSecrets:
  - name: test-registry
  # inject image pull secret for p2p endpoint
  - name: acr-credential-test-registry-p2p

可以看到,Pod已注入P2P相关annotation、P2P加速镜像地址以及对应的镜像拉取凭证,说明启用P2P加速成功。

启用客户端指标采集(可选)

P2P Metrics说明

打开Metrics

安装P2P时,打开Metrics配置。

p2p:

  v2:
    # Component for P2P v2
    image: registry-vpc.__ACK_REGION_ID__.aliyuncs.com/acs/dadi-agent
    imageTag: v0.1.2-72276d4-aliyun

    # Concurrency limit number of layers downloading by each node proxy
    proxyConcurrencyLimit: 128

    # The server port to communicate with P2P nodes
    p2pPort: 65002

    cache:
      # Disk cache capacity in bytes, default 4GB
      capacity: 4294967296
      # Set to 1 if you are using high-performance disks on your ECS, e.g. ESSD PL2/PL3
      aioEnable: 0
    exporter:
      # Set to true if you want to collect component metrics
      enable: false
      port: 65003

    # limit for downstream throughput
    throttleLimitMB: 512

访问方式

P2P YAML中关于exporter字段定义了Metrics的端口。

ExporterConfig:
  enable: true # 是否开启
  port: 65006  # 监听端口
  standaloneExporterPort: true # 是否采用独立端口暴露,如果为false,则通过http服务端口吐出

curl 127.0.0.1:$port/metrics可以得到Metrics结果如下。

# HELP DADIP2P_Alive 
# TYPE DADIP2P_Alive gauge
DADIP2P_Alive{node="192.168.69.172:65005",mode="agent"} 1.000000 1692156721833

# HELP DADIP2P_Read_Throughtput Bytes / sec
# TYPE DADIP2P_Read_Throughtput gauge
DADIP2P_Read_Throughtput{node="192.168.69.172:65005",type="pread",mode="agent"} 0.000000 1692156721833
DADIP2P_Read_Throughtput{node="192.168.69.172:65005",type="download",mode="agent"} 0.000000 1692156721833
DADIP2P_Read_Throughtput{node="192.168.69.172:65005",type="peer",mode="agent"} 0.000000 1692156721833
DADIP2P_Read_Throughtput{node="192.168.69.172:65005",type="disk",mode="agent"} 0.000000 1692156721833
DADIP2P_Read_Throughtput{node="192.168.69.172:65005",type="http",mode="agent"} 0.000000 1692156721833

# HELP DADIP2P_QPS 
# TYPE DADIP2P_QPS gauge
DADIP2P_QPS{node="192.168.69.172:65005",type="pread",mode="agent"} 0.000000 1692156721833
DADIP2P_QPS{node="192.168.69.172:65005",type="download",mode="agent"} 0.000000 1692156721833
DADIP2P_QPS{node="192.168.69.172:65005",type="peer",mode="agent"} 0.000000 1692156721833
DADIP2P_QPS{node="192.168.69.172:65005",type="disk",mode="agent"} 0.000000 1692156721833
DADIP2P_QPS{node="192.168.69.172:65005",type="http",mode="agent"} 0.000000 1692156721833

# HELP DADIP2P_MaxLatency us
# TYPE DADIP2P_MaxLatency gauge
DADIP2P_MaxLatency{node="192.168.69.172:65005",type="pread",mode="agent"} 0.000000 1692156721833
DADIP2P_MaxLatency{node="192.168.69.172:65005",type="download",mode="agent"} 0.000000 1692156721833
DADIP2P_MaxLatency{node="192.168.69.172:65005",type="peer",mode="agent"} 0.000000 1692156721833
DADIP2P_MaxLatency{node="192.168.69.172:65005",type="disk",mode="agent"} 0.000000 1692156721833
DADIP2P_MaxLatency{node="192.168.69.172:65005",type="http",mode="agent"} 0.000000 1692156721833

# HELP DADIP2P_Count Bytes
# TYPE DADIP2P_Count gauge
DADIP2P_Count{node="192.168.69.172:65005",type="pread",mode="agent"} 0.000000 1692156721833
DADIP2P_Count{node="192.168.69.172:65005",type="download",mode="agent"} 0.000000 1692156721833
DADIP2P_Count{node="192.168.69.172:65005",type="peer",mode="agent"} 0.000000 1692156721833
DADIP2P_Count{node="192.168.69.172:65005",type="disk",mode="agent"} 0.000000 1692156721833
DADIP2P_Count{node="192.168.69.172:65005",type="http",mode="agent"} 0.000000 1692156721833

# HELP DADIP2P_Cache 
# TYPE DADIP2P_Cache gauge
DADIP2P_Cache{node="192.168.69.172:65005",type="allocated",mode="agent"} 4294967296.000000 1692156721833
DADIP2P_Cache{node="192.168.69.172:65005",type="used",mode="agent"} 4294971392.000000 1692156721833

# HELP DADIP2P_Label 
# TYPE DADIP2P_Label gauge

指标说明

指标名

  • DADIP2P_Alive:服务是否存活。

  • DADIP2P_Read_Throughtput:P2P服务吞吐,单位:byte/s。

  • DADIP2P_QPS:QPS。

  • DADIP2P_MaxLatency:延迟统计,单位:us。

  • DADIP2P_Count:流量统计,单位:bytes。

  • DADIP2P_Cache:单机Cache用量,单位:bytes。

Tag

  • node:P2P Agent/Root的服务IP和端口。

  • type:指标类型。

    • pread:处理下游请求。

    • download:回源。

    • peer:P2P网络分发。

    • disk:处理磁盘。

    • http:处理HTTP请求。

    • allocated:缓存分配空间。

    • used:缓存使用空间。

指标示例

DADIP2P_Count{node="11.238.108.112:9877",type="http",mode="agent"} 4248808352.000000 1692157615810
Agent服务累计处理HTTP请求流量:4248808352字节。

DADIP2P_Cache{node="11.238.108.112:9877",type="used",mode="agent"} 2147487744.000000 1692157615810
当前Agent缓存用量:2147487744字节。

审计日志

开启审计日志

修改p2p configmapaudit字段为true

DeployConfig:
  mode: agent
  logDir: /dadi-p2p/log
  logAudit: true
  logAuditMode: stdout # 输出到控制台, file为输出到日志目录/dadi-p2p/log/audit.log

审计日志格式

格式如下,其含义为:从接收到请求至结果返回的处理耗时,单位:us。

2022/08/30 15:44:52|AUDIT|th=00007FBA247C5280|download[pathname=/https://cri-pi840la*****-registry.oss-cn-hangzhou.aliyuncs.com/docker/registry/v2/blobs/sha256/dd/dd65726c224b09836aeb6ecebd6baf58c96be727ba86da14e62835569896008a/data][offset=125829120][size=2097152][latency=267172]
....
2022/08/30 15:44:55|AUDIT|th=00007FBA2EFEAEC0|http:pread[pathname=/https://cri-pi840lacia*****-registry.oss-cn-hangzhou.aliyuncs.com/docker/registry/v2/blobs/sha256/dd/dd65726c224b09836aeb6ecebd6baf58c96be727ba86da14e62835569896008a/data][offset=127467520][size=65536][latency=21]

主要字段为:时间、 AUDIT、线程指针、操作码[pathname=][size=][latency=]。

其中AUDIT和线程指针一般不用关心,size为单次请求大小,若为负数则表示异常;latency为单次请求延迟,单位:us。

常见操作码如下:

  • http:pread:表示HTTP Proxy处理下游数据请求。

  • rpc:stat:表示P2P Agent获取文件长度。

  • rpc:pread:表示P2P Agent处理下游数据请求。

  • download:表示P2P Agent从上游下载数据。

  • filewrite:表示P2P Agent写入当前数据分片到缓存。

  • fileread:表示P2P Agent从缓存读取数据分片。

日志示例

download[pathname=mytest][offset=0][size=65536][latency=26461]
  ## P2P Agent从上游下载mytest文件[0,65536)这段数据的延迟为26461us
rpc:pread[pathname=mytest][offset=0][size=65536][latency=2]
  ## P2P Agent向下游返回mytest文件[0,65536)这段数据的延迟为2us
http:pread[pathname=mytest][offset=0][size=65536][latency=26461]
  ## 代理向从上游下载mytest文件[0,65536)这段数据的延迟为26461us

附录

P2P 加速效果参考

不同规格镜像拉取

测试镜像规格如下

  • 4 GB(512 MB * 8层)

  • 10 GB(10 GB * 1层)

  • 20 GB(4 GB * 5层,10 GB * 2层,512 MB * 40层, 20 GB * 1层,2 GB * 10层)

测试环境如下

  • ACK集群:1000节点

  • ECS规格:4核8 GB内存

  • 云盘规格:200 GB ESSD PL1

  • P2P Agent规格:1核1 GB内存,缓存4 GB

测试场景

1000 节点拉取相同镜像(含镜像下载后解压完成)

测试结果(P95耗时)

镜像规格

耗时

回源(Bucket)峰值吞吐(Gbps)

512 MB * 8层

116秒

2

10 GB * 1层

6分20秒

1.2

4 GB * 5层

9分15秒

5.1

10 GB * 2层

9分50秒

6.7

512 MB * 40层

7分55秒

3.8

20 GB * 1层

11分

2.5

2 GB * 10层

8分13秒

3.2