mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
kubeadm: fix WaitForAllControlPlaneComponents with anonymous auth
When the kube-apiserver has --anonymous-auth=false, the regular http.Client.Get() that WaitForAllControlPlaneComponents does will not work. Always use the discovery client when checking the health status of the kube-apiserver. Do a minor rework of struct fields and unit tests. Replace nil client in cmd/phases/join/waitcontrolplane.go.
This commit is contained in:
parent
62555cadc7
commit
310723b21c
@ -67,7 +67,12 @@ func runWaitControlPlanePhase(c workflow.RunData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
waiter, err := newControlPlaneWaiter(data.DryRun(), 0, nil, data.OutputWriter())
|
||||
client, err := data.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
waiter, err := newControlPlaneWaiter(data.DryRun(), 0, client, data.OutputWriter())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating waiter")
|
||||
}
|
||||
|
@ -118,7 +118,8 @@ func NewKubeWaiter(client clientset.Interface, timeout time.Duration, writer io.
|
||||
// on which to perform health checks.
|
||||
type controlPlaneComponent struct {
|
||||
name string
|
||||
url string
|
||||
addressPort string
|
||||
endpoint string
|
||||
}
|
||||
|
||||
// getControlPlaneComponentAddressAndPort parses the command in a static Pod
|
||||
@ -181,7 +182,6 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
||||
|
||||
type componentConfig struct {
|
||||
name string
|
||||
podKey string
|
||||
args []string
|
||||
defaultAddr string
|
||||
defaultPort string
|
||||
@ -190,24 +190,21 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
||||
|
||||
components := []componentConfig{
|
||||
{
|
||||
name: "kube-apiserver",
|
||||
podKey: constants.KubeAPIServer,
|
||||
name: constants.KubeAPIServer,
|
||||
args: []string{argAdvertiseAddress, argPort},
|
||||
defaultAddr: addressAPIServer,
|
||||
defaultPort: portAPIServer,
|
||||
endpoint: endpointLivez,
|
||||
},
|
||||
{
|
||||
name: "kube-controller-manager",
|
||||
podKey: constants.KubeControllerManager,
|
||||
name: constants.KubeControllerManager,
|
||||
args: []string{argBindAddress, argPort},
|
||||
defaultAddr: addressKCM,
|
||||
defaultPort: portKCM,
|
||||
endpoint: endpointHealthz,
|
||||
},
|
||||
{
|
||||
name: "kube-scheduler",
|
||||
podKey: constants.KubeScheduler,
|
||||
name: constants.KubeScheduler,
|
||||
args: []string{argBindAddress, argPort},
|
||||
defaultAddr: addressScheduler,
|
||||
defaultPort: portScheduler,
|
||||
@ -219,8 +216,8 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
||||
address, port := component.defaultAddr, component.defaultPort
|
||||
|
||||
values, err := getControlPlaneComponentAddressAndPort(
|
||||
podMap[component.podKey],
|
||||
component.podKey,
|
||||
podMap[component.name],
|
||||
component.name,
|
||||
component.args,
|
||||
)
|
||||
if err != nil {
|
||||
@ -236,7 +233,8 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
||||
|
||||
result = append(result, controlPlaneComponent{
|
||||
name: component.name,
|
||||
url: fmt.Sprintf("https://%s/%s", net.JoinHostPort(address, port), component.endpoint),
|
||||
addressPort: net.JoinHostPort(address, port),
|
||||
endpoint: component.endpoint,
|
||||
})
|
||||
}
|
||||
|
||||
@ -260,7 +258,8 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, ap
|
||||
errChan := make(chan error, len(components))
|
||||
|
||||
for _, comp := range components {
|
||||
fmt.Printf("[control-plane-check] Checking %s at %s\n", comp.name, comp.url)
|
||||
url := fmt.Sprintf("https://%s/%s", comp.addressPort, comp.endpoint)
|
||||
fmt.Printf("[control-plane-check] Checking %s at %s\n", comp.name, url)
|
||||
|
||||
go func(comp controlPlaneComponent) {
|
||||
tr := &http.Transport{
|
||||
@ -268,6 +267,7 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, ap
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
start := time.Now()
|
||||
statusCode := 0
|
||||
var lastError error
|
||||
|
||||
err := wait.PollUntilContextTimeout(
|
||||
@ -275,18 +275,30 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, ap
|
||||
constants.KubernetesAPICallRetryInterval,
|
||||
w.timeout,
|
||||
true, func(ctx context.Context) (bool, error) {
|
||||
resp, err := client.Get(comp.url)
|
||||
if err != nil {
|
||||
lastError = errors.WithMessagef(err, "%s check failed at %s", comp.name, comp.url)
|
||||
// The kube-apiserver check should use the client defined in the waiter
|
||||
// or otherwise the regular http client can fail when anonymous auth is enabled.
|
||||
if comp.name == constants.KubeAPIServer {
|
||||
result := w.client.Discovery().RESTClient().
|
||||
Get().AbsPath(comp.endpoint).Do(ctx).StatusCode(&statusCode)
|
||||
if err := result.Error(); err != nil {
|
||||
lastError = errors.WithMessagef(err, "%s check failed at %s", comp.name, url)
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
lastError = errors.WithMessagef(err, "%s check failed at %s", comp.name, url)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = resp.Body.Close()
|
||||
}()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
statusCode = resp.StatusCode
|
||||
}
|
||||
|
||||
if statusCode != http.StatusOK {
|
||||
lastError = errors.Errorf("%s check failed at %s with status: %d",
|
||||
comp.name, comp.url, resp.StatusCode)
|
||||
comp.name, url, statusCode)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
@ -73,9 +73,9 @@ func TestGetControlPlaneComponents(t *testing.T) {
|
||||
return podMap
|
||||
},
|
||||
expected: []controlPlaneComponent{
|
||||
{name: "kube-apiserver", url: fmt.Sprintf("https://[fd00:1::]:1111/%s", endpointLivez)},
|
||||
{name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:2222/%s", endpointHealthz)},
|
||||
{name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:3333/%s", endpointLivez)},
|
||||
{name: "kube-apiserver", addressPort: "[fd00:1::]:1111", endpoint: endpointLivez},
|
||||
{name: "kube-controller-manager", addressPort: "127.0.0.1:2222", endpoint: endpointHealthz},
|
||||
{name: "kube-scheduler", addressPort: "127.0.0.1:3333", endpoint: endpointLivez},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -106,9 +106,9 @@ func TestGetControlPlaneComponents(t *testing.T) {
|
||||
return podMap
|
||||
},
|
||||
expected: []controlPlaneComponent{
|
||||
{name: "kube-apiserver", url: fmt.Sprintf("https://[fd00:1::]:1111/%s", endpointLivez)},
|
||||
{name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:2222/%s", endpointHealthz)},
|
||||
{name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:3333/%s", endpointLivez)},
|
||||
{name: "kube-apiserver", addressPort: "[fd00:1::]:1111", endpoint: endpointLivez},
|
||||
{name: "kube-controller-manager", addressPort: "127.0.0.1:2222", endpoint: endpointHealthz},
|
||||
{name: "kube-scheduler", addressPort: "127.0.0.1:3333", endpoint: endpointLivez},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -133,9 +133,9 @@ func TestGetControlPlaneComponents(t *testing.T) {
|
||||
return podMap
|
||||
},
|
||||
expected: []controlPlaneComponent{
|
||||
{name: "kube-apiserver", url: fmt.Sprintf("https://192.168.0.1:6443/%s", endpointLivez)},
|
||||
{name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:10257/%s", endpointHealthz)},
|
||||
{name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:10259/%s", endpointLivez)},
|
||||
{name: "kube-apiserver", addressPort: "192.168.0.1:6443", endpoint: endpointLivez},
|
||||
{name: "kube-controller-manager", addressPort: "127.0.0.1:10257", endpoint: endpointHealthz},
|
||||
{name: "kube-scheduler", addressPort: "127.0.0.1:10259", endpoint: endpointLivez},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user