解决 Kubernetes 部署 Metrics Server 无法访问 Apiserver 问题

前言 系统环境: 部署方式:二进制Docker 版本:19.03.8kubernetes 版本:1.20.1操作系统版本:CentOS 7.8metrics server 版本:0.4.1 参考地址: 带你玩转 kubernetes-k8s 第 54 篇[1]二进...

前言

系统环境:

  • 部署方式:二进制
  • Docker 版本:19.03.8
  • kubernetes 版本:1.20.1
  • 操作系统版本:CentOS 7.8
  • metrics server 版本:0.4.1

参考地址:

  • 带你玩转 kubernetes-k8s 第 54 篇[1]
  • 二进制方式搭建 Kubernetes 1.19.3 高可用集群(五)部署 dashboard[2]

1. 问题描述

通过二进制方式部署完成 kubernetes 后,部署 Metrics Server 后,查看日志出现下面错误信息:


E1231 10:33:31.978715 1 configmap_cafile_content.go:243] key failed with:
missing content for CA bundle "client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file"
E1231 10:34:22.710836 1 configmap_cafile_content.go:243] kube-system/extension-apiserver-authentication failed with:
missing content for CA bundle "client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file"
E1231 10:34:31.978769 1 configmap_cafile_content.go:243] key failed with:
missing content for CA bundle "client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file"
根据错误日志信息,可以知道是缺少认证的证书文件,导致不能访问 kube-apiserver 而出现的问题。

2. 问题分析

查找资料分析原因

经过网上查找搜寻,从一篇博客中 https://www.lingjie.tech/article/2020-11-07/20 找到答案。之所以出现这个错误是因为 kube-apiserver 没有开启 API 聚合功能。所以需要配置 kube-apiserver 参数,开启聚合功能即可。

什么是 API 聚合

这里的 API 聚合机制 是 Kubernetes 1.7 版本引入的特性,能够将用户扩展的 API 注册到 kube-apiserver 上,仍然通过 API Server 的 HTTP URL 对新的 API 进行访问和操作。为了实现这个机制,Kubernetes 在 kube-apiserver 服务中引入了一个 API 聚合层(API Aggregation Layer),用于将 扩展 API 的访问请求转发到用户服务的功能。

为了能够将用户自定义的 API 注册到 Master 的 API Server 中,首先需要在 Master 节点所在服务器,配置 kube-apiserver 应用的启动参数来启用 API 聚合 功能,参数如下:

--runtime-config=api/all=true
--requestheader-allowed-names=aggregator
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-client-ca-file=/etc/kubernetes/pki/ca.pem
--proxy-client-cert-file=/etc/kubernetes/pki/proxy-client.pem
--proxy-client-key-file=/etc/kubernetes/pki/proxy-client-key.pem

如果 kube-apiserver 所在的主机上没有运行 kube-proxy,即无法通过服务的 ClusterIP 进行访问,那么还需要设置以下启动参数:

--enable-aggregator-routing=true

在设置完成重启 kube-apiserver 服务,就启用 API 聚合 功能了。

$ systemctl daemon-reload && systemctl restart kube-apiserver

3. 解决问题

按照上面的解决问题思路,我们可以开启 API 聚合功能,然后重启 Metrics Server 服务,步骤如下:

安装 cfssl 工具

## 下载三个组件
$ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O cfssl
$ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64  -O cfssljson
$ wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64  -O cfssl-certinfo

## 复制到 bin 目录下
$ chmod +x ./cfssl*
$ mv ./cfssl* /usr/local/bin/

创建 cfssl 配置文件

创建 proxy-client-csr.json 文件:

{
  "CN": "aggregator",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
生成证书和秘钥:
## Master1 执行下面命令生成证书
$ cfssl gencert \
  -profile=kubernetes \
  -ca=/etc/kubernetes/pki/ca.pem \
  -ca-key=/etc/kubernetes/pki/ca-key.pem \
  proxy-client-csr.json

查看生产的证书:

$ ls -l

-rw-r--r-- 1 root root 1017 1231 11:20 proxy-client.csr
-rw-r--r-- 1 root root  236 1231 11:07 proxy-client-csr.json
-rw------- 1 root root 1675 1231 11:20 proxy-client-key.pem
-rw-r--r-- 1 root root 1411 1231 11:20 proxy-client.pem

将证书访问指定的目录下,这里我将其放到 /etc/kubernetes/pki 下:

$ cp * /etc/kubernetes/pki/

复制到其它 Master 节点服务器中:

## 复制到 Master2
$ scp * 192.168.2.11:/etc/kubernetes/pki/
## 复制到 Master3
$ scp * 192.168.2.12:/etc/kubernetes/pki/

修改 kube-apiserver 参数

修改三个 Master 节点中全部 kube-apiserver 配置参数:

vi /etc/kubernetes/manifests/kube-apiserver.yaml
...
--runtime-config=api/all=true \
--requestheader-allowed-names=aggregator \
--requestheader-group-headers=X-Remote-Group \
--requestheader-username-headers=X-Remote-User \
--requestheader-extra-headers-prefix=X-Remote-Extra- \
--requestheader-client-ca-file=/etc/kubernetes/pki/ca.pem \
--proxy-client-cert-file=/etc/kubernetes/pki/proxy-client.pem \
--proxy-client-key-file=/etc/kubernetes/pki/proxy-client-key.pem \
...

参数说明:

  • –requestheader-client-ca-file: 客户端 CA 证书。
  • –requestheader-allowed-names: 允许访问的客户端 common names 列表,通过 header 中 –requestheader-username-headers 参数指定的字段获取。客户端 common names 的名称需要在 client-ca-file 中进行设置,将其设置为空值时,表示任意客户端都可访问。
  • –requestheader-username-headers: 参数指定的字段获取。
  • –requestheader-extra-headers-prefix: 请求头中需要检查的前缀名。
  • –requestheader-group-headers 请求头中需要检查的组名。
  • –requestheader-username-headers 请求头中需要检查的用户名。
  • –proxy-client-cert-file: 在请求期间验证 Aggregator 的客户端 CA 证书。
  • –proxy-client-key-file: 在请求期间验证 Aggregator 的客户端私钥。
  • –requestheader-allowed-names: 允许访问的客户端 common names 列表,通过 header 中 –requestheader-username-headers 参数指定的字段获取。客户端 common names 的名称需要在 client-ca-file 中进行设置,将其设置为空值时,表示任意客户端都可访问。

重启 kube-apiserver 组件

重启三个 Master 服务器中全部 kube-apiserver 组件:

$ systemctl daemon-reload && systemctl restart kube-apiserver

重启 Metrics Server 应用

查看已有的 metrics server 的 pod:

$ kubectl get pods -n kube-system | grep metrics-server

metrics-server-7455879dcc-w9dw7   1/1   Running   0   1d

删掉已有的 metrics server 的 pod,使其重新生成新的 pod 资源:

$ kubectl delete pods metrics-server-7455879dcc-w9dw7 -n kube-system

输入命令进行验证

等一段时间,然后输入下面命令进行测试:

[root@k8s-cluster-master-0040 ~]# kubectl top node
NAME                    CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
k8s-master-10     300m         3%     4788Mi          30%
k8s-master-11     800m         5%     5218Mi          31%
k8s-master-12     500m         4%     4900Mi          31%
k8s-woker-021     81m          1%     2930Mi          9%
k8s-woker-022     61m          0%     1658Mi          5%
k8s-woker-023     62m          0%     6061Mi          22%

可以观察到命令已经可以正常使用。


后记:

如果k8s 控制节点上未安装cni网络插件 ,则控制节点没有办法访问 metrics-server pod ip地址,还会导致下报错:

如果kube-proxy没有在Master上面运行,还需要配置–enable-aggregator-routing=true


couldn’t get resource list for metrics.k8s.io/v1beta1: the server is currently unable to handle the request
available_controller.go:316] v1beta1.metrics.k8s.io failed with: Get https://172.20.61.7:443: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

I0606 15:32:35.723004 8021 controller.go:105] OpenAPI AggregationController: Processing item v1beta1.metrics.k8s.io
E0606 15:32:35.723119 8021 controller.go:111] loading OpenAPI spec for “v1beta1.metrics.k8s.io” failed with: failed to retrieve openAPI spec, http error: ResponseCode: 503, Body: service unavailable
, Header: map[X-Content-Type-Options:[nosniff] Content-Type:[text/plain; charset=utf-8]]
I0606 15:32:35.723128 8021 controller.go:119] OpenAPI AggregationController: action for item v1beta1.metrics.k8s.io: Rate Limited Requeue.


E0606 15:32:37.115403 8021 available_controller.go:316] v1beta1.metrics.k8s.io failed with: Get https://192.168.188.220:443: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
E0606 15:32:42.121065 8021 available_controller.go:316] v1beta1.metrics.k8s.io failed with: Get https://192.168.188.220:443: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
E0606 15:33:02.914933 8021 memcache.go:135] couldn’t get resource list for metrics.k8s.io/v1beta1: the server is currently unable to handle the request
E0606 15:33:07.116376 8021 available_controller.go:316] v1beta1.metrics.k8s.io failed with: Get https://192.168.188.220:443: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

  • 发表于 2021-07-12 19:36
  • 阅读 ( 141 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
石天
石天

437 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章