mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 05:57:25 +00:00
Merge pull request #47348 from luxas/kubeadm_remove_validate_phase
Automatic merge from submit-queue kubeadm: Remove the validate phase as it's not needed **What this PR does / why we need it**: This validation code was added in v1.4 as a way to remove flakiness between deploying the control plane in Static Pods and deploying kube-discovery as a Deployment. That isn't the case anymore and we're not experiencing such flakiness, as we're using other methods like checking `/healthz` to determine a healthy control plane before proceeding. https://github.com/kubernetes/kubernetes/pull/43881 removed this logic from `kubeadm init` to having it as a phase. But that phase isn't needed or used in any way, so now I'm removing it here. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes # **Special notes for your reviewer**: Targets v1.8 **Release note**: ```release-note NONE ``` @kubernetes/sig-cluster-lifecycle-pr-reviews @timothysc @mikedanese
This commit is contained in:
commit
f9bf1f3b06
@ -42,7 +42,6 @@ filegroup(
|
|||||||
"//cmd/kubeadm/app/phases/certs:all-srcs",
|
"//cmd/kubeadm/app/phases/certs:all-srcs",
|
||||||
"//cmd/kubeadm/app/phases/kubeconfig:all-srcs",
|
"//cmd/kubeadm/app/phases/kubeconfig:all-srcs",
|
||||||
"//cmd/kubeadm/app/phases/token:all-srcs",
|
"//cmd/kubeadm/app/phases/token:all-srcs",
|
||||||
"//cmd/kubeadm/app/phases/validate:all-srcs",
|
|
||||||
"//cmd/kubeadm/app/preflight:all-srcs",
|
"//cmd/kubeadm/app/preflight:all-srcs",
|
||||||
"//cmd/kubeadm/app/util:all-srcs",
|
"//cmd/kubeadm/app/util:all-srcs",
|
||||||
],
|
],
|
||||||
|
@ -14,7 +14,6 @@ go_library(
|
|||||||
"kubeconfig.go",
|
"kubeconfig.go",
|
||||||
"phase.go",
|
"phase.go",
|
||||||
"preflight.go",
|
"preflight.go",
|
||||||
"validate.go",
|
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
@ -23,7 +22,6 @@ go_library(
|
|||||||
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/validate:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||||
"//cmd/kubeadm/app/util:go_default_library",
|
"//cmd/kubeadm/app/util:go_default_library",
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
@ -32,7 +32,6 @@ func NewCmdPhase(out io.Writer) *cobra.Command {
|
|||||||
|
|
||||||
cmd.AddCommand(NewCmdKubeConfig(out))
|
cmd.AddCommand(NewCmdKubeConfig(out))
|
||||||
cmd.AddCommand(NewCmdCerts())
|
cmd.AddCommand(NewCmdCerts())
|
||||||
cmd.AddCommand(NewCmdValidate())
|
|
||||||
cmd.AddCommand(NewCmdPreFlight())
|
cmd.AddCommand(NewCmdPreFlight())
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2017 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package phases
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/validate"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewCmdValidate() *cobra.Command {
|
|
||||||
var kubeconfig string
|
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Use: "validate",
|
|
||||||
Short: "Run end to end validation",
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
|
|
||||||
return validate.Validate(kubeconfig)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: what's the convention for defaulting a kubeconfig?
|
|
||||||
cmd.Flags().StringVar(&kubeconfig, "kubeconfig", os.Getenv("HOME")+"/.kube/config", "path to kubeconfig")
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
licenses(["notice"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = ["validate.go"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
deps = [
|
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/util:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
|
||||||
"//pkg/api:go_default_library",
|
|
||||||
"//pkg/api/v1/node:go_default_library",
|
|
||||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2017 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package validate
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
extensions "k8s.io/api/extensions/v1beta1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
kuberuntime "k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
|
||||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
|
||||||
nodeutil "k8s.io/kubernetes/pkg/api/v1/node"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Validate(kubeconfigPath string) error {
|
|
||||||
client, err := kubeconfigutil.ClientSetFromFile(kubeconfigPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println("[validate] Waiting for at least one node to register and become ready")
|
|
||||||
start := time.Now()
|
|
||||||
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
|
||||||
nodeList, err := client.Nodes().List(metav1.ListOptions{})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("[validate] Temporarily unable to list nodes (will retry)")
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
if len(nodeList.Items) < 1 {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
n := &nodeList.Items[0]
|
|
||||||
if !nodeutil.IsNodeReady(n) {
|
|
||||||
fmt.Println("[validate] First node has registered, but is not ready yet")
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("[validate] First node is ready after %f seconds\n", time.Since(start).Seconds())
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
if err := createAndWaitForADummyDeployment(client); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createAndWaitForADummyDeployment(client *clientset.Clientset) error {
|
|
||||||
dummyDeploymentBytes, err := kubeadmutil.ParseTemplate(DummyDeployment, struct{ ImageRepository, Arch string }{
|
|
||||||
ImageRepository: kubeadmapi.GlobalEnvParams.RepositoryPrefix,
|
|
||||||
Arch: runtime.GOARCH,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error when parsing dummy deployment template: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dummyDeployment := &extensions.Deployment{}
|
|
||||||
if err := kuberuntime.DecodeInto(api.Codecs.UniversalDecoder(), dummyDeploymentBytes, dummyDeployment); err != nil {
|
|
||||||
return fmt.Errorf("unable to decode dummy deployment %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
|
||||||
// TODO: we should check the error, as some cases may be fatal
|
|
||||||
if _, err := client.ExtensionsV1beta1().Deployments(metav1.NamespaceSystem).Create(dummyDeployment); err != nil {
|
|
||||||
fmt.Printf("[validate] Failed to create test deployment [%v] (will retry)\n", err)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
|
||||||
d, err := client.ExtensionsV1beta1().Deployments(metav1.NamespaceSystem).Get("dummy", metav1.GetOptions{})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("[validate] Failed to get test deployment [%v] (will retry)\n", err)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
if d.Status.AvailableReplicas < 1 {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println("[validate] Test deployment succeeded")
|
|
||||||
|
|
||||||
foreground := metav1.DeletePropagationForeground
|
|
||||||
if err := client.ExtensionsV1beta1().Deployments(metav1.NamespaceSystem).Delete("dummy", &metav1.DeleteOptions{
|
|
||||||
PropagationPolicy: &foreground,
|
|
||||||
}); err != nil {
|
|
||||||
fmt.Printf("[validate] Failed to delete test deployment [%v] (will ignore)\n", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
DummyDeployment = `
|
|
||||||
apiVersion: extensions/v1beta1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: dummy
|
|
||||||
name: dummy
|
|
||||||
namespace: kube-system
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: dummy
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: dummy
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- image: {{ .ImageRepository }}/pause-{{ .Arch }}:3.0
|
|
||||||
name: dummy
|
|
||||||
hostNetwork: true
|
|
||||||
`
|
|
||||||
)
|
|
Loading…
Reference in New Issue
Block a user