首页 > 其他分享 >k8s pod自动扩缩容

k8s pod自动扩缩容

时间:2024-02-06 15:12:53浏览次数:48  
标签:name 扩缩容 server metrics pod k8s

Pod自动扩缩容

为什么要扩缩容?

在实际的业务场景中,我们经常会遇到某个服务需要扩容的场景(如:对服务器性能压测、电商平台秒杀、大促活动、或由于资源紧张、工作负载降低等都需要对服务实例数进行扩缩容操作。)

node节点默认可以跑110个pod

在k8s中扩容分为两种:

1、node层面:

在使用k8s集群经常遇到一个问题是,我应该保持多大的节点规模来满足应用需求呢?cluster-autoscaler出现解决了这个问题,可以通过cluster-autoscaler实现节点级别的动态添加与删除,动态调整容器资源池,应对峰值流量。(这个技术基于云厂商的平台实现

2、pod层面

我们一般会使用deployment中的replicas参数,设置多个副本集来保证服务的高可用,但是这是一个固定的值,比如我们设置10个副本,就会启动10个pod同时running来提供服务。

如果我这个服务平时流量很少的时候,也就是10个pod同时running,而流量突然暴增时,又可能出现10个pod不够用的情况。针对这种情况怎么办?这时候就需要自动扩缩容:

k8s对pod的扩缩容分为:

手动和自动两种
1、手动模式:通过kubectl scale命令,这样需要每次去手动操作一次,而且不确定业务什么时候请求量就很大了,所以如果不能做到自动化的去扩缩容,这也是一件很麻烦的事。

2、自动模式:如果k8s系统能够根据pod当前的负载变化情况来自动的进行扩缩容就好了,因为这个过程本来就是不固定的,频繁发生的,所以纯手动的方式不现实。

自动扩缩容的方案有哪些?

kubernetes HPA(Horizontal Pod Autoscaling)生产用的多

通过此功能,只需简单的配置,便可以利用监控指标(cpu使用率、内存使用率)自动的扩容或缩容服务中的pod数量,当业务需求增加时,系统将无缝地自动增加适量pod容器,提高系统稳定性。

kubernetes KPA(Knative Pod Autoscaler)

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

kubernetes VPA(Vertical Pod Autoscaler)

垂直pod自动扩缩容,VPA会基于Pod的资源使用情况自动为集群设置资源占用的限制,从而让集群将Pod调度到有足够资源的最佳节点上。VPA也会保持最初容器定义中资源request和limit的占用比。

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

如何实现k8s中pod应用自动扩缩容?

基于HPA

要想实现自动扩缩容,需要考虑如下几点:

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

HPA v1 版本可以根据CPU使用率来进行自动扩缩容:

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

HPA v2版本可以根据自定义的指标进行自动扩缩容

2、如何采集资源指标?

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

基于KPA

1、根据并发请求数实现自动扩缩容

2、设置扩缩容边界实现自动扩缩容

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

相比HPA、KPA会考虑更多的场景,其中一个比较重要的流量突发的时候

基于VPA

当目前运行pod节点资源达不到VPA的推荐值,就会执行pod驱逐,重新部署新的足够资源的服务。VPA是k8s比较新的功能,目前不建议个人不建议生产环境使用,还没有在生产环境大规模实践过,不建议在线上环境使用自动更新模式,但是使用推荐模式你可以更好了解服务的资源使用情况。

官网:https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler

利用HPA基于CPU指标实现pod自动扩缩容

HPA 全称是 Horizontal Pod Autoscaler,翻译成中文是 POD 水平自动伸缩, HPA 可以基于 CPU 利用率对 deployment 、StatefulSet中的 pod 数量进行自动扩缩容(除了 CPU 也可以基于自定义的指标进行自 动扩缩容)。pod 自动缩放不适用于无法缩放的对象,比如 DaemonSets。

HPA 由 Kubernetes API 资源和控制器实现。控制器会周期性的获取平均 CPU 利用率,并与目标 值相比较后调整 deployment 中的副本数量。

image-20240205155029981

HorizontalPodAutoscaler 控制 Deployment 及其 ReplicaSet 的规模

监控指标从哪里来?

K8S 从 1.8 版本开始,CPU、内存等资源的 metrics 信息可以通过 Metrics API 来获取,用户可以 直接获取这些 metrics 信息(例如通过执行 kubect top 命令),HPA 使用这些 metics 信息来实现动态 伸缩。

Metrics server:

1、Metrics server 是 K8S 集群资源使用情况的聚合器

2、从 1.8 版本开始,Metrics server 可以通过 yaml 文件的方式进行部署

3、Metrics server 收集所有 node 节点的 metrics 信息和 pod 的指标信息(主要是 cpu 和内存)

HPA官网:https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale/#how-does-a-horizontalpodautoscaler-work

安装数据采集组件 metric-server

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

Github 地址:

https://github.com/kubernetes-sigs/metrics-server/

https://github.com/kubernetes-sigs/metrics-server/releases/tag/v0.6.1

1、部署 metrics-server 组件

通过离线包方式导入镜像

需要的镜像是:registry.cn-hangzhou.aliyuncs.com/google_containers/metricsserver:v0.6.1,导入到k8s每个节点上。

ctr -n=k8s.io images import metrics-server-0.6.1.tar.gz 

部署metrics-server服务

在/etc/kubernetes/manifests 里面改一下 apiserver 的配置

注意:这个是 k8s 在 1.17 的新特性,如果是 1.16 版本的可以不用添加,1.17 以后要添加。这个参 数的作用是 Aggregation 允许在不修改 Kubernetes 核心代码的同时扩展 Kubernetes API。

#只有master节点修改
vim /etc/kubernetes/manifests/kube-apiserver.yaml 

- --enable-aggregator-routing=true

image-20240205161014699

重新更新apiserver配置:

#重启k8s所有节点
[root@k8s-master ~]# systemctl restart kubelet.service 
[root@k8s-slave1 ~]# systemctl restart kubelet.service 

部署metrics-server服务

[root@k8s-master ~]# cat components.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
    rbac.authorization.k8s.io/aggregate-to-view: "true"
  name: system:aggregated-metrics-reader
rules:
- apiGroups:
  - metrics.k8s.io
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
  name: system:metrics-server
rules:
- apiGroups:
  - ""
  resources:
  - nodes/metrics
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server-auth-reader
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server:system:auth-delegator
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: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: system:metrics-server
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:metrics-server
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  strategy:
    rollingUpdate:
      maxUnavailable: 0
  template:
    metadata:
      labels:
        k8s-app: metrics-server
    spec:
      containers:
      - args:
        - /metrics-server
        - --cert-dir=/tmp
        - --secure-port=4443
        - --kubelet-insecure-tls
        - --kubelet-preferred-address-types=InternalIP
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.6.1
        imagePullPolicy: IfNotPresent
        livenessProbe:
          httpGet:
            path: /livez
            port: https
            scheme: HTTPS
          periodSeconds: 10
        name: metrics-server
        ports:
        - containerPort: 4443
          name: https
          protocol: TCP
        readinessProbe:
          httpGet:
            path: /readyz
            port: https
            scheme: HTTPS
          initialDelaySeconds: 20
          periodSeconds: 10
        resources:
          requests:
            cpu: 100m
            memory: 10Mi
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1000
        volumeMounts:
        - mountPath: /tmp
          name: tmp-dir
      nodeSelector:
        kubernetes.io/os: linux
      priorityClassName: system-cluster-critical
      serviceAccountName: metrics-server
      volumes:
      - emptyDir: {} 
        name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  labels:
    k8s-app: metrics-server
  name: v1beta1.metrics.k8s.io
spec:
  group: metrics.k8s.io
  groupPriorityMinimum: 100
  insecureSkipTLSVerify: true
  service:
    name: metrics-server
    namespace: kube-system
  version: v1beta1
  versionPriority: 100

image-20240205162121005

查看pod资源

image-20240205162317721

创建一个pod

在名称空间cheng-svc-test 里面创建一个pod,cpu、内存各100m

[root@k8s-master cheng-svc-test]# cat cheng-svc-pod-test.yaml 
# 基于deployment创建3个pod,加上标签。
apiVersion: apps/v1      
kind: Deployment         
metadata:
  name: nginx
  namespace: cheng-svc-test  
spec:
  replicas: 1                    
  selector:              
    matchLabels:
      app: nginx
  template:              
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: container-0
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi

image-20240205164903189

创建HPA v1(CPU)

nginx 服务正在运行,使用 kubectl autoscale 创建自动缩放器,实现对 nginx 这个 deployment 创建的 pod 自动扩缩容,下面的命令将会创建一个 HPA,HPA 将会根据 CPU,内存等资 源指标增加或减少副本数,创建一个可以实现如下目的的 hpa:

1)让副本数维持在 1-10 个之间(这里副本数指的是通过 deployment 部署的 pod 的副本数)

2)将所有 Pod 的平均 CPU 使用率维持在 20%(运行的每个 pod 如果是 100 毫核,这意味着平均 CPU 利用率为 20 毫核)

给上面nignx 这个 deployment 创建 HP

kubectl -n cheng-svc-test autoscale deployment nginx --cpu-percent=20 --min=1 --max=10

 kubectl -n cheng-svc-test get hpa


image-20240205170305290

image-20240206100001918

image-20240205170414497

给nginx创建一个svc,生产中也是访问svc的ip或者域名,不会直接访问pod ip

[root@k8s-master cheng-svc-test]# cat cheng-clusterip.yaml 
# 集群内,开启一个固定死的ip,svc的ip地址,负载均衡代理一组pod

apiVersion: v1
kind: Service
metadata:
  name: cheng-clusterip       # Service的名称 ,svc  ip,dns,自定义,做好按业务名称,通俗易懂
  namespace: cheng-svc-test    #和之前创建的后端放一个名称空间中
spec:
  selector:          # Label Selector,选择包含app=nginx标签的Pod,后面只要这个命名空间中带这个标签的server IP就会自动发现
    app: nginx  #之前创建pod中的保持一致
  ports:
  - name: service0
    targetPort: 80   # Pod的端口
    port: 80         # Service对外暴露的端口,也就是ClusterIP的port
    protocol: TCP    # 转发协议类型,支持TCP和UDP
  type: ClusterIP    # Service的类型
  
  

image-20240205171607843

image-20240205172138015

image-20240205172404644

image-20240205173010151

删除HPA

kubectl -n cheng-svc-test get hpa
 
kubectl -n cheng-svc-test delete hpa nginx

image-20240206100216537

创建HPA v2(内存)

创建pod

[root@k8s-slave1 ~]# cat cheng.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: cheng

---
apiVersion: apps/v1      
kind: Deployment         
metadata:
  name: nginx
  namespace: cheng  
spec:
  replicas: 1                    
  selector:              
    matchLabels:
      app: nginx
  template:              
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: container-0
        resources:
          limits:
            cpu: 100m
            memory: 60Mi
          requests:
            cpu: 100m
            memory: 60Mi

---
apiVersion: v1
kind: Service
metadata:
  name: cheng-clusterip       # Service的名称 ,svc  ip,dns,自定义,做好按业务名称,通俗易懂
  namespace: cheng    #和之前创建的后端放一个名称空间中
spec:
  selector:          # Label Selector,选择包含app=nginx标签的Pod,后面只要这个命名空间中带这个标签的server IP就会自动发现
    app: nginx  #之前创建pod中的保持一致
  ports:
  - name: service0
    targetPort: 80   # Pod的端口
    port: 80         # Service对外暴露的端口,也就是ClusterIP的port
    protocol: TCP    # 转发协议类型,支持TCP和UDP
  type: ClusterIP    # Service的类型

创建基于内存的hpa

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
  namespace: cheng  # 根据你的命名空间进行修改
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx  # 根据你的Deployment名称进行修改
  minReplicas: 1  # 最小副本数
  maxReplicas: 5  # 最大副本数
  metrics:
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 15 # 设置目标内存利用率为80%

[root@k8s-slave1 ~]# cat hpa-v1.yaml 
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
  namespace: cheng
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  metrics:
  - type: Resource
    resource:
      name: memory
      target:
        averageUtilization: 30
        type: Utilization
[root@k8s-slave1 ~]# 

进入pod,创建点数据

kubectl -n cheng exec -it nginx-cbc6577bd-kb6sn -- /bin/bash

dd if=/dev/zero of=/tmp/a

image-20240206142925453

image-20240206144702836

pod数据实时刷新

watch -n 1 kubectl top pod  -n cheng

image-20240206112237899

标签:name,扩缩容,server,metrics,pod,k8s
From: https://www.cnblogs.com/9527com/p/18009748

相关文章

  • k8s容器秒级事件监控软件-Kube-eventer
    下面是kube-eventer的github开源地址:https://github.com/AliyunContainerService/kube-eventer ---apiVersion:v1data:content:>-{"EventType":"{{.Type}}","EventNamespace":"{{.InvolvedObject.Namespace}}"......
  • K8S前置配置
    安装基础软件0.不能联网处理重启网络服务servicenetworkrestart查看报错信息,如果正常就pingwww.baidu.com看是否通,如果通了不用管journalctl-xe0.将networkmanager服务停了systemctlstopNetworkManagersystemctldisableNetworkManager再次重启服务servic......
  • 服务器-Kubernetes (K8S)单机部署实战 -- 001
       本篇博文是centos7系统安装kubernetes单机master节点操作。一:查看服务器配置信息   1.执行命令查看服务器cpu信息。安装kubernetes服务,cpu核心数必须大于2,内存大于2G。lscpu   2. 修改服务器设置信息,避免安装出现问题。    a.......
  • docker和k8s的区别
    docker是一个开源的应用容器引擎,开发者可以打包他们的应用以及依赖到一个容器中,发布到流行的liunx系统上,或者实现虚拟化。k8s是一个开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等。一、虚拟化角度:传统的虚拟技术,在将物理硬件虚拟成多套硬件后,需要......
  • 一句话总结Docker与K8S的关系
    一句话总结:Docker只是容器的一种,它面向的是单体,K8S可以管理多种容器,它面向的是集群,Docker可以作为一种容器方案被K8S管理。下文继续具体介绍。1、容器的核心概念介绍这几个核心概念:OCI、CR、Runc、Containerd、CRI。1.1、容器运行规范容器运行规范OCI(OpenContainerInitiat......
  • 在K8S中,K8S本身优势、适应场景及其特点有什么?
    Kubernetes(简称K8s)作为容器编排领域的事实标准,具有以下显著优势、适应场景及其特点:优势:微服务架构支持:Kubernetes非常适合部署和管理基于微服务的应用程序,每个服务可以独立运行在Pod中,并通过Service进行发现和通信。自动化部署与扩展:自动化的滚动更新、回滚以及水平扩展(HPA......
  • 在K8S中,常见部署K8S方式有哪些?
    在Kubernetes(K8s)中部署集群的方式多种多样,根据环境和需求的不同,常见的部署方式包括:手动部署从零开始手动配置每个节点上的所有组件。这包括安装Docker或容器运行时、设置网络插件、安装etcd集群、配置kube-apiserver、kube-controller-manager、kube-scheduler等控制面组件,并......
  • 在K8S中,K8S是如何实现集群管理的?
    在Kubernetes(简称K8s)中,集群管理主要涉及以下几个关键方面:分布式架构:Kubernetes采用的是主从式(Master-Worker)的分布式架构。其中,Master节点包括了控制平面组件,如kube-apiserver(提供API服务)、etcd(存储集群状态数据)、kube-scheduler(负责容器调度)、kube-controller-manager(运行各......
  • 在K8S中,Kubernetes与Docker的关系?
    在Kubernetes(简称K8s)与Docker之间,存在一种互补和依赖的关系:互补关系:Docker:提供容器化解决方案,允许开发人员将应用及其依赖打包到可移植的容器镜像中。Docker主要负责构建、运行和分发这些容器。Kubernetes:是一个容器编排系统,它的目标是自动化部署、扩展以及管理容器化的应用......
  • 在K8S中,Minikube、Kubectl、Kubelet是什么?
    在Kubernetes(简称K8s)生态系统中,Minikube、kubectl和kubelet是三个不同的组件,各自扮演着不同的角色:Minikube:Minikube是一个工具,用于在单个节点上部署一个本地的Kubernetes集群。这对于开发者在本地开发环境进行Kubernetes应用测试和调试非常有用。它能够在个人计算机上启动一个......