k8s driver: use right node selector on old k8s versions

Before kubernetes 1.14 nodes were labeled with the "beta.kubernetes.io/arch"
label instead of the "kubernetes.io/arch".

Current k8s version (v1.15) labels nodes with both labels but it's
deprecated and will removed in future versions.

At driver start get the current k8s api version and choose the right label to
use as node selector based on it.
This commit is contained in:
Simone Gotti 2019-07-08 13:51:31 +02:00
parent 378ee352c0
commit 7aea06fce8
2 changed files with 104 additions and 7 deletions

View File

@ -21,6 +21,8 @@ import (
"fmt"
"io"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
@ -62,6 +64,8 @@ const (
renewExecutorLeaseInterval = 10 * time.Second
staleExecutorLeaseInterval = 1 * time.Minute
informerResyncInterval = 10 * time.Second
k8sLabelArchBeta = "beta.kubernetes.io/arch"
)
type K8sDriver struct {
@ -77,6 +81,7 @@ type K8sDriver struct {
podLister listerscorev1.PodLister
cmLister listerscorev1.ConfigMapLister
leaseLister coordinationlistersv1.LeaseLister
k8sLabelArch string
}
type K8sPod struct {
@ -106,12 +111,29 @@ func NewK8sDriver(logger *zap.Logger, executorID, toolboxPath string) (*K8sDrive
}
d := &K8sDriver{
log: logger.Sugar(),
restconfig: kubecfg,
client: kubecli,
toolboxPath: toolboxPath,
namespace: namespace,
executorID: executorID,
log: logger.Sugar(),
restconfig: kubecfg,
client: kubecli,
toolboxPath: toolboxPath,
namespace: namespace,
executorID: executorID,
k8sLabelArch: corev1.LabelArchStable,
}
serverVersion, err := d.client.Discovery().ServerVersion()
if err != nil {
return nil, err
}
sv, err := parseGitVersion(serverVersion.GitVersion)
// if server version parsing fails just warn but ignore it
if err != nil {
d.log.Warnf("failed to parse k8s server version: %v", err)
}
if sv != nil {
// for k8s version < v1.14.x use old arch label
if sv.Major == 1 && sv.Minor < 14 {
d.k8sLabelArch = k8sLabelArchBeta
}
}
lists, err := d.client.Discovery().ServerPreferredResources()
@ -399,7 +421,7 @@ func (d *K8sDriver) NewPod(ctx context.Context, podConfig *PodConfig, out io.Wri
if podConfig.Arch != "" {
pod.Spec.NodeSelector = map[string]string{
corev1.LabelArchStable: string(podConfig.Arch),
d.k8sLabelArch: string(podConfig.Arch),
}
}
@ -736,3 +758,29 @@ func genEnvVars(env map[string]string) []corev1.EnvVar {
}
return envVars
}
type serverVersion struct {
Major int
Minor int
}
// k8s version is in this format: v0.0.0(-master+$Format:%h$)
var gitVersionRegex = regexp.MustCompile("v([0-9]+).([0-9]+).[0-9]+.*")
func parseGitVersion(gitVersion string) (*serverVersion, error) {
parsedVersion := gitVersionRegex.FindStringSubmatch(gitVersion)
if len(parsedVersion) != 3 {
return nil, fmt.Errorf("cannot parse git version %s", gitVersion)
}
sv := &serverVersion{}
var err error
sv.Major, err = strconv.Atoi(parsedVersion[1])
if err != nil {
return nil, err
}
sv.Minor, err = strconv.Atoi(parsedVersion[2])
if err != nil {
return nil, err
}
return sv, nil
}

View File

@ -19,6 +19,7 @@ import (
"context"
"io/ioutil"
"os"
"reflect"
"testing"
"time"
@ -253,3 +254,51 @@ func TestK8sPod(t *testing.T) {
})
}
func TestParseGitVersion(t *testing.T) {
tests := []struct {
gitVersion string
out *serverVersion
err bool
}{
{
gitVersion: "v1.8.0",
out: &serverVersion{Major: 1, Minor: 8},
},
{
gitVersion: "v1.12.0",
out: &serverVersion{Major: 1, Minor: 12},
},
{
gitVersion: "v1.12.20",
out: &serverVersion{Major: 1, Minor: 12},
},
{
gitVersion: "v1.12.8-test.10",
out: &serverVersion{Major: 1, Minor: 12},
},
{
gitVersion: "v1.a",
err: true,
},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
sv, err := parseGitVersion(tt.gitVersion)
if tt.err {
if err == nil {
t.Errorf("expected error, got nil error")
}
return
}
if err != nil {
t.Errorf("unexpected err: %v", err)
return
}
if !reflect.DeepEqual(sv, tt.out) {
t.Errorf("expected %v, got %v", tt.out, sv)
}
})
}
}