本文最后更新于:2024年7月24日 晚上
前言
Kubernetes 中大量用到了证书, 比如 ca 证书、以及 kubelet、apiserver、proxy、etcd 等组件,还有 kubeconfig 文件。
如果证书过期,轻则无法登录 Kubernetes 集群,重则整个集群异常。
为了解决证书过期的问题,一般有以下几种方式:
- 大幅延长证书有效期,短则 10 年,长则 100 年;
- 证书快过期是自动轮换,如 Rancher 的 K3s,RKE2 就采用这种方式;
- 增加证书过期的监控,便于提早发现证书过期问题并人工介入
本次主要介绍关于 Kubernetes 集群证书过期的监控,这里提供 3 种监控方案:
- 使用 Blackbox Exporter 通过 Probe 监控 Kubernetes apiserver 证书过期时间;
- 使用 kube-prometheus-stack 通过 apiserver 和 kubelet 组件监控获取相关证书过期时间;
- 使用 enix 的 x509-certificate-exporter监控集群所有 node 的
/etc/kubernetes/pki
和 /var/lib/kubelet
下的证书以及 kubeconfig 文件
方案一: Blackbox Exporter 监控 Kubernetes apiserver 证书过期时间
Blackbox Exporter 用于探测 HTTPS、HTTP、TCP、DNS、ICMP 和 grpc 等 Endpoint。在你定义 Endpoint 后,Blackbox Exporter 会生成指标,可以使用 Grafana 等工具进行可视化。Blackbox Exporter 最重要的功能之一是测量 Endpoint 的可用性。
当然, Blackbox Exporter 探测 HTTPS 后就可以获取到证书的相关信息, 就是利用这种方式实现对 Kubernetes apiserver 证书过期时间的监控.
配置步骤
-
调整 Blackbox Exporter 的配置, 增加 insecure_tls_verify: true
, 如下:
-
重启 blackbox exporter: kubectl rollout restart deploy ...
-
增加对 Kubernetes APIServer 内部端点 https://kubernetes.default.svc.cluster.local/readyz 的监控.
-
如果你没有使用 Prometheus Operator, 使用的是原生的 Prometheus, 则需要修改 Prometheus 配置文件的 configmap 或 secret, 添加 scrape config, 示例如下:
-
如果在使用 Prometheus Operator, 则可以增加如下 Probe CRD, Prometheus Operator 会自动将其转换并 merge 到 Prometheus 中.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| apiVersion: monitoring.coreos.com/v1 kind: Probe metadata: name: kubernetes-apiserver spec: interval: 60s module: http_2xx prober: path: /probe url: monitor-prometheus-blackbox-exporter.default.svc.cluster.local:9115 targets: staticConfig: static: - https://kubernetes.default.svc.cluster.local/readyz
|
最后, 可以增加 Prometheus 告警 Rule, 这里就直接用 Prometheus Operator 创建 PrometheusRule CRD 做示例了, 示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: prometheus-blackbox-exporter spec: groups: - name: prometheus-blackbox-exporter rules: - alert: BlackboxSslCertificateWillExpireSoon expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 30 for: 0m labels: severity: warning - alert: BlackboxSslCertificateWillExpireSoon expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 14 for: 0m labels: severity: critical - alert: BlackboxSslCertificateExpired annotations: description: |- SSL certificate has expired already VALUE = {{ $value }} LABELS = {{ $labels }} summary: SSL certificate expired (instance {{ $labels.instance }}) expr: probe_ssl_earliest_cert_expiry - time() <= 0 for: 0m labels: severity: emergency
|
效果
方案二: kube-prometheus-stack 通过 apiserver 和 kubelet 组件监控证书过期时间
这里可以参考我的文章:Prometheus Operator 与 kube-prometheus 之二 - 如何监控 1.23+ kubeadm 集群, 安装完成后, 开箱即用.
开箱即用内容包括:
- 抓取 apiserver 和 kubelet 指标;(即 serviceMonitor)
- 配置证书过期时间的相关告警; (即 PrometheusRule)
这里用到的指标有:
- apiserver
apiserver_client_certificate_expiration_seconds_count
apiserver_client_certificate_expiration_seconds_bucket
- kubelet
kubelet_certificate_manager_client_expiration_renew_errors
kubelet_server_expiration_renew_errors
kubelet_certificate_manager_client_ttl_seconds
kubelet_certificate_manager_server_ttl_seconds
监控效果
对应的 Prometheus 告警规则如下:
方案三: 使用 enix 的 x509-certificate-exporter
监控手段
该 Exporter 是通过监控集群所有 node 的指定目录或 path 下的证书文件以及 kubeconfig 文件来获取证书信息.
如果是使用 kubeadm 搭建的 Kubernetes 集群, 则可以监控如下包含证书的文件和 kubeconfig:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| watchFiles: - /var/lib/kubelet/pki/kubelet-client-current.pem - /etc/kubernetes/pki/apiserver.crt - /etc/kubernetes/pki/apiserver-etcd-client.crt - /etc/kubernetes/pki/apiserver-kubelet-client.crt - /etc/kubernetes/pki/ca.crt - /etc/kubernetes/pki/front-proxy-ca.crt - /etc/kubernetes/pki/front-proxy-client.crt - /etc/kubernetes/pki/etcd/ca.crt - /etc/kubernetes/pki/etcd/healthcheck-client.crt - /etc/kubernetes/pki/etcd/peer.crt - /etc/kubernetes/pki/etcd/server.crt watchKubeconfFiles: - /etc/kubernetes/admin.conf - /etc/kubernetes/controller-manager.conf - /etc/kubernetes/scheduler.conf
|
安装配置
编辑 values.yaml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
| kubeVersion: '' extraLabels: {} nameOverride: '' fullnameOverride: '' imagePullSecrets: [] image: registry: docker.io repository: enix/x509-certificate-exporter tag: pullPolicy: IfNotPresent psp: create: false rbac: create: true secretsExporter: serviceAccountName: serviceAccountAnnotations: {} clusterRoleAnnotations: {} clusterRoleBindingAnnotations: {} hostPathsExporter: serviceAccountName: serviceAccountAnnotations: {} clusterRoleAnnotations: {} clusterRoleBindingAnnotations: {} podExtraLabels: {} podAnnotations: {} exposePerCertificateErrorMetrics: false exposeRelativeMetrics: false metricLabelsFilterList: null secretsExporter: enabled: true debugMode: false replicas: 1 restartPolicy: Always strategy: {} resources: limits: cpu: 200m memory: 150Mi requests: cpu: 20m memory: 20Mi nodeSelector: {} tolerations: [] affinity: {} podExtraLabels: {} podAnnotations: {} podSecurityContext: {} securityContext: runAsUser: 65534 runAsGroup: 65534 readOnlyRootFilesystem: true capabilities: drop: - ALL secretTypes: - type: kubernetes.io/tls key: tls.crt includeNamespaces: [] excludeNamespaces: [] includeLabels: [] excludeLabels: [] cache: enabled: true maxDuration: 300 hostPathsExporter: debugMode: false restartPolicy: Always updateStrategy: {} resources: limits: cpu: 100m memory: 40Mi requests: cpu: 10m memory: 20Mi nodeSelector: {} tolerations: [] affinity: {} podExtraLabels: {} podAnnotations: {} podSecurityContext: {} securityContext: runAsUser: 0 runAsGroup: 0 readOnlyRootFilesystem: true capabilities: drop: - ALL watchDirectories: [] watchFiles: [] watchKubeconfFiles: [] daemonSets: cp: nodeSelector: node-role.kubernetes.io/master: '' tolerations: - effect: NoSchedule key: node-role.kubernetes.io/master operator: Exists watchFiles: - /var/lib/kubelet/pki/kubelet-client-current.pem - /etc/kubernetes/pki/apiserver.crt - /etc/kubernetes/pki/apiserver-etcd-client.crt - /etc/kubernetes/pki/apiserver-kubelet-client.crt - /etc/kubernetes/pki/ca.crt - /etc/kubernetes/pki/front-proxy-ca.crt - /etc/kubernetes/pki/front-proxy-client.crt - /etc/kubernetes/pki/etcd/ca.crt - /etc/kubernetes/pki/etcd/healthcheck-client.crt - /etc/kubernetes/pki/etcd/peer.crt - /etc/kubernetes/pki/etcd/server.crt watchKubeconfFiles: - /etc/kubernetes/admin.conf - /etc/kubernetes/controller-manager.conf - /etc/kubernetes/scheduler.conf nodes: watchFiles: - /var/lib/kubelet/pki/kubelet-client-current.pem - /etc/kubernetes/pki/ca.crt rbacProxy: enabled: false podListenPort: 9793 hostNetwork: false service: create: true port: 9793 annotations: {} extraLabels: {} prometheusServiceMonitor: create: true scrapeInterval: 60s scrapeTimeout: 30s extraLabels: {} relabelings: {} prometheusPodMonitor: create: false prometheusRules: create: true alertOnReadErrors: true readErrorsSeverity: warning alertOnCertificateErrors: true certificateErrorsSeverity: warning certificateRenewalsSeverity: warning certificateExpirationsSeverity: critical warningDaysLeft: 30 criticalDaysLeft: 14 extraLabels: {} alertExtraLabels: {} rulePrefix: '' disableBuiltinAlertGroup: false extraAlertGroups: [] extraDeploy: []
|
通过 Helm Chart 安装:
1 2
| helm repo add enix https://charts.enix.io helm install x509-certificate-exporter enix/x509-certificate-exporter
|
通过这个 Helm Chart 也会自动安装:
- ServiceMonitor
- PrometheusRule
其监控指标为:
监控效果
该 Exporter 还提供了一个比较花哨的 Grafana Dashboard, 如下:
Alert Rules 如下:
总结
为了监控 Kubernetes 集群的证书过期时间, 我们提供了 3 种方案, 各有优劣:
- 使用 Blackbox Exporter 通过 Probe 监控 Kubernetes apiserver 证书过期时间;
- 优势: 实现简单;
- 劣势: 只能监控 https 的证书;
- 使用 kube-prometheus-stack 通过 apiserver 和 kubelet 组件监控获取相关证书过期时间;
- 优势: 开箱即用, 安装 kube-prometheus-stack 后无需额外安装其他 exporter
- 劣势: 只能监控 apiserver 和 kubelet 的证书;
- 使用 enix 的 x509-certificate-exporter监控集群所有 node 的
/etc/kubernetes/pki
和 /var/lib/kubelet
下的证书以及 kubeconfig 文件
- 优势: 可以监控所有 node, 所有 kubeconfig 文件, 以及 所有 tls 格式的 secret 证书, 如果要监控 Kubernetes 集群以外的证书, 也可以如法炮制; 范围广而全;
- 需要额外安装: x509-certificate-exporter, 对应有 1 个 Deployment 和 多个 DaemonSet, 对 Kubernetes 集群的资源消耗不少.
可以根据您的实际情况灵活进行选择.
🎉🎉🎉
📚️参考文档