神精西西 發表於 2020-5-28 14:41:00

kubernetes弹性伸缩

<p class="md-end-block md-p"><span class="md-plain md-expand">在 Kubernetes 的生态中,在多个维度、多个层次提供了不同的组件来满足不同的伸缩场景。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">有三种弹性伸缩:</span></p>
<ul class="ul-list" data-mark="-">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain md-expand">CA(Cluster Autoscaler):Node级别自动扩/缩容&nbsp;</span><span class="md-plain">cluster-autoscaler组件</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">HPA(Horizontal Pod Autoscaler):Pod个数自动扩/缩容</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">VPA(Vertical Pod Autoscaler):Pod配置自动扩/缩容,主要是CPU、内存&nbsp;</span><span class="md-plain md-expand">addon-resizer组件</span></p>
</li>
</ul>
<p><span class="md-plain md-expand">如果在云上建议 HPA 结合 cluster-autoscaler 的方式进行集群的弹性伸缩管理。</span></p>
<h5>node自动扩容缩容</h5>
<p><span class="md-expand"><strong><span class="md-plain">扩容:</span></strong><span class="md-plain md-expand">Cluster AutoScaler 定期检测是否有充足的资源来调度新创建的 Pod,当资源不足时会调用 Cloud Provider 创建新的 Node。</span></span></p>
<p><img src="https://img2020.cnblogs.com/blog/1156961/202005/1156961-20200527092959397-99419410.png"></p>
<p><span class="md-expand"><strong><span class="md-plain">缩容:</span></strong><span class="md-plain md-expand">Cluster AutoScaler 也会定期监测 Node 的资源使用情况,当一个 Node 长时间资源利用率都很低时(低于 50%)自动将其所在虚拟机从云服务商中删除。此时,原来的 Pod 会自动调度到其他 Node 上面。</span></span></p>
<p><span class="md-expand"><img src="https://img2020.cnblogs.com/blog/1156961/202005/1156961-20200527093043395-1358650527.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain md-expand">支持的云提供商:</span></p>
<ul class="ul-list" data-mark="-">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">阿里云:<span class="md-link">https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/alicloud/README.md</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">AWS: <span class="md-link">https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md</span></span></p>
</li>
<li class="md-list-item md-focus-container">
<p class="md-end-block md-p md-focus"><span class="md-plain">Azure: <span class="md-link md-expand">https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/azure/README.md</span></span></p>
</li>
</ul>
<p>ansiable扩容node流程</p>
<p><img src="https://img2020.cnblogs.com/blog/1156961/202005/1156961-20200527093321972-875618659.png"></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">. 触发新增Node
</span><span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">. 调用Ansible脚本部署组件
</span><span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">. 检查服务是否可用
</span><span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">. 调用API将新Node加入集群或者启用Node自动加入
</span><span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">. 观察新Node状态
</span><span style="color: rgba(128, 0, 128, 1)">6</span>. 完成Node扩容,接收新Pod</pre>
</div>
<p>node缩容流程:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">#获取节点列表
kubectl get node

#设置不可调度
kubectl cordon $node_name

#驱逐节点上的pod
kubectl drain $node_name </span>--ignore-<span style="color: rgba(0, 0, 0, 1)">daemonsets

#移除节点
kubectl delete node $node_name</span></pre>
</div>
<h3>POD自动扩容缩容 (HPA)</h3>
<p>Horizontal Pod Autoscaler(HPA,Pod水平自动伸缩),根据资源利用率或者自定义指标自动调整replication controller, deployment 或 replica set,实现部署的自动扩展和缩减,让部署的规模接近于实际服务的负载。HPA不适于无法缩放的对象,例如DaemonSet。</p>
<p><img src="https://img2020.cnblogs.com/blog/1156961/202005/1156961-20200527101418022-1336379192.png"></p>
<h6>HPA基本原理</h6>
<p>Kubernetes 中的 Metrics Server 持续采集所有 Pod 副本的指标数据。HPA 控制器通过 Metrics Server 的 API(Heapster 的 API 或聚合 API)获取这些数据,基于用户定义的扩缩容规则进行计算,得到目标 Pod 副本数量。当目标 Pod 副本数量与当前副本数量不同时,HPA 控制器就向 Pod 的副本控制器(Deployment、RC 或 ReplicaSet)发起 scale 操作,调整 Pod 的副本数量,完成扩缩容操作。如图所示。</p>
<p><img src="https://img2020.cnblogs.com/blog/1156961/202005/1156961-20200527101515773-487026849.png"></p>
<p class="md-end-block md-p"><span class="md-plain md-expand">在弹性伸缩中,冷却周期是不能逃避的一个话题, 由于评估的度量标准是动态特性,副本的数量可能会不断波动。有时被称为颠簸, 所以在每次做出扩容缩容后,冷却时间是多少。</span></p>
<p class="md-end-block md-p"><span class="md-plain">在 HPA 中,<span><strong>默认的扩容冷却周期是 3 分钟,缩容冷却周期是 5 分钟。</strong></span></span></p>
<p class="md-end-block md-p"><span class="md-plain md-expand">可以通过调整kube-controller-manager组件启动参数设置冷却时间:</span></p>
<ul class="ul-list" data-mark="-">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">--horizontal-pod-autoscaler-downscale-delay :扩容冷却</span></p>
</li>
<li class="md-list-item md-focus-container">
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">--horizontal-pod-autoscaler-upscale-delay :缩容冷却</span></p>
</li>
</ul>
<h6>HPA的演进历程:</h6>
<p class="md-end-block md-p"><span class="md-plain md-expand">目前 HPA 已经支持了 autoscaling/v1、autoscaling/v2beta1和autoscaling/v2beta2 三个大版本 。</span></p>
<p class="md-end-block md-p"><span class="md-plain">目前大多数人比较熟悉是autoscaling/v1,这个版本只支持CPU一个指标的弹性伸缩。</span></p>
<p class="md-end-block md-p"><span class="md-plain">而autoscaling/v2beta1增加了支持自定义指标,autoscaling/v2beta2又额外增加了外部指标支持。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">而产生这些变化不得不提的是Kubernetes社区对监控与监控指标的认识与转变。从早期Heapster到Metrics Server再到将指标边界进行划分,一直在丰富监控生态。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">示例:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">#v1版本:
apiVersion:&nbsp;autoscaling</span>/<span style="color: rgba(0, 0, 0, 1)">v1
kind:&nbsp;HorizontalPodAutoscaler
metadata:
&nbsp;&nbsp;name:&nbsp;php</span>-<span style="color: rgba(0, 0, 0, 1)">apache
&nbsp;&nbsp;namespace:&nbsp;default
spec:
&nbsp;&nbsp;scaleTargetRef:
&nbsp;&nbsp;&nbsp;&nbsp;apiVersion:&nbsp;apps</span>/<span style="color: rgba(0, 0, 0, 1)">v1
&nbsp;&nbsp;&nbsp;&nbsp;kind:&nbsp;Deployment
&nbsp;&nbsp;&nbsp;&nbsp;name:&nbsp;php</span>-<span style="color: rgba(0, 0, 0, 1)">apache
&nbsp;&nbsp;minReplicas:&nbsp;</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;maxReplicas:&nbsp;</span><span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">
&nbsp;&nbsp;targetCPUUtilizationPercentage:&nbsp;</span><span style="color: rgba(128, 0, 128, 1)">50</span><span style="color: rgba(0, 0, 0, 1)">


#v2beta2版本:
apiVersion: autoscaling</span>/<span style="color: rgba(0, 0, 0, 1)">v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: php</span>-<span style="color: rgba(0, 0, 0, 1)">apache
namespace: default
spec:
scaleTargetRef:
    apiVersion: apps</span>/<span style="color: rgba(0, 0, 0, 1)">v1
    kind: Deployment
    name: php</span>-<span style="color: rgba(0, 0, 0, 1)">apache
minReplicas: </span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
maxReplicas: </span><span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">
metrics:
</span>-<span style="color: rgba(0, 0, 0, 1)"> type: Resource
    resource:
      name: cpu
      target:
      type: Utilization
      averageUtilization: </span><span style="color: rgba(128, 0, 128, 1)">50</span>
-<span style="color: rgba(0, 0, 0, 1)"> type: Pods
    pods:
      metric:
      name: packets</span>-per-<span style="color: rgba(0, 0, 0, 1)">second
      target:
      type: AverageValue
      averageValue: 1k
</span>-<span style="color: rgba(0, 0, 0, 1)"> type: Object
    </span><span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)">:
      metric:
      name: requests</span>-per-<span style="color: rgba(0, 0, 0, 1)">second
      describedObject:
      apiVersion: networking.k8s.io</span>/<span style="color: rgba(0, 0, 0, 1)">v1beta1
      kind: Ingress
      name: main</span>-<span style="color: rgba(0, 0, 0, 1)">route
      target:
      type: Value
      value: 10k
</span>-<span style="color: rgba(0, 0, 0, 1)"> type: External
    external:
      metric:
      name: queue_messages_ready
      selector: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">queue=worker_tasks</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      target:
      type: AverageValue
      averageValue: </span><span style="color: rgba(128, 0, 128, 1)">30</span></pre>
</div>
<h5>基于CPU指标缩放</h5>
<p class="md-end-block md-heading md-focus"><span class="md-plain md-expand">Kubernetes API Aggregation </span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">在 Kubernetes 1.7 版本引入了聚合层,允许第三方应用程序通过将自己注册到kube-apiserver上,仍然通过 API Server 的 HTTP URL 对新的 API 进行访问和操作。为了实现这个机制,Kubernetes 在 kube-apiserver 服务中引入了一个 API 聚合层(API Aggregation Layer),用于将扩展 API 的访问请求转发到用户服务的功能。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand"><img src="https://img2020.cnblogs.com/blog/1156961/202005/1156961-20200527103341374-1458453130.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain md-expand">当你访问 apis/metrics.k8s.io/v1beta1 的时候,实际上访问到的是一个叫作 kube-aggregator 的代理。而 kube-apiserver,正是这个代理的一个后端;而 Metrics Server,则是另一个后端 。通过这种方式,我们就可以很方便地扩展 Kubernetes 的 API 了。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">如果你使用kubeadm部署的,默认已开启。如果你使用二进制方式部署的话,需要在kube-APIServer中添加启动参数,增加以下配置:</span></p>
<div class="cnblogs_code">
<pre># <span style="color: rgba(0, 0, 255, 1)">vi</span> /opt/kubernetes/cfg/kube-<span style="color: rgba(0, 0, 0, 1)">apiserver.conf
...
</span>--requestheader-client-ca-<span style="color: rgba(0, 0, 255, 1)">file</span>=/opt/kubernetes/ssl/<span style="color: rgba(0, 0, 0, 1)">ca.pem \
</span>--proxy-client-cert-<span style="color: rgba(0, 0, 255, 1)">file</span>=/opt/kubernetes/ssl/<span style="color: rgba(0, 0, 0, 1)">server.pem \
</span>--proxy-client-key-<span style="color: rgba(0, 0, 255, 1)">file</span>=/opt/kubernetes/ssl/server-<span style="color: rgba(0, 0, 0, 1)">key.pem \
</span>--requestheader-allowed-names=<span style="color: rgba(0, 0, 0, 1)">kubernetes \
</span>--requestheader-extra-headers-prefix=X-Remote-Extra-<span style="color: rgba(0, 0, 0, 1)"> \
</span>--requestheader-group-headers=X-Remote-<span style="color: rgba(0, 0, 0, 1)">Group \
</span>--requestheader-username-headers=X-Remote-<span style="color: rgba(0, 0, 0, 1)">User \
</span>--enable-aggregator-routing=<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)"> \
...</span></pre>
</div>
<p>在设置完成重启 kube-apiserver 服务,就启用 API 聚合功能了。</p>
<h5 class="md-end-block md-heading md-focus"><span class="md-plain md-expand">部署 Metrics Server</span></h5>
<p class="md-end-block md-p"><span class="md-plain md-expand">Metrics Server是一个集群范围的资源使用情况的数据聚合器。作为一个应用部署在集群中。</span></p>
<p class="md-end-block md-p"><span class="md-plain">Metric server从每个节点上Kubelet公开的摘要API收集指标。 </span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">Metrics server通过Kubernetes聚合器注册在Master APIServer中。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand"><img src="https://img2020.cnblogs.com/blog/1156961/202005/1156961-20200527105946134-1943488615.png"></span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">部署清单地址:https://github.com/kubernetes-sigs/metrics-server</span></p>
<div class="cnblogs_code">
<pre># git clone https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">github.com/kubernetes-incubator/metrics-server</span>
<span style="color: rgba(0, 0, 0, 1)">
修改deployment.yaml文件,修正集群问题
问题1:metrics</span>-server默认使用节点hostname通过kubelet 10250端口获取数据,但是coredns里面没有该数据无法解析(<span style="color: rgba(128, 0, 128, 1)">10.96</span>.<span style="color: rgba(128, 0, 128, 1)">0.10</span>:<span style="color: rgba(128, 0, 128, 1)">53</span>),可以在metrics server启动命令添加参数 --kubelet-preferred-address-types=<span style="color: rgba(0, 0, 0, 1)">InternalIP 直接使用节点IP地址获取数据

问题2:kubelet 的10250端口使用的是https协议,连接需要验证tls证书。可以在metrics server启动命令添加参数</span>--kubelet-insecure-<span style="color: rgba(0, 0, 0, 1)">tls不验证客户端证书

问题3:yaml文件中的image地址k8s.gcr.io</span>/metrics-server-amd64:v0.<span style="color: rgba(128, 0, 128, 1)">3.0</span> 需要梯子,需要改成中国可以访问的image地址,可以使用aliyun的。这里使用hub.docker.com里的google镜像地址 image: mirrorgooglecontainers/metrics-server-amd64:v0.<span style="color: rgba(128, 0, 128, 1)">3.1</span><span style="color: rgba(0, 0, 0, 1)">

kubectl apply </span>-<span style="color: rgba(0, 0, 0, 1)">f .
kubectl get pod </span>-n kube-system</pre>
</div>
<p><span class="md-plain md-expand">可通过Metrics API在Kubernetes中获得资源使用率指标,例如容器CPU和内存使用率。这些度量标准既可以由用户直接访问(例如,通过使用<span><code>kubectl top</code><span class="md-plain md-expand">命令),也可以由集群中的控制器(例如,Horizontal Pod Autoscaler)用于进行决策。</span></span></span></p>
<p><span class="md-plain md-expand"><span><span class="md-plain md-expand">测试:</span></span></span></p>
<div class="cnblogs_code">
<pre>kubectl get --raw /apis/metrics.k8s.io/v1beta1/<span style="color: rgba(0, 0, 0, 1)">nodes
kubectl top node<br>kubectl get apiservice |grep metrics<br>kubectl describe apiservice v1beta1.metrics.k8s.io</span></pre>
</div>
<h5 class="md-end-block md-heading md-focus"><span class="md-plain md-expand">autoscaling/v1(CPU指标实践)</span></h5>
<p class="md-end-block md-p"><span class="md-plain md-expand">autoscaling/v1版本只支持CPU一个指标。</span></p>
<p class="md-end-block md-p md-focus">创建HPA策略:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"># kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
java</span>-demo-8548998c57-d4wkp   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          12m
java</span>-demo-8548998c57-w24x6   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          11m
java</span>-demo-8548998c57-wbnrs   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          11m
# kubectl autoscale deployment java</span>-demo --cpu-percent=<span style="color: rgba(128, 0, 128, 1)">50</span> --min=<span style="color: rgba(128, 0, 128, 1)">3</span> --max=<span style="color: rgba(128, 0, 128, 1)">10</span> --dry-run -o yaml &gt; hpa-<span style="color: rgba(0, 0, 0, 1)">v1.yaml
# </span><span style="color: rgba(0, 0, 255, 1)">cat</span> hpa-<span style="color: rgba(0, 0, 0, 1)">v1.yaml
apiVersion: autoscaling</span>/<span style="color: rgba(0, 0, 0, 1)">v1
kind: HorizontalPodAutoscaler
metadata:
name: java</span>-<span style="color: rgba(0, 0, 0, 1)">demo
spec:
maxReplicas: </span><span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">
minReplicas: </span><span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">
scaleTargetRef:
    apiVersion: apps</span>/<span style="color: rgba(0, 0, 0, 1)">v1
    kind: Deployment
    name: java</span>-<span style="color: rgba(0, 0, 0, 1)">demo
targetCPUUtilizationPercentage: </span><span style="color: rgba(128, 0, 128, 1)">50</span><span style="color: rgba(0, 0, 0, 1)">
# kubectl apply </span>-f hpa-<span style="color: rgba(0, 0, 0, 1)">v1.yaml
# kubectl get hpa
NAME      REFERENCE            TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
java</span>-demo   Deployment/java-demo   <span style="color: rgba(128, 0, 128, 1)">1</span>%/<span style="color: rgba(128, 0, 128, 1)">50</span>%    <span style="color: rgba(128, 0, 128, 1)">3</span>         <span style="color: rgba(128, 0, 128, 1)">10</span>      <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">          10m
# kubectl describe hpa java</span>-demo</pre>
</div>
<p class="md-end-block md-p"><span class="md-plain md-expand">scaleTargetRef:表示当前要伸缩对象是谁</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">targetCPUUtilizationPercentage:当整体的资源利用率超过50%的时候,会进行扩容。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">开启压测:</span></p>
<div class="cnblogs_code">
<pre># <span style="color: rgba(0, 0, 255, 1)">yum</span> <span style="color: rgba(0, 0, 255, 1)">install</span> httpd-tools -<span style="color: rgba(0, 0, 0, 1)">y
# kubectl get svc
NAME         TYPE      CLUSTER</span>-IP   EXTERNAL-<span style="color: rgba(0, 0, 0, 1)">IP   PORT(S)   AGE
java</span>-demo    ClusterIP   <span style="color: rgba(128, 0, 128, 1)">10.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.215</span>   &lt;none&gt;      <span style="color: rgba(128, 0, 128, 1)">80</span>/<span style="color: rgba(0, 0, 0, 1)">TCP    171m
# ab </span>-n <span style="color: rgba(128, 0, 128, 1)">100000</span> -c <span style="color: rgba(128, 0, 128, 1)">100</span> http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">10.0.0.215/index</span>
This is ApacheBench, Version <span style="color: rgba(128, 0, 128, 1)">2.3</span> &lt;$Revision: <span style="color: rgba(128, 0, 128, 1)">1430300</span> $&gt;<span style="color: rgba(0, 0, 0, 1)">
Copyright </span><span style="color: rgba(128, 0, 128, 1)">1996</span> Adam Twiss, Zeus Technology Ltd, http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">www.zeustech.net/</span>
Licensed to The Apache Software Foundation, http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">www.apache.org/</span>
<span style="color: rgba(0, 0, 0, 1)">
Benchmarking </span><span style="color: rgba(128, 0, 128, 1)">10.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.215</span><span style="color: rgba(0, 0, 0, 1)"> (be patient)
Completed </span><span style="color: rgba(128, 0, 128, 1)">10000</span><span style="color: rgba(0, 0, 0, 1)"> requests
Completed </span><span style="color: rgba(128, 0, 128, 1)">20000</span><span style="color: rgba(0, 0, 0, 1)"> requests
Completed </span><span style="color: rgba(128, 0, 128, 1)">30000</span><span style="color: rgba(0, 0, 0, 1)"> requests
Completed </span><span style="color: rgba(128, 0, 128, 1)">40000</span><span style="color: rgba(0, 0, 0, 1)"> requests
Completed </span><span style="color: rgba(128, 0, 128, 1)">50000</span><span style="color: rgba(0, 0, 0, 1)"> requests
Completed </span><span style="color: rgba(128, 0, 128, 1)">60000</span><span style="color: rgba(0, 0, 0, 1)"> requests
Completed </span><span style="color: rgba(128, 0, 128, 1)">70000</span><span style="color: rgba(0, 0, 0, 1)"> requests
Completed </span><span style="color: rgba(128, 0, 128, 1)">80000</span><span style="color: rgba(0, 0, 0, 1)"> requests
apr_socket_recv: Connection refused (</span><span style="color: rgba(128, 0, 128, 1)">111</span><span style="color: rgba(0, 0, 0, 1)">)
Total of </span><span style="color: rgba(128, 0, 128, 1)">85458</span> requests completed</pre>
</div>
<p>检测扩容状态</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"># kubectl get hpa
NAME      REFERENCE            TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
java</span>-demo   Deployment/java-demo   <span style="color: rgba(128, 0, 128, 1)">1038</span>%/<span style="color: rgba(128, 0, 128, 1)">50</span>%   <span style="color: rgba(128, 0, 128, 1)">3</span>         <span style="color: rgba(128, 0, 128, 1)">10</span>      <span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">         165m

# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
java</span>-demo-77d4f5cdcf-4chv4   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          56s
java</span>-demo-77d4f5cdcf-9bkz7   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          56s
java</span>-demo-77d4f5cdcf-bk9mk   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          156m
java</span>-demo-77d4f5cdcf-bv68j   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          41s
java</span>-demo-77d4f5cdcf-khhlv   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          41s
java</span>-demo-77d4f5cdcf-nvdjh   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          56s
java</span>-demo-77d4f5cdcf-pqxvb   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          41s
java</span>-demo-77d4f5cdcf-pxgl9   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          41s
java</span>-demo-77d4f5cdcf-qqk6q   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          156m
java</span>-demo-77d4f5cdcf-tkct6   <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span>   Running   <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">          156m

# kubectl top pod
NAME                         CPU(cores)   MEMORY(bytes)   
java</span>-demo-77d4f5cdcf-<span style="color: rgba(0, 0, 0, 1)">4chv4   2m         269Mi         
java</span>-demo-77d4f5cdcf-<span style="color: rgba(0, 0, 0, 1)">bk9mk   2m         246Mi         
java</span>-demo-77d4f5cdcf-<span style="color: rgba(0, 0, 0, 1)">cwzwz   2m         177Mi         
java</span>-demo-77d4f5cdcf-<span style="color: rgba(0, 0, 0, 1)">cz7hj   3m         220Mi         
java</span>-demo-77d4f5cdcf-<span style="color: rgba(0, 0, 0, 1)">fb9zl   3m         197Mi         
java</span>-demo-77d4f5cdcf-<span style="color: rgba(0, 0, 0, 1)">ftjht   3m         194Mi         
java</span>-demo-77d4f5cdcf-<span style="color: rgba(0, 0, 0, 1)">qdxqf   2m         174Mi         
java</span>-demo-77d4f5cdcf-<span style="color: rgba(0, 0, 0, 1)">qx52w   2m         175Mi         
java</span>-demo-77d4f5cdcf-<span style="color: rgba(0, 0, 0, 1)">rfrlh   3m         220Mi         
java</span>-demo-77d4f5cdcf-xjzjt   2m         176Mi</pre>
</div>
<p><span class="md-plain">工作流程:hpa -&gt; apiserver -&gt; kube aggregation -&gt; metrics-server -&gt; kubelet(cadvisor)</span></p>
<h5 class="md-end-block md-heading md-focus"><span class="md-plain md-expand">autoscaling/v2beta2(多指标)</span></h5>
<p class="md-end-block md-p"><span class="md-plain md-expand">为满足更多的需求, HPA 还有 autoscaling/v2beta1和 autoscaling/v2beta2两个版本。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">这两个版本的区别是 autoscaling/v1beta1支持了 Resource Metrics(CPU)和 Custom Metrics(应用程序指标),而在 autoscaling/v2beta2的版本中额外增加了External Metrics的支持。</span></p>
<div class="cnblogs_code">
<pre>apiVersion: autoscaling/<span style="color: rgba(0, 0, 0, 1)">v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: java</span>-<span style="color: rgba(0, 0, 0, 1)">demo
namespace: default
spec:
scaleTargetRef:
    apiVersion: apps</span>/<span style="color: rgba(0, 0, 0, 1)">v1
    kind: Deployment
    name: web
minReplicas: </span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
maxReplicas: </span><span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">
metrics:
</span>-<span style="color: rgba(0, 0, 0, 1)"> resource:
    type: Resource
      name: cpu
      target:
      averageUtilization: </span><span style="color: rgba(128, 0, 128, 1)">60</span><span style="color: rgba(0, 0, 0, 1)">
      type: Utilization</span></pre>
</div>
<p class="md-end-block md-p"><span class="md-plain md-expand">与上面v1版本效果一样,只不过这里格式有所变化。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">v2还支持其他另种类型的度量指标,:Pods和Object。 </span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">type: Pods
pods:
metric:
    name: packets</span>-per-<span style="color: rgba(0, 0, 0, 1)">second
target:
    type: AverageValue
    averageValue: 1k</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">type: Object
</span><span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)">:
metric:
    name: requests</span>-per-<span style="color: rgba(0, 0, 0, 1)">second
describedObject:
    apiVersion: networking.k8s.io</span>/<span style="color: rgba(0, 0, 0, 1)">v1beta1
    kind: Ingress
    name: main</span>-<span style="color: rgba(0, 0, 0, 1)">route
target:
    type: Value
    value: 2k</span></pre>
</div>
<p class="md-end-block md-p"><span class="md-plain md-expand">metrics中的type字段有四种类型的值:Object、Pods、Resource、External。 </span></p>
<ul class="ul-list" data-mark="-">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain md-expand">Resource:指的是当前伸缩对象下的pod的cpu和memory指标,只支持Utilization和AverageValue类型的目标值。</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">Object:指的是指定k8s内部对象的指标,数据需要第三方adapter提供,只支持Value和AverageValue类型的目标值。</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">Pods:指的是伸缩对象Pods的指标,数据需要第三方的adapter提供,只允许AverageValue类型的目标值。</span></p>
</li>
<li class="md-list-item md-focus-container">
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">External:指的是k8s外部的指标,数据同样需要第三方的adapter提供,只支持Value和AverageValue类型的目标值。</span></p>
</li>
</ul>
<div class="cnblogs_code">
<pre>apiVersion: autoscaling/<span style="color: rgba(0, 0, 0, 1)">v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: java</span>-<span style="color: rgba(0, 0, 0, 1)">demo
namespace: default
spec:
scaleTargetRef:
    apiVersion: apps</span>/<span style="color: rgba(0, 0, 0, 1)">v1
    kind: Deployment
    name: java</span>-<span style="color: rgba(0, 0, 0, 1)">demo
minReplicas: </span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
maxReplicas: </span><span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">
metrics:
</span>-<span style="color: rgba(0, 0, 0, 1)"> type: Resource
    resource:
      name: cpu
      target:
      type: Utilization
      averageUtilization: </span><span style="color: rgba(128, 0, 128, 1)">50</span>
-<span style="color: rgba(0, 0, 0, 1)"> type: Pods
    pods:
      metric:
      name: packets</span>-per-<span style="color: rgba(0, 0, 0, 1)">second
      target:
      type: AverageValue
      averageValue: 1k
</span>-<span style="color: rgba(0, 0, 0, 1)"> type: Object
    </span><span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)">:
      metric:
      name: requests</span>-per-<span style="color: rgba(0, 0, 0, 1)">second
      describedObject:
      apiVersion: networking.k8s.io</span>/<span style="color: rgba(0, 0, 0, 1)">v1beta1
      kind: Ingress
      name: main</span>-<span style="color: rgba(0, 0, 0, 1)">route
      target:
      type: Value
      value: 10k</span></pre>
</div>
<h3 class="md-end-block md-heading md-focus"><span class="md-plain md-expand">基于Prometheus自定义指标缩放</span></h3>
<p>&nbsp;资源指标只包含CPU、内存,一般来说也够了。但如果想根据自定义指标:如请求qps/5xx错误数来实现HPA,就需要使用自定义指标了,目前比较成熟的实现是 Prometheus Custom Metrics。自定义指标由Prometheus来提供,再利用k8s-prometheus-adpater聚合到apiserver,实现和核心指标(metric-server)同样的效果。</p>
<p><span class="md-plain">工作流程:hpa -&gt; apiserver -&gt; kube aggregation -&gt; prometheus-adapter -&gt; prometheus -&gt; pods</span></p>
<p><span class="md-plain"><img src="https://img2020.cnblogs.com/blog/1156961/202005/1156961-20200528093646629-1234493254.png"></span></p>
<h6 class="md-end-block md-heading md-focus"><span class="md-plain md-expand">部署 Custom Metrics Adapter</span></h6>
<p class="md-end-block md-p"><span class="md-plain md-expand">但是prometheus采集到的metrics并不能直接给k8s用,因为两者数据格式不兼容,还需要另外一个组件(k8s-prometheus-adpater),将prometheus的metrics 数据格式转换成k8s API接口能识别的格式,转换以后,因为是自定义API,所以还需要用Kubernetes aggregator在主APIServer中注册,以便直接通过/apis/来访问。</span></p>
<p class="md-end-block md-p"><span class="md-plain"> <span class="md-link">https://github.com/DirectXMan12/k8s-prometheus-adapter</span></span></p>
<p class="md-end-block md-p"><span class="md-plain">该 PrometheusAdapter 有一个稳定的Helm Charts,我们直接使用。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">先准备下helm环境:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">wget</span> https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz</span>
<span style="color: rgba(0, 0, 255, 1)">tar</span> zxvf helm-v3.<span style="color: rgba(128, 0, 128, 1)">0.0</span>-linux-amd64.<span style="color: rgba(0, 0, 255, 1)">tar</span><span style="color: rgba(0, 0, 0, 1)">.gz
</span><span style="color: rgba(0, 0, 255, 1)">mv</span> linux-amd64/helm /usr/bin/<span style="color: rgba(0, 0, 0, 1)">
helm repo add stable http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirror.azure.cn/kubernetes/charts</span>
<span style="color: rgba(0, 0, 0, 1)">helm repo update
helm repo list</span></pre>
</div>
<p>部署prometheus-adapter,指定prometheus地址:</p>
<div class="cnblogs_code">
<pre># helm <span style="color: rgba(0, 0, 255, 1)">install</span> prometheus-adapter stable/prometheus-adapter --namespace kube-system --set prometheus.url=http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">prometheus.kube-system,prometheus.port=9090</span>
# helm list -n kube-<span style="color: rgba(0, 0, 0, 1)">system
NAME                  NAMESPACE       REVISION      UPDATED                                 STATUS      CHART                  APP VERSION
prometheus</span>-adapter      kube-system   <span style="color: rgba(128, 0, 128, 1)">1</span>               <span style="color: rgba(128, 0, 128, 1)">2020</span>-<span style="color: rgba(128, 0, 128, 1)">05</span>-<span style="color: rgba(128, 0, 128, 1)">28</span> <span style="color: rgba(128, 0, 128, 1)">11</span>:<span style="color: rgba(128, 0, 128, 1)">38</span>:<span style="color: rgba(128, 0, 128, 1)">35.156622425</span> +<span style="color: rgba(128, 0, 128, 1)">0800</span> CST deployed      prometheus-adapter-<span style="color: rgba(128, 0, 128, 1)">2.3</span>.<span style="color: rgba(128, 0, 128, 1)">1</span> v0.<span style="color: rgba(128, 0, 128, 1)">6.0</span><span style="color: rgba(0, 0, 0, 1)"><br></span></pre>
</div>
<p>确保适配器注册到APIServer:</p>
<div class="cnblogs_code">
<pre># kubectl get apiservices |<span style="color: rgba(0, 0, 255, 1)">grep</span><span style="color: rgba(0, 0, 0, 1)"> custom
# kubectl get </span>--raw <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/apis/custom.metrics.k8s.io/v1beta1</span><span style="color: rgba(128, 0, 0, 1)">"</span></pre>
</div>
<h6>基于QPS指标实践</h6>
<p>&nbsp;部署应用暴露prometheus指标接口,可以通过访问service看到</p>
<div class="cnblogs_code">
<pre>apiVersion: apps/<span style="color: rgba(0, 0, 0, 1)">v1
kind: Deployment
metadata:
labels:
    app: metrics</span>-<span style="color: rgba(0, 0, 0, 1)">app
name: metrics</span>-<span style="color: rgba(0, 0, 0, 1)">app
spec:
replicas: </span><span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">
selector:
    matchLabels:
      app: metrics</span>-<span style="color: rgba(0, 0, 0, 1)">app
template:
    metadata:
      labels:
      app: metrics</span>-<span style="color: rgba(0, 0, 0, 1)">app
      annotations:
      prometheus.io</span>/scrape: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">true</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      prometheus.io</span>/port: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">80</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      prometheus.io</span>/path: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/metrics</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
    spec:
      containers:
      </span>- image: lizhenliang/metrics-<span style="color: rgba(0, 0, 0, 1)">app
      name: metrics</span>-<span style="color: rgba(0, 0, 0, 1)">app
      ports:
      </span>-<span style="color: rgba(0, 0, 0, 1)"> name: web
          containerPort: </span><span style="color: rgba(128, 0, 128, 1)">80</span><span style="color: rgba(0, 0, 0, 1)">
      resources:
          requests:
            cpu: 200m
            memory: 256Mi
      readinessProbe:
          httpGet:
            path: </span>/<span style="color: rgba(0, 0, 0, 1)">
            port: </span><span style="color: rgba(128, 0, 128, 1)">80</span><span style="color: rgba(0, 0, 0, 1)">
          initialDelaySeconds: </span><span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">
          periodSeconds: </span><span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">
      livenessProbe:
          httpGet:
            path: </span>/<span style="color: rgba(0, 0, 0, 1)">
            port: </span><span style="color: rgba(128, 0, 128, 1)">80</span><span style="color: rgba(0, 0, 0, 1)">
          initialDelaySeconds: </span><span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">
          periodSeconds: </span><span style="color: rgba(128, 0, 128, 1)">5</span>
---<span style="color: rgba(0, 0, 0, 1)">
apiVersion: v1
kind: Service
metadata:
name: metrics</span>-<span style="color: rgba(0, 0, 0, 1)">app
labels:
    app: metrics</span>-<span style="color: rgba(0, 0, 0, 1)">app
spec:
ports:
</span>-<span style="color: rgba(0, 0, 0, 1)"> name: web
    port: </span><span style="color: rgba(128, 0, 128, 1)">80</span><span style="color: rgba(0, 0, 0, 1)">
    targetPort: </span><span style="color: rgba(128, 0, 128, 1)">80</span><span style="color: rgba(0, 0, 0, 1)">
selector:
    app: metrics</span>-<span style="color: rgba(0, 0, 0, 1)">app


# curl </span><span style="color: rgba(128, 0, 128, 1)">10.99</span>.<span style="color: rgba(128, 0, 128, 1)">15.240</span>/<span style="color: rgba(0, 0, 0, 1)">metrics
# HELP http_requests_total The amount of requests </span><span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> total
# TYPE http_requests_total counter
http_requests_total </span><span style="color: rgba(128, 0, 128, 1)">86</span><span style="color: rgba(0, 0, 0, 1)">
# HELP http_requests_per_second The amount of requests per second the latest ten seconds
# TYPE http_requests_per_second gauge
http_requests_per_second </span><span style="color: rgba(128, 0, 128, 1)">0.5</span></pre>
</div>
<p>创建HPA策略</p>
<p>使用Prometheus提供的指标测试来测试自定义指标(QPS)的自动缩放。</p>
<div class="cnblogs_code">
<pre># <span style="color: rgba(0, 0, 255, 1)">vi</span> app-hpa-<span style="color: rgba(0, 0, 0, 1)">v2.yml
apiVersion: autoscaling</span>/<span style="color: rgba(0, 0, 0, 1)">v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: metrics</span>-app-<span style="color: rgba(0, 0, 0, 1)">hpa
namespace: default
spec:
scaleTargetRef:
    apiVersion: apps</span>/<span style="color: rgba(0, 0, 0, 1)">v1
    kind: Deployment
    name: metrics</span>-<span style="color: rgba(0, 0, 0, 1)">app
minReplicas: </span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
maxReplicas: </span><span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">
metrics:
</span>-<span style="color: rgba(0, 0, 0, 1)"> type: Pods
    pods:
      metric:
      name: http_requests_per_second
      target:
      type: AverageValue
      averageValue: 800m   # 800m 即0.8个</span>/秒</pre>
</div>
<h6 class="md-end-block md-heading md-focus"><span class="md-plain md-expand">配置适配器收集特定的指标</span></h6>
<p class="md-end-block md-p"><span class="md-plain md-expand">当创建好HPA还没结束,因为适配器还不知道你要什么指标(http_requests_per_second),HPA也就获取不到Pod提供指标。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand"> ConfigMap在default名称空间中编辑prometheus-adapter ,并seriesQuery在该rules: 部分的顶部添加一个新的: </span></p>
<div class="cnblogs_code">
<pre># kubectl edit cm prometheus-adapter -n kube-<span style="color: rgba(0, 0, 0, 1)">system
apiVersion: v1
kind: ConfigMap
metadata:
labels:
    app: prometheus</span>-<span style="color: rgba(0, 0, 0, 1)">adapter
    chart: prometheus</span>-adapter-v0.<span style="color: rgba(128, 0, 128, 1)">1.2</span><span style="color: rgba(0, 0, 0, 1)">
    heritage: Tiller
    release: prometheus</span>-<span style="color: rgba(0, 0, 0, 1)">adapter
name: prometheus</span>-<span style="color: rgba(0, 0, 0, 1)">adapter
data:
config.yaml: </span>|<span style="color: rgba(0, 0, 0, 1)">
    rules:
    </span>- seriesQuery: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">http_requests_total{kubernetes_namespace!="",kubernetes_pod_name!=""}</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
      resources:
      overrides:
          kubernetes_namespace: {resource: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">namespace</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}
          kubernetes_pod_name: {resource: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">pod</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}
      name:
      matches: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">^(.*)_total</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      as: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">${1}_per_second</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      metricsQuery: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">sum(rate(&lt;&lt;.Series&gt;&gt;{&lt;&lt;.LabelMatchers&gt;&gt;})) by (&lt;&lt;.GroupBy&gt;&gt;)</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
...</span></pre>
</div>
<p class="md-end-block md-p"><span class="md-plain md-expand">该规则将http_requests在2分钟的间隔内收集该服务的所有Pod的平均速率。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">测试API:</span></p>
<div class="cnblogs_code">
<pre>kubectl get --raw <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests_per_second</span><span style="color: rgba(128, 0, 0, 1)">"</span></pre>
</div>
<p>压测</p>
<div class="cnblogs_code">
<pre>ab -n <span style="color: rgba(128, 0, 128, 1)">100000</span> -c <span style="color: rgba(128, 0, 128, 1)">100</span>http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">10.99.15.240/metrics</span></pre>
</div>
<p>查看PHA状态</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">kubectl get hpa
kubectl describe hpa metrics</span>-app-hpa</pre>
</div>
<p>小结</p>
<p><img src="https://img2020.cnblogs.com/blog/1156961/202005/1156961-20200528143751341-1897836585.png"></p>
<ol class="ol-list" start="">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain md-expand">通过/metrics收集每个Pod的http_request_total指标;</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">prometheus将收集到的信息汇总;</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">APIServer定时从Prometheus查询,获取request_per_second的数据;</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">HPA定期向APIServer查询以判断是否符合配置的autoscaler规则;</span></p>
</li>
<li class="md-list-item md-focus-container">
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">如果符合autoscaler规则,则修改Deployment的ReplicaSet副本数量进行伸缩。</span></p>
</li>
</ol><br><br>
来源:https://www.cnblogs.com/yuezhimi/p/12970558.html
頁: [1]
查看完整版本: kubernetes弹性伸缩