mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +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
|
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 {
|
if err != nil {
|
||||||
return errors.Wrap(err, "error creating waiter")
|
return errors.Wrap(err, "error creating waiter")
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,9 @@ func NewKubeWaiter(client clientset.Interface, timeout time.Duration, writer io.
|
|||||||
// controlPlaneComponent holds a component name and an URL
|
// controlPlaneComponent holds a component name and an URL
|
||||||
// on which to perform health checks.
|
// on which to perform health checks.
|
||||||
type controlPlaneComponent struct {
|
type controlPlaneComponent struct {
|
||||||
name string
|
name string
|
||||||
url string
|
addressPort string
|
||||||
|
endpoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
// getControlPlaneComponentAddressAndPort parses the command in a static Pod
|
// getControlPlaneComponentAddressAndPort parses the command in a static Pod
|
||||||
@ -181,7 +182,6 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
|||||||
|
|
||||||
type componentConfig struct {
|
type componentConfig struct {
|
||||||
name string
|
name string
|
||||||
podKey string
|
|
||||||
args []string
|
args []string
|
||||||
defaultAddr string
|
defaultAddr string
|
||||||
defaultPort string
|
defaultPort string
|
||||||
@ -190,24 +190,21 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
|||||||
|
|
||||||
components := []componentConfig{
|
components := []componentConfig{
|
||||||
{
|
{
|
||||||
name: "kube-apiserver",
|
name: constants.KubeAPIServer,
|
||||||
podKey: constants.KubeAPIServer,
|
|
||||||
args: []string{argAdvertiseAddress, argPort},
|
args: []string{argAdvertiseAddress, argPort},
|
||||||
defaultAddr: addressAPIServer,
|
defaultAddr: addressAPIServer,
|
||||||
defaultPort: portAPIServer,
|
defaultPort: portAPIServer,
|
||||||
endpoint: endpointLivez,
|
endpoint: endpointLivez,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "kube-controller-manager",
|
name: constants.KubeControllerManager,
|
||||||
podKey: constants.KubeControllerManager,
|
|
||||||
args: []string{argBindAddress, argPort},
|
args: []string{argBindAddress, argPort},
|
||||||
defaultAddr: addressKCM,
|
defaultAddr: addressKCM,
|
||||||
defaultPort: portKCM,
|
defaultPort: portKCM,
|
||||||
endpoint: endpointHealthz,
|
endpoint: endpointHealthz,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "kube-scheduler",
|
name: constants.KubeScheduler,
|
||||||
podKey: constants.KubeScheduler,
|
|
||||||
args: []string{argBindAddress, argPort},
|
args: []string{argBindAddress, argPort},
|
||||||
defaultAddr: addressScheduler,
|
defaultAddr: addressScheduler,
|
||||||
defaultPort: portScheduler,
|
defaultPort: portScheduler,
|
||||||
@ -219,8 +216,8 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
|||||||
address, port := component.defaultAddr, component.defaultPort
|
address, port := component.defaultAddr, component.defaultPort
|
||||||
|
|
||||||
values, err := getControlPlaneComponentAddressAndPort(
|
values, err := getControlPlaneComponentAddressAndPort(
|
||||||
podMap[component.podKey],
|
podMap[component.name],
|
||||||
component.podKey,
|
component.name,
|
||||||
component.args,
|
component.args,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -235,8 +232,9 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, controlPlaneComponent{
|
result = append(result, controlPlaneComponent{
|
||||||
name: component.name,
|
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))
|
errChan := make(chan error, len(components))
|
||||||
|
|
||||||
for _, comp := range 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) {
|
go func(comp controlPlaneComponent) {
|
||||||
tr := &http.Transport{
|
tr := &http.Transport{
|
||||||
@ -268,6 +267,7 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, ap
|
|||||||
}
|
}
|
||||||
client := &http.Client{Transport: tr}
|
client := &http.Client{Transport: tr}
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
statusCode := 0
|
||||||
var lastError error
|
var lastError error
|
||||||
|
|
||||||
err := wait.PollUntilContextTimeout(
|
err := wait.PollUntilContextTimeout(
|
||||||
@ -275,18 +275,30 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, ap
|
|||||||
constants.KubernetesAPICallRetryInterval,
|
constants.KubernetesAPICallRetryInterval,
|
||||||
w.timeout,
|
w.timeout,
|
||||||
true, func(ctx context.Context) (bool, error) {
|
true, func(ctx context.Context) (bool, error) {
|
||||||
resp, err := client.Get(comp.url)
|
// The kube-apiserver check should use the client defined in the waiter
|
||||||
if err != nil {
|
// or otherwise the regular http client can fail when anonymous auth is enabled.
|
||||||
lastError = errors.WithMessagef(err, "%s check failed at %s", comp.name, comp.url)
|
if comp.name == constants.KubeAPIServer {
|
||||||
return false, nil
|
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()
|
||||||
|
}()
|
||||||
|
statusCode = resp.StatusCode
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
if statusCode != http.StatusOK {
|
||||||
_ = resp.Body.Close()
|
|
||||||
}()
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
lastError = errors.Errorf("%s check failed at %s with status: %d",
|
lastError = errors.Errorf("%s check failed at %s with status: %d",
|
||||||
comp.name, comp.url, resp.StatusCode)
|
comp.name, url, statusCode)
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,9 +73,9 @@ func TestGetControlPlaneComponents(t *testing.T) {
|
|||||||
return podMap
|
return podMap
|
||||||
},
|
},
|
||||||
expected: []controlPlaneComponent{
|
expected: []controlPlaneComponent{
|
||||||
{name: "kube-apiserver", url: fmt.Sprintf("https://[fd00:1::]:1111/%s", endpointLivez)},
|
{name: "kube-apiserver", addressPort: "[fd00:1::]:1111", endpoint: endpointLivez},
|
||||||
{name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:2222/%s", endpointHealthz)},
|
{name: "kube-controller-manager", addressPort: "127.0.0.1:2222", endpoint: endpointHealthz},
|
||||||
{name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:3333/%s", endpointLivez)},
|
{name: "kube-scheduler", addressPort: "127.0.0.1:3333", endpoint: endpointLivez},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -106,9 +106,9 @@ func TestGetControlPlaneComponents(t *testing.T) {
|
|||||||
return podMap
|
return podMap
|
||||||
},
|
},
|
||||||
expected: []controlPlaneComponent{
|
expected: []controlPlaneComponent{
|
||||||
{name: "kube-apiserver", url: fmt.Sprintf("https://[fd00:1::]:1111/%s", endpointLivez)},
|
{name: "kube-apiserver", addressPort: "[fd00:1::]:1111", endpoint: endpointLivez},
|
||||||
{name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:2222/%s", endpointHealthz)},
|
{name: "kube-controller-manager", addressPort: "127.0.0.1:2222", endpoint: endpointHealthz},
|
||||||
{name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:3333/%s", endpointLivez)},
|
{name: "kube-scheduler", addressPort: "127.0.0.1:3333", endpoint: endpointLivez},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -133,9 +133,9 @@ func TestGetControlPlaneComponents(t *testing.T) {
|
|||||||
return podMap
|
return podMap
|
||||||
},
|
},
|
||||||
expected: []controlPlaneComponent{
|
expected: []controlPlaneComponent{
|
||||||
{name: "kube-apiserver", url: fmt.Sprintf("https://192.168.0.1:6443/%s", endpointLivez)},
|
{name: "kube-apiserver", addressPort: "192.168.0.1:6443", endpoint: endpointLivez},
|
||||||
{name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:10257/%s", endpointHealthz)},
|
{name: "kube-controller-manager", addressPort: "127.0.0.1:10257", endpoint: endpointHealthz},
|
||||||
{name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:10259/%s", endpointLivez)},
|
{name: "kube-scheduler", addressPort: "127.0.0.1:10259", endpoint: endpointLivez},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user