更新时间:2023-12-26 GMT+08:00
分享

CCE容器实例弹性伸缩到CCI服务

Virtual Kubelet是基于社区Virtual Kubelet开源项目开发的插件,该插件支持用户在短时高负载场景下,将部署在CCE上的容器实例(Pod)弹性创建到云容器实例CCI服务上,以减少集群扩容带来的消耗。弹性Pod实例可以在创建无状态负载(Deployment)、有状态负载(StatefulSet)、普通任务(Job)、定时任务(CronJob)四种资源类型时设置,也可以在单独创建Pod时在YAML中指定Label,详情请参见通过标签labels设置弹性策略

具体功能如下:

  • 支持容器实例实现秒级弹性伸缩:Virtual Kubelet插件将自动为您在云容器实例CCI侧创建容器实例,减少运维成本。
  • 无缝对接容器镜像服务SWR,支持使用公用镜像和私有镜像。
  • 支持CCI容器实例的事件同步、监控、日志、exec、查看状态等操作。
  • 支持查看虚拟弹性节点的节点容量信息。
  • 支持CCE和CCI两侧实例的service网络互通。

约束及限制

  • 仅支持VPC网络模式的CCE Standard集群和CCE Turbo集群(virtual-kubelet 1.2.5版本及以上支持),暂不支持ARM集群。如果集群中包含ARM节点,插件实例将不会部署至ARM节点。
  • 调度到CCI的实例的存储类型支持ConfigMap、Secret、EmptyDir、DownwardAPI、Projected、PersistentVolumeClaims几种Volume类型,其中Projected和DownwardAPI类型仅virtual-kubelet 1.3.25版本及以上支持。
    • EmptyDir:不支持子路径。
    • PersistentVolumeClaims:只支持SFS、SFS Turbo云存储类型,且只支持使用CSI类型的StorageClass。
    • Projected:如配置了serviceAccountToken类型的source,那么弹性到CCI后挂载的会是对应service-account-token secret中的token,该token为长期有效的token且没有预期受众,即expirationSeconds和audience两项配置不会生效。
  • 暂不支持守护进程集(DaemonSet)以及HostNetwork网络模式的容器实例(Pod)弹性到CCI。
  • 跨CCE和CCI实例Service网络互通只支持集群内访问(ClusterIP)类型。不支持在init-container中访问CCE侧ClusterIP service。
  • 跨CCE和CCI实例,在对接LoadBalancer类型的Service或Ingress时:
    1. 禁止指定健康检查端口,在CCE集群下,由于CCI的容器与CCE的容器在ELB注册的后端使用端口不一致,指定健康检查端口会导致部分后端健康检查异常。
    2. 跨集群使用Service对接同一个ELB的监听器时,需确认健康检查方式,避免服务访问异常。
    1. 跨CCE和CCI实例,在对接共享型LoadBalancer类型的Service时,需要放通node安全组下100.125.0.0/16网段的容器端口。
    2. 当前对接LoadBalancer类型的Service或Ingress仅支持auto和enforce调度策略。
  • 集群所在子网不能与10.247.0.0/16重叠,否则会与CCI命名空间下的Service网段冲突,导致无法使用。
  • 使用插件前需要用户在CCI界面对CCI服务进行授权。
  • 安装virtual-kubelet插件后会在CCI服务新建一个名为"cce-burst-"+集群ID的命名空间,该命名空间完全由virtual-kubelet管理,不建议直接在CCI服务使用该命名空间,如需使用CCI服务,请另外新建命名空间。
  • 弹性到CCI的业务量不同时,插件的资源占用也不相同。业务申请的POD、Secret、CongfigMap、PV、PVC会占用虚机资源。建议用户评估自己的业务使用量,按以下规格申请对应的虚机大小:1000pod+1000CM(300KB)推荐2U4G规格节点,2000pod+2000CM推荐4U8G规格节点,4000pod+4000CM推荐8U16G规格节点。
  • 当弹性到CCI的资源调度失败时,virtual-kubelet节点会被锁定半小时,期间无法调度至CCI。用户可通过CCE集群控制台,使用kubectl工具查看virtual-kubelet节点状态,若节点被锁定,可手动解锁virtual-kubelet。

  • 使用日志管理功能采集弹性到CCI的Pod中的日志具有如下约束:
    • 当前仅支持容器文件路径采集。
    • 依赖virtual-kubelet的Service互通能力,请在安装插件时勾选“网络互通”开关。
    • 弹性到CCI的Pod不支持日志策略热更新,即更新日志策略后需要重新部署弹性到CCI的Pod才可生效。
    • 日志采集会增加Pod内存消耗,Pod被单个日志策略关联时,建议您预留50MB的内存。Pod被多个日志策略关联时,每多一个关联的日志策略,建议您额外再多预留5MB的内存。
    • 单条日志长度限制为250KB,如果超过则会被丢弃。
    • 不支持指定系统、设备、cgroup、tmpfs等挂载目录的日志采集,这些目录下的日志文件将不会被采集。
    • 同一个容器中关联到同一个日志策略的待采集的日志文件不能重名,如果有重复文件则只会采集到采集器首次感知到的日志文件。
    • 日志文件的文件名,最大长度为190,超过长度限制的日志文件将不会被采集。

Pod规格的计算与约束

Pod规格的计算方式遵循如下规则:
  1. 所有应用容器和初始化容器对某个资源的Requests和Limits均会被设置为相等的值,若配置了Limits,则取Limits值,没有配Limits,则取Requests值。
  2. Pod对某个资源的Requests和Limits,是取如下两项的较大者:
    1. 所有应用容器对某个资源的Limits之和。
    2. 所有初始化容器对某个资源Limits的最大值。

Pod规格约束:

  1. Pod的CPU需大于0。
  2. 经过资源自动规整后,Pod的CPU在0.25核~32核范围内,或者等于48核或64核;Memory在1Gi~512Gi范围内,且必须为1Gi的整数倍,且满足CPU/Memory配比值在1:2~1:8之间。

资源自动规整

对弹性到CCI的Pod,若其配置的资源规格不满足CCI容器规范,且规格不高于32U 256Gi,virtual-kubelet会自动尝试将Pod资源向上规整到满足CCI容器规范的范围,以规整后的资源规格创建Pod到CCI。

自动规整规则如下:

  1. 将Pod中除了BestEffort的每个应用容器和初始化容器的CPU向上调整至0.25核的整数倍, Memory向上调整至大于等于0.2Gi。
  2. 若此时Pod的CPU大于32U或者Memory大于256Gi,则不再继续进行自动规整,否则继续自动规整。
  3. 将整个Pod的Memory向上调整至1Gi的整数倍。
  4. 若Pod Memory/CPU的比值小于2,则将Pod Memory向上调整至大于等于CPU的2倍,且满足是1Gi的整数倍;若Pod Memory/CPU的比值大于8,则将Pod CPU向上调整至大于等于Memory的1/8,且满足是0.25核的整数倍。
  5. 以上对Pod级别资源向上调整造成的增量CPU和Memory,全部添加到Pod中第一个不为BestEffort的应用容器上。

安装插件

  1. 在CCE控制台,单击集群名称进入集群,单击左侧导航栏的“插件中心”,在右侧找到CCE突发弹性引擎插件,单击“安装”
  2. 在“规格配置”步骤中,勾选“网络互通”后的选择框,可实现CCE集群中的Pod与CCI集群中的Pod通过Kubernetes Service互通。

    图1 勾选“网络互通”

  3. 单击“安装”

    勾选了网络互通后,会在CCI运行的Pod中注入一个sidecar用于支持service访问的能力,查询到的运行容器数量会比定义的多一个,属于正常情况。

通过标签labels设置弹性策略

您成功安装virtual-kubelet插件后,在工作负载中添加virtual-kubelet.io/burst-to-cci这个标签即可设置弹性到CCI。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
  namespace: default
  labels:
    virtual-kubelet.io/burst-to-cci: 'auto'    # 弹性到CCI
spec:
  replicas: 2
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
        - image: 'nginx:perl'
          name: container-0
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
            limits:
              cpu: 250m
              memory: 512Mi
          volumeMounts: []
      imagePullSecrets:
        - name: default-secret

创建弹性至CCI的负载时需要在工作负载或Pod的labels中添加如下字段:

virtual-kubelet.io/burst-to-cci: "auto"

其中,value值支持以下选项:

  • auto:根据用户集群内调度器实际打分结果自动决定是否弹性至CCI,其中在TaintToleration算法上会优先选择调度到CCE节点。
  • localPrefer集群资源不足时,将Pod部署到CCI
  • enforce:强制调度至CCI。
  • off:不调度至CCI。

使用profile管理线下IDC和云上分配数量

使用profile配置管理集群内pod,通过labelSelector类方式关联profile和pod,并配置关联pod的分配策略,实现pod在线下IDC和云上的分配或数量限制。

约束与限制

  • 客户可通过Profile配置管理集群内pod策略,仍兼容原有pod的label内burst-to-cci的配置方式,优先级比profile高。
  • localPrefer不可同时配置local、cci。
  • auto和localPrefer策略允许关联未被profile关联过的pod,enforce策略不允许关联未被profile关联过的pod。
  • 目前profile在配置localPrefer策略下,为避免全局性问题,在极限场景下限制local数量的配置可能会失效。
  • 在deployment滚动升级场景下,推荐配置尽可能小的maxSurge值(如直接配置为0),避免出现升级时限制maxNum的区域调度量少于预期的现象。
  • pod只能关联一个profile,即关联度最大的profile。若pod创建后,对其label进行修改导致与原profile不匹配,pod会重新选择关联度最大的profile进行关联。关联度最大的profile确定方法:
    • 根据profile中obejectLables计算labelSelector内matchLabels的数量及matchExpression的数量之和,和最大的profile即为pod关联度最大的profile;
    • 若出现和相同的profile,选择profile的name字母序最小的profile为pod关联度最大的profile。
  • 不支持使用log-agent插件采集profile管理的负载日志。

使用方式

配置local maxNum和scaleDownPriority
apiVersion: scheduling.cci.io/v1
kind: ScheduleProfile
metadata:
  name: test-cci-profile
  namespace: default
spec:
  objectLabels:
    matchLabels:
      app: nginx
  strategy: localPrefer
  location:
    local: 
      maxNum: 20 # 当前暂不支持local/cci同时配置maxNum
      scaleDownPriority: 10
    cci: {}
status:
  phase: initialized
  restrict:
    local: 20 # restrict内随着location内配置进行填写,即不会同时出现 local/cci
  used:
    local: 20
    cci: 0

配置cci maxNum和scaleDownPriority

apiVersion: scheduling.cci.io/v1
kind: ScheduleProfile
metadata:
  name: test-cci-profile
  namespace: default
spec:
  objectLabels:
    matchLabels:
      app: nginx
  strategy: localPrefer
  location:
    local: {}
    cci:
      maxNum: 20 # 当前暂不支持local/cci同时配置maxNum
      scaleDownPriority: 10
status:
  phase: initialized
  restrict:
    cci: 20 # restrict内随着location内配置进行填写,即不会同时出现 local/cci
  used:
    local: 0
    cci: 20

参数说明:

  • strategy:调度策略选择。可配置策略值:auto、enforce、localPrefer;
  • location内可配置线下IDC和云上pod限制数量maxNum和pod缩容优先级scaleDownPriority,maxNum取值范围[0~int32],scaleDownPriority取值范围[-100, 100];

创建无状态负载,使用selector方式选择含有app:nginx的pod,关联上文创建的profile。

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nginx
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: container-1
          image: nginx:latest
          imagePullPolicy: IfNotPresent
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
            limits:
              cpu: 250m
              memory: 512Mi
      imagePullSecrets:
        - name: default-secret

卸载插件

  1. 登录CCE控制台,进入集群,在左侧导航栏选择“插件管理”,在右侧“已安装插件”页签下,单击virtual kubelet下的“卸载”。
  2. 在弹出的窗口中,单击“是”,可卸载该插件。(卸载插件会自动删除CCI侧的所有资源,以确保不会有资源残留造成额外计费)
  • 由于virtual-kubelet插件卸载时会在集群中启动Job用于清理资源,卸载插件时请保证集群中至少有一个可以调度的节点,否则卸载插件会失败。若已经因无可调度节点造成插件卸载失败,需要在有可调度节点后重新单击插件卸载。
  • 如果在未卸载virtual-kubelet插件的情况下直接删除集群,CCI侧的资源不会被自动清理,会导致CCI侧资源残留,可能会造成额外计费。因此请确保完成以下任意一操作。
    • 在删除集群前先卸载virtual-kubelet插件。
    • 在直接删除集群后登录CCI控制台删除名为cce-burst-${CLUSTER_ID}的命名空间。
    • 集群休眠时CCI侧正在运行的实例不会自动停止,会持续运行并计费。因此如不需要实例继续运行,请确保在集群休眠前将弹性到CCI的负载实例数缩至0。

更多操作

分享:

    相关文档

    相关产品