kubelet提供api请求接口

kubelet 提供的 API 接口认证

node安装参考

kubelet 启动后监听多个端口,用于接收 kube-apiserver 或其它客户端发送的请求:

1
2
3
4
[root@k8s-3 ~]#  netstat -lnpt|grep kubelet
tcp 0 0 127.0.0.1:46395 0.0.0.0:* LISTEN 8941/kubelet
tcp 0 0 127.0.0.1:10248 0.0.0.0:* LISTEN 8941/kubelet
tcp6 0 0 :::10250 :::* LISTEN 8941/kubelet
  • 10248: healthz http 服务
  • 10250: https 服务,访问该端口时需要认证和授权(即使访问 /healthz 也需要)
  • 未开启只读端口 10255
  • 从 K8S v1.10 开始,去除了 –cadvisor-port 参数(默认 4194 端口),不支持访问 cAdvisor UI & API

kubelet 接收 10250 端口的 https 请求,可以访问如下资源:

  • /pods、/runningpods
  • /metrics、/metrics/cadvisor、/metrics/probes
  • /spec
  • /stats、/stats/container
  • /logs
  • /run/、/exec/, /attach/, /portForward/, /containerLogs/
    详情参考

    由于关闭了匿名认证,同时开启了 webhook 授权,所有访问 10250 端口 https API 的请求都需要被认证和授权。
    预定义的 ClusterRole system:kubelet-api-admin 授予访问 kubelet 所有 API 的权限(kube-apiserver 使用的 kubernetes 证书 User 授予了该权限):

1
2
3
4
5
6
7
8
9
10
11
12
13
# kubectl describe clusterrole system:kubelet-api-admin
Name: system:kubelet-api-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
nodes/log [] [] [*]
nodes/metrics [] [] [*]
nodes/proxy [] [] [*]
nodes/spec [] [] [*]
nodes/stats [] [] [*]
nodes [] [] [get list watch proxy]

kubelet api 认证和授权

kubelet 配置了如下认证参数:

  • –anonymous-auth=false: 设置为 false,不允许匿名�访问 10250 端口
  • –authentication-token-webhook=true: 指定签名客户端证书的 CA 证书,开启 HTTPs 证书认证
  • –client-ca-file=/etc/kubernetes/ssl/kubernetes-ca.pem: 开启 HTTPs bearer token 认证
  • –authorization-mode=Webhook: 开启 RBAC 授权

    kubelet 收到请求后,使用 clientCAFile 对证书签名进行认证,或者查询 bearer token 是否有效。如果两者都没通过,则拒绝请求,提示 Unauthorized

1
2
[root@k8s-master-01-2 ~]# curl -s --cacert /etc/kubernetes/ssl/kubernetes-ca.pem https://172.21.16.204:10250/metrics
Unauthorized

    通过认证后,kubelet 使用 SubjectAccessReview API 向 kube-apiserver 发送请求,查询证书或 token 对应的 user、group 是否有操作资源的权限(RBAC);

证书认证和授权

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 权限不足
# curl -s --cacert /etc/kubernetes/ssl/kubernetes-ca.pem --cert /etc/kubernetes/ssl/kube-controller-manager.pem --key /etc/kubernetes/ssl/kube-controller-manager-key.pem https://172.21.16.204:10250/metrics
Forbidden (user=system:kube-controller-manager, verb=get, resource=nodes, subresource=metrics)

# 使用部署 kubectl 命令行工具时创建的、具有最高权限的 admin 证书
# curl -s --cacert /etc/kubernetes/ssl/kubernetes-ca.pem --cert /etc/kubernetes/ssl/admin.pem --key /etc/kubernetes/ssl/admin-key.pem https://172.21.16.204:10250/metrics|head
# HELP apiserver_audit_event_total Counter of audit events generated and sent to the audit backend.
# TYPE apiserver_audit_event_total counter
apiserver_audit_event_total 0
# HELP apiserver_audit_requests_rejected_total Counter of apiserver requests rejected due to an error in audit logging backend.
# TYPE apiserver_audit_requests_rejected_total counter
apiserver_audit_requests_rejected_total 0
# HELP apiserver_client_certificate_expiration_seconds Distribution of the remaining lifetime on the certificate used to authenticate a request.
# TYPE apiserver_client_certificate_expiration_seconds histogram
apiserver_client_certificate_expiration_seconds_bucket{le="0"} 0
apiserver_client_certificate_expiration_seconds_bucket{le="21600"} 0
  • 注意: –cacert、–cert、–key 的参数值必须是文件路径,否则返回 401 Unauthorized;

bear token 认证和授权

    创建一个 ServiceAccount,将它和 ClusterRole system:kubelet-api-admin 绑定,从而具有调用 kubelet API 的权限

1
2
3
4
5
horization.k8s.io/kubelet-api-test created
# SECRET=$(kubectl get secrets | grep kubelet-api-test | awk '{print $1}')
# TOKEN=$(kubectl describe secret ${SECRET} | grep -E '^token' | awk '{print $2}')
# echo ${TOKEN}
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Imt1YmVsZXQtYXBpLXRlc3QtdG9rZW4tNGJra3MiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoia3ViZWxldC1hcGktdGVzdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6Ijk3MDRhZDEwLWNlYjQtMTFlOS04ZDIwLWZhMTYzZTVhZjgzMyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0Omt1YmVsZXQtYXBpLXRlc3QifQ.ishvOaC5tppYKDNpEOXIiVhVtgjyqzjySZjzndot5Z5U9MkY9LN8ZSMWRe6lNsB1UuTgEWTsHlG3OIRfExnHehYhWIt59V9e39KKbeY17hHoT-RZSaD6GoB449t_vUdIJedd1FGZ8DckQvDr6X5fMuD7MSU3vRL077j-uls-y4IW5kaJHeAGJfc6eWoCnv96DCbI8mQ8yuYbwLFpfIPLb4u6FPkwMQL2KXy6FhWPY1va6zAh4LdjGWhH6IAkKleq0aqfMwvmlnk1_OUmnmBoGJGuB96IwqBATP0jFzrd-Sv6af3RsSYz2r8YzJUj3kat9bd__HNCCXampYYr8ffu8YEdn-J9p6HK13FWU4O9QSIDrRONNIOpUXclJ-ov3z6N1hiIcVq5UJU6xR2z4ccvPXmH9Sj7p8CquqKEuobZxK97TFtECGlb2Ex43u4t0UHRo23UCQA-qP2Zs4-U2Zmf_qu3I-Lm7jzuYzXFCAb27yZx_XOUY-ycnKhtM6PpUfVKhkcHfWBOYY-QtBEbYf6yHRqCWcjrsZ63C_B56qAYaU5ca3hAcr6RBuHmmHISGESlLbmrpGgJ_ajd5mrJSh3Z_qdqu-Xt0Ya0NLfXgAcGi5n8xWJLztRTeyHrFTj7g82MqERUfFk9bdLHcz77xmrNLnhRZ87GW9sTZLw8QRUjF1g
1
2
3
4
5
6
7
8
9
10
11
# curl -s --cacert /etc/kubernetes/ssl/kubernetes-ca.pem -H "Authorization: Bearer ${TOKEN}" https://172.21.16.204:10250/metrics|head
# HELP apiserver_audit_event_total Counter of audit events generated and sent to the audit backend.
# TYPE apiserver_audit_event_total counter
apiserver_audit_event_total 0
# HELP apiserver_audit_requests_rejected_total Counter of apiserver requests rejected due to an error in audit logging backend.
# TYPE apiserver_audit_requests_rejected_total counter
apiserver_audit_requests_rejected_total 0
# HELP apiserver_client_certificate_expiration_seconds Distribution of the remaining lifetime on the certificate used to authenticate a request.
# TYPE apiserver_client_certificate_expiration_seconds histogram
apiserver_client_certificate_expiration_seconds_bucket{le="0"} 0
apiserver_client_certificate_expiration_seconds_bucket{le="21600"} 0

cadvisor 和 metrics

    cadvisor 是内嵌在 kubelet 二进制中的,统计所在节点各容器的资源(CPU、内存、磁盘、网卡)使用情况的服务.

在访问api-server安全端口之前,我们需要做一些操作才能访问,否则无法进行访问

在浏览器访问kube-apiserver安全端口

    提示证书不被信任,这是因为 kube-apiserver 的 server 证书是我们创建的根证书 ca.pem 签名的,需要将根证书 ca.pem 导入操作系统,并设置永久信任。
img

    给浏览器生成一个 client 证书,访问 apiserver 的 6443 https 端口时使用。这里使用部署 kubectl 命令行工具时创建的 admin 证书、私钥和上面的 ca 证书,创建一个浏览器可以使用 PKCS#12/PFX 格式的证书:

  • 会提示输入密码,这里密码需要记住,一会倒入证书到浏览器的时候需要

    1
    2
    3
    # openssl pkcs12 -export -out admin.pfx -inkey admin-key.pem -in admin.pem -certfile kubernetes-ca.pem
    Enter Export Password:
    Verifying - Enter Export Password:
  • 将创建的 admin.pfx 导入到系统的证书中,
    img

再次访问 apiserver 地址,提示选择一个浏览器证书,这里选中上面导入的 admin.pfx
img

  • 提示需要输入系统的密码,这里是mac的电脑
    img

  • 被授权访问 kube-apiserver 的安全端口
    img

客户端选择证书的原理
  • 证书选择是在客户端和服务端 SSL/TLS 握手协商阶段商定的;
  • 服务端如果要求客户端提供证书,则在握手时会向客户端发送一个它接受的 CA 列表;
  • 客户端查找它的证书列表(一般是操作系统的证书,对于 Mac 为 keychain),看有没有被 CA 签名的证书,如果有,则将它们提供给用户选择(证书的私钥);
  • 用户选择一个证书私钥,然后客户端将使用它和服务端通信;

    在浏览器访问 https://172.21.16.204:10250/metricshttps://172.21.16.204:10250/metrics/cadvisor 分别返回 kubelet 和 cadvisor 的 metrics。
img
img

  • 原因: kubelet配置文件设置--anonymous-auth=false不允许匿名证书访问 10250 的 https 服务,所以我们才需要配置证书来进行访问
坚持原创技术分享,您的支持将鼓励我继续创作!
0%