一、概述

  1、接下来介绍在k8s上运行pod对象时我们如何去监控我们系统级的资源指标以及业务级别的资源指标。数据如何获取和监控。在此之前先介绍一下Pod对象的资源请求和资源限制。即容器的资源需求和资源限制。在docker中说到过容器是可以资源限额的,在启动容器时候我们可以定义一个容器可以使用多少的cpu和内存资源。在当时说过cpu资源是可压缩资源,一个pod或一个容器在应该获取指定资源获取不到时等待即可,但是对内存来讲就不是这样的,假如他用到的资源不够就有可能会因为内存资源耗尽而被killd 。不过在我们k8s之上资源有两个维度限制,一个是定义其起始值,一个是定义其终结值。

    a、requests:可以使用资源的requests来定义pod至少会用到多少CPU或内存资源。即资源需求,最低保障。

    b、limits:即限额,也叫限制,也是硬限制。一般来讲我们的requests是小于等于limits的。

二、Pod资源限额  

  1、虽然这些限制是应用在容器之上的,我们一般会把其称之为Pod的资源需求或Pod的资源限制。配置之前先描述一下二者的不同指标。

    a、CPU:在k8s上一个单位的cpu相当于我们对应的一颗虚拟CPU,一颗CPU是指一颗逻辑CPU,也就是指一个核心。或者是一个超线程。一个两核双线程的CPU其实是会被虚拟成4颗逻辑cpu。 1个cpu还能被单独划分成子单位。一个核心相当于1000个毫核心。也就是milicores。也即 500m=0.5CPU

    b、内存:计量单位为E、P、T、G、M、K,一般而言我们以Ei,Pi...等为计量单位。

  2、我们一般是这样划分CPU的资源指标占用量的。比如有一个区间是我们的CPU limit,假设我们现在一个pod中的某一容器最多只能使用0.5个cpu核心,那么我们就定义cpu.limits=500m,但是这500m是其硬上限。即多用是不可以的,不用的话是可以的。除此之外我们还有一个限制叫request,意思是我们要想运行这个容器至少得有多少个cpu才行。假如cpu.requests=200m,意思就是我们要想能够确保这个容器运行至少得给其0.2个cpu核心。这是他最低保障。并不是他上来真正会用这么多,而是说要确保被调度的目标节点上得有这么多空闲cpu可用。每一个节点已经有多少资源被分配出去了就是靠这个节点上所运行的所有容器的cpu的requests加起来。比如我们现在有4个容器,每个容器至少需要0.5核我们cpu只有四核则意味着还有2核空闲,因此我们随后调度时如果一个pod中的容器要求至少要使用3个cpu那么在第一次预选时就被淘汰了,因为他无法在节点资源级满足这个对应的容器的需要。所以我们去计算一个pod中的容器需要多少资源时是靠这个requests作为他的需求量的。cpu.limits叫最大保证,如果我们系统资源无法保证你能用500m,但是至少要确保要有cpu.requests中定义的200m这么多的资源可用。所以我们说cpu.requests对我们系统调度来说是非常重要的。

    

  3、接下来我们简单创建一个pod看看定义他的资源需求以后他是怎么运行的。我们定义资源需求他只定义了资源的请求下限。我们明确说他至少要有200m,但很有可能系统上有4个cpu核心,而这个应用程序因为bug或其它原因把这四核全吃了也是有可能的。因此我们一般而言要把需求和上限要同时使用,不然其有可能会吃掉节点所有资源。所以我们这两个维度的限制作用各不相同。requests需求用于确保我们在调度时以确保对应节点上要拥有这么多资源满足这个pod运行的某些功能时的基本需求。而limits则用于限制这个容器无论怎么运行绝对不能超过的资源阈值。

    a、首先我们来看其定义方式。可以看到对应的使用方式我们可以在explain的连接中查看

[root@k8smaster ~]# kubectl explain pods.spec.containers.resources
KIND: Pod
VERSION: v1 RESOURCE: resources <Object> DESCRIPTION:
Compute Resources required by this container. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources ResourceRequirements describes the compute resource requirements. FIELDS:
limits <map[string]string>
Limits describes the maximum amount of compute resources allowed. More
info:
https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ requests <map[string]string>
Requests describes the minimum amount of compute resources required. If
Requests is omitted for a container, it defaults to Limits if that is
explicitly specified, otherwise to an implementation-defined value. More
info:
https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

    b、首先我们去除前面打的污点然后再创建pod

[root@k8smaster metrics]# kubectl taint node k8snode1 node-type-
node/k8snode1 untainted
[root@k8smaster metrics]# kubectl taint node k8snode2 node-type-
node/k8snode2 untainted
[root@k8smaster metrics]# cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels: #也可以在此处写上{app:myapp,tier:frontend}代替下面两行
app: myapp #应用层级标签
tier: frontend #架构层级标签,在分层架构中属于frontend层
annotations:
wohaoshuai.com/created-by: "cluster admin"
spec:
containers: #是一个列表,具体定义方式如下
- name: myapp
image: ikubernetes/stress-ng #压测用的容器
command: ["/usr/bin/stress-ng","-m 1","-c 1","--metrics-brief"] #-m 1表示启动一个子进程对内存做压测,-c 1表示启动一个子进程对cpu做压测。--metrics-brief表示使用简洁的输出格式。
resources:
requests:
cpu: "200m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "200Mi"
[root@k8smaster metrics]# kubectl apply -f pod-demo.yaml
pod/pod-demo created
[root@k8smaster metrics]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
myapp-deploy-5d9c6985f5-46rtw / Running 3h 10.244.2.12 k8snode2
myapp-deploy-5d9c6985f5-7nhwq / Running 3h 10.244.1.9 k8snode1
myapp-deploy-5d9c6985f5-p8gsg / Running 3h 10.244.2.13 k8snode2
pod-demo / Running 2m 10.244.2.14 k8snode2

    c、b中的pod好像会压出问题,此处我们只压测cpu

[root@k8smaster metrics]# cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels: #也可以在此处写上{app:myapp,tier:frontend}代替下面两行
app: myapp #应用层级标签
tier: frontend #架构层级标签,在分层架构中属于frontend层
annotations:
wohaoshuai.com/created-by: "cluster admin"
spec:
containers: #是一个列表,具体定义方式如下
- name: myapp
image: ikubernetes/stress-ng #压测用的容器
command: ["/usr/bin/stress-ng","-c 1","--metrics-brief"] #-c 1表示启动一个子进程对cpu做压测。--metrics-brief表示使用简洁的输出格式。
resources:
requests:
cpu: "200m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
[root@k8smaster metrics]# kubectl apply -f pod-demo.yaml
pod/pod-demo created
[root@k8smaster metrics]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
myapp-deploy-5d9c6985f5-46rtw / Running 3h 10.244.2.12 k8snode2
myapp-deploy-5d9c6985f5-7nhwq / Running 3h 10.244.1.9 k8snode1
myapp-deploy-5d9c6985f5-p8gsg / Running 3h 10.244.2.13 k8snode2
pod-demo / Running 32s 10.244.2.15 k8snode2 [root@k8smaster ~]# kubectl exec -it pod-demo top #可以看到cpu用了25%,我们虚拟机cpu为2核,因为容器上限为500m因此使用率为25%
Mem: 1605360K used, 261688K free, 19624K shrd, 2108K buff, 1002740K cached
CPU: % usr % sys % nic % idle % io % irq % sirq
Load average: 2.16 1.32 0.89 /
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
root R % % {stress-ng-cpu} /usr/bin/stress-ng -c --metrics-brief
root S % % /usr/bin/stress-ng -c --metrics-brief
root R % % top

    d、requests是定义了能够被调度器作为基本衡量条件的调度值使用的,比如我们调度器他能根据requests属性定义的资源请求量来判定哪些节点能够接受这个pod去运行。对每一个节点来讲他们会把所有容器的资源需求量加起来作为已分配处理的配额。

  4、需要说明的是容器中的可见资源量和他们的可用资源量不是一回事。我们限制了以后,比如使用limit限制资源限额,使用requests限制资源需求。使用free命令看到的应该是整个节点上的内存而不会仅仅是当前这个容器中的内存。那么这样会有问题,比如我在容器中运行一个jvm,jvm上的很多程序在跑起来怎么区分队列层呢?可能会使用默认节点可用内存的百分之多少的样子,如果我们在容器中看到的内存可用量不是对应的容器的最大限额而是节点的内存量这儿可能就有点麻烦,计算结果有可能吞掉整个容器内存都不够。所以我们说目前来讲在容器的资源限制方面在这个维度上还是存在一些问题的。另外,我们每创建一个pod以后我们去describe这个pod可以看到我们pod有个QoS Class(服务质量类别)。因此我们在容器中限制了资源应用以后他会自动被分配一个叫QoS的。他会自动属于某个QoS类别。默认情况下QoS类别有三个:

    a、Guranteed:保证。即每个容器的cpu资源设置了相同值的requests和limit属性。即cpu的资源需求量,内存资源需求量两边都定义了,并且requests都等于limits。即同时设置了CPU和内存的requests和limits,最重要的是要满足 cpu.limits=cpu.requests同理memory.limits=memory.requests。这类pod就具有最高优先级,即我们现在有很多Pod需要运行的时候假如节点资源不够无法满足所有的pod的容器去运行这类容器是要被优先运行的。因为他的优先级最高。而但凡这样做了属性设置的会被自动归类为Guranteed类别。

    b、Burstable:至少有一个容器设置了cpu或内存资源的requests属性。其定义了requests但是可能没有定义limit之类的。因此这一类就具有中等优先级。我们刚刚设置了内存的requests也设置了cpu的requests,但是内存和cpu的requests和其limit是不相等的。因此其被自动归类为Burstable。

[root@k8smaster metrics]# cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels: #也可以在此处写上{app:myapp,tier:frontend}代替下面两行
app: myapp #应用层级标签
tier: frontend #架构层级标签,在分层架构中属于frontend层
annotations:
wohaoshuai.com/created-by: "cluster admin"
spec:
containers: #是一个列表,具体定义方式如下
- name: myapp
image: ikubernetes/myapp:v1
resources:
requests:
cpu: "200m"
memory: "512Mi"
limits:
cpu: "200m"
memory: "512Mi"
[root@k8smaster metrics]# kubectl apply -f pod-demo.yaml
pod/pod-demo created
[root@k8smaster metrics]# kubectl describe pods pod-demo |grep QoS
QoS Class: Guaranteed

    c、BestEffort:没有任何一个容器设置了requests或limits属性;最低优先级别

[root@k8smaster metrics]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-deploy-5d9c6985f5-46rtw / Running 1d
myapp-deploy-5d9c6985f5-7nhwq / Running 1d
myapp-deploy-5d9c6985f5-p8gsg / Running 1d
pod-demo / Running 10m [root@k8smaster metrics]# kubectl describe pod myapp-deploy-5d9c6985f5-46rtw |grep QoS
QoS Class: BestEffort

  5、需要注意的是当内存资源紧缺时,即资源不够用时BestEffort中的容器会被优先终止以腾出资源确保其它两种类型的pod中的容器能正常运行。如果一个节点上只有Guranteed和Burstable类型的容器资源不够用时又会杀优先级较低的Burstable。现在我们可能有很多pod中的容器都属于Burstable那么我们应该先杀哪个呢?因此他需要有一种计算标准去终止。其实在我们对应的k8s代码中有一段设置的是尽可能把他对应的requests资源已经占用量比例较大的给关掉。比如我们现在有两个pod,对第一个pod来讲他的内存的limits是1G,他的requests是512M,而现在已经占了500M了,已经满足基本最低需求了。对第二个pod来讲他需求2G,最低要求1G,现在已经占据512了。第一个pod占了500M,第二个占了512M,第二个基本保证是1G,第一个基本保证是512M,那么谁会被干掉呢?他是这样来评估的,就是谁已分配的量已经接近其需求量那么就认为说他其实没有空间了,马上就会被干掉了,所以第一个会被干掉。即已占用量与需求量的比例越大则优先被干掉,不管用了多少。

    

三、heapster

  1、刚刚有个很尴尬的地方在于,我创建了这样的限制pod以后我想观察Pod到底占了多少资源呢?比如我们分配说limits是512M,requests是256M,我现在想看看到底用了多少要怎么看呢?我们可以用kubectl top,不过此时没法用,因为我们k8s集群top命令应用是依赖于集群上部署一个addons叫heapster,意思是说我们整个k8s需要一个运行在集群级别的各pod甚至是各节点资源用量的采集和存储工具。kubectl top这样的命令是根据采集和存储数据的机制而显示的。如果没有这样的heapster我们系统中的top是没法运行的,包括我们部署的dashboard中的某些资源用量的显示功能也是依赖于heapster的。简单来讲我们可以这样来理解,我们虽然在节点级我们曾经使用过top,stat,vmstat等命令能够统计节点级的进程使用资源。但是当k8s运行在众多节点以后每一个pod运行在哪儿都没法确定,这个pod进程中到底占了多少资源并且要用同一视图查看时是没法的,因为他只是在节点级。所以为了实现这样的功能我们就需要在整个集群上部署一个统一的资源指标收集和存储工具,至少我们要有一个收集功能。当我们需要看的时候他要联系到每一个节点上,通过每一个节点的agent来获取到这个节点之上的每一个进程甚至是节点本身的资源用量,而后用kubectl top命令来显示。但是我们系统默认没有部署此工具,他需要单独额外部署一套这样的工具,传统的k8s集群中默认建议使用的指标数据的采集和存储工具叫HeapSter,但是HeapSter只是一个汇聚指标数据的,因为每个节点上都要采集节点自身的和上面运行的pod的指标数据。这个数据收集完以后也只在节点级别有效。因此我们需要一个集中统一来收集并存储的工具。

  2、那么HeapSter是一套什么样的架构呢?首先在每个节点上我们运行了一个工具叫kubelet,这是作为集群的代理插件的一个非常重要的组件,kubelet其实是能够获取当前系统上由他所负责创建和管理的各种资源对象,尤其是Pod的相关信息数据,但是真正完整去采集节点级和pod的数据是kubelet中的有一个子组件也是kubelet的一个插件叫cAdvisor,早些时候cAdvisor是一个单独的组件,较新的版本中其已经是kubelet内建的一个功能了,即装上Kubelet就有了。他是专门负责收集当前节点上各pod上的各容器以及当前节点在节点级的各种系统级资源指标的占用量,比如节点级和pod级的cpu,内存和存储用量等信息。他可以去收集这些信息,收集完了后你可以在单节点查看,早些时候的版本是支持的,现在已经不支持了。因此kubelet中没有打开这个功能,默认情况下我们把kubelet的cAdvisor这个功能打开以后他会监听在默认叫做4194端口上。现在我们为了安全起见已经自动把这个功能给关掉了。他不需要用户主动连接他去采集数据,而是主动报告给 。我们的HeapSter是专门为我们的k8s集群上去收集由cAdvisor在每一个节点上采集的数据为统一的存储位的这么一个工具。所以我们在集群上托管运行一个pod,这个pod就叫HeapSter,而后各cAdvisor就能够向这个pod去主动发送报告其所采集到的数据。所以其是一个统一的各种指标数据的收集工具。收集完成后他可以缓存在内存中,但内存是有限的,所以他只能缓存一段时间的数据用于让我们的kubectl top查看。我想看历史上昨天,前天,以及趋势数据是怎么样的,发报告给HeapSter是没法做这个功能的,能做一段时间历史数据的缓存。因为他使用缓存系统来存储的。如果我们想要长期存储得靠另一个组件叫做influxDB,他是由HeapSter调用的外部的一个持续数据库存储系统。我们HeapSter采集了数据以后可以整合存储到其中。这样就能达到持久存储的目的。这样我们就能查看历史中的资源使用情况,不过我们需要借助于另外一个工具来查看,一个非常漂亮的图形界面的提供者Grafana。他可以将influxDB作为数据源。这样我们就能愉快的展示influxDB中曾经采集到的每一个pod甚至是每一个节点的相关数据的统计结果了。

    

  3、一般而言pod的资源监控的大体行为可分为三类指标。

    a、kubernetes系统指标

    b、容器指标:指容器的cpu,内存,存储等资源利用状况

    c、应用指标:即我们业务指标中的应用程序中的自身的一些指标数据。接收了多少用户请求,内部有多少个子进程大概在处理什么请求。

  4、对k8s来讲,有几个核心的组件。有一个叫kube-dns默认就已经被装上去了。还有就是dashboard,现在就是另一个HeapSter。要想安装部署HeapSter就需要安装上面所述的三个组件:HeapSter,InfluxDB,Grafana。而这三个组件要想能够在系统级和整个集群级收集各名称空间中的pod资源的指标数据在RBAC强制已经启用的条件下他们还要定义RBAC的各种基于角色资源控制所需要依赖的资源授权才行。所以我们还应该使用他的rbac的一些资源特性。

三、部署HeapSter

  1、部署InfluxDB。他是一个持续数据库系统,我们这儿直接部署并使用其功能即可,更何况我们有了k8s编排工具以后他所有的设置做好自动识别以后使用他的配置清单文件应用就可以直接生效了。但是要注意的是HeapSter和InfluxDB是有依赖关系的,InfluxDB将被HeapSter所依赖,因此HeapSter去访问InfluxDB他的访问端点是什么呢?正常情况下我们InfluxDB应该是一个服务器上运行的进程,访问时应该是InfluxDB监听了一个地址的一个端口。因此我们HeapSter应该通过这个地址的这个端口来访问他。现在我们如果把他们都托管到我们k8s集群上我们InfluxDB作为一个pod来讲:第一他的数据需不需要持久存储?如果需要持久存储我们需要给其提供一个有存储能力的存储卷。无论是nfs,glusterfs等等,不过默认情况下这个存储卷功能默认情况下并没有配置。所以你自己在生产环境中使用时并不能拿那个在线清单直接用,而是应该把清单下下来根据自己的存储卷的使用状态给其编辑修改好以后再运用。第二,如果InfluxDB如果自身down了会怎么样?他down了可能会被其控制器重建,重建以后IP肯定就变了,因此HeapSter访问他时不能直接使用其IP进行访问。而应该用service,并且也可以用servicename去访问。因此coredns还是被依赖。

    a、部署链接为https://github.com/kubernetes-retired/heapster/blob/master/deploy/kube-config/influxdb/influxdb.yaml,我们先看看他的内容

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: monitoring-influxdb
namespace: kube-system
spec:
replicas:
template:
metadata:
labels:
task: monitoring
k8s-app: influxdb
spec:
containers:
- name: influxdb
image: k8s.gcr.io/heapster-influxdb-amd64:v1.5.2
volumeMounts:
- mountPath: /data
name: influxdb-storage
volumes:
- name: influxdb-storage
emptyDir: {} #意味着这个pod删除后就废了,所以建议生产环境中要改为真正意义的具有持久存储功能的存储卷
---
apiVersion: v1
kind: Service
metadata:
labels:
task: monitoring
# For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
# If you are NOT using this as an addon, you should comment out this line.
kubernetes.io/cluster-service: 'true'
kubernetes.io/name: monitoring-influxdb
name: monitoring-influxdb
namespace: kube-system
spec:
ports:
- port:
targetPort:
selector:
k8s-app: influxdb

    b、当influxdb定义完以后他的service名称叫monitoring-influxdb,并且他被部署在kube-system名称空间,上面也是。然后监听在8086端口。所以我们前面的HeapSter访问他时应该使用monitoring-influxdb再加上namespace再加上svc.cluster.local这样的后缀来访问,当然也可以使用相对名称。此处我们部署时需要修改我们apiVersion

[root@k8smaster metrics]# cat influxdb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: monitoring-influxdb
namespace: kube-system
spec:
replicas:
selector:
matchLabels:
task: monitoring
k8s-app: influxdb
template:
metadata:
labels:
task: monitoring
k8s-app: influxdb
spec:
containers:
- name: influxdb
image: k8s.gcr.io/heapster-influxdb-amd64:v1.5.2
volumeMounts:
- mountPath: /data
name: influxdb-storage
volumes:
- name: influxdb-storage
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
labels:
task: monitoring
# For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
# If you are NOT using this as an addon, you should comment out this line.
kubernetes.io/cluster-service: 'true'
kubernetes.io/name: monitoring-influxdb
name: monitoring-influxdb
namespace: kube-system
spec:
ports:
- port:
targetPort:
selector:
k8s-app: influxdb
[root@k8smaster metrics]# kubectl apply -f influxdb.yaml
deployment.apps/monitoring-influxdb unchanged
service/monitoring-influxdb unchanged

    c、此时我们可以看到相应的svc和pod以及pod的很多初始化信息

[root@k8smaster metrics]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> /UDP,/TCP 110d
kubernetes-dashboard NodePort 10.109.237.216 <none> :/TCP 19d
monitoring-influxdb ClusterIP 10.102.40.103 <none> /TCP 1d
[root@k8smaster metrics]# kubectl get pods -n kube-system |grep influxdb
monitoring-influxdb-848b9b66f6-tjvz4 / Running 1d
[root@k8smaster metrics]# kubectl logs monitoring-influxdb-848b9b66f6-tjvz4 -n kube-system
ts=--26T02::.400423Z lvl=info msg="InfluxDB starting" log_id=0HUw2ih0000 version=unknown branch=unknown commit=unknown
ts=--26T02::.400448Z lvl=info msg="Go runtime" log_id=0HUw2ih0000 version=go1.10.3 maxprocs=
ts=--26T02::.576298Z lvl=info msg="Using data dir" log_id=0HUw2ih0000 service=store path=/data/data
ts=--26T02::.576409Z lvl=info msg="Open store (start)" log_id=0HUw2ih0000 service=store trace_id=0HUw2jO0000 op_name=tsdb_open op_event=start
ts=--26T02::.576439Z lvl=info msg="Open store (end)" log_id=0HUw2ih0000 service=store trace_id=0HUw2jO0000 op_name=tsdb_open op_event=end op_elapsed=.032ms
ts=--26T02::.576457Z lvl=info msg="Opened service" log_id=0HUw2ih0000 service=subscriber
ts=--26T02::.576461Z lvl=info msg="Starting monitor service" log_id=0HUw2ih0000 service=monitor
ts=--26T02::.576464Z lvl=info msg="Registered diagnostics client" log_id=0HUw2ih0000 service=monitor name=build
ts=--26T02::.576467Z lvl=info msg="Registered diagnostics client" log_id=0HUw2ih0000 service=monitor name=runtime
...

  2、部署HeapSter

    a、部署时需要依赖于rbac的设定。对应yaml连接为https://raw.githubusercontent.com/kubernetes-retired/heapster/master/deploy/kube-config/rbac/heapster-rbac.yaml

[root@k8smaster metrics]# cat heapster-rbac.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: heapster
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:heapster
subjects:
- kind: ServiceAccount
name: heapster
namespace: kube-system
[root@k8smaster metrics]# kubectl apply -f heapster-rbac.yaml
clusterrolebinding.rbac.authorization.k8s.io/heapster created

    b、部署HeapSter,对应yaml链接为https://raw.githubusercontent.com/kubernetes-retired/heapster/master/deploy/kube-config/influxdb/heapster.yaml。下载后做些许修改即可

[root@k8smaster metrics]# cat heapster.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: heapster
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: heapster
namespace: kube-system
spec:
replicas:
selector:
matchLabels:
task: monitoring
k8s-app: heapster
template:
metadata:
labels:
task: monitoring
k8s-app: heapster
spec:
serviceAccountName: heapster
containers:
- name: heapster
image: k8s.gcr.io/heapster-amd64:v1.5.4
imagePullPolicy: IfNotPresent
command:
- /heapster
- --source=kubernetes:https://kubernetes.default
- --sink=influxdb:http://monitoring-influxdb.kube-system.svc:8086
---
apiVersion: v1
kind: Service
metadata:
labels:
task: monitoring
# For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
# If you are NOT using this as an addon, you should comment out this line.
kubernetes.io/cluster-service: 'true'
kubernetes.io/name: Heapster
name: heapster
namespace: kube-system
spec:
ports:
- port:
targetPort:
type: NodePort
selector:
k8s-app: heapster
[root@k8smaster metrics]# kubectl apply -f heapster.yaml
serviceaccount/heapster created
deployment.apps/heapster created
service/heapster created
[root@k8smaster metrics]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> /TCP 110d
[root@k8smaster metrics]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
heapster NodePort 10.100.27.100 <none> :/TCP 20s
kube-dns ClusterIP 10.96.0.10 <none> /UDP,/TCP 110d
kubernetes-dashboard NodePort 10.109.237.216 <none> :/TCP 19d
monitoring-influxdb ClusterIP 10.102.40.103 <none> /TCP 1d
[root@k8smaster metrics]# kubectl get pod -n kube-system|grep heap
heapster-84c9bc48c4-pfgn7 / Running 49s

  3、接下来我们部署grafana

    a、对应的链接为https://raw.githubusercontent.com/kubernetes-retired/heapster/master/deploy/kube-config/influxdb/grafana.yaml下载后修改部分内容即可使用

[root@k8smaster metrics]# cat grafana.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: monitoring-grafana
namespace: kube-system
spec:
replicas:
selector:
matchLabels:
task: monitoring
k8s-app: grafana
template:
metadata:
labels:
task: monitoring
k8s-app: grafana
spec:
containers:
- name: grafana
image: k8s.gcr.io/heapster-grafana-amd64:v5.0.4
ports:
- containerPort:
protocol: TCP
volumeMounts:
- mountPath: /etc/ssl/certs
name: ca-certificates
readOnly: true
- mountPath: /var
name: grafana-storage
env:
- name: INFLUXDB_HOST
value: monitoring-influxdb
- name: GF_SERVER_HTTP_PORT
value: ""
# The following env variables are required to make Grafana accessible via
# the kubernetes api-server proxy. On production clusters, we recommend
# removing these env variables, setup auth for grafana, and expose the grafana
# service using a LoadBalancer or a public IP.
- name: GF_AUTH_BASIC_ENABLED
value: "false"
- name: GF_AUTH_ANONYMOUS_ENABLED
value: "true"
- name: GF_AUTH_ANONYMOUS_ORG_ROLE
value: Admin
- name: GF_SERVER_ROOT_URL
# If you're only using the API Server proxy, set this value instead:
# value: /api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
value: /
volumes:
- name: ca-certificates
hostPath:
path: /etc/ssl/certs
- name: grafana-storage
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
labels:
# For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
# If you are NOT using this as an addon, you should comment out this line.
kubernetes.io/cluster-service: 'true'
kubernetes.io/name: monitoring-grafana
name: monitoring-grafana
namespace: kube-system
spec:
# In a production setup, we recommend accessing Grafana through an external Loadbalancer
# or through a public IP.
# type: LoadBalancer
# You could also use NodePort to expose the service at a randomly-generated port
# type: NodePort
ports:
- port:
targetPort:
selector:
k8s-app: grafana
type: NodePort
[root@k8smaster metrics]# kubectl apply -f grafana.yaml
deployment.apps/monitoring-grafana created
service/monitoring-grafana created
[root@k8smaster metrics]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
heapster NodePort 10.100.27.100 <none> :/TCP 12m
kube-dns ClusterIP 10.96.0.10 <none> /UDP,/TCP 110d
kubernetes-dashboard NodePort 10.109.237.216 <none> :/TCP 19d
monitoring-grafana NodePort 10.98.72.62 <none> :/TCP 20s
monitoring-influxdb ClusterIP 10.102.40.103 <none> /TCP 1d
[root@k8smaster metrics]# kubectl get pods -n kube-system |grep gran
[root@k8smaster metrics]# kubectl get pods -n kube-system |grep gra
monitoring-grafana-555545f477-g7hdd / Running 2m

    b、访问192.168.10.10:30070即可

  4、接下来运行我们的kubectl top命令,此时我们可以发现还是不能使用这个命令,显示获取不到各节点的10255下的容器信息

[root@k8smaster metrics]# kubectl logs heapster-84c9bc48c4-pfgn7 -n kube-system
I0827 ::30.880667 heapster.go:] /heapster --source=kubernetes:https://kubernetes.default --sink=influxdb:http://monitoring-influxdb.kube-system.svc:8086
I0827 ::30.880741 heapster.go:] Heapster version v1.5.4
I0827 ::30.881054 configs.go:] Using Kubernetes client with master "https://kubernetes.default" and version v1
I0827 ::30.881092 configs.go:] Using kubelet port
I0827 ::31.003814 influxdb.go:] created influxdb sink with options: host:monitoring-influxdb.kube-system.svc: user:root db:k8s
I0827 ::31.003943 heapster.go:] Starting with InfluxDB Sink
I0827 ::31.003952 heapster.go:] Starting with Metric Sink
I0827 ::31.036488 heapster.go:] Starting heapster on port
E0827 ::05.007881 manager.go:] Error in scraping containers from kubelet:192.168.10.12:: failed to get all container stats from Kubelet URL "http://192.168.10.12:10255/s
tats/container/": Post http://192.168.10.12:10255/stats/container/: dial tcp 192.168.10.12:10255: getsockopt: connection refusedE0827 06:12:05.011822 1 manager.go:101] Error in scraping containers from kubelet:192.168.10.11:10255: failed to get all container stats from Kubelet URL "http://192.168.10.11:10255/s
tats/container/": Post http://192.168.10.11:10255/stats/container/: dial tcp 192.168.10.11:10255: getsockopt: connection refusedE0827 06:12:05.012647 1 manager.go:101] Error in scraping containers from kubelet:192.168.10.10:10255: failed to get all container stats from Kubelet URL "http://192.168.10.10:10255/s
tats/container/": Post http://192.168.10.10:10255/stats/container/: dial tcp 192.168.10.10:10255: getsockopt: connection refused

  5、kubernetes的HeapSter从1.11 版本开始就已经开始废弃了,从1.12版本就直接彻底废除了。妈的,部署半天就这样翻车了。

    

Kubernetes 学习22 kubernetes容器资源需求资源限制及HeapSter(翻车章节)的更多相关文章

  1. kubernetes学习笔记之十二:资源指标API及自定义指标API

    第一章.前言 以前是用heapster来收集资源指标才能看,现在heapster要废弃了从1.8以后引入了资源api指标监视 资源指标:metrics-server(核心指标) 自定义指标:prome ...

  2. kubernetes学习01—kubernetes介绍

    本文收录在容器技术学习系列文章总目录 一.简介 1.Kubernetes代码托管在GitHub上:https://github.com/kubernetes/kubernetes/. 2.Kubern ...

  3. Kubernetes 学习13 kubernetes pv pvc configmap 和secret

    一.概述 1.我们在pvc申请的时候未必就有现成的pv能正好符合这个pvc在申请中指定的条件,毕竟上一次的成功是我们有意设定了有一些满足有一些不满足的前提下我们成功创建了一个pvc并且被pod绑定所使 ...

  4. Kubernetes 学习15 kubernetes 认证及serviceaccount

    一.概述 1.通过此前描述可以知道k8s是以后运行我们生产环境中重要应用程序的尤其是无状态程序的一个非常重要的平台.这里面能托管一些核心应用以及核心数据,很显然对于k8s对应接口的访问不是任何人都可以 ...

  5. Kubernetes 学习23 kubernetes资源指标API及自定义指标API

    一.概述 1.上集中我们说到,官方文档提示说从k8s 1.11版本开始,将监控体系指标数据获取机制移向新一代的监控模型.也就意味着对于我们的k8s来讲现在应该有这样两种资源指标被使用.一种是资源指标, ...

  6. Kubernetes 学习5 kubernetes资源清单定义入门

    一.kubernetes是有一个restful风格的 API,把各种操作对象都一律当做资源来管理.并且可通过标准的HTTP请求的方法 GET,PUT,DELETE,POST,等方法来完成操作,不过是通 ...

  7. Kubernetes学习之pause容器

    根据代码看到,pause容器运行着一个非常简单的进程,它不执行任何功能,一启动就永远把自己阻塞住了, 它的作用就是扮演PID1的角色,并在子进程称为"孤儿进程"的时候,通过调用wa ...

  8. 深入剖析Kubernetes学习笔记:容器基础(05-06)

    05 :从进程说起 1.容器本身没有价值,有价值的是"容器编排" 2.什么是进程? 一旦"程序"被执行起来,它就从磁盘上的二进制文件,变成 1.计算机内存中的数 ...

  9. Kubernetes 学习11 kubernetes ingress及ingress controller

    一.上集回顾 1.Service 3种模型:userspace,iptables,ipvs 2.Service类型 ClusterIP,NodePort NodePort:client -> N ...

随机推荐

  1. Python3实现一个简单的tcp客户端,用于测试服务端端口开放情况

    需要Python的socket模块儿,windows使用netstat -an查看端口状态,Linux使用netstat -tunlp查看端口状态. # client 客户端 # TCP必须建立连接 ...

  2. 【LEETCODE】38、167题,Two Sum II - Input array is sorted

    package y2019.Algorithm.array; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.array * ...

  3. GC收集器

    新生代收集器 Serial New 单线程收集器,工作时必须暂停其他线程: 简单高效,没有线程交互开销: 基于复制算法: Parallel New 对Serial的改进,多线程: CPU数量<4 ...

  4. 少儿编程|Scratch编程教程系列合集,总有一款适合你

    如果觉得资源不错,友情转发,贵在分享!!! 少儿编程Scratch: 少儿编程Scratch第一讲:Scratch完美的初体验少儿编程Scratch第二讲:奇妙的接球小游戏少儿编程Scratch第三讲 ...

  5. jwt 0.9.0(二)jwt官网资料总结

    1.JWT描述 Jwt token由Header.Payload.Signature三部分组成,这三部分之间以小数点”.”连接,JWT token长这样: eyJhbGciOiJIUzI1NiIsIn ...

  6. 【SQL Server数据迁移】64位的机器:SQL Server中查询ORACLE的数据

    从SQL Server中查询ORACLE中的数据,可以在SQL Server中创建到ORACLE的链接服务器来实现的,但是根据32位 .64位的机器和软件, 需要用不同的驱动程序来实现. 在64位的机 ...

  7. idea 中激活 JRebel

    JRebel介绍: JRebel是一款JVM插件,它使得Java代码修改后不用重启系统,立即生效.IDEA上原生是不支持热部署的,一般更新了 Java 文件后要手动重启 Tomcat 服务器,修改才能 ...

  8. Mysql之锁的基本介绍

    数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则.对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外.MySQL数据 ...

  9. sql 作业创建

    转载:https://jingyan.baidu.com/article/adc81513be3423f722bf7351.html

  10. 10 查询字符串,X字段必须包含(不包含)XX;_all原理

    指定某个字段,必须要包含XX字符 GET /beauties/my/_search?q=Name:Chang Wei   搜出 某个字段不包含XX字符 的所有内容 GET /beauties/my/_ ...