mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
Merge pull request #68639 from liggitt/scheduler-legacy-config
Coerce componentconfig/v1alpha1 KubeSchedulerConfiguration to kubescheduler.config.k8s.io/v1alpha1
This commit is contained in:
commit
7b62ae3186
@ -20,9 +20,12 @@ go_library(
|
|||||||
"//pkg/scheduler/apis/config/validation:go_default_library",
|
"//pkg/scheduler/apis/config/validation:go_default_library",
|
||||||
"//pkg/scheduler/factory:go_default_library",
|
"//pkg/scheduler/factory:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/config:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/config:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
|
@ -17,11 +17,16 @@ limitations under the License.
|
|||||||
package options
|
package options
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||||
kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
kubeschedulerscheme "k8s.io/kubernetes/pkg/scheduler/apis/config/scheme"
|
kubeschedulerscheme "k8s.io/kubernetes/pkg/scheduler/apis/config/scheme"
|
||||||
@ -40,8 +45,48 @@ func loadConfigFromFile(file string) (*kubeschedulerconfig.KubeSchedulerConfigur
|
|||||||
func loadConfig(data []byte) (*kubeschedulerconfig.KubeSchedulerConfiguration, error) {
|
func loadConfig(data []byte) (*kubeschedulerconfig.KubeSchedulerConfiguration, error) {
|
||||||
configObj := &kubeschedulerconfig.KubeSchedulerConfiguration{}
|
configObj := &kubeschedulerconfig.KubeSchedulerConfiguration{}
|
||||||
if err := runtime.DecodeInto(kubeschedulerscheme.Codecs.UniversalDecoder(), data, configObj); err != nil {
|
if err := runtime.DecodeInto(kubeschedulerscheme.Codecs.UniversalDecoder(), data, configObj); err != nil {
|
||||||
|
|
||||||
|
// if this is a componentconfig/v1alpha1 KubeSchedulerConfiguration object, coerce it to kubescheduler.config.k8s.io/v1alpha1 with a warning
|
||||||
|
// TODO: drop this block in 1.13
|
||||||
|
if runtime.IsNotRegisteredError(err) {
|
||||||
|
originalErr := err
|
||||||
|
var (
|
||||||
|
u = &unstructured.Unstructured{}
|
||||||
|
codec = json.NewYAMLSerializer(json.DefaultMetaFactory, kubeschedulerscheme.Scheme, kubeschedulerscheme.Scheme)
|
||||||
|
legacyConfigGVK = schema.GroupVersionKind{Group: "componentconfig", Version: "v1alpha1", Kind: "KubeSchedulerConfiguration"}
|
||||||
|
)
|
||||||
|
// attempt to decode to an unstructured object
|
||||||
|
obj, gvk, err := codec.Decode(data, nil, u)
|
||||||
|
|
||||||
|
// if this errored, or the object we read was not the legacy alpha gvk, return the original error
|
||||||
|
if err != nil || gvk == nil || *gvk != legacyConfigGVK {
|
||||||
|
return nil, originalErr
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("WARNING: the provided config file is an unsupported apiVersion (%q), which will be removed in future releases\n\n", legacyConfigGVK.GroupVersion().String())
|
||||||
|
fmt.Printf("WARNING: switch to command-line flags or update your config file apiVersion to %q\n\n", kubeschedulerconfigv1alpha1.SchemeGroupVersion.String())
|
||||||
|
fmt.Printf("WARNING: apiVersions at alpha-level are not guaranteed to be supported in future releases\n\n")
|
||||||
|
|
||||||
|
// attempt to coerce to the new alpha gvk
|
||||||
|
if err := meta.NewAccessor().SetAPIVersion(obj, kubeschedulerconfigv1alpha1.SchemeGroupVersion.String()); err != nil {
|
||||||
|
// return the original error on failure
|
||||||
|
return nil, originalErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to encode the coerced apiVersion back to bytes
|
||||||
|
buffer := bytes.NewBuffer([]byte{})
|
||||||
|
if err := codec.Encode(obj, buffer); err != nil {
|
||||||
|
// return the original error on failure
|
||||||
|
return nil, originalErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-attempt to load the coerced apiVersion
|
||||||
|
return loadConfig(buffer.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return configObj, nil
|
return configObj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +111,17 @@ leaderElection:
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invalidconfigFile := filepath.Join(tmpDir, "scheduler_invalid.yaml")
|
||||||
|
if err := ioutil.WriteFile(invalidconfigFile, []byte(fmt.Sprintf(`
|
||||||
|
apiVersion: componentconfig/v1alpha2
|
||||||
|
kind: KubeSchedulerConfiguration
|
||||||
|
clientConnection:
|
||||||
|
kubeconfig: "%s"
|
||||||
|
leaderElection:
|
||||||
|
leaderElect: true`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// flag-specified kubeconfig
|
// flag-specified kubeconfig
|
||||||
flagKubeconfig := filepath.Join(tmpDir, "flag.kubeconfig")
|
flagKubeconfig := filepath.Join(tmpDir, "flag.kubeconfig")
|
||||||
if err := ioutil.WriteFile(flagKubeconfig, []byte(fmt.Sprintf(`
|
if err := ioutil.WriteFile(flagKubeconfig, []byte(fmt.Sprintf(`
|
||||||
@ -195,9 +206,53 @@ users:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "config file in componentconfig/v1alpha1",
|
name: "config file in componentconfig/v1alpha1",
|
||||||
options: &Options{ConfigFile: oldconfigFile},
|
options: &Options{
|
||||||
expectedError: "no kind \"KubeSchedulerConfiguration\" is registered for version \"componentconfig/v1alpha1\" in scheme",
|
ConfigFile: oldconfigFile,
|
||||||
|
ComponentConfig: func() kubeschedulerconfig.KubeSchedulerConfiguration {
|
||||||
|
cfg, err := newDefaultComponentConfig()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return *cfg
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
// TODO: switch this to expect an error in 1.13 when the special-case coercion is removed from loadConfig
|
||||||
|
// expectedError: "no kind \"KubeSchedulerConfiguration\" is registered for version \"componentconfig/v1alpha1\"",
|
||||||
|
expectedUsername: "config",
|
||||||
|
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
||||||
|
SchedulerName: "default-scheduler",
|
||||||
|
AlgorithmSource: kubeschedulerconfig.SchedulerAlgorithmSource{Provider: &defaultSource},
|
||||||
|
HardPodAffinitySymmetricWeight: 1,
|
||||||
|
HealthzBindAddress: "0.0.0.0:10251",
|
||||||
|
MetricsBindAddress: "0.0.0.0:10251",
|
||||||
|
FailureDomains: "kubernetes.io/hostname,failure-domain.beta.kubernetes.io/zone,failure-domain.beta.kubernetes.io/region",
|
||||||
|
LeaderElection: kubeschedulerconfig.KubeSchedulerLeaderElectionConfiguration{
|
||||||
|
LeaderElectionConfiguration: apiserverconfig.LeaderElectionConfiguration{
|
||||||
|
LeaderElect: true,
|
||||||
|
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
||||||
|
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
||||||
|
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
||||||
|
ResourceLock: "endpoints",
|
||||||
|
},
|
||||||
|
LockObjectNamespace: "kube-system",
|
||||||
|
LockObjectName: "kube-scheduler",
|
||||||
|
},
|
||||||
|
ClientConnection: apimachineryconfig.ClientConnectionConfiguration{
|
||||||
|
Kubeconfig: configKubeconfig,
|
||||||
|
QPS: 50,
|
||||||
|
Burst: 100,
|
||||||
|
ContentType: "application/vnd.kubernetes.protobuf",
|
||||||
|
},
|
||||||
|
PercentageOfNodesToScore: 50,
|
||||||
|
BindTimeoutSeconds: &defaultBindTimeoutSeconds,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "invalid config file in componentconfig/v1alpha2",
|
||||||
|
options: &Options{ConfigFile: invalidconfigFile},
|
||||||
|
expectedError: "no kind \"KubeSchedulerConfiguration\" is registered for version \"componentconfig/v1alpha2\"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "kubeconfig flag",
|
name: "kubeconfig flag",
|
||||||
|
Loading…
Reference in New Issue
Block a user