• HPAVPAKPA自动扩缩容


    HPA-VPA实现pod自动扩缩容

    背景

    弹性伸缩是根据用户的业务需求和策略,自动“调整”其“弹性资源”的管理服务。通过弹
    性伸缩功能,用户可设置定时、周期或监控策略,恰到好处地增加或减少“弹性资源”,并完
    成实例配置,保证业务平稳健康运行。

    在实际工作中,我们常常需要做一些扩容缩容操作,如:电商平台在 618 和双十一搞秒
    杀活动;由于资源紧张、工作负载降低等都需要对服务实例数进行扩缩容操作。

    扩缩容种类

    1、Node 层面:
    对 K8s 物理节点扩容和缩容,根据业务规模实现物理节点自动扩缩容,仅支持云主机。

    2、Pod 层面:
    我们一般会使用Deployment中的replicas参数,设置多个副本集来保证服务的高可用,但是这是一个固定的值,比如我们设置 10 个副本,就会启 10 个 pod 同时 running 来提供服务。如果这个服务平时流量很少的时候,也是 10 个 pod 同时在 running,而流量突然暴增时,又可能出现 10 个 pod 不够用的情况。针对这种情况怎么办?就需要扩容和缩容。

    HPA

    • 通过哪些指标决定扩缩容?

    HPA v1 版本可以根据 CPU 使用率来进行自动扩缩容:
    但是并非所有的系统都可以仅依靠 CPU 或者 Memory 指标来扩容,对于大多数 Web应用的后端来说,基于每秒的请求数量进行弹性伸缩来处理突发流量会更加的靠谱,所以对于一个自动扩缩容系统来说,我们不能局限于 CPU、Memory 基础监控数据,每秒请求数 RPS 等自定义指标也是十分重要。

    HPA v2 版本可以根据自定义的指标进行自动扩缩容
    注意:hpa v1 只能基于 cpu 做扩容所用,hpa v2 可以基于内存和自定义的指标做扩容和缩容

    • 如何采集资源指标?

    如果我们的系统默认依赖 Prometheus,自定义的 Metrics 指标则可以从各种数据源或者 exporter 中获取,基于拉模型的 Prometheus 会定期从数据源中拉取数据。 也可以基于 metrics-server 自动获取节点和 pod 的资源指标。

    • 如何实现自动扩缩容?

    K8s 的 HPA controller 已经实现了一套简单的自动扩缩容逻辑,默认情况下,每 30s 检测一次指标,只要检测到了配置 HPA 的目标值,则会计算出预期的工作负载的副本数,再进行扩缩容操作。同时,为了避免过于频繁的扩缩容,默认在 5min 内没有重新扩缩容的情况下,才会触发扩缩容。 HPA 本身的算法相对比较保守,可能并不适用于很多
    场景。例如,一个快速的流量突发场景,如果正处在 5min 内的 HPA 稳定期,这个时候根据 HPA 的策略,会导致无法扩容。

    KPA

    KPA(Knative Pod Autoscaler): 请求数扩缩容

    基于请求数对 Pod 自动扩缩容,KPA 的主要限制在于它不支持基于 CPU 的自动扩缩容。

    1. 根据并发请求数实现自动扩缩容
    2. 设置扩缩容边界实现自动扩缩容

    扩缩容边界指应用程序提供服务的最小和最大Pod数量,通过设置应用程序提供服务的最小和最大Pod数量,实现自动扩缩容。

    相比 HPA,KPA 会考虑更多的场景,其中一个比较重要的是流量突发的时候,可以结合HPA使用。k8s的HPA controller已经实现了简单的扩缩容逻辑,默认30s检测一次,只要检测到了HPA的目标值,则会计算出预期的工作负载副本数,再进行扩缩容,同时,为了避免过于频繁的扩缩容,默认在5min内没有重新扩缩容的情况下,才会触发扩缩容,所以导致无法应对很多紧急产生问题,例如,一个快速流量突发场景,如果正处于5min内的HPA稳定器,这个时候根据HPA策略,会导致无法扩容,另外,在一些serverless场景下,有缩容到0然后冷启动的需求,但HPA默认不支持。

    针对VPA的部署及案例使用,等待后续更新

    参考github地址:https://knative.dev/docs/install/

    安装参考:https://knative.dev/docs/install/install-serving-with-yaml/

    VPA

    VPA(Vertical Pod Autoscaler): 垂直Pod自动扩缩容

    VPA会基于pod资源使用情况自动为集群设置资源占用的限制,从而让集群将Pod调度到有足够资源的最佳节点。

    VPA也会保持最初容器定义中资源request和limit的占比,她会根据容器资源使用率自动设置pod的CPU和内存的requests,从而允许在节点上进行适当的调度,以便为每个Pod提供适当的可用节点,它既可以缩小过度请求资源的容器,也可以根据情况随时提升资源不足的容量。

    使用限制:

    vpa不能和HPA一起使用

    VPA好处:

    Pod 资源用其所需,所以集群节点使用效率高。
    Pod 会被安排到具有适当可用资源的节点上。不必运行基准测试任务来确定 CPU 和内存请求的合适值。
    VPA 可以随时调整 CPU 和内存请求,无需人为操作,因此可以减少维护时间

    缺点

    VPA 是 Kubernetes 比较新的功能,还没有在生产环境大规模实践过,不建议在线上环境使
    用自动更新模式,但是使用推荐模式你可以更好了解服务的资源使用情况。

    CA

    CA(Cubernetes cluster-auto)

    1、什么是 cluster-autoscaler
    Cluster Autoscaler (CA)是一个独立程序,是用来弹性伸缩 kubernetes 集群的。它可以自动根据部署应用所请求的资源量来动态的伸缩集群。当集群容量不足时,它会自动去Cloud Provider (支持 GCE、GKE 和 AWS)创建新的 Node,而在 Node 长时间资源利用率很低时自动将其删除以节省开支。

    项目地址:https://github.com/kubernetes/autoscaler

    2、Cluster Autoscaler 什么时候伸缩集群?
    在以下情况下,集群自动扩容或者缩放:
    扩容:由于资源不足,某些 Pod 无法在任何当前节点上进行调度
    缩容: Node 节点资源利用率较低时,且此 node 节点上存在的 pod 都能被重新调度到其他 node 节点上运行

    3、什么时候集群节点不会被 CA 删除?
    1)节点上有 pod 被 PodDisruptionBudget 控制器限制。
    2)节点上有命名空间是 kube-system 的 pods。
    3)节点上的 pod 不是被控制器创建,例如不是被 deployment, replica set, job, statefulset 创建。
    4)节点上有 pod 使用了本地存储。
    5)节点上 pod 驱逐后无处可去,即没有其他 node 能调度这个 pod
    6)节点有注解:"cluster-autoscaler.kubernetes.io/scale-down-disabled": "true"(在 CA1.0.3 或更高版本中受支持)

    扩展:什么是 PodDisruptionBudget?
    通过 PodDisruptionBudget 控制器可以设置应用 POD 集群处于运行状态最低个数,也
    可以设置应用 POD 集群处于运行状态的最低百分比,这样可以保证在主动销毁应用
    POD 的时候,不会一次性销毁太多的应用 POD,从而保证业务不中断。

    4、Horizontal Pod Autoscaler 如何与 Cluster Autoscaler 一起使用?
    Horizontal Pod Autoscaler 会根据当前 CPU 负载更改部署或副本集的副本数。如果负
    载增加,则 HPA 将创建新的副本,集群中可能有足够的空间,也可能没有足够的空间。
    如果没有足够的资源,CA 将尝试启动一些节点,以便 HPA 创建的 Pod 可以运行。如果
    负载减少,则 HPA 将停止某些副本。结果,某些节点可能变得利用率过低或完全为空,
    然后 CA 将终止这些不需要的节点。

    扩展:如何防止节点被 CA 删除?
    节点可以打上以下标签:
    "cluster-autoscaler.kubernetes.io/scale-down-disabled": "true"

    可以使用 kubectl 将其添加到节点(或从节点删除):
    $ kubectl annotate node cluster-autoscaler.kubernetes.io/scale-down-
    disabled=true

    服务使用前提

    • 安装组件metrics-server

    metrics-server 是一个集群范围内的资源数据集和工具,同样的,metrics-server 也只是显示数据,并不提供数据存储服务,主要关注的是资源度量 API 的实现,比如 CPU、文件描述符、内存、请求延时等指标,metric-server 收集数据给 k8s 集群内使用,如 kubectl,hpa,scheduler 等.

    metrics-server组件部署

    1. 获取镜像
    # 通过离线方式获取
    k8s.gcr.io/metrics-server-amd64:v0.3.6 和 k8s.gcr.io/addon-resizer:1.8.4
    
    1. 服务部署
    # 1.在/etc/kubernetes/manifests 里面改一下apiserver的配置
    注意:这个是 k8s 在 1.7 的新特性,如果是 1.16 版本的可以不用添加,1.17 以后要添加。这个参
    数的作用是 Aggregation 允许在不修改 Kubernetes 核心代码的同时扩展 Kubernetes API。
    [root@xianchaomaster1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
    增加如下内容
    - --enable-aggregator-routing=true
    
    # 2. 更新配置
    kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml 
    kubectl apply -f metrics.yaml
    
    # metrics.yaml文件
    [root@master1 yml]# cat metrics.yaml 
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: metrics-server:system:auth-delegator
      labels:
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:auth-delegator
    subjects:
    - kind: ServiceAccount
      name: metrics-server
      namespace: kube-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: metrics-server-auth-reader
      namespace: kube-system
      labels:
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: extension-apiserver-authentication-reader
    subjects:
    - kind: ServiceAccount
      name: metrics-server
      namespace: kube-system
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: metrics-server
      namespace: kube-system
      labels:
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: system:metrics-server
      labels:
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      - nodes
      - nodes/stats
      - namespaces
      verbs:
      - get
      - list
      - watch
    - apiGroups:
      - "extensions"
      resources:
      - deployments
      verbs:
      - get
      - list
      - update
      - watch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: system:metrics-server
      labels:
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:metrics-server
    subjects:
    - kind: ServiceAccount
      name: metrics-server
      namespace: kube-system
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: metrics-server-config
      namespace: kube-system
      labels:
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: EnsureExists
    data:
      NannyConfiguration: |-
        apiVersion: nannyconfig/v1alpha1
        kind: NannyConfiguration
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: metrics-server
      namespace: kube-system
      labels:
        k8s-app: metrics-server
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
        version: v0.3.6
    spec:
      selector:
        matchLabels:
          k8s-app: metrics-server
          version: v0.3.6
      template:
        metadata:
          name: metrics-server
          labels:
            k8s-app: metrics-server
            version: v0.3.6
          annotations:
            scheduler.alpha.kubernetes.io/critical-pod: ''
            seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
        spec:
          priorityClassName: system-cluster-critical
          serviceAccountName: metrics-server
          containers:
          - name: metrics-server
            image: k8s.gcr.io/metrics-server-amd64:v0.3.6
            imagePullPolicy: IfNotPresent
            command:
            - /metrics-server
            - --metric-resolution=30s
            - --kubelet-preferred-address-types=InternalIP
            - --kubelet-insecure-tls
            ports:
            - containerPort: 443
              name: https
              protocol: TCP
          - name: metrics-server-nanny
            image: k8s.gcr.io/addon-resizer:1.8.4
            imagePullPolicy: IfNotPresent
            resources:
              limits:
                cpu: 100m
                memory: 300Mi
              requests:
                cpu: 5m
                memory: 50Mi
            env:
              - name: MY_POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: MY_POD_NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
            volumeMounts:
            - name: metrics-server-config-volume
              mountPath: /etc/config
            command:
              - /pod_nanny
              - --config-dir=/etc/config
              - --cpu=300m
              - --extra-cpu=20m
              - --memory=200Mi
              - --extra-memory=10Mi
              - --threshold=5
              - --deployment=metrics-server
              - --container=metrics-server
              - --poll-period=300000
              - --estimator=exponential
              - --minClusterSize=2
          volumes:
            - name: metrics-server-config-volume
              configMap:
                name: metrics-server-config
          tolerations:
            - key: "CriticalAddonsOnly"
              operator: "Exists"
            - key: node-role.kubernetes.io/master
              effect: NoSchedule
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: metrics-server
      namespace: kube-system
      labels:
        addonmanager.kubernetes.io/mode: Reconcile
        kubernetes.io/cluster-service: "true"
        kubernetes.io/name: "Metrics-server"
    spec:
      selector:
        k8s-app: metrics-server
      ports:
      - port: 443
        protocol: TCP
        targetPort: https
    ---
    apiVersion: apiregistration.k8s.io/v1
    kind: APIService
    metadata:
      name: v1beta1.metrics.k8s.io
      labels:
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    spec:
      service:
        name: metrics-server
        namespace: kube-system
      group: metrics.k8s.io
      version: v1beta1
      insecureSkipTLSVerify: true
      groupPriorityMinimum: 100
      versionPriority: 100
    
    
    # 3.验证metrics-server是否部署成功
    [root@master1 yml]# kubectl get pods -n kube-system |grep metrics
    metrics-server-5c7c5b6d67-bndpb       2/2     Running            0          4m39s
    
    # 4.测试kubectl top命令
    [root@master1 yml]# kubectl top nodes
    NAME      CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
    master1   693m         17%    3477Mi          45%       
    master2   1747m        43%    4121Mi          26%       
    master3   341m         8%     1456Mi          9%        
    node1     3219m        80%    7801Mi          50%       
    node2     3729m        93%    4391Mi          28% 
    

    扩缩容示例

    HPA示例①:

    创建php-apache服务,利用HPA进行自动扩缩容

    1. 使用dockerfile创建php镜像
    [root@master1 php]# cat dockerfile 
    FROM php:5-apache
    ADD index.php /var/www/html/index.php
    RUN chmod a+rx index.php
    
    [root@master1 php]# cat index.php 
    <?php
    $x = 0.0001;
    for ($i = 0; $i <= 1000000;$i++) {
    $x += sqrt($x);
    }
    echo "OK!";
    ?>
    
    # 构建镜像
    [root@master1 php]# docker build -t xianchao/hpa-example:v1 .
    
    # 打包镜像
    docker save -o hpa-example.tar.gz xianchao/hpa-example:v1
    
    # 上传至各个工作节点并解压
    docker load -i hpa-example.tar.gz
    

    2.部署php-apache服务

    [root@master1 php]# cat php-apache.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: php-apache
    spec:
      selector:
        matchLabels:
          run: php-apache
      replicas: 1
      template:
        metadata:
          labels:
            run: php-apache
        spec:
          containers:
          - name: php-apache
            image: xianchao/hpa-example:v1
            ports:
            - containerPort: 80
            resources:
              limits:
                cpu: 500m
              requests:
                cpu: 200m
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: php-apache
      labels:
        run: php-apache
    spec:
      ports:
      - port: 80
      selector:
        run: php-apache
        
    # 更新资源清单文件
    [root@master1 php]# kubectl apply -f php-apache.yaml 
    
    # 验证php是否部署成功(服务注入了istio,所以是2个pod)
    [root@master1 php]# kubectl get pods 
    NAME                             READY   STATUS     RESTARTS   AGE
    php-apache-77d6fb6ff9-h92xr      2/2     Running    0          83s
    

    3.创建HPA

    • 命令行创建HPA(默认是v1版,即仅针对CPU监控,无法针对内存,否则使用v2,即yaml清单方式)
    # 实现目的:
    1. 让副本数维持在1-10个之间(副本数指deployment部署的pod副本数)
    2. 将所有pod的平均CPU使用率维持在50%(通过kubectl top看到的每个pod如果是200毫核,这意味着平均cpu使用率为100毫核)
    
    
    # hpa扩容计算方式
    如果hpa设定cpu使用率为50%,在创建deployment时设定最小pod cpu使用率为200m,那么当流量达到200m/50%= 100m时不会对deployment所管理的pod扩容,当超出50%,pod达到cpu使用率为130%,超出50%,那么对pod流量均摊50%,就需要创建三个pod副本数。
    
    # 利用命令行方式创建HPA
    kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
    --cpu-percent=50:表示cpu使用率不超过50%
    --min:最少一个pod
    --max:最多10个pod
    
    # 验证HPA是否创建成功(由于没有请求,所以cpu消耗为0%)
    [root@master1 php]# kubectl get hpa
    NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    php-apache   Deployment/php-apache   2%/50%    1         10        1          2m14s
    
    # 针对php-apache服务压测(针对cpu),新开启一个终端,不断对php-apache发起请求
    kubectl run v1 -it --image=busybox --image-pull-policy=IfNotPresent /bin/sh
    / # while true;do wget -q -O - http://php-apache.default.svc.cluster.local;done
    
    # 同时查看hpa(当流量达到175%产生4个副本)
    `为啥是4个副本呢? - 监控cpu超过50%产生1个副本175就是4个`
    [root@master1 php]# kubectl get hpa 
    NAME         REFERENCE               TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
    php-apache   Deployment/php-apache   175%/50%   1         10        1          68m
    [root@master1 php]# kubectl get hpa 
    NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    php-apache   Deployment/php-apache   2%/50%    1         10        4          73m
    
    # 注意:
    扩缩容副本数不是在一瞬间完成,存在等待时间
    
    • yaml清单创建HPA
    # 1.创建ng容器
    [root@xianchaomaster1 ~]# cat nginx.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-hpa
    spec:
      selector:
        matchLabels:
          app: nginx
    replicas: 1
    template:
      metadata:
        labels:
          app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.9.1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        resources:
          requests:
            cpu: 0.01
            memory: 25Mi
          limits:
            cpu: 0.05
            memory: 60Mi
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      selector:
        app: nginx
      type: NodePort
      ports:
      - name: http
        protocol: TCP
        port: 80
        targetPort: 80
    
    # 2.更新资源清单文件
    [root@xianchaomaster1 ~]# kubectl apply -f nginx.yaml
    
    # 3.注意:
    nginx的pod中需要有resource和limits字段,否则hpa会采集不到内存指标
    
    # 4.创建一个hpa
    [root@xianchaomaster1 ~]# cat hpa-v1.yaml
    apiVersion: autoscaling/v2beta1
    kind: HorizontalPodAutoscaler
    metadata:
      name: nginx-hpa
    spec:
      maxReplicas: 10				# 最大副本数
      minReplicas: 1				# 最小副本数
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment			# 关联之前ng的deployment
        name: nginx-hpa				# deployment名称
      metrics:
      - type: Resource
        resource:
          name: memory				
          targetAverageUtilization: 60	# 不能超过60%的使用率
          
     # 5.更新资源配置清单
     [root@xianchaomaster1 ~]# kubectl apply -f hpa-v1.yaml
     
     # 6.查看创建的 hpa
     [root@xianchaomaster1 ~]# kubectl get hpa
     NAME            REFERENCE           TARGETS        MINPODS   MAXPODS  REPLICAS 
     nginx-hpa    Deployment/nginx-hpa    5%/60%           1 		   10	 	 1
     
     # 7.压测nginx的内存,hpa会对pod自动扩缩容(登录创建的pod,压测)
     dd if=/dev/zero of=/tmp/a
     
     # 8.打开新的终端,查看hpa(200%为当前内存使用率,60%表示所有pod的内存维持在60%,200/60=4个pod)
     [root@master1 php]# kubectl get hpa 
      NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
      nginx-hpa   Deployment/nginx-hpa   200%/60%    1         10        4          73m
    
    # 9.查看pod数量(产生四个pod)
    [root@master1 nginx]# kubectl get deployment
    NAME            READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-hpa        4/4     4            4           25m
    
    # 10.取消对nginx内存的压测,hpa会对pod自动缩容
    [root@master1 nginx]# kubectl exec -it nginx-hpa-fb74696c-6m6st -- /bin/sh
    删除压测文件
    rm -rf /tmp/a
    
    # 11.查看hpa检测情况
    [root@xianchaomaster1 ~]# kubectl get hpa
    显示如下,可看到内存使用率已经降到 5%:
    NAME 		REFERENCE 				TARGETS     MINPODS 	MAXPODS  REPLICAS 		AGE
    nginx-hpa    Deployment/nginx-hpa      5%/60%       1 			10		 1 			26m
    
    # 扩展
    [root@master1 nginx]# kubectl get hpa.v2beta2.autoscaling -o yaml > 1.yaml
    

    VPA示例②:

    Vertical Pod Autoscaler(VPA):垂直 Pod 自动扩缩容,用户无需为其 pods 中的容器设置最新的资源 request。配置后,它将根据使用情况自动设置 request,从而允许在节点上进行适当的调度,以便为每个 pod 提供适当的资源量。

    1.安装VPA

    # 上传vpa相关镜像文件
    [root@xianchaonode1 ~]# docker load -i vpa-admission-controller_0_8_0.tar.gz
    [root@xianchaonode1 ~]# docker load -i vpa-recommender_0_8_0.tar.gz
    [root@xianchaonode1 ~]# docker load -i vpa-updater_0_8_0.tar.gz
    
    # 上传vpa安装包
    [root@xianchaomaster1~]# unzip autoscaler-vertical-pod-autoscaler-0.8.0.zip
    [root@xianchaomaster1 ~]# cd /root/autoscaler-vertical-pod-autoscaler-0.8.0/vertical-
    pod-autoscaler/deploy
    修改 admission-controller-deployment.yaml 里的 image:
    image: scofield/vpa-admission-controller:0.8.0
    imagePullPolicy: IfNotPresent
    修改 recommender-deployment.yaml 里的 image:
    image: scofield/vpa-recommender:0.8.0
    imagePullPolicy: IfNotPresent
    修改 updater-deployment.yaml 文件里的 image:
    image: scofield/vpa-updater:0.8.0
    imagePullPolicy: IfNotPresent
    [root@xianchaomaster1]# cd /root/autoscaler-vertical-pod-autoscaler-0.8.0/vertical-pod-
    autoscaler/hack
    
    # 执行安装脚本
    [root@xianchaomaster1 hack]# ./vpa-up.sh
    
    # 验证是否部署成功:
    [root@xianchaomaster1]# kubectl get pods -n kube-system | grep vpa
    vpa-admission-controller-777694497b-6rrd4 1/1 Running 0 86s
    vpa-recommender-64f6765bd9-ckmvf 1/1 Running 0 86s
    vpa-updater-c5474f4c7-vq82f 1/1 Running 0 86s
    

    2.测试vpa实现pod自动扩缩容

    2.1 updateMode:Off 只查看推荐数值,不实际应用到容器

    • 部署一个nginx服务,部署到namespace: vpa名称空间下
    [root@xianchaomaster1 ~]# mkdir vpa
    [root@xianchaomaster1 ~]# cd vpa/
    [root@xianchaomaster1 vpa]# kubectl create ns vpa
    [root@xianchaomaster1 vpa]# cat vpa-1.yaml
    apiVersion: apps/v1
    kind: Deployment
      metadata:
      labels:
        app: nginx
       name: nginx
      namespace: vpa
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - image: nginx
            name: nginx
            imagePullPolicy: IfNotPresent
            resources:
              requests:
                cpu: 200m
                memory: 300Mi
                
    [root@xianchaomaster1 vpa]# kubectl apply -f vpa-1.yaml
    [root@xianchaomaster1 vpa]# kubectl get pods -n vpa
    NAME READY STATUS RESTARTS AGE
    nginx-5f598bd784-fknwq 1/1 Running 0 6s
    nginx-5f598bd784-ljq75 1/1 Running 0 6s
    
    • 在ng管理的pod前端创建四层代理service
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      namespace: vpa
    spec:
      type: NodePort
      ports:
      - port: 80
        targetPort: 80
      selector:
        app: nginx
    [root@xianchaomaster1 vpa]# kubectl apply -f vpa-service-1.yaml
    [root@xianchaomaster1 vpa]# kubectl get svc -n vpa
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    nginx NodePort 10.109.35.41 <none> 80:31957/TCP 3m28s
    [root@xianchaomaster1 vpa]# curl -I 192.168.40.180:31957
    HTTP/1.1 200 OK
    #显示 200 说明代理没问题
    
    • 创建VPA,先使用updateMode: off 这种模式仅获取资源推荐值,但不更新pod
    [root@xianchaomaster1 vpa]# cat vpa-nginx.yaml
    apiVersion: autoscaling.k8s.io/v1beta2
    kind: VerticalPodAutoscaler
    metadata:
      name: nginx-vpa
      namespace: vpa
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind: Deployment
        name: nginx
      updatePolicy:
        updateMode: "Off"
      resourcePolicy:
        containerPolicies:
        - containerName: "nginx"
          minAllowed:
            cpu: "500m"
            memory: "100Mi"
         maxAllowed:
           cpu: "2000m"
           memory: "2600Mi"
        
    [root@xianchaomaster1 vpa]# kubectl apply -f vpa-nginx.yaml
    [root@xianchaomaster1 vpa]# kubectl get vpa -n vpa
    NAME AGE
    nginx-vpa 6s
    
    # 查看vpa详情
    [root@xianchaomaster1 vpa]# kubectl describe vpa nginx-vpa -n vpa
    ····略
    Recommendation:
      Container Recommendations:
        Container Name: nginx
        Lower Bound:
          Cpu: 500m
          Memory: 262144k
       Target:
         Cpu: 500m
         Memory: 262144k
       Uncapped Target:
         Cpu: 25m
         Memory: 262144k
       Upper Bound:
         Cpu: 1349m
         Memory: 1410936619
    Events: <none>
    
    # 注:
    Lower Bound: 下限值
    Target: 推荐值
    Upper Bound: 上限值
    Uncapped Target: 如果没有为 VPA 提供最小或最大边界,则表示目标利用率
    上面结果表示,推荐的 Pod 的 CPU 请求为 500m,推荐的内存请求为 262144k字节。
    
    • nginx压测,查看vpa给出推荐值
    [root@xianchaomaster1 vpa]# yum -y install httpd-tools ab
    [root@xianchaomaster1 vpa]# ab -c 100 -n 10000000 http://192.168.40.180:31957/
    
    # 过几分钟后观察 VPA Recommendation 变化
    [root@xianchaomaster1 vpa]# kubectl describe vpa nginx-vpa -n vpa
    Recommendation:
      Container Recommendations:
        Container Name: nginx
        Lower Bound:
          Cpu: 500m
          Memory: 262144k
        Target:
          Cpu: 763m
          Memory: 262144k
        Uncapped Target:
          Cpu: 763m
          Memory: 262144k
        Upper Bound:
          Cpu: 2
          Memory: 934920074
    Events: <none>
    
    从以上信息可以看出,VPA 对 Pod 给出了推荐值: Cpu: 763m ,因为我们这里设置了
    updateMode: "Off",所以不会更新 Pod
    
    [root@xianchaomaster1 vpa]# kubectl get pods -n vpa
    NAME READY STATUS RESTARTS AGE
    nginx-5f598bd784-fknwq 1/1 Running 0 79m
    nginx-5f598bd784-ljq75 1/1 Running 0 79m
    

    2.2 updateMode:On

    • 部署nginx deployment
    # 将updateMoe改为"Auto",看vpa的动作变化
    更改deployment中nginx的cpu和内存request最小使用
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: nginx
      name: nginx
      namespace: vpa
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - image: nginx
            name: nginx
            imagePullPolicy: IfNotPresent
            resources:
              requests:
                cpu: 100m
                memory: 50Mi
          
    [root@xianchaomaster1 vpa]# kubectl apply -f vpa-nginx-1.yaml
    [root@xianchaomaster1 vpa]# kubectl get pods -n vpa
    NAME READY STATUS RESTARTS AGE
    nginx-b75478445-jxp5d 1/1 Running 0 30s
    nginx-b75478445-psh2j 1/1 Running 0 30s
    
    • 部署vpa
    [root@xianchaomaster1 vpa]# cat vpa-nginx.yaml
    apiVersion: autoscaling.k8s.io/v1beta2
    kind: VerticalPodAutoscaler
    metadata:
      name: nginx-vpa-2
      namespace: vpa
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind: Deployment
        name: nginx
      updatePolicy:
        updateMode: "Auto"
      resourcePolicy:
        containerPolicies:
        - containerName: "nginx"
          minAllowed:
            cpu: "500m"
            memory: "100Mi"
         maxAllowed:
           cpu: "2000m"
           memory: "2600Mi"
           
    [root@xianchaomaster1 vpa]# kubectl apply -f vpa-nginx.yaml
    [root@xianchaomaster1 vpa]# kubectl get vpa -n vpa
    NAME MODE CPU MEM PROVIDED AGE
    nginx-vpa Off 500m 262144k True 72m
    nginx-vpa-2 Auto 9s
    
    • 压测,使用describe查看vpa详情
    [root@master1 VPA]# ab -c 100 -n 10000000 http://10.200.2.192:32328/
    
    # 过几分钟后查看vpa详情,只关注容器 recommendations
    [root@xianchaomaster1 ~]# kubectl describe vpa nginx-vpa -n vpa |tail -n 20
    Target 变成了 Cpu: 656m ,Memory: 262144k
    
    # 查看event事件(vpa执行evictedbyvpa,自动停止nginx,使用vpa推荐资源启动nginx)
    kubect get event -n vpa
    
    # 查看vpa重启的nginx
    [root@xianchaomaster1 ~]# kubectl describe pods nginx-b75478445-9sd46 -n vpa
    Requests:
      cpu: 656m
      memory: 262144k
    
  • 相关阅读:
    字符编码解码
    综合练习[购物车]
    for 循环实例
    数据类型
    字符串格式化输出
    集成开发环境
    while循环实例
    赋值运算符、逻辑运算符、表达式
    if,else语句猜最大值
    计算今天和今天的上一月的日期
  • 原文地址:https://www.cnblogs.com/tcy1/p/15509233.html
Copyright © 2020-2023  润新知