其他分享
首页 > 其他分享> > Kubernetes基本入门-元数据资源(四)

Kubernetes基本入门-元数据资源(四)

作者:互联网

元数据型资源

HPA

HPA全称HorizontalPodAutoscaler,Pod水平自动扩缩,可以根据CPU利用率自动扩缩RC、Deployment、RS或StatefulSet中的Pod数量,目的是自动扩缩工作负载以满足需求。
水平扩缩意味着对增加的负载的响应是部署更多的Pod。 与"垂直(Vertical)"扩缩不同,对于Kubernetes,垂直扩缩意味着将更多资源(例如:内存或 CPU)分配给已经为工作负载运行的Pod。如果负载减少,并且Pod的数量高于配置的最小值,HPA会指示工作负载资源(Deployment、StatefulSet或其他类似资源)缩减。水平Pod自动扩缩不适用于无法扩缩的对象(例如:DaemonSet)

  1. 如何工作

HorizontalPodAutoscaler被实现为Kubernetes API资源和控制器。HPA的工作示意图如下所示:
image.png
HPA控制Deployment及其RS的规模,Kubernetes将水平Pod自动扩缩实现为一个间歇运行的控制回路,它不是一个连续的过程。间隔由kube-controller-manager的--horizontal-pod-autoscaler-sync-period参数设置(默认间隔为15秒)。
每个时间段内,控制器管理器根据每个HPA定义指定的指标查询资源利用率。控制器管理器找到由scaleTargetRef定义的目标资源,然后根据目标资源的.spec.selector标签选择Pod,并从资源指标API(针对每个Pod的资源指标)或自定义指标获取指标API(适用于所有其他指标)。

HPA的常见用途是将其配置为从聚合API(metrics.k8s.io、custom.metrics.k8s.io 或 external.metrics.k8s.io)获取指标。metrics.k8s.io API通常由名为Metrics Server的插件提供,需要单独启动。

  1. 实现细节

从最基本的角度来看,Pod水平自动扩缩控制器根据当前指标和期望指标来计算扩缩比例。

说明:期望副本数 = ceil[当前副本数 * (当前指标 / 期望指标)]

例如,如果当前指标值为200m,而期望值为100m,则副本数将加倍, 因为200.0 / 100.0 == 2.0如果当前值为 50m,则副本数将减半,因为50.0 / 100.0 == 0.5。如果比率足够接近1.0(在全局可配置的容差范围内,默认为 0.1), 则控制平面会跳过扩缩操作。

在检查容差并决定最终值之前,控制平面还会考虑是否缺少任何指标,以及有多少Pod已就绪。所有设置了删除时间戳的Pod(带有删除时间戳的对象正在关闭/移除的过程中)都会被忽略,所有失败的Pod都会被丢弃。

如果某个Pod缺失度量值,将会被搁置,只在最终确定扩缩数量时再考虑。如果HPA指定的是targetAverageValue或targetAverageUtilization,那么它会将指定Pod度量值的平均值当做currentMetricValue。当使用CPU指标来扩缩时,任何还未就绪(还在初始化,或者可能是不健康的)状态的Pod或最近的指标度量值采集于就绪状态前的Pod,该Pod也会被搁置。在排除掉被搁置的Pod后,扩缩比例就会根据currentMetricValue/desiredMetricValue计算出来。

由于技术限制,HPA控制器在确定是否保留某些CPU指标时无法准确确定Pod首次就绪的时间(默认值为30秒,该值使用--horizontal-pod-autoscaler-initial-readiness-delay标志配置),如果Pod未准备好并在其启动后的一个可配置的短时间窗口内转换为未准备好,它会认为Pod尚未准备好。 一旦Pod准备就绪,如果发生在自启动后较长的可配置的时间内(默认5分钟,该值由-horizontal-pod-autoscaler-cpu-initialization-period标志配置),它就会认为任何向准备就绪的转换都是第一个。

如果缺失某些度量值,控制平面会更保守地重新计算平均值,在需要缩小时假设这些Pod消耗目标值的100%, 需要放大时假设这些Pod消耗了0%目标值,这可以在一定程度上抑制扩缩的幅度。此外,如果存在任何尚未就绪的Pod,工作负载会在不考虑遗漏指标或尚未就绪的Pod的情况下进行扩缩, 控制器保守地假设尚未就绪的Pod消耗了期望指标的0%,从而进一步降低了扩缩的幅度。

考虑到尚未准备好的Pod和缺失的指标后,控制器会重新计算使用率。如果新的比率与扩缩方向相反,或者在容差范围内,则控制器不会执行任何扩缩操作。在其他情况下,新比率用于决定对Pod数量的任何更改。平均利用率的原始值是通过HPA状态体现的,而不考虑尚未准备好的Pod或缺少的指标,即使使用新的使用率也是如此。

如果创建HPA时指定了多个指标,那么会按照每个指标分别计算扩缩副本数,取最大值进行扩缩。如果任何一个指标无法顺利地计算出扩缩副本数(比如,通过API获取指标时出错),并且可获取的指标建议缩容,那么本次扩缩会被跳过。如果一个或多个指标给出的desiredReplicas值大于当前值,HPA仍然能实现扩容。

在HPA控制器执行扩缩操作之前,会记录扩缩建议信息。控制器会在操作时间窗口中考虑所有的建议信息,并从中选择得分最高的建议。这个值可通过kube-controller-manager服务的启动参数--horizontal-pod-autoscaler-downscale-stabilization进行配置,默认值为5分钟。这个配置可以让系统更为平滑地进行缩容操作,从而消除短时间内指标值快速波动产生的影响。

更多内容参考:

如下为HPA的官方使用示例:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  # HPA的伸缩对象描述,HPA会动态修改该对象的pod数量
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  # HPA的最小pod数量和最大pod数量
  minReplicas: 1
  maxReplicas: 10
  # 监控的指标数组,支持多种类型的指标共存
  metrics:
  # Object类型的指标
  - type: Object
    object:
      metric:
        # 指标名称
        name: requests-per-second
      # 监控指标的对象描述,指标数据来源于该对象
      describedObject:
        apiVersion: networking.k8s.io/v1beta1
        kind: Ingress
        name: main-route
      # Value类型的目标值,Object类型的指标只支持Value和AverageValue类型的目标值
      target:
        type: Value
        value: 10k
  # Resource类型的指标
  - type: Resource
    resource:
      name: cpu
      # Utilization类型的目标值,Resource类型的指标只支持Utilization和AverageValue类型的目标值
      target:
        type: Utilization
        averageUtilization: 50
  # Pods类型的指标
  - type: Pods
    pods:
      metric:
        name: packets-per-second
      # AverageValue类型的目标值,Pods指标类型下只支持AverageValue类型的目标值
      target:
        type: AverageValue
        averageValue: 1k
  # External类型的指标
  - type: External
    external:
      metric:
        name: queue_messages_ready
        # 该字段与第三方的指标标签相关联,(此处官方文档有问题,正确的写法如下)
        selector:
          matchLabels:
            env: "stage"
            app: "myapp"
      # External指标类型下只支持Value和AverageValue类型的目标值
      target:
        type: AverageValue
        averageValue: 30

PodTemplate

负载资源的控制器通常使用Pod模板(Pod Template) 来创建Pod并管理它们。Pod模板是包含在工作负载对象中的规范,用来创建Pod。这类负载资源包括Deployment、Job和DaemonSets等。工作负载的控制器会使用负载对象中的PodTemplate来生成实际的Pod。PodTemplate是用来运行应用时指定的负载资源的目标状态的一部分。
下面的示例是一个简单的Job的清单,其中的template指示启动一个容器。该Pod中的容器会打印一条消息之后暂停。

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    # 这里是 Pod 模版
    spec:
      containers:
      - name: hello
        image: busybox
        command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
      restartPolicy: OnFailure
    # 以上为 Pod 模版

修改Pod模版或者切换到新的Pod模版都不会对已经存在的Pod起作用。Pod不会直接收到模版的更新。相反,新的Pod会被创建出来,与更改后的Pod模版匹配。
例如,Deployment控制器针对每个Deployment对象确保运行中的Pod与当前的Pod模版匹配。如果模版被更新,则Deployment必须删除现有的Pod,基于更新后的模版创建新的Pod。每个工作负载资源都实现了自己的规则,用来处理对Pod模版的更新。
在节点上,kubelet并不直接监测或管理与Pod模版相关的细节或模版的更新,这些细节都被抽象出来。这种抽象和关注点分离简化了整个系统的语义,并且使得用户可以在不改变现有代码的前提下就能扩展集群的行为。

LimitRange

LimitRange从字面意义上指的是对范围进行限制,实际上是对CPU和内存资源使用范围的限制。如果在一个设置有默LimitRange控制的名称空间创建容器,且该容器没有声明自己的内存限制时,会被指定默认内存限制。
下面给出一个限制范围对象的配置文件,该配置声明了默认的内存请求和默认的内存限制:

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256Mi
    type: Container

选择一个名称空间(default-mem-example)创建限制范围:

kubectl apply -f https://k8s.io/examples/admin/resource/memory-defaults.yaml --namespace=default-mem-example

如果在default-mem-example名称空间创建容器,并且该容器没有声明自己的内存请求和限制值,它将被指定默认的内存请求256M和默认的内存限制512M。
下面是具有一个容器的Pod的配置文件,容器未指定内存请求和限制。

apiVersion: v1
kind: Pod
metadata:
  name: default-mem-demo
spec:
  containers:
  - name: default-mem-demo-ctr
    image: nginx

创建Pod

kubectl apply -f https://k8s.io/examples/admin/resource/memory-defaults-pod.yaml --namespace=default-mem-example

查看Pod详情:输出内容显示该Pod的容器有256M的内存请求和512M的内存限制。这些都是LimitRange设置的默认值。

kubectl get pod default-mem-demo --output=yaml --namespace=default-mem-example

# 输出结果
containers:
- image: nginx
  imagePullPolicy: Always
  name: default-mem-demo-ctr
  resources:
    limits:
      memory: 512Mi
    requests:
      memory: 256Mi

更多内容查看:LimitRange

标签:指标,控制器,入门,Kubernetes,扩缩,Pod,HPA,资源,name
来源: https://www.cnblogs.com/starsray/p/16227830.html