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:
parent
378ee352c0
commit
7aea06fce8
|
@ -21,6 +21,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -62,6 +64,8 @@ const (
|
||||||
renewExecutorLeaseInterval = 10 * time.Second
|
renewExecutorLeaseInterval = 10 * time.Second
|
||||||
staleExecutorLeaseInterval = 1 * time.Minute
|
staleExecutorLeaseInterval = 1 * time.Minute
|
||||||
informerResyncInterval = 10 * time.Second
|
informerResyncInterval = 10 * time.Second
|
||||||
|
|
||||||
|
k8sLabelArchBeta = "beta.kubernetes.io/arch"
|
||||||
)
|
)
|
||||||
|
|
||||||
type K8sDriver struct {
|
type K8sDriver struct {
|
||||||
|
@ -77,6 +81,7 @@ type K8sDriver struct {
|
||||||
podLister listerscorev1.PodLister
|
podLister listerscorev1.PodLister
|
||||||
cmLister listerscorev1.ConfigMapLister
|
cmLister listerscorev1.ConfigMapLister
|
||||||
leaseLister coordinationlistersv1.LeaseLister
|
leaseLister coordinationlistersv1.LeaseLister
|
||||||
|
k8sLabelArch string
|
||||||
}
|
}
|
||||||
|
|
||||||
type K8sPod struct {
|
type K8sPod struct {
|
||||||
|
@ -106,12 +111,29 @@ func NewK8sDriver(logger *zap.Logger, executorID, toolboxPath string) (*K8sDrive
|
||||||
}
|
}
|
||||||
|
|
||||||
d := &K8sDriver{
|
d := &K8sDriver{
|
||||||
log: logger.Sugar(),
|
log: logger.Sugar(),
|
||||||
restconfig: kubecfg,
|
restconfig: kubecfg,
|
||||||
client: kubecli,
|
client: kubecli,
|
||||||
toolboxPath: toolboxPath,
|
toolboxPath: toolboxPath,
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
executorID: executorID,
|
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()
|
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 != "" {
|
if podConfig.Arch != "" {
|
||||||
pod.Spec.NodeSelector = map[string]string{
|
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
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue