vpa updater 源码分析

1. updater整体逻辑

updater整体逻辑是比较简单的。

(1)定义了一个NewUpdater的对象

(2)然后每隔1分钟,执行NewUpdater.RunOnce

1.1 updater参数

updater轮转周期,默认是1分钟
updaterInterval = flag.Duration("updater-interval", 1*time.Minute, `How often updater should run`)

rs最小可用的副本数。比如默认是2表示,如果一个rs当前只有2个副本可用,本轮是不会驱逐的,保障rs服务的可用性
minReplicas = flag.Int("min-replicas", 2, `Minimum number of replicas to perform update`)

pod每轮的驱逐比例
evictionToleranceFraction = flag.Float64("eviction-tolerance", 0.5,`Fraction of replica count that can be evicted for update, if more than one pod can be evicted.`)

驱逐限速,这里用了令牌桶算法,就个就是令牌桶的QPS。如果是0或者-1表示不限速,默认是不限速
evictionRateLimit = flag.Float64("eviction-rate-limit", -1,`Number of pods that can be evicted per seconds. A rate limit set to 0 or -1 will disable the rate limiter.`)

令牌桶的burst大小
evictionRateBurst = flag.Int("eviction-rate-burst", 1, `Burst of pods that can be evicted.`)

暴露Prometheus metrics指标的地址
address = flag.String("address", ":8943", "The address to expose Prometheus metrics.")

是否检验AdmissionControllerStatus。如果开启的话,updater必须等
useAdmissionControllerStatus = flag.Bool("use-admission-controller-status", true,
      "If true, updater will only evict pods when admission controller status is valid.")

vpa作用的命名空间,默认是所有命名空间
namespace          = os.Getenv("NAMESPACE")
vpaObjectNamespace = flag.String("vpa-object-namespace", apiv1.NamespaceAll, "Namespace to search for VPA objects. Empty means all namespaces will be used.")
)

1.2 NewUpdater结构体对象

// NewUpdater creates Updater with given configuration
func NewUpdater(
    cgClient dynamic.Interface,                          // 为了操作cgroups资源,增加的dynamic客户端
    cgGvr schema.GroupVersionResource,                   // cgroups的 gvr
    kubeClient kube_client.Interface,                   
    vpaClient *vpa_clientset.Clientset,                  
    minReplicasForEvicition int,                        
    evictionRateLimit float64,
    evictionRateBurst int,
    evictionToleranceFraction float64,
    useAdmissionControllerStatus bool,
    statusNamespace string,
    recommendationProcessor vpa_api_util.RecommendationProcessor,   //  处理推荐资源相关的process,在vertical-pod-autoscaler/pkg/utils/vpa/capping.go
    evictionAdmission priority.PodEvictionAdmission,                 // 默认为空
    selectorFetcher target.VpaTargetSelectorFetcher,                 // selector相关
    priorityProcessor priority.PriorityProcessor,                    // 驱逐优先级处理。会更加资源diff进行过滤
    namespace string,
) (Updater, error) {
    evictionRateLimiter := getRateLimiter(evictionRateLimit, evictionRateBurst)
    factory, err := eviction.NewPodsEvictionRestrictionFactory(kubeClient, minReplicasForEvicition, evictionToleranceFraction)
    if err != nil {
        return nil, fmt.Errorf("Failed to create eviction restriction factory: %v", err)
    }
    return &updater{
        cgClient:                     cgClient,
        cgGvr:                        cgGvr,
        vpaLister:                    vpa_api_util.NewVpasLister(vpaClient, make(chan struct{}), namespace),
        podLister:                    newPodLister(kubeClient, namespace),
        eventRecorder:                newEventRecorder(kubeClient),
        evictionFactory:              factory,
        recommendationProcessor:      recommendationProcessor,
        evictionRateLimiter:          evictionRateLimiter,
        evictionAdmission:            evictionAdmission,
        priorityProcessor:            priorityProcessor,
        selectorFetcher:              selectorFetcher,
        useAdmissionControllerStatus: useAdmissionControllerStatus,
        statusValidator: status.NewValidator(
            kubeClient,
            status.AdmissionControllerStatusName,
            statusNamespace,
        ),
    }, nil
}


1.3 updater流程

每隔1分钟进行以下的运行逻辑:

  1. 获取所有的vpa, 并进行遍历,对于每个vpa而言,执行以下步骤

    1.1 如果vpa.model != auto 或者vpa.model != recreate, 直接跳过这个vpa

    1.2 根据vpa对应的selector, 获取所有的pods,假设为 allPods

    1.3 从allPods中过滤deletionTimestamp != nil 的pods, 假设为 activesPods

    1.4 从activesPods中过滤可以进行驱逐的pod, 假设为canEvictedPods. 判断逻辑如下:

    • updater启动时有两个参数:defaultUpdateThreshold = 0.10。podLifetimeUpdateThreshold = time.Hour * 12

      含义为:

      如果一个pod从开始运行到当前时间,没有超过12小时(podLifetimeUpdateThreshold),不能进行驱逐

      如果一个pod从资源改变在 0.1范围内,不应该驱逐。这个0.1是 cpu + memory的和。

    • 结合OOM事件,判断pod是否应该Evict,这个目前待确定细节

  2. 经过第一步,得到一个map, key=vap, value= canEvictedPods (这是一个列表,表示需要驱逐的pod)

  3. 遍历上诉map, 针对某个vpa进行以下逻辑判断。

    updater启动时还有两个参数,控制没轮驱逐时pod的数量

    • evictionTolerance 表示当前没轮驱逐的比例,默认0.5。 假设当前vpa对应的canEvictedPods有10个pod, 那么当前只会驱逐5个。
    • min-replica 表示rs最少可用的pod数量。例如一个rs 当前只有2个pod running, 就是前面满足了驱逐条件,到这里也不会驱逐。


热升级调整的逻辑:

(1)修改 podLifetimeUpdateThreshold = 30s

(2)跳过canEvictedPods逻辑

2. updater驱逐逻辑如下:

每隔1分钟进行以下的运行逻辑:

  1. 获取所有的vpa, 并进行遍历,对于每个vpa而言,执行以下步骤

    1.1 如果vpa.model != auto 或者vpa.model != recreate, 直接跳过这个vpa

    1.2 根据vpa对应的selector, 获取所有的pods,假设为 allPods

    1.3 从allPods中过滤deletionTimestamp != nil 的pods, 假设为 activesPods

    1.4 从activesPods中过滤可以进行驱逐的pod, 假设为canEvictedPods. 判断逻辑如下:

    • updater启动时有两个参数:defaultUpdateThreshold = 0.10。podLifetimeUpdateThreshold = time.Hour * 12

      含义为:

      如果一个pod从开始运行到当前时间,没有超过12小时(podLifetimeUpdateThreshold),不能进行驱逐

      如果一个pod从资源改变在 0.1范围内,不应该驱逐。这个0.1是 cpu + memory的和。

    • 结合OOM事件,判断pod是否应该Evict,这个目前待确定细节

  2. 经过第一步,得到一个map, key=vap, value= canEvictedPods (这是一个列表,表示需要驱逐的pod)

  3. 遍历上诉map, 针对某个vpa进行以下逻辑判断。

    updater启动时还有两个参数,控制没轮驱逐时pod的数量

    • evictionTolerance 表示当前没轮驱逐的比例,默认0.5。 假设当前vpa对应的canEvictedPods有10个pod, 那么当前只会驱逐5个。
    • min-replica 表示rs最少可用的pod数量。例如一个rs 当前只有2个pod running, 就是前面满足了驱逐条件,到这里也不会驱逐。

2.1 总结

感觉驱逐逻辑迁移到cgroupManager可以如下:

(1)继承上诉的步骤1,步骤2,因为是热升级,所以不用关注步骤三(考虑min-replica )

(2)OOM事件会影响pod驱逐,但是是热升级的情况下感觉可以忽略

3.vpa的修改pod资源的逻辑

  • vap修改的都是pod的request值,但是limit值会按照比例进行扩缩

  • Deploy yaml中没有指定limit,vpa也不会修改limit

  • vpa不会修改pod的QOS类型

举例说明会更清楚一点:

场景1 deploy yaml中设置了requet, limit

假设deploy yaml中定义的资源为:(这里limit:request=2:1)

    resources:
      limits:
        cpu: 2
        memory: 2Gi
      requests:
        cpu: 1
        memory: 1Gi

而vpa推荐值为:cpu=25m mem=262144k。那么这个pod实际运行时的request如下:

    resources:
      limits:                 //limit会改变,会维持limit:request=2:1的关系
        cpu: 50m
        memory: 500Mi
      requests:              // request采用的是vpa的值
        cpu: 25m
        memory: 262144k


场景2 pod yaml只中设置了requet没有设置limit

假设pod yaml中定义的资源为:(这里没有limit)

 resources:
      requests:
        cpu: 1
        memory: 1Gi

而vpa推荐值为:cpu=25m mem=262144k。那么这个pod实际运行时的request如下:

    resources:     
      requests:              // request采用的是vpa的值。也不会有limit
        cpu: 25m
        memory: 262144k

场景3 pod yaml没有设置resources

假设pod yaml中定义没有定义资源:(besteffort)

而vpa推荐值为:cpu=25m mem=262144k。那么这个pod实际运行时的request如下:

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

推荐阅读更多精彩内容