• K8s---HPA弹性伸缩


    一、HPA概述

    1.1、HPAjieshao 

    • HPA全称Horizontal Pod Autoscaler,即水平Pod自动伸缩器,可以根据观察到的CPU、内存使用率或自定义度量标准来自动增加或者减少Pod的数量,但是HPA不适用于无法扩、缩容的对象,例如DaemonSet,通常都作用与Deployment
    • HPA控制器会定期调整RC或者Deployment的副本数,使对象数量符合用户定义规则的数量
    • 既然是通过CPU、内存等指标来自动扩、缩容Pod,那么HPA肯定是需要一个能监控这些硬件资源的组件,则例的组件有很多选择,例如metrices-server、Heapster等,这里使用metrices-server

    metrices-server从api-server中获取cpu、内存使用率等监控指标

    1.2、HPA伸缩过程

    1、收集HPA控制下所有Pod最近的cpu使用情况(CPU utilization)
    2、对比在扩容条件里记录的cpu限额(CPUUtilization)
    3、调整实例数(必须要满足不超过最大/最小实例数)
    4、每隔30s做一次自动扩容的判断

    CPU utilization的计算方法是用cpu usage(最近一分钟的平均值,通过metrics可以直接获取到)除以cpu request(这里cpu request就是我们在创建容器时制定的cpu使用核心数)得到一个平均值,这个平均值可以理解为:平均每个Pod CPU核心的使用占比。

    1.3、HPA 的工作原理

    k8s中的某个Metrics Server(Heapster或自定义Metrics Server)持续采集所有Pod副本的指标数据。

    HPA控制器通过Metrics Server的API(Heapster的API或聚合API)获取这些数据,基于用户定义的扩缩容规则进行计算,得到目标Pod副本数量。

    当目标Pod副本数量与当前副本数量不同时,HPA控制器就访问Pod的副本控制器(Deployment 、RC或者ReplicaSet)发起scale操作,调整Pod的副本数量,完成扩缩容操作。

    总结:HPA 通过监控分析一些控制器控制的所有 Pod 的负载变化情况来确定是否需要调整 Pod 的副本数量。

    1.4、指标的类型

    Master的kube-controller-manager服务持续监测目标Pod的某种性能指标,以计算是否需要调整副本数量。目前k8s支持的指标类型如下。

    ◎ Pod资源使用率:Pod级别的性能指标,通常是一个比率值,例如CPU使用率。 
    ◎ Pod自定义指标:Pod级别的性能指标,通常是一个数值,例如接收的请求数量。 
    ◎ Object自定义指标或外部自定义指标:通常是一个数值,需要容器应用以某种方式提供,例如通过HTTP URL“/metrics”提供,或者使用外部服务提供的指标采集URL。

    k8s从1.11版本开始,弃用基于Heapster组件完成Pod的CPU使用率采集的机制,全面转向基于Metrics Server完成数据采集。Metrics Server将采集到的Pod性能指标数据通过聚合API(Aggregated API)如metrics.k8s.io、custom.metrics.k8s.io和external.metrics.k8s.io提供给HPA控制器进行查询。关于聚合API和聚合器(API Aggregator)的概念我们后面详细讲解。

    1.5、扩缩容策略

    通过 伸缩系数 判断是否要进行扩容或缩容。

    HPA会根据获得的指标数值,应用相应的算法算出一个伸缩系数,此系数是指标的期望值与目前值的比值,如果大于1表示扩容,小于1表示缩容。

    容忍度
    --horizontal-pod-autoscaler-tolerance:容忍度

    它允许一定范围内的使用量的不稳定,现在默认为0.1,这也是出于维护系统稳定性的考虑。

    例如,设定HPA调度策略为cpu使用率高于50%触发扩容,那么只有当使用率大于55%或者小于45%才会触发伸缩活动,HPA会尽力把Pod的使用率控制在这个范围之间。

    算法

    具体的每次扩容或者缩容的多少Pod的算法为: 期望副本数 = ceil[当前副本数 * ( 当前指标 / 期望指标 )]

    举个栗子

    当前metric值是200m,期望值是100m,那么pod副本数将会翻一倍,因为 比率为 200.0 / 100.0 = 2.0;
    如果当前值是 50m ,我们会将pod副本数减半,因为 50.0 / 100.0 == 0.5
    如果比率接近1.0,如0.9或1.1(即容忍度是0.1),将不会进行缩放(取决于内置的全局参数容忍度,–horizontal-pod-autoscaler-tolerance,默认值为0.1)。

    此外,存在几种Pod异常的情况,如下所述。

    ◎  Pod正在被删除(设置了删除时间戳):将不会计入目标Pod副本数量。

    ◎ Pod的当前指标值无法获得:本次探测不会将这个Pod纳入目标Pod副本数量,后续的探测会被重新纳入计算范围。

    ◎ 如果指标类型是CPU使用率,则对于正在启动但是还未达到Ready状态的Pod,也暂时不会纳入目标副本数量范围。可以通过kube-controller-manager服务的启动参数--horizontal-pod-autoscaler-initial-readiness-delay设置首次探测Pod是否Ready的延时时间,默认值为30s。另一个启动参数--horizontal-pod-autoscaler-cpuinitialization-period设置首次采集Pod的CPU使用率的延时时间。

    注意:

    • 每次最大扩容pod数量不会超过当前副本数量的2倍
    • 如果某些pod的容器没有需要的的资源metrics,自动伸缩将不会根据这些metrics进行伸缩。
    • 如果指定了targetAverageValue 或者 targetAverageUtilization,currentMetricValue是所有目标pod的metric取均值。在检查容忍度和确定最终值之前,会结合参考pod是否就绪、是否丢失metrics。
    • 设置了删除时间戳的所有Pod(即处于关闭状态的Pod)和所有失败的Pod将被丢弃。

    冷却和延迟机制

    使用HPA管理一组副本时,有可能因为metrics动态变化而导致副本数频繁波动,这种现象叫做 “颠簸”。

    想象一种场景:

    当pod所需要的CPU负荷过大,从而在创建一个新pod的过程中,系统的CPU使用量可能会同样在有一个攀升的过程。所以,在每一次作出决策后的一段时间内,将不再进行扩展决策。对于扩容而言,这个时间段为3分钟,缩容为5分钟

    • -- horizontal-pod-autoscaler-downscale- delay :这个参数用于告诉autoscaler做完缩容操作后需要等多久才能进行下一次缩容,默认值是5分钟。
    • --horizontal-pod-autoscaler-upscale-delay: 这个参数用于告诉autoscaler做完扩容操作后需要等多久才能进行下一次扩容,默认值是3分钟。
    • 注意:使用者需要知道调整这个参数可能造成的影响。设置得太长,HPA对负载变化的响应也会变长;太短又会导致自动伸缩“颠簸”。

    Pod延迟探测机制

    如果指标类型是CPU使用率,则对于正在启动但是还未达到Ready状态的Pod,也暂时不会纳入目标副本数量范围。

    • 可以通过kube-controller-manager服务的启动参数--horizontal-pod-autoscaler-initial-readiness-delay设置首次探测Pod是否Ready的延时时间,默认值为30s。
    • 另一个启动参数--horizontal-pod-autoscaler-cpuinitialization-period设置首次采集Pod的CPU使用率的延时时间。

    1.6、HPA获取自定义指标(Custom Metrics)的底层实现(基于Prometheus)

    Kubernetes是借助Agrregator APIServer扩展机制来实现Custom Metrics。Custom Metrics APIServer是一个提供查询Metrics指标的API服务(Prometheus的一个适配器),这个服务启动后,kubernetes会暴露一个叫custom.metrics.k8s.io的API,当请求这个URL时,请求通过Custom Metics APIServer去Prometheus里面去查询对应的指标,然后将查询结果按照特定格式返回。

    二、HPA的metrics的分类

    要支持最新的custom(包括external)的metrics,也需要使用新版本的HPA:autoscaling/v2beta1,里面增加四种类型的Metrics:Resource、Pods、Object、External,每种资源对应不同的场景,下面分别说明:

    • Resource支持k8s里Pod的所有系统资源(包括cpu、memory等),但是一般只会用cpu,memory因为不太敏感而且跟语言相关:大多数语言都有内存池及内置GC机制导致进程内存监控不准确。
    • Pods类型的metrics表示cpu,memory等系统资源之外且是由Pod自身提供的自定义metrics数据,比如用户可以在web服务的pod里提供一个promesheus metrics的自定义接口,里面暴露了本pod的实时QPS监控指标,这种情况下就应该在HPA里直接使用Pods类型的metrics。
    • Object类型的metrics表示监控指标不是由Pod本身的服务提供,但是可以通过k8s的其他资源Object提供metrics查询,比如ingress等,一般Object是需要汇聚关联的Deployment下的所有的pods总的指标。
    • External类型的metrics也属于自定义指标,与Pods和Object不同的是,其监控指标的来源跟k8s本身无关,metrics的数据完全取自外部的系统。

    在HPA最新的版本 autoscaling/v2beta2 中又对metrics的配置和HPA扩缩容的策略做了完善,特别是对 metrics 数据的目标指标值的类型定义更通用灵活:包括AverageUtilization、AverageValue和Value,但是不是所有的类型的Metrics都支持三种目标值的,具体对应关系如下表。

    HPA里的各种类型的Metrics和Metrics Target Type的对应支持关系表

    Metrics Type \ Target TypeAverageUtilizationAverageValueValue备注(query metrics)
    Resource(pod’s cpu/memory etc.)YesYesNopods metrics list
    Pods(pod’s other metrics)NoYesNopods metrics list
    Object(k8s object)NoYesYesobject metrics
    External(not k8s object)NoYesYesexternal metrics list

    三、HPA的使用说明

    先看个最简单的HPA的定义的例子

    1. apiVersion: autoscaling/v2beta2
    2. kind: HorizontalPodAutoscaler
    3. metadata:
    4. name: php-apache
    5. spec:
    6. scaleTargetRef:
    7. apiVersion: apps/v1
    8. kind: Deployment
    9. name: php-apache
    10. minReplicas: 1
    11. maxReplicas: 10
    12. metrics:
    13. - type: Resource
    14. resource:
    15. name: cpu
    16. target:
    17. type: Utilization
    18. averageUtilization: 50

    从上面的例子可以看出,HPA的spec定义由三个必填部分组成:

    1. HPA控制的目标workload,即scaleTargetRef,理论上HPA可以对任意支持scale子接口( sub-resource )的workload做弹性伸缩,不过statefulset一般代表有状态服务,副本不可随便修改,而Job一般代表短生命周期的,所以基本可以认为HPA目前是专门控制deployment的扩缩容的(不建议直接控制RS,否则将无法滚动升级)。
    2. 弹性扩缩容的上下边界,minReplicas和maxReplicas,也就是说HPA的扩缩容也不能是漫无边际,如果计算出的副本数超过max则统一取maxReplicas,maxReplicas是为了保护k8s集群的资源被耗尽,minReplicas则相反,而且minReplicas必须不大于maxReplicas,但是也要大于0(k8s v1.16之后才放开允许Objetct和External类型的metrics的minReplicas为0,需要apiserver开启–feature-gates mapStringBool HPAScaleToZero=true),两者相等就相当于关闭了自动伸缩功能了,总的来说minReplicas和maxReplicas边界机制避免metrics数据异常导致的副本数不受控,特别是HPA在k8s最新的v1.18版本也依然是alpha特性,强烈建议大家谨慎设置这两个边界。
    3. metrics指标类型和目标值,在autoscaling/v1里只有targetCPUUtilizationPercentage,autoscaling/v2beta1开始就扩展为metrics数组了,也就是说一个HPA可以同时设置多个类型维度的metrics目标指标,如果有多个HPA 将会依次考量各个指标,然后最终HPA Controller选择一个会选择扩缩幅度最大的那个为最终扩容副本数。在最新的autoscaling/v2beta2版本的HPA中,metrics type共有4种类型:Resource、Pods、Object、External,target里则定义了metrics的目标期望值,这里target的type也有三种类型Utilization,AverageValue和 Value,不同的metrics type都只能支持部分target type(详见上面表格)
    4. 此外,在autoscaling/v2beta2的HPA的spec里还新增了一个Behavior可选结构,它是用来精确控制HPA的扩容和缩容的速度。

    完整的HPA的定义可参考k8s的官方API文档

    默认HPA spec里不配置任何metrics的话k8s会默认设置cpu的Resouce,且目标类型是AverageUtilization value为80%。

    四、HPA部署

    4.1、HPA版本

    查看HPA所有版本

    1. [root@master C]# kubectl api-versions |grep autoscaling
    2. autoscaling/v1 #只支持通过CPU为参考依据来改变Pod的副本数
    3. autoscaling/v2beta1 #支持通过CPU、内存、连接数或者自定义规则为参考依据
    4. autoscaling/v2beta2 #和v2beta1差不多

    查看当前版本

    1. [root@master C]# kubectl explain hpa
    2. KIND: HorizontalPodAutoscaler
    3. VERSION: autoscaling/v1 #可以看到使用的默认版本是v1
    4. DESCRIPTION:
    5. configuration of a horizontal pod autoscaler.
    6. FIELDS:
    7. apiVersion
    8. APIVersion defines the versioned schema of this representation of an
    9. object. Servers should convert recognized schemas to the latest internal
    10. value, and may reject unrecognized values. More info:
    11. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
    12. kind
    13. Kind is a string value representing the REST resource this object
    14. represents. Servers may infer this from the endpoint the client submits
    15. requests to. Cannot be updated. In CamelCase. More info:
    16. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
    17. metadata
    18. Standard object metadata. More info:
    19. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
    20. spec
    21. behaviour of autoscaler. More info:
    22. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
    23. status
    24. current information about the autoscaler.
    25. 指定使用版本,这里并不是修改,相当于执行这条命令时,指定了下版本

      1. [root@master C]# kubectl explain hpa --api-version=autoscaling/v2beta1
      2. KIND: HorizontalPodAutoscaler
      3. VERSION: autoscaling/v2beta1
      4. DESCRIPTION:
      5. HorizontalPodAutoscaler is the configuration for a horizontal pod
      6. autoscaler, which automatically manages the replica count of any resource
      7. implementing the scale subresource based on the metrics specified.
      8. FIELDS:
      9. apiVersion <string>
      10. APIVersion defines the versioned schema of this representation of an
      11. object. Servers should convert recognized schemas to the latest internal
      12. value, and may reject unrecognized values. More info:
      13. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
      14. kind <string>
      15. Kind is a string value representing the REST resource this object
      16. represents. Servers may infer this from the endpoint the client submits
      17. requests to. Cannot be updated. In CamelCase. More info:
      18. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
      19. metadata
      20. metadata is the standard object metadata. More info:
      21. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
      22. spec
      23. spec is the specification for the behaviour of the autoscaler. More info:
      24. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
      25. status
      26. status is the current information about the autoscaler.
      27. 4.2、 HPA部署

        (1)部署metrics-server

        1. [root@master kube-system]# kubectl top nodes #查看节点状态,因为没有安装,所以会报错
        2. Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)
        • 编写yaml文件,注意端口和镜像
        1. [root@master kube-system]# vim components-v0.5.0.yaml
        2. apiVersion: v1
        3. kind: ServiceAccount
        4. metadata:
        5. labels:
        6. k8s-app: metrics-server
        7. name: metrics-server
        8. namespace: kube-system
        9. ---
        10. apiVersion: rbac.authorization.k8s.io/v1
        11. kind: ClusterRole
        12. metadata:
        13. labels:
        14. k8s-app: metrics-server
        15. rbac.authorization.k8s.io/aggregate-to-admin: "true"
        16. rbac.authorization.k8s.io/aggregate-to-edit: "true"
        17. rbac.authorization.k8s.io/aggregate-to-view: "true"
        18. name: system:aggregated-metrics-reader
        19. rules:
        20. - apiGroups:
        21. - metrics.k8s.io
        22. resources:
        23. - pods
        24. - nodes
        25. verbs:
        26. - get
        27. - list
        28. - watch
        29. ---
        30. apiVersion: rbac.authorization.k8s.io/v1
        31. kind: ClusterRole
        32. metadata:
        33. labels:
        34. k8s-app: metrics-server
        35. name: system:metrics-server
        36. rules:
        37. - apiGroups:
        38. - ""
        39. resources:
        40. - pods
        41. - nodes
        42. - nodes/stats
        43. - namespaces
        44. - configmaps
        45. verbs:
        46. - get
        47. - list
        48. - watch
        49. ---
        50. apiVersion: rbac.authorization.k8s.io/v1
        51. kind: RoleBinding
        52. metadata:
        53. labels:
        54. k8s-app: metrics-server
        55. name: metrics-server-auth-reader
        56. namespace: kube-system
        57. roleRef:
        58. apiGroup: rbac.authorization.k8s.io
        59. kind: Role
        60. name: extension-apiserver-authentication-reader
        61. subjects:
        62. - kind: ServiceAccount
        63. name: metrics-server
        64. namespace: kube-system
        65. ---
        66. apiVersion: rbac.authorization.k8s.io/v1
        67. kind: ClusterRoleBinding
        68. metadata:
        69. labels:
        70. k8s-app: metrics-server
        71. name: metrics-server:system:auth-delegator
        72. roleRef:
        73. apiGroup: rbac.authorization.k8s.io
        74. kind: ClusterRole
        75. name: system:auth-delegator
        76. subjects:
        77. - kind: ServiceAccount
        78. name: metrics-server
        79. namespace: kube-system
        80. ---
        81. apiVersion: rbac.authorization.k8s.io/v1
        82. kind: ClusterRoleBinding
        83. metadata:
        84. labels:
        85. k8s-app: metrics-server
        86. name: system:metrics-server
        87. roleRef:
        88. apiGroup: rbac.authorization.k8s.io
        89. kind: ClusterRole
        90. name: system:metrics-server
        91. subjects:
        92. - kind: ServiceAccount
        93. name: metrics-server
        94. namespace: kube-system
        95. ---
        96. apiVersion: v1
        97. kind: Service
        98. metadata:
        99. labels:
        100. k8s-app: metrics-server
        101. name: metrics-server
        102. namespace: kube-system
        103. spec:
        104. ports:
        105. - name: https
        106. port: 443
        107. protocol: TCP
        108. targetPort: https
        109. selector:
        110. k8s-app: metrics-server
        111. ---
        112. apiVersion: apps/v1
        113. kind: Deployment
        114. metadata:
        115. labels:
        116. k8s-app: metrics-server
        117. name: metrics-server
        118. namespace: kube-system
        119. spec:
        120. selector:
        121. matchLabels:
        122. k8s-app: metrics-server
        123. strategy:
        124. rollingUpdate:
        125. maxUnavailable: 0
        126. template:
        127. metadata:
        128. labels:
        129. k8s-app: metrics-server
        130. spec:
        131. containers:
        132. - args:
        133. - --cert-dir=/tmp
        134. - --secure-port=4443
        135. - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        136. - --kubelet-use-node-status-port
        137. - --metric-resolution=15s
        138. - --kubelet-insecure-tls
        139. image: registry.cn-shenzhen.aliyuncs.com/zengfengjin/metrics-server:v0.5.0
        140. imagePullPolicy: IfNotPresent
        141. livenessProbe:
        142. failureThreshold: 3
        143. httpGet:
        144. path: /livez
        145. port: https
        146. scheme: HTTPS
        147. periodSeconds: 10
        148. name: metrics-server
        149. ports:
        150. - containerPort: 4443
        151. name: https
        152. protocol: TCP
        153. readinessProbe:
        154. failureThreshold: 3
        155. httpGet:
        156. path: /readyz
        157. port: https
        158. scheme: HTTPS
        159. initialDelaySeconds: 20
        160. periodSeconds: 10
        161. resources:
        162. requests:
        163. cpu: 100m
        164. memory: 200Mi
        165. securityContext:
        166. readOnlyRootFilesystem: true
        167. runAsNonRoot: true
        168. runAsUser: 1000
        169. volumeMounts:
        170. - mountPath: /tmp
        171. name: tmp-dir
        172. nodeSelector:
        173. kubernetes.io/os: linux
        174. priorityClassName: system-cluster-critical
        175. serviceAccountName: metrics-server
        176. volumes:
        177. - emptyDir: {}
        178. name: tmp-dir
        179. ---
        180. apiVersion: apiregistration.k8s.io/v1
        181. kind: APIService
        182. metadata:
        183. labels:
        184. k8s-app: metrics-server
        185. name: v1beta1.metrics.k8s.io
        186. spec:
        187. group: metrics.k8s.io
        188. groupPriorityMinimum: 100
        189. insecureSkipTLSVerify: true
        190. service:
        191. name: metrics-server
        192. namespace: kube-system
        193. version: v1beta1
        194. versionPriority: 100
        • 部署
        1. [root@master kube-system]# kubectl apply -f components-v0.5.0.yaml
        2. serviceaccount/metrics-server created
        3. clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
        4. clusterrole.rbac.authorization.k8s.io/system:metrics-server created
        5. rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
        6. clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
        7. clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
        8. service/metrics-server created
        9. deployment.apps/metrics-server created
        10. apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
        11. #查看创建的pod
        12. [root@master kube-system]# kubectl get pods -n kube-system| egrep 'NAME|metrics-server'
        13. NAME READY STATUS RESTARTS AGE
        14. metrics-server-5944675dfb-q6cdd 0/1 ContainerCreating 0 6s
        15. #查看日志
        16. [root@master kube-system]# kubectl logs metrics-server-5944675dfb-q6cdd -n kube-system
        17. I0718 03:06:39.064633 1 serving.go:341] Generated self-signed cert (/tmp/apiserver.crt, /tmp/apiserver.key)
        18. I0718 03:06:39.870097 1 configmap_cafile_content.go:202] Starting client-ca::kube-system::extension-apiserver-authentication::client-ca-file
        19. I0718 03:06:39.870122 1 configmap_cafile_content.go:202] Starting client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
        20. I0718 03:06:39.870159 1 shared_informer.go:240] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::client-ca-file
        21. I0718 03:06:39.870160 1 shared_informer.go:240] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
        22. I0718 03:06:39.870105 1 requestheader_controller.go:169] Starting RequestHeaderAuthRequestController
        23. I0718 03:06:39.871166 1 shared_informer.go:240] Waiting for caches to sync for RequestHeaderAuthRequestController
        24. I0718 03:06:39.872804 1 dynamic_serving_content.go:130] Starting serving-cert::/tmp/apiserver.crt::/tmp/apiserver.key
        25. I0718 03:06:39.875741 1 secure_serving.go:197] Serving securely on [::]:4443
        26. I0718 03:06:39.876050 1 tlsconfig.go:240] Starting DynamicServingCertificateController
        27. I0718 03:06:39.970469 1 shared_informer.go:247] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::client-ca-file
        28. I0718 03:06:39.970575 1 shared_informer.go:247] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
        29. I0718 03:06:39.971610 1 shared_informer.go:247] Caches are synced for RequestHeaderAuthRequestController
        30. #如果报错的化,可以修改apiserver的yaml文件,这是k8s的yaml文件
        31. [root@master kube-system]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
        32. 40 - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
        33. 41 - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
        34. 42 - --enable-aggregator-routing=true #添加这行
        35. 43 image: registry.aliyuncs.com/google_containers/kube-apiserver:v1.18.0
        36. 44 imagePullPolicy: IfNotPresent
        37. #保存退出
        38. [root@master kube-system]# systemctl restart kubelet #修改后重启kubelet
        39. #再次查看节点信息
        40. [root@master kube-system]# kubectl top node
        41. NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
        42. master 327m 4% 3909Mi 23%
        43. node 148m 1% 1327Mi 8%

        (2)创建Deployment

        • 这里创建一个nginx的deployment
        1. [root@master test]# cat nginx.yaml
        2. apiVersion: apps/v1
        3. kind: Deployment
        4. metadata:
        5. name: nginx
        6. spec:
        7. selector:
        8. matchLabels:
        9. run: nginx
        10. replicas: 1
        11. template:
        12. metadata:
        13. labels:
        14. run: nginx
        15. spec:
        16. containers:
        17. - name: nginx
        18. image: nginx:1.15.2
        19. ports:
        20. - containerPort: 80
        21. resources:
        22. limits:
        23. cpu: 500m
        24. requests: #想要HPA生效,必须添加requests声明
        25. cpu: 200m
        26. ---
        27. apiVersion: v1
        28. kind: Service
        29. metadata:
        30. name: nginx
        31. labels:
        32. run: nginx
        33. spec:
        34. ports:
        35. - port: 80
        36. selector:
        37. run: nginx
        • 访问测试
        1. [root@master test]# kubectl get pods -o wide
        2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
        3. nginx-9cb8d65b5-tq9v4 1/1 Running 0 14m 10.244.1.22 node <none> <none>
        4. [root@master test]# kubectl get svc nginx
        5. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
        6. nginx ClusterIP 172.16.169.27 <none> 80/TCP 15m
        7. [root@master test]# kubectl describe svc nginx
        8. Name: nginx
        9. Namespace: default
        10. Labels: run=nginx
        11. Annotations: Selector: run=nginx
        12. Type: ClusterIP
        13. IP: 172.16.169.27
        14. Port: <unset> 80/TCP
        15. TargetPort: 80/TCP
        16. Endpoints: 10.244.1.22:80
        17. Session Affinity: None
        18. Events: <none>
        19. [root@node test]# curl 172.16.169.27 #访问成功
        20. html>
        21. <html>
        22. <head>
        23. <title>Welcome to nginx!title>
        24. <style>
        25. body {
        26. width: 35em;
        27. margin: 0 auto;
        28. font-family: Tahoma, Verdana, Arial, sans-serif;
        29. }
        30. style>
        31. head>
        32. <body>
        33. <h1>Welcome to nginx!h1>
        34. <p>If you see this page, the nginx web server is successfully installed and
        35. working. Further configuration is required.p>
        36. <p>For online documentation and support please refer to
        37. <a href="http://nginx.org/">nginx.orga>.<br/>
        38. Commercial support is available at
        39. <a href="http://nginx.com/">nginx.coma>.p>
        40. <p><em>Thank you for using nginx.em>p>
        41. body>
        42. html>

        (3)基于CPU创建HPA

        1. #创建一个cpu利用率达到20,最大10个pod,最小1个,这里没有指定版本所以默认是v1版本,而v1版本只能以CPU为标准
        2. [root@master test]# kubectl autoscale deployment nginx --cpu-percent=20 --min=1 --max=10
        3. horizontalpodautoscaler.autoscaling/nginx autoscaled
        4. #TARGETS可以看到使用率
        5. [root@master test]# kubectl get hpa
        6. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
        7. nginx Deployment/nginx 0%/20% 1 10 1 86s
        8. #创建一个测试pod增加负载,访问地址要和pod的svc地址相同
        9. [root@master ~]# kubectl run busybox -it --image=busybox -- /bin/sh -c 'while true; do wget -q -O- http://10.244.1.22; done'
        10. #过一分钟后看hap的使用率,REPLICAS是当前pod的数量
        11. [root@master test]# kubectl get hpa
        12. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
        13. nginx Deployment/nginx 27%/20% 1 10 5 54m
        14. [root@master test]# kubectl get pods #再看pod数量,发现已经增加到了5个
        15. NAME READY STATUS RESTARTS AGE
        16. bustbox 1/1 Running 0 119s
        17. nginx-9cb8d65b5-24dg2 1/1 Running 0 57s
        18. nginx-9cb8d65b5-c6n98 1/1 Running 0 87s
        19. nginx-9cb8d65b5-ksjzv 1/1 Running 0 57s
        20. nginx-9cb8d65b5-n77fm 1/1 Running 0 87s
        21. nginx-9cb8d65b5-tq9v4 1/1 Running 0 84m
        22. [root@master test]# kubectl get deployments.apps
        23. NAME READY UP-TO-DATE AVAILABLE AGE
        24. nginx 5/5 5 5 84m
        25. #此时,停止压测,过好几分钟后再次查看pod数量和使用率
        26. [root@master test]# kubectl delete pod busybox #终止后,删除pod
        27. [root@master test]# kubectl get hpa #虽然使用率已经降到0了,但是可以看到当前REPLICAS的数量还5,这个需要等一会就会缩容
        28. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
        29. nginx Deployment/nginx 0%/20% 1 10 5 58m
        30. #过了几分钟后,可以看到pod数量已经回到了1
        31. [root@master test]# kubectl get hpa
        32. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
        33. nginx Deployment/nginx 0%/20% 1 10 1 64m
        34. [root@master test]# kubectl get pods
        35. NAME READY STATUS RESTARTS AGE
        36. nginx-9cb8d65b5-tq9v4 1/1 Running 0 95m

        (4)基于内存创建的HPA

        1. #先把上面创建的资源删除
        2. [root@master test]# kubectl delete horizontalpodautoscalers.autoscaling nginx
        3. horizontalpodautoscaler.autoscaling "nginx" deleted
        4. [root@master test]# kubectl delete -f nginx.yaml
        5. deployment.apps "nginx" deleted
        6. service "nginx" deleted
        • 重新编写yaml文件
        1. [root@master test]# cat nginx.yaml
        2. apiVersion: apps/v1
        3. kind: Deployment
        4. metadata:
        5. name: nginx
        6. spec:
        7. selector:
        8. matchLabels:
        9. run: nginx
        10. replicas: 1
        11. template:
        12. metadata:
        13. labels:
        14. run: nginx
        15. spec:
        16. containers:
        17. - name: nginx
        18. image: nginx:1.15.2
        19. ports:
        20. - containerPort: 80
        21. resources:
        22. limits:
        23. cpu: 500m
        24. memory: 60Mi
        25. requests:
        26. cpu: 200m
        27. memory: 25Mi
        28. ---
        29. apiVersion: v1
        30. kind: Service
        31. metadata:
        32. name: nginx
        33. labels:
        34. run: nginx
        35. spec:
        36. ports:
        37. - port: 80
        38. selector:
        39. run: nginx
        40. [root@master test]# kubectl apply -f nginx.yaml
        41. deployment.apps/nginx created
        42. service/nginx created
        • 创建HPA
        1. [root@master test]# vim hpa-nginx.yaml
        2. apiVersion: autoscaling/v2beta1 #上面的hpa版本有提到过,使用基于内存的hpa需要换个版本
        3. kind: HorizontalPodAutoscaler
        4. metadata:
        5. name: nginx-hpa
        6. spec:
        7. maxReplicas: 10 #1-10的pod数量限制
        8. minReplicas: 1
        9. scaleTargetRef: #指定使用hpa的资源对象,版本、类型、名称要和上面创建的相同
        10. apiVersion: apps/v1
        11. kind: Deployment
        12. name: nginx
        13. metrics:
        14. - type: Resource
        15. resource:
        16. name: memory
        17. targetAverageUtilization: 50 #限制%50的内存
        1. [root@master test]# kubectl apply -f hpa-nginx.yaml
        2. horizontalpodautoscaler.autoscaling/nginx-hpa created
        3. [root@master test]# kubectl get hpa
        4. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
        5. nginx-hpa Deployment/nginx 7%/50% 1 10 1 59s
        • 更换终端进行测试
        1. #在pod中执行命令,增加内存负载
        2. [root@master ~]# kubectl exec -it nginx-78f4944bb8-2rz7j -- /bin/sh -c 'dd if=/dev/zero of=/tmp/file1'
        • 等待负载上去,然后查看pod数量与内存使用率
        1. [root@master test]# kubectl get hpa
        2. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
        3. nginx-hpa Deployment/nginx 137%/50% 1 10 1 12m
        4. [root@master test]# kubectl get hpa
        5. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
        6. nginx-hpa Deployment/nginx 14%/50% 1 10 3 12m
        7. [root@master test]# kubectl get pods
        8. NAME READY STATUS RESTARTS AGE
        9. nginx-78f4944bb8-2rz7j 1/1 Running 0 21m
        10. nginx-78f4944bb8-bxh78 1/1 Running 0 34s
        11. nginx-78f4944bb8-g8w2h 1/1 Running 0 34s
        12. #与CPU相同,内存上去了也会自动创建pod

      28. 相关阅读:
        给网页添加背景音乐
        Python字符串—String
        php健身房教练预约系统网站
        GC日志开启及分析
        git仓库清理
        【ArcGIS微课1000例】0040:ArcGIS栅格二值化实验教程
        信息安全-大数据安全需求分析与安全保护工程
        Power Apps-使用power Automate流
        Salesforce ServiceCloud考证学习(2)
        50、Spring WebFlux 的 自动配置 的一些介绍,与 Spring MVC 的一些对比
      29. 原文地址:https://blog.csdn.net/WuDan_1112/article/details/126335691