默认情况下, heapster 使用 http 协议访问每个 kubelet 节点的10255这个非安全端口, 在kubelet 关闭此端口的情况下, 仅允许通过 https 通信时, heapster 找 kubelet拿数据成了大问题
基础环境:
auth mode: RBAC
kubelet port: only https(10250)
kubelet ca: SelfSign
创建 ServiceAccount
1 | apiVersion: v1 |
创建 ClusterRoleBinding
官方文档中的配置如下:
1 | kind: ClusterRoleBinding |
官方文档中的配置在 heapster 使用 http 协议访问 kubelet 10255 端口的时候时没有任何问题的, 但是用这份配置访问 kubelet 的 10250 端口, 你在 heapster 的 console log 日志中, 可以看到 403 Forbidden 的报错, 因为绑定的角色权限没有达到要求, 所以你需要下面这份绑定文件
1 | kind: ClusterRoleBinding |
其实只是绑定的角色从 system:heapster
换成了 system:kubelet-api-admin
创建 heapster 服务
以下是官方示例:
1 | apiVersion: extensions/v1beta1 |
我们需要对如下参数做修改:
- –source=kubernetes:https://这里写你master的域名:6443
- –sink=influxdb:http://这里写你influxdb的地址或域名:8086
--sink
配置中有如下参数可以选择
- inClusterConfig - Use kube config in service accounts associated with Heapster’s namespace. (default: true)
- kubeletPort - kubelet port to use (default: 10255)
- kubeletHttps - whether to use https to connect to kubelets (default: false)
- insecure - whether to trust Kubernetes certificates (default: false)
- auth - client auth file to use. Set auth if the service accounts are not usable.
- useServiceAccount - whether to use the service account token if one is mounted at /var/run/secrets/kubernetes.io/serviceaccount/token (default: false)
需要设置访问 kubelet 的安全端口, 需要如下参数
- kubeletPort 10250 访问10250端口
- kubeletHttps true 以https协议访问
- insecure true 信任kubernetes证书
- useServiceAccount true 使用挂载进来的SA账户进行访问
最终的配置结果如下:
1 | --source=kubernetes:https://k8s-master:6443?useServiceAccount=true&kubeletHttps=true&kubeletPort=10250&insecure=true |
这里着重说明一下insecure
配置, 一般情况下, kubelet 节点在没有静态配置服务端证书的情况下, kubelet 节点会自动生成一个自签名的服务端证书到指定或默认的目录下. 这个证书是独立于kubernetes集群的证书, 不是kubernetes集群根证书所签发的. 所以理论上, 在 kubernetse 的双向认证中, 当 apiserver 向 kubelet主动发起 https 请求后, 服务端首先会将自己的服务端证书发送给客户端(apiserver), 一般情况下, apiserver 是需要校验服务端证书是否可信的. 但是在 apiserver 与 kubelet 通信中比较特殊, 默认情况下, apiserver 是不会校验 kubelet 的服务端证书的, 因为 kubelet 一般是独立于k8集群的自签名证书, 如果真的校验, 结果肯定是服务端证书不可信, 所以索性默认就不校验了, 而是直接将 apiserver 持有的 kubelet 客户端证书发送给 kubelet, 供 kubelet 校验, 此时, kubelet 依据配置中指定的ca证书对 apiserver 发来的客户端证书进行校验.
话题再回到insecure
配置. 如果你设置这个参数为true
, 还要使用 https 协议去访问 kubelet, 那么 heapster 日志中将会报证书验证失败的错误. heapster 会取到每个 kubelet 的IP地址, 然后进行访问, 但问题是, kubelet 在自签名证书时, 默认依据的是自己的主机名, 所以 heapster 以 https 访问 kubelet, 一是证书不是自己持有的根证书签发的,不可信; 二是服务端的地址限定是基于DNS的主机名, 并没有设置IP, 所以也不会校验通过
参考文档: