Skip to content

Commit a3cbfb6

Browse files
authored
feat: scrape minimum kubelet version from k8s nodes (#223)
* feat: scrape minimum kubelet version from k8s nodes * log pinger errors
1 parent 7243acc commit a3cbfb6

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

pkg/ping/build.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import (
88
"k8s.io/apimachinery/pkg/version"
99
)
1010

11-
func pingAttributes(info *version.Info, pods []string) console.ClusterPing {
11+
func pingAttributes(info *version.Info, pods []string, minKubeletVersion *string) console.ClusterPing {
1212
vs := strings.Split(info.GitVersion, "-")
1313
return console.ClusterPing{
1414
CurrentVersion: strings.TrimPrefix(vs[0], "v"),
1515
Distro: lo.ToPtr(findDistro(append(pods, info.GitVersion))),
16+
KubeletVersion: minKubeletVersion,
1617
}
1718
}

pkg/ping/pinger.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ package ping
33
import (
44
"context"
55

6-
"github.com/pluralsh/deployment-operator/pkg/client"
6+
"github.com/Masterminds/semver/v3"
77
"github.com/samber/lo"
88
corev1 "k8s.io/api/core/v1"
99
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1010
"k8s.io/client-go/discovery"
11+
"k8s.io/client-go/kubernetes"
12+
"k8s.io/klog/v2"
1113
"k8s.io/kubectl/pkg/cmd/util"
14+
15+
"github.com/pluralsh/deployment-operator/pkg/client"
1216
)
1317

1418
type Pinger struct {
@@ -28,27 +32,66 @@ func New(console client.Client, discovery *discovery.DiscoveryClient, factory ut
2832
func (p *Pinger) Ping() error {
2933
info, err := p.discoveryClient.ServerVersion()
3034
if err != nil {
35+
klog.ErrorS(err, "failed to get server version")
3136
return err
3237
}
3338

3439
cs, err := p.factory.KubernetesClientSet()
3540
if err != nil {
41+
klog.ErrorS(err, "failed to create kubernetes clientset")
3642
return nil
3743
}
3844

39-
podNames := []string{}
45+
var podNames []string
4046
// can find some distro information by checking what's running in kube-system
41-
if pods, err := cs.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}); err == nil {
47+
if pods, err := cs.CoreV1().Pods("kube-system").List(context.Background(), metav1.ListOptions{}); err == nil {
4248
podNames = lo.Map(pods.Items, func(pod corev1.Pod, ind int) string {
4349
return pod.Name
4450
})
4551
}
4652

47-
attrs := pingAttributes(info, podNames)
53+
minKubeletVersion := p.minimumKubeletVersion(cs)
54+
55+
attrs := pingAttributes(info, podNames, minKubeletVersion)
4856
if err := p.consoleClient.PingCluster(attrs); err != nil {
4957
attrs.Distro = nil
5058
return p.consoleClient.PingCluster(attrs) // fallback to no distro to support old console servers
5159
}
5260

5361
return nil
5462
}
63+
64+
// minimumKubeletVersion tries to scrape a minimum kubelet version across all nodes in the cluster.
65+
// It is expected that the kubelet will report to the API a valid SemVer-ish version.
66+
// If no parsable version is found across all nodes, nil will be returned.
67+
func (p *Pinger) minimumKubeletVersion(client *kubernetes.Clientset) *string {
68+
nodes, err := client.CoreV1().Nodes().List(context.Background(), metav1.ListOptions{})
69+
if err != nil {
70+
klog.ErrorS(err, "failed to list nodes")
71+
return nil
72+
}
73+
74+
minKubeletVersion := new(semver.Version)
75+
for _, node := range nodes.Items {
76+
kubeletVersion, _ := semver.NewVersion(node.Status.NodeInfo.KubeletVersion)
77+
if kubeletVersion == nil {
78+
continue
79+
}
80+
81+
// Initialize with first correctly parsed version
82+
if len(minKubeletVersion.Original()) == 0 {
83+
minKubeletVersion = kubeletVersion
84+
continue
85+
}
86+
87+
if kubeletVersion.LessThan(minKubeletVersion) {
88+
minKubeletVersion = kubeletVersion
89+
}
90+
}
91+
92+
if len(minKubeletVersion.Original()) == 0 {
93+
return nil
94+
}
95+
96+
return lo.ToPtr(minKubeletVersion.Original())
97+
}

0 commit comments

Comments
 (0)