kubenetes--资源调度

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除

出自B站博主教程笔记:

完整版Kubernetes(K8S)全套入门+微服务实战项目,带你一站式深入掌握K8S核心能力_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1MT411x7GH/?spm_id_from=333.337.search-card.all.click

首先再回顾下有状态应用与无状态应用:

一、Label和Selector

1、标签(Label)

1.1、配置文件

标签的创建:在各类资源的 ++metadata.labels++ 中进行配置

1.2、kubectl

(1)临时创建label

cpp 复制代码
 [root@k8s ~]# kubectl label po <资源名称> app=hello [-n 命名空间]

(2)修改已经存在的标签

cs 复制代码
 [root@k8s ~]# kubectl label po <资源名称> app=hello2 --overwrite

(3)查看 label

-A 显示NAMESPACE信息;--show-labels 显示标签信息;-l 匹配标签内容

cs 复制代码
 # selector 按照 label 单值查找节点
 [root@k8s ~]# kubectl get po -A -l app=hello
 ​
 # 查看所有节点的 labels
 [root@k8s ~]# kubectl get po --show-labels

2、选择器(Selector)

2.1、配置文件

在各对象的配置 ++spec.selector++其他可以写 selector 的属性中编写

2.2、kubectl

cs 复制代码
 # 匹配单个值,查找 app=hello 的 pod
 [root@k8s ~]# kubectl get po -A -l app=hello
 ​
 # 匹配多个值
 [root@k8s ~]# kubectl get po -A -l 'k8s-app in (metrics-server, kubernetes-dashboard)'
 ​
 # 查找 version!=1 and app=nginx 的 pod 信息
 [root@k8s ~]# kubectl get po -l version!=1,app=nginx
 ​
 # 不等值 + 语句
 [root@k8s ~]# kubectl get po -A -l version!=1,'app in (busybox, nginx)'

二、Deployment--无状态应用

1、功能

1.1、创建

cs 复制代码
 创建一个 deployment
 [root@k8s ~]# kubectl create deploy nginx-deploy --image=nginx:1.7.9
 或执行
 [root@k8s ~]# kubectl create -f xxx.yaml --record
 --record 会在 annotation 中记录当前命令创建或升级了资源,后续可以查看做过哪些变动操作。
 ​
 -查看部署信息
 [root@k8s ~]# kubectl get deployments
 ​
 -查看 rs
 [root@k8s ~]# kubectl get rs
 ​
 -查看 pod 以及展示标签,可以看到是关联的那个 rs
 [root@k8s ~]# kubectl get pods --show-labels

1.2、滚动更新

只有修改 了 deployment 配置文件中的 template 中的属性后 ,++才会触发更新操作++;

cs 复制代码
 # 修改 nginx 版本号
 [root@k8s ~]# kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
 # 或者通过 edit 命令编辑文件
 [root@k8s ~]# kubectl edit deployment nginx-deployment

查看信息

cs 复制代码
 # 查看滚动更新的过程
 [root@k8s ~]# kubectl rollout status deploy <deployment_name>
 ​
 # 查看部署描述,最后展示发生的事件列表也可以看到滚动更新过程
 [root@k8s ~]# kubectl describe deploy <deployment_name>
 ​
 # 获取部署信息;UP-TO-DATE 表示已经有多少副本达到了配置中要求的数目
 [root@k8s ~]# kubectl get deployments
 NAME            READY   UP-TO-DATE      AVALIABLE       AGE
 nginx-deploy    3/3     3               3               20m
 ​
 # 通过查看rs可以发现创建了一个新的;并且旧的rs用作后续回滚
 [root@k8s ~]# kubectl get rs
 NAME                     DESIRED     CURRENT        REDAY       AGE
 nginx-deploy-757980f7    0           0              0           2m
 nginx-deploy-3498ds02    3           3              3           24m
  
 # 查看pod,发现每一个pod都是新的,关联到新rs
 [root@k8s ~]# kubectl get pods
 NAME                            REDAY   STATUS  RESTARTS    AGE
 nginx-deploy-3498ds02-ef323     1/1     Running 0           5m53s
 nginx-deploy-3498ds02-fe345     1/1     Running 0           5m53s
 nginx-deploy-3498ds02-54fde     1/1     Running 0           5m53s

多个滚动更新并行

假设当前有 5 个 nginx:1.7.9 版本,你想将版本更新为 1.9.1,当更新成功第三个以后 ,你马上又将期望更新的版本改为 1.9.2,那么此时会立马删除之前的三个,并且立马开启更新 1.9.2 的任务

1.3、回滚

有时候你可能想回退一个Deployment ,例如,当Deployment不稳定时,比如一直crash looping

默认情况下,++kubernetes会在系统中保存前两次的Deployment的rollout历史记录++ ,以便你可以随时会退(你可以修改++revision history limit++ 来更改保存的revision数)。

示例:更新 deployment 时参数不小心写错,如 nginx:1.9.1 写成了 nginx:1.91

cs 复制代码
 [root@k8s ~]# kubectl set image deployment/nginx-deploy nginx=nginx:1.91
 ​
 # 监控滚动升级状态,由于镜像名称错误,下载镜像失败,因此更新过程会卡住
 [root@k8s ~]# kubectl rollout status deployments nginx-deploy
 ​
 # 结束监听后,获取 rs 信息,我们可以看到新增的 rs 副本数是 2 个
 [root@k8s ~]# kubectl get rs
 NAME                     DESIRED     CURRENT        REDAY       AGE
 nginx-deploy-757980f7    0           0              0           2m
 nginx-deploy-3498ds02    3           3              3           24m
 nginx-deploy-f23f4f43    1           1              0           50s
 ​
 # 查看pods信息;看到关联到新的 rs 的 pod,状态处于 ImagePullBackOff 状态
 [root@k8s ~]# kubectl get pods
 NAME                            READY   STATUS              RESTARTS    AGE
 nginx-deploy-3498ds02-ef323     1/1     Running             0           13m
 nginx-deploy-3498ds02-fe345     1/1     Running             0           13m
 nginx-deploy-3498ds02-54fde     1/1     Running             0           13m
 nginx-deploy-3498ds02-dw543     0/1     ImagePullBackOff    0           70s
 ​
 # 查看pods创建时具体发生事件
 [root@k8s ~]# kubectl describe po nginx-deploy-3498ds02-dw543

为了修复这个问题,我们需要找到需要回退的 revision 进行回退

cs 复制代码
 # 获取 revison 的列表;CHANGE-CAUSE记录的是创建或修改时使用--record添加的修改原因
 [root@k8s ~]# kubectl rollout history deployment/nginx-deploy 
 deployment.apps/nginx-deploy
 REVISION        CHANGE-CAUSE
 2               <none>
 3               <none>
 4               <none>
 ​
 # 查看某个版本的详细信息
 [root@k8s ~]# kubectl rollout history deployment/nginx-deploy --revision=2 
 deployment.app/nginx-deploy with revision #2
 Pod Template:
   Labels:          app=nginx-deploy...
   Containers:
     nginx:
       Image:        nginx:1.9.1
       Port:         <none>
       ...

版本回退:确认要回退的版本后,执行以下命令回退版本

cs 复制代码
 # 回退到上一个版本
 [root@k8s ~]# kubectl rollout undo deployment/nginx-deploy
 # 回退到指定的 revision
 [root@k8s ~]# kubectl rollout undo deployment/nginx-deploy --to-revision=2

检查确认回退成功;

cs 复制代码
 # 查看发现,我们的版本已经回退到对应的 revison 上了
 [root@k8s ~]# kubectl get deployment 和 kubectl describe deployment 

++可以通过设置 .spec.revisonHistoryLimit 来指定 deployment 保留多少 revison,如果设置为 0,则不允许 deployment 回退了++

1.4、扩容缩容

原理:基于同一套模板,帮我们创建新的副本出来

通过 ++kube scale++ 命令可以进行**++自动扩容/缩容++,以及通过 kube edit 编辑 replcas 也可以实现扩容/缩容**

cs 复制代码
 # 将名为nginx-deploy的deploy中的副本数3扩容到6个
 [root@k8s ~]# kubectl scale --replicas=6 deploy nginx-deploy
 ​
 # 查看数量会发现nginx-deploy的数量变为6个
 [root@k8s ~]# kubectl get deploy
 NAME                READY       UP-TO-DATE      AVALIABLE       AGE
 nginx-deploy        6/6         6               6               55m
 ​
 # pod的数量也会变成6个
 [root@k8s ~]# kubectl get pod
 ​
 # 但是RS不会发生变化
 [root@k8s ~]# kubectl get rs

扩容与缩容只是直接创建副本数没有更新 pod template 因此不会创建新的 rs

1.5、暂停与恢复

由于每次对 pod template 中的信息发生修改 后,都会触发更新 deployment 操作 ,那么此时如果频繁修改信息,就会产生多次更新,而实际上只需要执行最后一次更新即可,当出现此类情况时我们就可以暂停 deployment 的 rollout;其命令如下:

cs 复制代码
 [root@k8s ~]# kubectl rollout pause deployment <name>
 ​
 # 暂停后,尝试对容器进行修改,然后查看是否发生更新操作了
 [root@k8s ~]# kubectl set image deploy <name> nginx=nginx:1.17.9
 [root@k8s ~]# kubectl get po 
 ​
 # 可看到实际并没有发生修改,此时我们再次进行修改一些属性,如限制 nginx 容器的最大cpu为 0.2 核,最大内存为 128M,最小内存为 64M,最小 cpu 为 0.1 核
 [root@k8s ~]# kubectl set resources deploy <deploy_name> -c <container_name> --limits=cpu=200m,memory=128Mi --requests=cpu100m,memory=64Mi
 ​
 # 格式化输出;看到配置确实发生了修改
 [root@k8s ~]# kubectl get deploy <name> -oyaml
 [root@k8s ~]# kubectl get po     # 发现没有被更新
 ​
 ​
 # 此时再恢复 rollout
 [root@k8s ~]# kubectl rollout resume deploy <name>
 ​
 # 恢复后,我们再次查看 rs 和 po 信息,我们可以看到就开始进行滚动更新操作了
 [root@k8s ~]# kubectl get rs
 [root@k8s ~]# kubectl get po

2、配置文件

cs 复制代码
 apiVersion: apps/v1 # deployment api 版本
 kind: Deployment    # 资源类型为 deployment
 metadata:       # 元信息
   labels:           # 标签
     app: nginx-deploy   # 具体的 key: value 配置形式
   name: nginx-deploy    # deployment 的名字
   namespace: default    # 所在的命名空间
 spec:
   replicas: 1               # 期望副本数
   revisionHistoryLimit: 10  # 进行滚动更新后,保留的历史版本数
   selector:                 # 选择器,用于找到匹配的 RS
     matchLabels:                # 按照标签匹配
       app: nginx-deploy             # 匹配的标签key/value
   strategy:                 # 更新策略
     rollingUpdate:              # 滚动更新配置
       maxSurge: 25% # 进行滚动更新时,更新的个数最多可以超过期望副本数的个数/比例
       maxUnavailable: 25% # 进行滚动更新时,最大不可用比例更新比例,表示在所有副本数中,最多可以有多少个不更新成功
     type: RollingUpdate # 更新类型,采用滚动更新
   template: # pod 模板
     metadata:       # pod 的元信息
       labels:       # pod 的标签
         app: nginx-deploy
     spec:   # pod 期望信息
       containers:           # pod 的容器
       - image: nginx:1.7.9              # 镜像
         imagePullPolicy: IfNotPresen    # 拉取策略
         name: nginx                     # 容器名称
       restartPolicy: Always # 重启策略
       terminationGracePeriodSeconds: 30 # 删除操作最多宽限多长时间

三、StatefulSet

StatefulSet中每个Pod的Dns格式为statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local

  • serviceName为Headless Service的名字
  • 0..N-1为Pod所在的序号,从0开始到N-1=
  • statefulSetName为statefulSet的名字
  • namespace为服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace
  • .cluster.local 为Cluster Domain

1、功能

1.1、创建

cs 复制代码
 [root@k8s ~]# kubectl create -f web.yaml
 ​
 # 查看 service => svc 和 statefulset => sts
 [root@k8s ~]# kubectl get service
 NAME        TYPE        CLUSTER-IP      RORT(S)     AGE
 kubernetes  ClusterIP   10.96.0.1       <none>      12h
 nginx       ClusterIP   None            <none>      27s
  
 [root@k8s ~]# kubectl get statefulset
 NAME        READY       AGE
 web         2/2         30s
 ​
 # 查看 持久卷(PVC) 信息,这里没有创建PV,因此PVC创建不出来
 [root@k8s ~]# kubectl get pvc
 NAME    STATUS  VOLUME  CAPACITY    ACCESS MODES    STOPAGECLASS    AGE
 www-web-0   Pending                                                 5m22s
 ​
 # 查看创建的 pod,这些 pod 是有序的
 [root@k8s ~]# kubectl get pods -l app=nginx
 NAME    REDAY   STATUS  RESTARTS    AGE
 web-0   1/1     Running 0           46s
 web-1   1/1     Running 0           44s
 ​
 # 查看这些 pod 的 dns
 # 运行一个 pod,基础镜像为 busybox 工具包,利用里面的 nslookup 可以看到 dns 信息
 [root@k8s ~]# kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
 /# nslookup web-0.nginx
 Server:         10.96.0.10
 Address 1:      10.96.0.10 kube-dns.kube-system.svc.cluster.local
 ​
 Name:   web-0.nginx
 Address 1:  10.244.169.148  web-0.nginx.default.svc.cluster.local

1.2、扩容缩容

cs 复制代码
 # 扩容
 [root@k8s ~]# kubectl scale statefulset web --replicas=5
 ​
 # 缩容
 [root@k8s ~]# kubectl patch statefulset web -p '{"spec":{"replicas":3}}'

1.3、镜像更新

目前还不支持直接更新 image,需要 patch 来间接实现

cs 复制代码
 [root@k8s ~]# kubectl patch sts web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:1.9.1"}]'
 ​
 # 当然使用edit、set等也可

(1)RollingUpdate

StatefulSet 也可以采用滚动更新策略,同样是修改 pod template 属性后会触发更新 ,但是由于 pod 是有序 的,在 StatefulSet 中更新时是基于 pod 的顺序倒序更新的

灰度发布/金丝雀发布

目标:++将项目上线后产生问题的影响,尽量降到最低++;

利用滚动更新中的 ++partition 属性++,可以实现简易的灰度发布的效果

例如我们有 5 个 pod,如果当前 ++partition 设置为 3++ ,那么此时滚动更新时,++只会更新那些序号 >= 3 的 pod;++利用该机制,我们可以通过控制 partition 的值,来决定只更新其中一部分 pod,确认没有问题后再主键增大更新的 pod 数量,最终实现全部 pod 更新

(2)OnDelete

++修改完yaml中template中的内容后++ , 只有在 pod 被删除时会进行更新操作,通俗来说,就是想更新哪个pod就删除哪个,删除后会马上创建一个更新好的Pod;

1.4、删除

StatefulSet直接关联到Pod,所以没有rs;所以只需要删除 StatefulSet 和 Headless Service

级联删除:删除 statefulset 时会同时删除 pods(默认方式)

cs 复制代码
 [root@k8s ~]# kubectl delete statefulset web

非级联删除 :删除 statefulset 时不会删除 pods,++删除 sts 后,pods 就没人管了++,此时再删除 pod 不会重建的

cs 复制代码
 [root@k8s ~]# kubectl delete sts web --cascade=false
 ​
 # 删除 service
 [root@k8s ~]# kubectl delete service nginx

1.5、删除pvc

StatefulSet删除后PVC还会保留着,数据不再使用的话也需要删除

cs 复制代码
 [root@k8s ~]# kubectl delete pvc www-web-0 www-web-1

2、配置文件

cs 复制代码
 ---         # 在yaml文件中,---之中的嵌套的内容表示在一段yaml中嵌套另外一段yaml内容
 apiVersion: v1
 kind: Service
 metadata:
   name: nginx
   labels:
     app: nginx
 spec:
   ports:
   - port: 80
     name: web
   clusterIP: None
   selector:
     app: nginx
 ---     
 apiVersion: apps/v1 
 kind: StatefulSet       # StatefulSet 类型的资源
 metadata:
   name: web             # StatefulSet 对象的名字
 spec:
   serviceName: "nginx"  # 使用哪个 service 来管理 dns
   replicas: 2   
   selector:
     matchLabels:
     app: nginx
   template:
     metadata:
       labels:
         app: nginx
     spec:
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:      # 容器内部要暴露的端口
         - containerPort: 80 # 具体暴露的端口号
           name: web         # 该端口配置的名字
         volumeMounts:   # 加载数据卷
         - name: www     # 指定加载哪个数据卷
           mountPath: /usr/share/nginx/html  # 加载到容器中的哪个目录
   volumeClaimTemplates:     # 数据卷模板
   - metadata:       # 数据卷的描述
       name: www     # 数据卷的名称
       annotations:  # 数据卷的注解
         volume.alpha.kubernetes.io/storage-class: anything
     spec:   # 数据卷的期望配置
       accessModes: [ "ReadWriteOnce" ]  # 访问模式
       resources:    # 
         requests:
           storage: 1Gi  # 需要1G的存储资源

四、DaemonSet

1、配置文件

fluentd-ds-yaml

cs 复制代码
 apiVersion: apps/v1
 kind: DaemonSet         # 创建DaemonSet 资源
 metadata:
   name: fluentd         # 名字
 spec:
   selector:
     matchLabels:
       app: logging      # 匹配标签名字与值;与下面template的label名字与值对应
   template:
     metadata:
       labels:
         app: logging
         id: fluentd
       name: fluentd
     spec:
       containers:
       - name: fluentd-es
         image: agilestacks/fluentd-elasticsearch:v1.3.0
         env:        # 环境变量配置
          - name: FLUENTD_ARGS   # 环境变量的 key
            value: -qq           # 环境变量的 value
         volumeMounts:   # 加载数据卷,避免数据丢失
          - name: containers # 数据卷的名字
            mountPath: /var/lib/docker/containers    # 将数据卷挂载到容器内的哪个目录
          - name: varlog
            mountPath: /varlog
       volumes:      # 定义数据卷
          - hostPath:    # 数据卷类型, 主机路径模式,也就是与node共享目录
              path: /var/lib/docker/containers
            name: containers # 定义的数据卷名称
          - hostPath:
              path: /var/log
            name: varlog
 ​

2、不指定Node节点

cs 复制代码
 [root@k8s ~]# kubectl create -f fluentd-ds.yaml
 [root@k8s ~]# kubectl get daemonset 或 kubectl get ds
 NAME    DESIRED CURRENT     READY   UP-TO-DATE  AVALIABLE   NODE SELECTOR   AGE
 fluentd 2       2           2       2           2           <none>          20s
 ​
 [root@k8s ~]# kubectl get po -o -wide
 NAME   READY   STATUS   RESTARTS    AGE IP  NODE   NOMINATED NODE   READINESS GATES 
 fluentd-fgwp2 1/1 Running  0        3m  10.244.36.102 k8s-node1 <none>     <none>
 fluentd-lxh3x 1/1 Running  0        3m  10.244.36.157 k8s-node2 <none>     <none>

发现,不指定Node节点的话 ,创建DaemonSet资源时,默认会往每一个非Master节点中部署

2、指定Node节点

DaemonSet 会忽略 Node 的 unschedulable 状态,有两种方式来指定 Pod 只运行在指定的 Node 节点上:

2.1、nodeSelector

只调度到匹配指定 label 的 Node 上

cs 复制代码
 # 先为 Node 打上标签
 [root@k8s ~]# kubectl label nodes k8s-node1 svc_type=microsvc
 ​
 # 然后再yaml配置文件中的 daemonset 配置中设置 nodeSelector
 spec:
   template:
     spec:
       nodeSelector:
         svc_type: microsvc
         
 [root@k8s ~]# kubectl get ds
 NAME    DESIRED CURRENT     READY   UP-TO-DATE  AVALIABLE   NODE SELECTOR   AGE
 fluentd 1       1           1       1           1           svc_type=microsvc   33s
 ​
 [root@k8s ~]# kubectl get po -o -wide
 NAME   READY   STATUS   RESTARTS    AGE IP  NODE   NOMINATED NODE   READINESS GATES 
 fluentd-frgh6  1/1 Running  0       56s 10.244.36.103 k8s-node1  <none>     <none>

2.2、nodeAffinity

功能更丰富的 Node 选择器,比如支持集合操作

nodeAffinity 目前支持两种:requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution,分别代表必须满足条件和优选条件。

比如下面的例子代表调度到包含标签 wolfcode.cn/framework-name 并且值为 spring 或 springboot 的 Node 上,并且优选还带有标签 another-node-label-key=another-node-label-value 的Node。

cs 复制代码
 apiVersion: v1
 kind: Pod
 metadata:
   name: with-node-affinity
 spec:
   affinity:
     nodeAffinity:
       requiredDuringSchedulingIgnoredDuringExecution:
         nodeSelectorTerms:
         - matchExpressions:
           - key: wolfcode.cn/framework-name
             operator: In
             values:
             - spring
             - springboot
       preferredDuringSchedulingIgnoredDuringExecution:
       - weight: 1
         preference:
           matchExpressions:
           - key: another-node-label-key
             operator: In
             values:
             - another-node-label-value
   containers:
   - name: with-node-affinity
     image: pauseyyf/pause

2.3、podAffinity

调度到满足条件的 Pod 所在的 Node 上

podAffinity 基于 Pod 的标签来选择 Node,仅调度到满足条件Pod 所在的 Node 上,支持 podAffinity 和 podAntiAffinity。这个功能比较绕,以下面的例子为例:

  • 如果一个 "Node 所在空间中包含至少一个带有 auth=oauth2 标签且运行中的 Pod",那么可以调度到该 Node
  • 不调度到 "包含至少一个带有 auth=jwt 标签且运行中 Pod"的 Node 上
cs 复制代码
 apiVersion: v1
 kind: Pod
 metadata:
   name: with-pod-affinity
 spec:
   affinity:
     podAffinity:
       requiredDuringSchedulingIgnoredDuringExecution:
       - labelSelector:
           matchExpressions:
           - key: auth
             operator: In
             values:
             - oauth2
         topologyKey: failure-domain.beta.kubernetes.io/zone
     podAntiAffinity:
       preferredDuringSchedulingIgnoredDuringExecution:
       - weight: 100
         podAffinityTerm:
           labelSelector:
             matchExpressions:
             - key: auth
               operator: In
               values:
               - jwt
           topologyKey: kubernetes.io/hostname
   containers:
   - name: with-pod-affinity
     image: pauseyyf/pause

3、滚动更新

默认为RollingUpdate,但不建议使用,建议使用 OnDelete 模式,这样避免频繁更新 ds

五、HPA自动扩/缩容

通过++观察 pod 的 cpu、内存使用率++ 或++自定义 metrics 指标++进行自动的扩容或缩容 pod 的数量。

通常用于 ++Deployment++,不适用于无法扩/缩容的对象,如 DaemonSet

控制管理器每隔30s (可以通过++--horizontal-pod-autoscaler-sync-period修改++ )查询metrics的资源使用情况

1、开启指标服务

Kubernetes 1.8 开始,++资源使用指标++ (如容器 CPU 和内存使用率)通过 Metrics API 在 Kubernetes 中获取, ++metrics-server 替代了heapster++。Metrics Server 实现了Resource Metrics API,Metrics Server 是集群范围资源使用数据的聚合器。 Metrics Server 从每个节点上的 Kubelet 公开的 Summary API 中采集指标信息。

官方文档: Resource metrics pipeline | Kubernetes

cs 复制代码
 # 下载 metrics-server 组件配置文件
 [root@k8s ~]# wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -O metrics-server-components.yaml
 ​
 # 修改镜像地址为国内的地址
 [root@k8s ~]# sed -i 's/k8s.gcr.io\/metrics-server/registry.cn-hangzhou.aliyuncs.com\/google_containers/g' metrics-server-components.yaml
 ​
 # 修改容器的tls配置,不验证tls,在containers的args参数中增加 --kubelet-insecure-tls 参数
 [root@k8s ~]# vim metrics-server-components.yaml
 ​
 # 安装组件
 [root@k8s ~]# kubectl apply -f metrics-server-components.yaml
 ​
 # 查看 pod 状态
 [root@k8s ~]# kubectl get pods --all-namespaces | grep metrics
 kube-system  metrics-server-55db4f88bc-gw88n    1/1     Running     0       36s

2、cpu、内存指标监控

++实现 cpu 或内存的监控++,首先有个前提条件是该对象必须配置了 resources.requests.cpuresources.requests.memory 才可以,可以配置当 cpu/memory 达到上述配置的百分比后进行扩容或缩容

<创建一个 HPA>

  1. 先准备一个好一个有做资源限制的 deployment

  2. 执行命令 kubectl autoscale deploy <deploy_name> --cpu-percent=20 --min=2 --max=5

  3. 通过 kubectl get hpa 可以获取 HPA 信息

(测试):找到对应服务的 service,编写循环测试脚本提升内存与 cpu 负载

编写nginx-svc.yamlnginx-deploy.yaml</u>

cs 复制代码
 # nginx-svc.yaml:
 apiVersion: v1
 kind: Service
 metadata:
   name: nginx-svc
   labels:
     app:nginx
 spec:
   selector:
     app:nginx-deploy
   ports:
   - port: 80
     targetPort: 80
     name: web
   type: NodePort
   
 # nginx-deploy.yaml:
 apiVersion: apps/v1 
 kind: Deployment
 metadata:
   labels:   
     app: nginx-deploy 
   name: nginx-deploy 
   namespace: default    
 spec:
   replicas: 1               
   revisionHistoryLimit: 10  
   selector:                 
     matchLabels:                
       app: nginx-deploy         
   strategy:             
     rollingUpdate:          
       maxSurge: 25% 
       maxUnavailable: 25% 
     type: RollingUpdate
   template: 
     metadata:       
       labels:       
         app: nginx-deploy
     spec:   
       containers:       
       - image: nginx:1.7.9              
         imagePullPolicy: IfNotPresent   
         name: nginx
         resources:  # 限制资源使用
           limits: 
             cpu: 200m
             memory: 128Mi
           requests:
             cpu: 100m
             memory: 128Mi
       restartPolicy: Always
       terminationGracePeriodSeconds: 30 

开始创建

cs 复制代码
 # 创建一个有做资源限制的 deployment
 [root@k8s ~]# kubectl create apply -f nginx-deploy.yaml
 [root@k8s ~]# kubectl create apply -f nginx-svc.yaml
 ​
 # 执行命令增加一个自动的HPA:--min:最小实例数为2,--max:最多实例数
 [root@k8s ~]# kubectl autoscale deploy <deploy_name> --cpu-percent=20 --min=2 --max=5
 [root@k8s ~]# kubectl get svc
 NAME        TYPE        CLUSTER-IP      EXTERNAL-IP     PORT(S)     AGE
 kubernetes    ...
 nginx-svc   NodePort    10.96.49.86     <none>          80:32057/TCP    9s
 ​
 # node1节点中死循环执行访问服务请求
 [root@k8s-Node1 ~]# while true; do wget -q -O- http://<10.96.49.86> > /dev/null ; done
 ​
 # 在master上可执行以下命令查看服务资源负载情况
 [root@k8s ~]# kubectl top pods
 NAME                                CPU(cores)          MEMORY(bytes)
 ...
 nginx-deploy-56696fbb5-wf666        2m                  1Mi
 ​
 # 查看 HPA 资源使用情况
 [root@k8s ~]# kubectl get hpa
 NAME          REFERENCE               TARGETS  MINPODS  MAXPODS   REPLICAS    AGE
 nginx-deploy  Deployment/nginx-deploy 19%/20%     2        5         4        33m
 ​
 # 发现使用情况快达到20%并可能超出,此时查看deploy
 [root@k8s ~]# kubectl get deploy
 NAME            READY       UP-TO-DATE          AVALIABLE       AGE
 nginx-deploy    4/4         4                   4               40m

可以通过多台机器执行上述命令,++增加负载++ ,当超过负载后可以查看 pods 的扩容情况 ++kubectl get pods++

++扩容测试完成后,再关闭循环执行的指令++,让 cpu 占用率降下来,然后过 5 分钟后查看自动缩容情况;会发现自动缩容,慢慢降回去;

3、自定义metrics

  • 控制管理器开启**++--horizontal-pod-autoscaler-use-rest-clients++**
  • 控制管理器的**++--apiserver++** 指向API Server Aggregator
  • 在**++API Server Aggregator++**中注册自定义的metrics AP
相关推荐
诡异森林。1 小时前
Docker--Docker网络原理
网络·docker·容器
ALex_zry1 小时前
Docker Macvlan网络配置实战:解决“network already exists“错误
网络·docker·php
IT小辉同学1 小时前
Docker如何更换镜像源提高拉取速度
spring cloud·docker·eureka
matrixlzp2 小时前
K8S Service 原理、案例
云原生·容器·kubernetes
GnixAij3 小时前
Docker SSH端口转发
docker·ssh
angushine4 小时前
让Docker端口映射受Firewall管理而非iptables
运维·docker·容器
玄明Hanko5 小时前
生产环境到底能用Docker部署MySQL吗?
后端·mysql·docker
玄明Hanko5 小时前
Quarkus+Docker最全面完整教程:手把手搞定Java云原生
后端·docker·云原生
SimonLiu0095 小时前
清理HiNas(海纳斯) Docker日志并限制日志大小
java·docker·容器
coder_copy6 小时前
IDEA 2024 使用总结,踩坑
docker·intellij-idea