github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/pkg/runtime/kubernetes/join_nodes.go (about)

     1  // Copyright © 2022 Alibaba Group Holding Ltd.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package kubernetes
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"net"
    21  
    22  	"github.com/sirupsen/logrus"
    23  	"golang.org/x/sync/errgroup"
    24  	"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
    25  
    26  	"github.com/sealerio/sealer/pkg/runtime/kubernetes/kubeadm"
    27  	utilsnet "github.com/sealerio/sealer/utils/net"
    28  	"github.com/sealerio/sealer/utils/yaml"
    29  )
    30  
    31  func (k *Runtime) joinNodes(newNodes, masters []net.IP, kubeadmConfig kubeadm.KubeadmConfig, token v1beta3.BootstrapTokenDiscovery) error {
    32  	if len(newNodes) == 0 {
    33  		return nil
    34  	}
    35  
    36  	//TODO: bugfix: keep the same CRISocket with InitConfiguration
    37  	if err := k.initKube(newNodes); err != nil {
    38  		return err
    39  	}
    40  
    41  	kubeadmConfig.JoinConfiguration.Discovery.BootstrapToken = &token
    42  	kubeadmConfig.JoinConfiguration.Discovery.BootstrapToken.APIServerEndpoint = net.JoinHostPort(k.getAPIServerVIP().String(), "6443")
    43  	kubeadmConfig.JoinConfiguration.ControlPlane = nil
    44  
    45  	if err := k.configureLvs(masters, newNodes); err != nil {
    46  		return fmt.Errorf("failed to configure lvs rule for apiserver: %v", err)
    47  	}
    48  
    49  	eg, _ := errgroup.WithContext(context.Background())
    50  
    51  	for _, n := range newNodes {
    52  		node := n
    53  		eg.Go(func() error {
    54  			logrus.Infof("start to join %s as worker", node)
    55  			joinNodeCmd, err := k.Command(JoinNode, k.getNodeNameOverride(node))
    56  			if err != nil {
    57  				return err
    58  			}
    59  
    60  			myKubeadmConfig := kubeadmConfig
    61  
    62  			if output, err := k.infra.CmdToString(node, nil, GetCustomizeCRISocket, ""); err == nil && output != "" {
    63  				myKubeadmConfig.JoinConfiguration.NodeRegistration.CRISocket = output
    64  			}
    65  			joinConfig, err := yaml.MarshalWithDelimiter(myKubeadmConfig.JoinConfiguration, myKubeadmConfig.KubeletConfiguration)
    66  			if err != nil {
    67  				return err
    68  			}
    69  			writeJoinConfigCmd := fmt.Sprintf("mkdir -p /etc/kubernetes && echo \"%s\" > %s", joinConfig, KubeadmFileYml)
    70  
    71  			err = k.checkMultiNetworkAddVIPRoute(node)
    72  			if err != nil {
    73  				return fmt.Errorf("failed to check multi network: %v", err)
    74  			}
    75  
    76  			if err = k.infra.CmdAsync(node, nil, writeJoinConfigCmd); err != nil {
    77  				return fmt.Errorf("failed to set join kubeadm config on host(%s) with cmd(%s): %v", node, writeJoinConfigCmd, err)
    78  			}
    79  
    80  			if err = k.infra.CmdAsync(node, nil, joinNodeCmd); err != nil {
    81  				return fmt.Errorf("failed to join node %s: %v", node, err)
    82  			}
    83  
    84  			logrus.Infof("succeeded in joining %s as worker", node)
    85  			return nil
    86  		})
    87  	}
    88  	return eg.Wait()
    89  }
    90  
    91  func (k *Runtime) checkMultiNetworkAddVIPRoute(node net.IP) error {
    92  	result, err := k.infra.CmdToString(node, nil, fmt.Sprintf(RemoteCheckRoute, node), "")
    93  	if err != nil {
    94  		return err
    95  	}
    96  	if result == utilsnet.RouteOK {
    97  		return nil
    98  	}
    99  
   100  	cmd := fmt.Sprintf(RemoteAddRoute, k.getAPIServerVIP(), node)
   101  	if _, err := k.infra.Cmd(node, nil, cmd); err != nil {
   102  		return err
   103  	}
   104  	return nil
   105  }