Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support getting certificate information from a kubeconfig file #61

Merged
merged 4 commits into from
Apr 2, 2021

Conversation

treydock
Copy link
Contributor

The idea is to query the user certificate inside /etc/kubernetes/admin.conf. Example output queried on my dev Kubernetes cluster:

$  curl "http:https://kubecontroller-dev:9219/probe?module=kubeconfig&target=/etc/kubernetes/admin.conf"
# HELP ssl_kubeconfig_cert_not_after NotAfter expressed as a Unix Epoch Time for a certificate found in a kubeconfig
# TYPE ssl_kubeconfig_cert_not_after gauge
ssl_kubeconfig_cert_not_after{cn="kubernetes",dnsnames="",emails="",ips="",issuer_cn="kubernetes",kubeconfig="/etc/kubernetes/admin.conf",name="kubernetes",ou="",serial_no="335833545820969761192653058045228355723340563282",type="cluster"} 1.73817534e+09
ssl_kubeconfig_cert_not_after{cn="kubernetes-admin",dnsnames="",emails="",ips="",issuer_cn="kubernetes",kubeconfig="/etc/kubernetes/admin.conf",name="kubernetes-admin",ou="",serial_no="3629461269801086488",type="user"} 1.63743128e+09
# HELP ssl_kubeconfig_cert_not_before NotBefore expressed as a Unix Epoch Time for a certificate found in a kubeconfig
# TYPE ssl_kubeconfig_cert_not_before gauge
ssl_kubeconfig_cert_not_before{cn="kubernetes",dnsnames="",emails="",ips="",issuer_cn="kubernetes",kubeconfig="/etc/kubernetes/admin.conf",name="kubernetes",ou="",serial_no="335833545820969761192653058045228355723340563282",type="cluster"} 1.58049534e+09
ssl_kubeconfig_cert_not_before{cn="kubernetes-admin",dnsnames="",emails="",ips="",issuer_cn="kubernetes",kubeconfig="/etc/kubernetes/admin.conf",name="kubernetes-admin",ou="",serial_no="3629461269801086488",type="user"} 1.58049534e+09
# HELP ssl_probe_success If the probe was a success
# TYPE ssl_probe_success gauge
ssl_probe_success 1
# HELP ssl_prober The prober used by the exporter to connect to the target
# TYPE ssl_prober gauge
ssl_prober{prober="kubeconfig"} 1

Also works to read kubelet configs and their associated certificates:

$  curl "http:https://kubeworker01-dev:9219/probe?module=kubeconfig&target=/etc/kubernetes/kubelet.conf"
# HELP ssl_kubeconfig_cert_not_after NotAfter expressed as a Unix Epoch Time for a certificate found in a kubeconfig
# TYPE ssl_kubeconfig_cert_not_after gauge
ssl_kubeconfig_cert_not_after{cn="kubernetes",dnsnames="",emails="",ips="",issuer_cn="kubernetes",kubeconfig="/etc/kubernetes/kubelet.conf",name="default-cluster",ou="",serial_no="335833545820969761192653058045228355723340563282",type="cluster"} 1.73817534e+09
ssl_kubeconfig_cert_not_after{cn="system:node:kubeworker01-dev",dnsnames="",emails="",ips="",issuer_cn="kubernetes",kubeconfig="/etc/kubernetes/kubelet.conf",name="default-auth",ou="",serial_no="158874210270431228542581699797837542620",type="user"} 1.637427849e+09
# HELP ssl_kubeconfig_cert_not_before NotBefore expressed as a Unix Epoch Time for a certificate found in a kubeconfig
# TYPE ssl_kubeconfig_cert_not_before gauge
ssl_kubeconfig_cert_not_before{cn="kubernetes",dnsnames="",emails="",ips="",issuer_cn="kubernetes",kubeconfig="/etc/kubernetes/kubelet.conf",name="default-cluster",ou="",serial_no="335833545820969761192653058045228355723340563282",type="cluster"} 1.58049534e+09
ssl_kubeconfig_cert_not_before{cn="system:node:kubeworker01-dev",dnsnames="",emails="",ips="",issuer_cn="kubernetes",kubeconfig="/etc/kubernetes/kubelet.conf",name="default-auth",ou="",serial_no="158874210270431228542581699797837542620",type="user"} 1.605891849e+09
# HELP ssl_probe_success If the probe was a success
# TYPE ssl_probe_success gauge
ssl_probe_success 1
# HELP ssl_prober The prober used by the exporter to connect to the target
# TYPE ssl_prober gauge
ssl_prober{prober="kubeconfig"} 1

@ribbybibby
Copy link
Owner

Hi @treydock, thank you for this PR. It looks really good, however it doesn't seem to support paths relative to the kubeconfig file:

ERRO[0048] error=open certs/example/ca.pem: no such file or directory target=/Users/ribbybibby/.kube/config prober=kubeconfig timeout=10s  source="ssl_exporter.go:93"

Cluster config looks like this and is valid:

clusters:
  - cluster:
      certificate-authority: certs/example/ca.pem
      server: https://master.example.com
    name: example

@treydock
Copy link
Contributor Author

treydock commented Mar 1, 2021

@ribbybibby I added a commit that should fix the issue where a relative path is used. Let me know if the changes work for you. It assumes if the path is /home/user/.kube/config then your example would be /home/user/.kube/certs/example/ca.pem

prober/kubeconfig.go Outdated Show resolved Hide resolved
// Path is relative to kubeconfig path
if !filepath.IsAbs(c.Cluster.CertificateAuthority) {
newPath := filepath.Join(filepath.Dir(k.Path), c.Cluster.CertificateAuthority)
c.Cluster.CertificateAuthority = newPath
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relative paths still aren't working for me, I'm getting the same error. I don't think this assignment is actually modifying the value that's passed to collectKubeconfigMetrics.

Perhaps you could move this logic into collectKubeconfigMetrics?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the issue is I was trying to modify the slice element from within the loop which won't work. Instead I am creating a new slice using modified value and using that new slice for the main struct. I am also moving the parsing logic entirely to parsing function so can test the parsing without having to actually have a full cert setup. I added a test case from your example YAML.

Copy link
Owner

@ribbybibby ribbybibby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the prompt responses to my review, I'm sorry I haven't been so responsive in following up! This looks all good now.

@ribbybibby ribbybibby merged commit 5265251 into ribbybibby:master Apr 2, 2021
@treydock
Copy link
Contributor Author

@ribbybibby Would it be possible to get a tag/release that includes this pull request?

@ribbybibby
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants