Kubernetes学习之Metrics-Server

一、资源监控
Kubernetes有多个数据指标需要采集相关的数据,而这些指标大体上可以分为两个组成部分:监控集体本身和监控Pod对象,在集群监控层面,目标是监控整个Kubernetes集群的健康状况,包括集群中的所有工作节点是否运行正常、系统资源容量大小、每个工作节点上运行的容器化应用的数量以及整个集群的资源利用率等等,它们通常可以分为如下一些可衡量的指标。
1)节点资源状态:这个领域的众多指标都与资源利用状况有关,主要有网络带宽、磁盘空间、CPU和内存的利用率;基于这些度量指标,管理员能够评估集群规模的合理性。
2)节点数量:当今,众多公有云服务商均以客户使用实例数量计算费用,于是即时了解到集群中的可用节点数量可以为用户计算所需要支付的费用提供参考指标。
3)运行的Pod对象:正在运行的Pod对象数量能够用于评估可用节点的数量是否够多,以及在节点发生故障时它们是否能够承接整个工作负载。
另一方面,Pod资源对象的监控需求大体上可以分为三类:Kubernetes指标、容器指标和应用指标。
1)Kubernetes指标:用于监控特定应用程序相关的Pod对象的部署过程、当前副本数量、期望副本数量、部署过程进展状态、健康状态检测及网络服务器的可用性等等,这些指标数据需要经由Kubernetes系统接口获取。
2)容器指标:容器额资源需求、资源限制以及CPU、内存、磁盘空间、网络带宽等等资源的实际占用状况等等。
3)应用程序指标:应用程序自身内建的指标,通常与其所处理的业务规则相关、例如,关系型数据库应用程序可能会内建用于暴露索引状态有关的指标,以及表和关系的统计信息等等。
监控集群所有的节点一种方法是通过DaemonSet控制器在每个节点上都部署一个用于监控指标数据采集功能的Pod对象运行监控代理程序(agent),并在集群上部署一个收集各节点上由代理程序采集的监控数据的中心监控系统,统一进行数据的采集、存储和展示。这种部署方式给了管理员很大的自主空间,但是必定难以形成统一之势。

二、新一代监控架构
Kubernetes如此强大的原因之一就是其灵活的可扩展性,其中表现得尤为抢眼的是,它通过API集合器为开发人员提供了轻松扩展API资源的能力,Kubernetes在1.7版本中引入的自定义指标API(custom metrics API)以及在1.8版本中引入的资源指标API(resource metrics API,简称为指标API)都属于这种类型的扩展。
资源指标API主要供核心系统组件使用,如调度程序、HPA和"kubectl top"命令等等,虽然是以扩展方式实现API,但它提供的是kubernetes系统必备的"核心指标",因此不适用于与第三方监控系统集成,如Prometheus等。另一方面,自定义指标API则为用户提供了自行按需扩展指标的接口,它允许用户自定义指标类型的API Server并直接聚合进主API Server中,因此具有更广泛的使用场景。简单总结起来就是,新一代的Kubernetes监控系统架构主要由核心指标流水线和监控系统指标流水线协同组成,具体如下:
1)核心指标流水线
由kubectl、资源评估器、metrics-server以及由API Server提供的API群组(由API Server对象提供)组成,它们可用于为Kubernetes系统提供核心指标,从而能够了解并操作其内部组件和核心程序。截止目前,相关的指标主要包括CPU累计使用、内存即时使用率、Pod的资源占有率及容器的磁盘占用率等几个。所用到的度量指标核心系统组件包括调度逻辑(基于指标数据的调度程序和应用规模的水平缩放),以及部分UI组件(如kubectl top命令和Dashboard)等等。
在这里插入图片描述
2)监控指标流水线
监控指标流水线用于从系统收集各种指标数据并提供给终端用户、存储系统以及HPA控制器等使用,它收集的数据指标也被称为非核心指标,但它们通常也包含核心指标(未必是Kubernetes可以理解的格式)以及其他指标。自定义指标API允许用户任意扩展任意数量的特定于应用程序的指标,例如,其指标可能包括队列长度和每秒入口请求数等等。Kubernetes系统本身不会提供此类组件,也不会对这些指标提供相关的解释,它有赖于用户按需选择使用的第三方解决方案。
一个能同时资源指标API和自定义指标API的组件是第二版的HorizontalPod-Autoscaler控制器(HPAv2),它实现了基于观察到的指标自动缩放Deployment或ReplicaSet类型控制器管控下的Pod副本数量。HPA的第一个版本只能根据观察的CPU利用率进行扩展,尽管在某些情况下很有用,但CPU并不总是最适合自动调整应用程序的度量指标。
从根本上来说,资源指标API和自定义指标API都仅仅是API的定义和规范,它们自身都并非具体的API实现。目前,资源指标API的实现较为主流的是metrics-server,而自定义指标API则以构建在监控系统Prometheus之上的k8s-prometheus-adapter最广为接收。事实上,Prometheus也是CNCF旗下的项目之一,并得到了Kubernetes系统上众多组件的原生支持。

三、部署Metrics Server
Metrics Server是集群级别的资源利用率数据的聚合器(aggregator),它的创建于不少方面都受到了Heapster的启发,且于功能和特性上完全可视作一个仅服务于指标数据的简化版Heapster。Metrics Server通过Kubernetes聚合器(kube-aggregator)注册到主API Server之上,而后基于kubelet的Summary API收集每个节点上的指标数据,并将它们存储于内存中然后以指标API格式提供。
在这里插入图片描述
Metrics Server基于内存存储,重启后数据将全部丢失,而且它仅能留存最近收集到的指标数据,因此,如果用户期望访问历史数据,就不得不借助于第三方的监控系统(如Prometheus)等等,或者自行开发以实现其功能。
Metrics Server是Kubernetes多个核心组件的基础依赖,因此,它应该默认部署于集群中。一般来说,Metrics Server在每个集群中仅会运行一个实例,启动时,它将自动初始化与各节点的连接,因此出于安全的考虑,它需要运行于普通节点而非Master主机之上,直接使用项目本身提供的资源配置清单即能轻松完成metrics-server的部署。

1)下载metric-server部署的yaml文件到本地

wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.7/components.yaml

2)拉取metric-server的镜像到本地

]# docker pull zhaoqinchang/metrics-server:0.3.7
0.3.7: Pulling from zhaoqinchang/metrics-server
9ff2acc3204b: Pull complete 
9d14b55ff9a0: Pull complete 
Digest: sha256:c0efe772bb9e5c289db6cc4bc2002c268507d0226f2a3815f7213e00261c38e9
Status: Downloaded newer image for zhaoqinchang/metrics-server:0.3.7
docker.io/zhaoqinchang/metrics-server:0.3.7

3)修改components.yaml文件为如下内容

]# cat components.yaml 
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: system:aggregated-metrics-reader
  labels:
    rbac.authorization.k8s.io/aggregate-to-view: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
rules:
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods", "nodes"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  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: RoleBinding
metadata:
  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: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
  name: v1beta1.metrics.k8s.io
spec:
  service:
    name: metrics-server
    namespace: kube-system
  group: metrics.k8s.io
  version: v1beta1
  insecureSkipTLSVerify: true
  groupPriorityMinimum: 100
  versionPriority: 100
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: metrics-server
  namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    k8s-app: metrics-server
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  template:
    metadata:
      name: metrics-server
      labels:
        k8s-app: metrics-server
    spec:
      serviceAccountName: metrics-server
      volumes:
      # mount in tmp so we can safely use from-scratch images and/or read-only containers
      - name: tmp-dir
        emptyDir: {}
      containers:
      - name: metrics-server
        image: zhaoqinchang/metrics-server:0.3.7    #修改镜像为刚刚拉取下来的镜像
        imagePullPolicy: IfNotPresent
        args:
          - --cert-dir=/tmp
          - --secure-port=4443
        command:                 #添加以下三行command命令
            - /metrics-server
            - --kubelet-preferred-address-types=InternalIP
            - --kubelet-insecure-tls
        ports:
        - name: main-port
          containerPort: 4443
          protocol: TCP
        securityContext:
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1000
        volumeMounts:
        - name: tmp-dir
          mountPath: /tmp
      nodeSelector:
        kubernetes.io/os: linux
---
apiVersion: v1
kind: Service
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    kubernetes.io/name: "Metrics-server"
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    k8s-app: metrics-server
  ports:
  - port: 443
    protocol: TCP
    targetPort: main-port
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: system:metrics-server
rules:
- apiGroups:
  - ""
  resources:
  - pods
  - nodes
  - nodes/stats
  - namespaces
  - configmaps
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  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

4)部署metric-server

]# kubectl apply  -f components.yaml 
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
serviceaccount/metrics-server created
deployment.apps/metrics-server created
service/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created

]# kubectl get pods -n kube-system  -o wide 
NAME                              READY   STATUS    RESTARTS   AGE    IP             NODE     NOMINATED NODE   READINESS GATES
coredns-66bff467f8-h7rjz          1/1     Running   21         72d    10.244.0.142   master   <none>           <none>
coredns-66bff467f8-jvqf8          1/1     Running   21         72d    10.244.0.144   master   <none>           <none>
etcd-master                       1/1     Running   23         72d    172.16.2.200   master   <none>           <none>
kube-apiserver-master             1/1     Running   97         72d    172.16.2.200   master   <none>           <none>
kube-controller-manager-master    1/1     Running   23         72d    172.16.2.200   master   <none>           <none>
kube-flannel-ds-amd64-26qv9       1/1     Running   28         72d    172.16.2.200   master   <none>           <none>
kube-flannel-ds-amd64-fzxxc       1/1     Running   16         72d    172.16.2.101   node1    <none>           <none>
kube-flannel-ds-amd64-lgggd       1/1     Running   3          3d5h   172.16.2.202   node2    <none>           <none>
kube-proxy-255z5                  1/1     Running   23         72d    172.16.2.200   master   <none>           <none>
kube-proxy-8mh7c                  1/1     Running   17         72d    172.16.2.101   node1    <none>           <none>
kube-proxy-gsbn6                  1/1     Running   16         72d    172.16.2.202   node2    <none>           <none>
kube-scheduler-master             1/1     Running   23         72d    172.16.2.200   master   <none>           <none>
metrics-server-7b8dbfc8bc-l8sxd   1/1     Running   0          16s    10.244.1.163   node1    <none>           <none>

5)查看metric-server资源对象的详细信息

]# kubectl describe pods metrics-server-7b8dbfc8bc-4ck84  -n kube-system
Name:         metrics-server-7b8dbfc8bc-4ck84
Namespace:    kube-system
Priority:     0
Node:         node1/172.16.2.101
Start Time:   Sun, 27 Sep 2020 15:25:03 +0800
Labels:       k8s-app=metrics-server
              pod-template-hash=7b8dbfc8bc
Annotations:  <none>
Status:       Running
IP:           10.244.1.165
IPs:
  IP:           10.244.1.165
Controlled By:  ReplicaSet/metrics-server-7b8dbfc8bc
Containers:
  metrics-server:
    Container ID:  docker://7db90ed46c704a75fbf42c0e7ad7996a0968ab26e1b04ec56367324865fb3abd
    Image:         zhaoqinchang/metrics-server:0.3.7
    Image ID:      docker-pullable://zhaoqinchang/metrics-server@sha256:c0efe772bb9e5c289db6cc4bc2002c268507d0226f2a3815f7213e00261c38e9
    Port:          4443/TCP
    Host Port:     0/TCP
    Args:
      --cert-dir=/tmp
      --secure-port=4443
    State:          Running
      Started:      Sun, 27 Sep 2020 15:25:04 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /tmp from tmp-dir (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from metrics-server-token-vszdg (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  tmp-dir:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  <unset>
  metrics-server-token-vszdg:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  metrics-server-token-vszdg
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  kubernetes.io/os=linux
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  31s        default-scheduler  Successfully assigned kube-system/metrics-server-7b8dbfc8bc-4ck84 to node1
  Normal  Pulled     <invalid>  kubelet, node1     Container image "zhaoqinchang/metrics-server:0.3.7" already present on machine
  Normal  Created    <invalid>  kubelet, node1     Created container metrics-server
  Normal  Started    <invalid>  kubelet, node1     Started container metrics-server

6)查看metric.k8s.io是否出现在Kubernetes集群的API群组列表中

]# kubectl api-versions | grep metrics 
metrics.k8s.io/v1beta1

四、使用kubectl top命令
kubectl top命令可显示节点和Pod对象的资源使用信息,它依赖于集群中的资源指标API来收集各项指标数据。它包含有node和pod两个子命令,可分别显示Node对象和Pod对象的相关资源占用率。
列出Node资源占用率命令的语法格式为"kubectl top node [-l label | NAME]",例如下面显示所有节点的资源占用状况的结果中显示了各节点累计CPU资源占用时长及百分比,以及内容空间占用量及占用比例。必要时,也可以在命令直接给出要查看的特定节点的标识,以及使用标签选择器进行节点过滤:

]# kubectl top node
NAME     CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
master   179m         8%     1660Mi          43%       
node1    81m          4%     908Mi           23%       
node2    78m          3%     1036Mi          26%   

.
而名称空间级别的Pod对象资源占用率的使用方法会略有不同,使用时,一般应该跟定名称空间及使用标签选择器过滤出目标Pod对象。命令的语法格式为"kubectl top pod [NAME | -l label] [--all-namespaces] [--containers=false|true]",例如,下面显示kube-system名称空间下的Pod资源使用状况:

]:~# kubectl top  pod   -n taobao-spider 
NAME                        NAME          CPU(cores)   MEMORY(bytes)   
coredns-66bff467f8-h7rjz    coredns       3m           76Mi            
coredns-66bff467f8-jvqf8    coredns       1m           69Mi            
....................

kubectl top命令为用户提供简洁、快速获取Node对象及Pod对象系统资源占用状况的接口,是集群运行和维护的常用命令之一。


版权声明:本文为Micky_Yang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。