概要
在apiserver中开启聚合层,这里我们使用一套独立的证书,在以往我使用的是apiserver证书,官方明确说了不要这样操作
kubernetes 集群资源监控之前可以通过 heapster 来获取数据,在 1.11 开始开始逐渐废弃 heapster 了,采用 metrics-server 来代替,metrics-server 是集群的核心监控数据的聚合器,它从 kubelet 公开的 Summary API 中采集指标信息,metrics-server 是扩展的 APIServer,依赖于kube-aggregator,因为我们需要在 APIServer 中开启相关参数。
引用官网的冲突说明
CA-重用和冲突
Kubernetes apiserver 有两个客户端 CA 选项:
–client-ca-file
–requestheader-client-ca-file
这些功能中的每个功能都是独立的;如果使用不正确,可能彼此冲突。
–client-ca-file:当请求到达 Kubernetes apiserver 时,如果启用了此选项,则 Kubernetes apiserver 会检查请求的证书。如果它是由 –client-ca-file 引用的文件中的 CA 证书之一签名的,并且用户是公用名CN=的值,而组是组织O= 的取值,则该请求被视为合法请求。请参阅 关于 TLS 身份验证的文档。
–requestheader-client-ca-file:当请求到达 Kubernetes apiserver 时,如果启用此选项,则 Kubernetes apiserver 会检查请求的证书。如果它是由文件引用中的 –requestheader-client-ca-file 所签署的 CA 证书之一签名的,则该请求将被视为潜在的合法请求。然后,Kubernetes apiserver 检查通用名称CN=是否是 –requestheader-allowed-names 提供的列表中的名称之一。如果名称允许,则请求被批准;如果不是,则请求被拒绝。
如果同时提供了 –client-ca-file 和–requestheader-client-ca-file,则首先检查 –requestheader-client-ca-file CA,然后再检查–client-ca-file。通常,这些选项中的每一个都使用不同的 CA(根 CA 或中间 CA)。常规客户端请求与 –client-ca-file 相匹配,而聚合请求与 –requestheader-client-ca-file 相匹配。但是,如果两者都使用同一个 CA,则通常会通过 –client-ca-file 传递的客户端请求将失败,因为 CA 将与 –requestheader-client-ca-file 中的 CA 匹配,但是通用名称 CN= 将不匹配 –requestheader-allowed-names 中可接受的通用名称之一。这可能导致您的 kubelet 和其他控制平面组件以及最终用户无法向 Kubernetes apiserver 认证。
因此,请对用于控制平面组件和最终用户鉴权的 –client-ca-file 选项和用于聚合 apiserver 鉴权的 –requestheader-client-ca-file 选项使用不同的 CA 证书。
警告: 除非您了解风险和保护 CA 用法的机制,否则 不要 重用在不同上下文中使用的 CA。
如果您未在运行 API 服务器的主机上运行 kube-proxy,则必须确保使用以下 kube-apiserver 标志启用系统:
–enable-aggregator-routing=true
OK,我们既然了解了为什么不要这样去操作,那我们在这里重新定义一套专用的证书
创建证书
创建 CA 配置文件
cat > aggregator-ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"aggregator": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
字段说明:
profiles : 可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile。
signing :表示该证书可用于签名其它证书;生成的 aggregator-ca.pem 证书中 CA=TRUE。
server auth :表示 Client 可以用该 CA 对 Server 提供的证书进行验证。
client auth :表示 Server 可以用该 CA 对 Client 提供的证书进行验证。
创建 CA 证书签名请求
cat > aggregator-ca-csr.json <<EOF
{
"CN": "aggregator",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Shanghai",
"L": "Shanghai",
"O": "k8s",
"OU": "System"
}
],
"ca": {
"expiry": "87600h"
}
}
EOF
字段说明:
“CN” :Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法。
“O” :Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);
生成 CA 证书和私钥
cfssl gencert -initca aggregator-ca-csr.json | cfssljson -bare aggregator-ca
ls aggregator-ca*
aggregator-ca-config.json aggregator-ca.csr aggregator-ca-csr.json aggregator-ca-key.pem
创建 kubernetes 证书
创建 aggregator 证书签名请求文件
cat > aggregator-csr.json <<EOF
{
"CN": "aggregator",
"hosts": [
"10.0.0.1",
"172.0.0.1",
"127.0.0.1",
"10.0.0.101",
"10.0.0.102",
"10.0.0.103",
"10.0.0.99",
"10.0.0.98",
"10.0.0.97",
"10.0.0.90",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Shanghai",
"L": "Shanghai",
"O": "k8s",
"OU": "System"
}
]
}
EOF
如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表,由于该证书后续被 etcd 集群和 kubernetes master 集群使用,所以上面分别指定了 etcd 集群、kubernetes master 集群的主机 IP 和 kubernetes 服务的服务 IP(一般是 kube-apiserver 指定的 service-cluster-ip-range 网段的第一个 IP,如 10.254.0.1)。
以上物理节点的 IP 也可以更换为主机名。
生成 aggregator 证书和私钥
cfssl gencert -ca=aggregator-ca.pem -ca-key=aggregator-ca-key.pem -config=aggregator-ca-config.json -profile=aggregator aggregator-csr.json | cfssljson -bare aggregator
ls aggregator*
aggregator.csr aggregator-csr.json aggregator-key.pem aggregator.pem
分发证书
将生成的证书和秘钥文件(后缀名为.pem)拷贝到 Master 节点的 /opt/kubernetes/ssl 目录下。
cp *.pem /etc/kubernetes/ssl
开启聚合层 API
kube-apiserver 增加以下配置:
# 聚合层配置
--requestheader-client-ca-file=/opt/kubernetes/ssl/aggregator-ca.pem \
--requestheader-allowed-names=aggregator \
--requestheader-extra-headers-prefix=X-Remote-Extra- \
--requestheader-group-headers=X-Remote-Group \
--requestheader-username-headers=X-Remote-User \
--proxy-client-cert-file=/opt/kubernetes/ssl/aggregator.pem \
--proxy-client-key-file=/opt/kubernetes/ssl/aggregator-key.pem \
--runtime-config=api/all=true \
注意:
–requestheader-XXX、–proxy-client-XXX 是 kube-apiserver 的 aggregator layer 相关的配置参数,metrics-server & HPA 需要使用;
–requestheader-client-ca-file:用于签名 –proxy-client-cert-file 和 –proxy-client-key-file 指定的证书;在启用了 metric aggregator 时使用;
如果 —requestheader-allowed-names 不为空,则—proxy-client-cert-file 证书的 CN 必须位于 allowed-names 中,默认为 aggregator;
如果 kube-apiserver 机器没有运行 kube-proxy,则还需要添加 --enable-aggregator-routing=true 参数;
requestheader-client-ca-file 指定的 CA 证书,必须具有 client auth and server auth
有很多的文档都说在要做以下操作:
这里特别说明一下,现在新版本中不需要了,请要去多此一举,这个配置已经弃用。
kube-controller-manager
添加如下配置参数:
--horizontal-pod-autoscaler-use-rest-clients=true
用于配置 HPA 控制器使用 REST 客户端获取 metrics 数据
重启 kube-apiserver:
systemctl restart kube-apiserver
布署metrics server
下载yaml文件
kubectl apply -f metrics-server.yaml
注意:这里我修改了metrics-server的启动命令,增加了–kubelet-preferred-address-types=InternalIP和–kubelet-insecure-tls参数,否则metrics server可能会从kubelet拿不到监控数据。具体报错可以通过kubectl logs metrics-server-7875f8bf59-xzttf -n kube-system命令查看
如果部署集群的时候,CA 证书并没有把各个节点的 IP 签上去,所以这里 metrics-server 通过 IP 去请求时,提示签的证书没有对应的 IP(错误:x509: cannot validate certificate for 192.168.33.11 because it doesn’t contain any IP SANs),我们可以添加一个–kubelet-insecure-tls参数跳过证书校验
注意官方也提了生产环境中不建议开始证书跳过
那有的人可能就说我就不开启证书跳过,行不行呢?当然可以。而且也是官方推荐的生产环境的做法。
我们可以配置证书自动颁发,有兴趣的朋友可以咨询我。
验证metrics server
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-master 282m 14% 1159Mi 61%
k8s-master2 244m 12% 745Mi 57%
k8s-node1 161m 8% 398Mi 56%
k8s-node2 156m 7% 430Mi 61%
kubectl top pod -n kube-system
NAME CPU(cores) MEMORY(bytes)
coredns-5ffbfd976d-wrsrj 7m 20Mi
kube-flannel-ds-6zjmg 4m 18Mi
kube-flannel-ds-dzz9g 5m 16Mi
kube-flannel-ds-r9hm6 5m 22Mi
kube-flannel-ds-ss6f7 4m 22Mi
kuboard-7986796cf8-m82bz 0m 6Mi
metrics-server-7875f8bf59-xzttf 2m 30Mi