Kubernetes學習之Metrics-Server

Micky_Yang發表於2020-09-26

一、資源監控
  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物件系統資源佔用狀況的介面,是叢集執行和維護的常用命令之一。

相關文章