https://github.com/kubernetes-sigs/metrics-server
k8s: 1.16
metrics-server 在现在的k8s版本里已经不是用来提供监控数据了,具体是从哪个版本开始就不清楚了。
现在主要用于HPA弹性伸缩,以及kubectl top的数据。
metrics-server属于扩展api的方式提供服务,就是给k8s的api接口加一个api, 只要访问这个api的请求都会被k8s转发给扩展api。
请求大致流程:
具体的内容需要了解官方文档:
https://kubernetes.io/docs/tasks/access-kubernetes-api/configure-aggregation-layer/
总体来说: 因为metrics-server访问apiserver的权限都通过serviceaccount完成了,所以只要做metrics-server验证apiserver发送过来的请求就可以。
一、安装
在k8s的二进制安装包里有包含安装各种部件的yaml文件。这里先把包里给的基础yaml文件执行了。
auth-delegator.yaml, auth-reader.yaml, resource-reader.yaml 都是给metrics-server的授权文件,这里先执行了。
[root@k8s-master1 metrics-server]# kubectl apply -f auth-delegator.yaml,auth-reader.yaml,resource-reader.yaml
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
[root@k8s-master1 metrics-server]#
metrics-apiservice.yaml 是用来创建扩展的api的。 里面有访问的api路径以及转发到那个service。
metrics-server-service.yaml 就是service文件,也一起执行了。
[root@k8s-master1 metrics-server]# kubectl apply -f metrics-apiservice.yaml,metrics-server-service.yaml
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
service/metrics-server created
[root@k8s-master1 metrics-server]#
metrics-server-deployment.yaml
这个文件里的镜像连得是海外的,可能不能下载,需要改一下。
实在没有地方下载也可以使用阿里云的容器镜像服务,里面有用户下载传上去的, 不过安全性无法保证,有一些可能是用户根据dockerfile自己构建的。 我这里使用自己传到阿里的这个, 是从google云下载并push到这里的,保证原装。
registry.cn-beijing.aliyuncs.com/yangxingxing/metrics-server-amd64:v0.3.4
然后metrics-server的启动参数就这样启动也可以, 连接的是kubelet的http端口。
一些参数的介绍:
--kubelet-port=10250 # 请求kubelet的10250端口。
--kubelet-insecure-tls # 不认证kubelet https端口的ssl证书。
--deprecated-kubelet-completely-insecure=true #不使用https连接kubelet, 使用http连接,metrics-server本身不推荐。
--kubelet-certificate-authority #指定用来验证kubelet证书的ca证书。kubelet的https端口的证书认证,默认情况下kubelet是自签的证书,这种情况没有CA证书。
--kubelet-preferred-address-types #连接kubelet的几种方式。一般用InternalIP,因为pod里面解析不了kubelet的主机名,用ip连接比较好。
# 这里的证书无所谓, apiserver不会认证, 因为metrics-server使用serveraccount认证了。就是metrics-server https端口的证书。
--tls-cert-file # metrics-server自身的ssl证书, 如果不指定, 会自签。
--tls-private-key
--kubelet-preferred-address-types
表示连接kubelet的方式,如:
InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
例子:
可以连接kubelet的10250端口,是https的端口,然后加上--kubelet-insecure-tls参数。
containers:
- name: metrics-server
image: registry.cn-beijing.aliyuncs.com/yangxingxing/metrics-server-amd64:v0.3.4
command:
- /metrics-server
- --metric-resolution=30s
# These are needed for GKE, which doesn't support secure communication yet.
# Remove these lines for non-GKE clusters, and when GKE supports token-based auth.
- --kubelet-port=10250
- --kubelet-insecure-tls
# - --deprecated-kubelet-completely-insecure=true
- --kubelet-preferred-address-types=InternalIP
ports:
- containerPort: 443
name: https
protocol: TCP
然后文件下面的metrics-server-nanny部分,image也可以使用这个做测试:
registry.cn-beijing.aliyuncs.com/yangxingxing/addon-resizer:1.8.5
addon-resizer 是用来垂直扩展另外一个容器的,也就是metrics-server, 会在metrics-server启动以后根据k8s集群中的节点数量,动态的修改metrics-server的资源限制。
而addon-resizer容器本身的资源限制就看情况了。
mountPath: /etc/config
command:
- /pod_nanny
- --config-dir=/etc/config
- --cpu=100m
- --extra-cpu=0.5m
- --memory=200Mi
- --extra-memory=2Mi
- --threshold=5
- --deployment=metrics-server-v0.3.4
- --container=metrics-server
- --poll-period=300000
- --estimator=exponential
# Specifies the smallest cluster (defined in number of nodes)
# resources will be scaled to.
- --minClusterSize=5
volumes:
二、apiserver的设置。
--requestheader-client-ca-file
--requestheader-allowed-names
--proxy-client-cert-file
--proxy-client-key-file
--requestheader-extra-headers-prefix
--requestheader-group-headers
--requestheader-username-headers
apiserver启动的时候需要添加上面的几个参数。
1、requestheader-client-ca-file
这个参数是用来认证来源客户端的证书的,与--client-ca-file不同的是,requestheader-client-ca-file认证通过以后还需要匹配--requestheader-allowed-names参数指定的证书common name名称,可以指定多个。
要注意requestheader-client-ca-file与--client-ca-file的区别,而且ca不要使用相同的一个,不然会出问题。因为他们的认证方式是这个样子的:
(--requestheader-client-ca-file and --requestheader-allowed-names) or --client-ca-file
如果使用相同的ca, 会导致--requestheader-client-ca-file认证通过, 然后就会去判断--requestheader-allowed-names,如果没有通过,认证就失败了。
一般情况下, --requestheader-client-ca-file与--requestheader-allowed-names用来认证扩展的api服务,就是创建kind: APIService的服务,如 metrics-server就是这样的。
--client-ca-file 是认证一般用户的。
为什么要这样就跟k8s对扩展api的认证以及扩展api对k8s的认证有关系了,跟kube-system下的一个叫做extension-apiserver-authentication的configmap有关系,requestheader-client-ca-file和上面的一堆参数都会写到这个configmap里。
2、requestheader-allowed-names
与--requestheader-client-ca-file是一对。可以用 空 表示接受所有的cn名称, --requestheader-allowed-names="", 这里的名称要包含proxy-client-cert-file证书的common name, 用于扩展api验证apiserver发来的请求。
3、proxy-client-cert-file, proxy-client-key-file
apiserver连接扩展api服务的时候使用的证书。
4、requestheader-extra-headers-prefix,requestheader-group-headers,requestheader-username-headers
帮助里建议指定这些值, 存放用户名与组名还有额外信息的http头部。
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
apiserver会在收到客户端请求以后,获取相关数据, 在请求扩展api的时候在http的head里添加这些信息。
X-Remote-User: <username>
X-Remote-Group: <group>
X-Remote-Extra-Scopes: <prefix>
上面的username, group, prefix会根据请求的客户端信息, 添加以后发给扩展api。
扩展api从configmap里获取到使用的http头部, 从头部信息里获取用户信息,从而对请求数据里的用户做匹配。
5、授权相关
上面几个参数的信息也会写到kube-system命名空间的extension-apiserver-authentication configmap里。
[root@k8s-master1 metrics-server]# kubectl get configmap/extension-apiserver-authentication -n kube-system -o yaml
apiVersion: v1
data:
client-ca-file: |
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----
requestheader-allowed-names: '["metrics-server","mytest","extr.kubernetes"]'
requestheader-client-ca-file: |
-----BEGIN CERTIFICATE-----
MIIF5TCCA82gAwIBAgIJAMz1NYcFkpXPMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD
VQQGEwJDTjELMAkGA1UECAwCQkoxCzAJBgNVBAcMAkJKMRgwFgYDVQQKDA9leHRy
YS5xZnBheS5uZXQxCzAJBgNVBAsMAm9wMRswGQYDVQQDDBJjYS5leHRyYS5xZnBh
eS5uZXQxGzAZBgkqhkiG9w0BCQEWDG9wQHFmcGF5LmNvbTAeFw0xOTExMTEwMzQ0
MjlaFw0yOTExMDgwMzQ0MjlaMIGIMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkox
CzAJBgNVBAcMAkJKMRgwFgYDVQQKDA9leHRyYS5xZnBheS5uZXQxCzAJBgNVBAsM
Am9wMRswGQYDVQQDDBJjYS5leHRyYS5xZnBheS5uZXQxGzAZBgkqhkiG9w0BCQEW
DG9wQHFmcGF5LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJ8g
seMxZY3O1/aVWADMgOkh3VWkTtdY4BYhxkL5+AKRdJEvKOLY6pLBJILMHGt394gV
BpF8IzRBfYwzUzIzT6ZGhDPisOwf6NbyiXyK/2LdOedHIYSAbLt53Xm66mlwFfRl
oGcTeHVSTIJ+yVFFrz7PEpBa0a7lcObbAvnVeNDmIMjq8Vou/M/1XTTZF2Vn6jiP
VkqhUYbNJTloOMUJ1eW2c9wGw0mbR+MRzJiTNicZUOKE660xpeDv84qhO1Bf5+bF
oajpy1fLokSBY0YAYJy0W2CKlapqvwhgsQL2kOTtgZnX6cEWOHaLPPu7GhEgZxVB
m7hi8y5xIJsgsDqEON7fgx72IfGVUpgHpgkLfXmdBdGwaltCH/qk4T24l9yG/Z01
dmgqGpZEE37GsPEB/aOfYIBbSoowsWocvKym2R5YiTZ4vnLvWLMM9sz9ADy70oWa
t13edw34DP3IjQH27W0cePcvc9HJiOpDzJOWb+WYPeDASTaaynLAD7bTNDdmulIE
aW48ZeX9+fLpl0njmthmrQRxIK4LYJAuAlrA/1J2V2kQeQdJVENVfhh04u2jkAuN
GesMAbYDeutHGX2KnzXzit/pXls7/2FQFXbVnpz7OSdyBTnejq4VTBEG9ZsSQUim
tQa30u5BBYJX1qT6AGZzSim9jirfrFoKXhasXDrLAgMBAAGjUDBOMB0GA1UdDgQW
BBTAVb41JTWILhMEcOp8VXaBuBlOzjAfBgNVHSMEGDAWgBTAVb41JTWILhMEcOp8
VXaBuBlOzjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCbrgkLIkGa
Ztw+9YaNapEFsG8GhFl9ujbBKKeeDluiuLBo9EYkPqKqyjecoFBb/xYxPwLNyaFF
fHC/ZDGFIzUsAPUyZdagkCrchUJmJe1qCl4yAOSDwumcsC49KcxRI7hKyHIDPaGR
kSUDFyEFmiBjyd6rIxp++gHDv/kt/HFieR286EL9mTUDjfQHi5RYkCCCz2Tlz3iy
CIYWM5MxGB6MuzKc8CiBs/fO5whwaY1vIOVeyipb3J6rJFYKBh9yMEKFZEugKefG
+cmdd/Llijw+vMnPUHZSuRxO8F8tHEsoPUi0SFV9vLpaPCRn+0+g8IWaljQlat5B
jUexMSatLuvaOPv3jj5txjsNhtCVS3SuAghxBZ6z6t1mOzEzRAvbS8pnrbERuQxd
5StyXEgtjxFFpS2K+8gsHzkZINXdIKfo5BrjpMCoEYzUBuk4HANJJnYZuvwpzHW4
6HRJUTUwnkMNaBFWWJpECUiJKpxU+m7bv/XMbKClWrc+iMUM9T9SG/yA9VpmD9Vx
7aIgqLvFhE1roXENo2K8rpVA6nCR6yJZeczdfEtQALhNWWK1fdfCu7M/8xKQiNUZ
oHWW2HLepdxqwn9MWLmIuLyVzkGM5GSCI9Q6HVca6M/8Tsp2h3xPMbWr6erjusT/
Kg8n72kuaOa61PTCKn6+jrKYLvIVdj3x+w==
-----END CERTIFICATE-----
requestheader-extra-headers-prefix: '["X-Remote-Extra-"]'
requestheader-group-headers: '["X-Remote-Group"]'
requestheader-username-headers: '["X-Remote-User"]'
kind: ConfigMap
metadata:
creationTimestamp: "2019-11-05T04:10:47Z"
name: extension-apiserver-authentication
namespace: kube-system
resourceVersion: "1629916"
selfLink: /api/v1/namespaces/kube-system/configmaps/extension-apiserver-authentication
uid: ce4fe2e8-8a9d-4c5e-a366-14ea0a57bd0e
[root@k8s-master1 metrics-server]#
第一个ca证书是client-ca-file参数带来的,不用管它。主要是下面的那一系列。
metrics-server启动以后会去获取这个configmap, 得到这些数据。
后面apiserver请求metrics-server的时候,metrics-server就会对来访问的证书用里面的CA证书做验证,然后就是requestheader-allowed-names里面有没有对应的名称,然后对apiserver的认证就完毕了。
在之后的requestheader-username-headers所传递的http头部信息,可能是因为请求里面还包含客户端的信息, 然后metrics-server与http头作对比,这样metrics-server就知道了这个请求是经过apiserver认证过得,可以执行。
requestheader-allowed-names: '["metrics-server","mytest","extr.kubernetes"]'
这个里面这么多是测试的时候加的,一会就去掉了。里面只有proxy-client-cert-file证书指定的那个common name有效。
6、
在metrics-server这里,requestheader-client-ca-file, requestheader-allowed-names用来验证客户端的功能其实都没有用到,只是为了放到configmap里,让metrics-server获取到。 metrics-server也是因为跑在pod里了,一些权限都通过serviceaccount实现了。
三、最后
apiserver节点需要可以访问metrics-server的services, 所以需要安装kube-proxy以及网络组件(如:flannel),而kube-proxy要正常运行就需要节点在集群里kubectl get node可以看到, 所以还要安装kubelet。
来一下apiserver的参数吧:
/usr/local/k8s/bin/kube-apiserver \
--logtostderr=false \
--log-dir=/usr/local/k8s/logs \
--v=4 \
--etcd-servers=https://172.100.101.190:2379,https://172.100.101.192:2379,https://172.100.102.140:2379 \
--etcd-cafile=/usr/local/k8s/ssl/cacert.pem \
--etcd-certfile=/usr/local/k8s/ssl/kube-apiserver.crt \
--etcd-keyfile=/usr/local/k8s/ssl/kube-apiserver.key \
--bind-address=172.100.101.190 \
--advertise-address=172.100.101.190 \
--secure-port=6443 \
--tls-cert-file=/usr/local/k8s/ssl/kube-apiserver.crt \
--tls-private-key-file=/usr/local/k8s/ssl/kube-apiserver.key \
--enable-bootstrap-token-auth \
--authorization-mode=RBAC,Node \
--client-ca-file=/usr/local/k8s/ssl/cacert.pem \
--service-cluster-ip-range=10.0.0.0/16 \
--service-node-port-range=20000-50000 \
--allow-privileged \
--kubelet-https \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
--service-account-key-file=/usr/local/k8s/ssl/cakey.pem \
##
--requestheader-client-ca-file=/usr/local/k8s/ssl/extr.kubernetes/cacert.pem \
--requestheader-allowed-names=extr.kubernetes \
--proxy-client-cert-file=/usr/local/k8s/ssl/extr.kubernetes/extr.kubernetes.crt \
--proxy-client-key-file=/usr/local/k8s/ssl/extr.kubernetes/extr.kubernetes.key \
--requestheader-extra-headers-prefix=X-Remote-Extra- \
--requestheader-group-headers=X-Remote-Group \
--requestheader-username-headers=X-Remote-User
过程中要实时查看metrics-server的日志,以及apiserver的日志。
[root@k8s-master1 conf]# kubectl top node k8s-node1
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-node1 216m 10% 1994Mi 51%
[root@k8s-master1 conf]# kubectl top node k8s-node2
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-node2 195m 9% 1954Mi 50%
可以使用top查看状态就完事了。注意在多apiserver的环境里,如果只设置了一台,会出现一会能用一会不能用的情况。
认证的参数
Kubernetes apiserver:对发出请求的用户身份认证,并对请求的 API 路径执行鉴权。
Kubernetes apiserver:将请求转发到扩展 apiserver
扩展 apiserver:认证来自 Kubernetes apiserver 的请求
扩展 apiserver:对来自原始用户的请求鉴权
扩展 apiserver:执行
--proxy-client-cert-file
--proxy-client-key-file
apiserver
访问扩展api
时提供的证书。
--requestheader-client-ca-file
--requestheader-allowed-names
认证客户端证书的CA与名称限制。
在扩展API这里, 扩展API
通过请求apiserver
,获取configmap
:extension-apiserver-authentication
里的CA, 来认证apiserver
发过来的证书。
原本以为不加这两个参数也可以, --client-ca也可以认证。
但是发现不加的话,下面这三个参数不会写入configmap。
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
apiserver
在对客户端确认完身份以后, 把已经确认的用户名告诉扩展api
,通过http头部信息传递。
这三个参数就是配置http的头部名称。
扩展api通过请求apiserver, 获取configmap
:extension-apiserver-authentication
里存储的头部名称。从对应的http头部里获取用户名。
对apiserver
转发过来的请求用户做认证。
问题
error: metrics not available yet
root@k8smaster1:~# kubectl top node
error: metrics not available yet
root@k8smaster1:~#
-
如果metrics是刚起来的,可能还没有有采集够数据,等一会试试。
-
等一会还不行,并且访问的kubelet https端口, 可能是因为权限不够。
查看日志:
root@k8smaster1:~# kubectl logs -f pods/metrics-server-v0.3.6-75bf8bfc98-xcj7s -n kube-system -c metrics-server
unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:k8snode02: unable to fetch metrics from Kubelet k8snode02 (172.100.101.192): request failed - "403 Forbidden", response: "Forbidden (user=system:serviceaccount:kube-system:metrics-server, verb=get, resource=nodes, subresource=stats)
查看日志发现serviceaccount metrics-server没有get nodes/stats的权限。
kubelet的鉴权也就那么几种, stats是其中之一。
https://www.yxingxing.net/archives/kubelet-20201216-authentication
我这里kubelet使用的webhook认证以及鉴权,如果kubelet默认的匿名访问以及鉴权mode没有修改,应该也不会出现这个问题。
知道原因,解决办法就很简单了。单独创建clusterrole,或者给metrics-server现有的clusterrole添加权限。 这里是添加。
修改resource-reader.yaml
文件, 添加权限:
- apiGroups:
- ""
resources:
- nodes/stats
verbs:
- '*'
添加以后,完整的rules是这个样子:
rules:
- apiGroups:
- ""
resources:
- pods
- nodes
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- "apps"
resources:
- deployments
verbs:
- get
- list
- update
- watch
- nonResourceURLs:
- /metrics
verbs:
- get
- apiGroups:
- ""
resources:
- nodes/stats
verbs:
然后应用一下就可以了。