github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/pkg/cluster-runtime/scale.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 clusterruntime
    16  
    17  import (
    18  	"fmt"
    19  	"net"
    20  
    21  	netutils "github.com/sealerio/sealer/utils/net"
    22  
    23  	"github.com/sealerio/sealer/common"
    24  	"github.com/sealerio/sealer/pkg/registry"
    25  	"github.com/sealerio/sealer/pkg/runtime"
    26  	"github.com/sirupsen/logrus"
    27  )
    28  
    29  func (i *Installer) ScaleUp(newMasters, newWorkers []net.IP) (registry.Driver, runtime.Driver, error) {
    30  	masters := i.infraDriver.GetHostIPListByRole(common.MASTER)
    31  	master0 := masters[0]
    32  	workers := getWorkerIPList(i.infraDriver)
    33  	registryDeployHosts := []net.IP{master0}
    34  	all := append(newMasters, newWorkers...)
    35  	rootfs := i.infraDriver.GetClusterRootfsPath()
    36  
    37  	logrus.Debug("check ssh of new nodes")
    38  	_, err := CheckNodeSSH(i.infraDriver, append(newMasters, newWorkers...))
    39  	if err != nil {
    40  		return nil, nil, err
    41  	}
    42  
    43  	if len(newMasters) != 0 {
    44  		logrus.Debug("check ssh of workers")
    45  		_, err = CheckNodeSSH(i.infraDriver, workers)
    46  		if err != nil {
    47  			return nil, nil, err
    48  		}
    49  	}
    50  
    51  	// set HostAlias
    52  	if err := i.infraDriver.SetClusterHostAliases(all); err != nil {
    53  		return nil, nil, err
    54  	}
    55  	// distribute rootfs
    56  	if err := i.Distributor.Distribute(all, rootfs); err != nil {
    57  		return nil, nil, err
    58  	}
    59  
    60  	if err := i.runClusterHook(master0, PreScaleUpCluster); err != nil {
    61  		return nil, nil, err
    62  	}
    63  
    64  	if err := i.runHostHook(PreInitHost, all); err != nil {
    65  		return nil, nil, err
    66  	}
    67  
    68  	if err := i.containerRuntimeInstaller.InstallOn(all); err != nil {
    69  		return nil, nil, err
    70  	}
    71  
    72  	crInfo, err := i.containerRuntimeInstaller.GetInfo()
    73  	if err != nil {
    74  		return nil, nil, err
    75  	}
    76  
    77  	// reconcile registry node if local registry is ha mode.
    78  	if i.regConfig.LocalRegistry != nil && *i.regConfig.LocalRegistry.HA {
    79  		registryDeployHosts, err = registry.NewInstaller(netutils.RemoveIPs(masters, newMasters), i.regConfig.LocalRegistry, i.infraDriver, i.Distributor).Reconcile(masters)
    80  		if err != nil {
    81  			return nil, nil, err
    82  		}
    83  	}
    84  
    85  	registryConfigurator, err := registry.NewConfigurator(registryDeployHosts, crInfo, i.regConfig, i.infraDriver, i.Distributor)
    86  	if err != nil {
    87  		return nil, nil, err
    88  	}
    89  
    90  	if err = registryConfigurator.InstallOn(newMasters, newWorkers); err != nil {
    91  		return nil, nil, err
    92  	}
    93  
    94  	registryDriver, err := registryConfigurator.GetDriver()
    95  	if err != nil {
    96  		return nil, nil, err
    97  	}
    98  
    99  	kubeRuntimeInstaller, err := getClusterRuntimeInstaller(i.clusterRuntimeType, i.infraDriver,
   100  		crInfo, registryDriver.GetInfo(), i.KubeadmConfig)
   101  	if err != nil {
   102  		return nil, nil, err
   103  	}
   104  
   105  	if err := kubeRuntimeInstaller.ScaleUp(newMasters, newWorkers); err != nil {
   106  		return nil, nil, err
   107  	}
   108  
   109  	if err := i.runHostHook(PostInitHost, all); err != nil {
   110  		return nil, nil, err
   111  	}
   112  
   113  	if err := i.runClusterHook(master0, PostScaleUpCluster); err != nil {
   114  		return nil, nil, err
   115  	}
   116  
   117  	runtimeDriver, err := kubeRuntimeInstaller.GetCurrentRuntimeDriver()
   118  	if err != nil {
   119  		return nil, nil, err
   120  	}
   121  
   122  	if err := i.setRoles(runtimeDriver); err != nil {
   123  		return nil, nil, err
   124  	}
   125  
   126  	if err := i.setNodeLabels(all, runtimeDriver); err != nil {
   127  		return nil, nil, err
   128  	}
   129  
   130  	if err = i.setNodeTaints(all, runtimeDriver); err != nil {
   131  		return nil, nil, err
   132  	}
   133  
   134  	return registryDriver, runtimeDriver, nil
   135  }
   136  
   137  func (i *Installer) ScaleDown(mastersToDelete, workersToDelete []net.IP) (registry.Driver, runtime.Driver, error) {
   138  	masters := i.infraDriver.GetHostIPListByRole(common.MASTER)
   139  	master0 := masters[0]
   140  	workers := getWorkerIPList(i.infraDriver)
   141  	remainWorkers := netutils.RemoveIPs(workers, workersToDelete)
   142  
   143  	crInfo, err := i.containerRuntimeInstaller.GetInfo()
   144  	if err != nil {
   145  		return nil, nil, err
   146  	}
   147  
   148  	registryDeployHosts := []net.IP{master0}
   149  	// reconcile registry node if local registry is ha mode.
   150  	if i.regConfig.LocalRegistry != nil && *i.regConfig.LocalRegistry.HA {
   151  		registryDeployHosts, err = registry.NewInstaller(masters, i.regConfig.LocalRegistry, i.infraDriver, i.Distributor).Reconcile(netutils.RemoveIPs(masters, mastersToDelete))
   152  		if err != nil {
   153  			return nil, nil, err
   154  		}
   155  	}
   156  
   157  	registryConfigurator, err := registry.NewConfigurator(registryDeployHosts, crInfo, i.regConfig, i.infraDriver, i.Distributor)
   158  	if err != nil {
   159  		return nil, nil, err
   160  	}
   161  
   162  	registryDriver, err := registryConfigurator.GetDriver()
   163  	if err != nil {
   164  		return nil, nil, err
   165  	}
   166  
   167  	kubeRuntimeInstaller, err := getClusterRuntimeInstaller(i.clusterRuntimeType, i.infraDriver,
   168  		crInfo, registryDriver.GetInfo(), i.KubeadmConfig)
   169  	if err != nil {
   170  		return nil, nil, err
   171  	}
   172  
   173  	runtimeDriver, err := kubeRuntimeInstaller.GetCurrentRuntimeDriver()
   174  	if err != nil {
   175  		return nil, nil, err
   176  	}
   177  
   178  	if len(mastersToDelete) != 0 {
   179  		logrus.Debug("check ssh of remainWorkers")
   180  		_, err := CheckNodeSSH(i.infraDriver, remainWorkers)
   181  		if err != nil {
   182  			return nil, nil, fmt.Errorf("because master list changed, we need connect to all existing workers to maintain some configs, but failed: %v", err)
   183  		}
   184  	}
   185  
   186  	logrus.Debug("check ssh of nodesToDelete")
   187  	disconnetedMasters, err := CheckNodeSSH(i.infraDriver, mastersToDelete)
   188  	if err != nil {
   189  		logrus.Warn(err.Error())
   190  	}
   191  	disconnetedWorkers, err := CheckNodeSSH(i.infraDriver, workersToDelete)
   192  	if err != nil {
   193  		logrus.Warn(err.Error())
   194  	}
   195  
   196  	if err := i.resetAndScaleDown(kubeRuntimeInstaller, registryConfigurator, netutils.RemoveIPs(mastersToDelete, disconnetedMasters), netutils.RemoveIPs(workersToDelete, disconnetedWorkers)); err != nil {
   197  		return nil, nil, err
   198  	}
   199  
   200  	if err := i.onlyScaleDown(kubeRuntimeInstaller, disconnetedMasters, disconnetedWorkers); err != nil {
   201  		return nil, nil, err
   202  	}
   203  
   204  	return registryDriver, runtimeDriver, nil
   205  }
   206  
   207  func (i *Installer) resetAndScaleDown(kubeRuntimeInstaller runtime.Installer, registryConfigurator registry.Configurator, mastersToDelete, workersToDelete []net.IP) error {
   208  	allToDelete := append(mastersToDelete, workersToDelete...)
   209  
   210  	if err := i.runHostHook(PreCleanHost, allToDelete); err != nil {
   211  		return err
   212  	}
   213  
   214  	if err := kubeRuntimeInstaller.ScaleDown(mastersToDelete, workersToDelete); err != nil {
   215  		return err
   216  	}
   217  
   218  	if err := registryConfigurator.UninstallFrom(mastersToDelete, workersToDelete); err != nil {
   219  		return err
   220  	}
   221  
   222  	if err := i.containerRuntimeInstaller.UnInstallFrom(allToDelete); err != nil {
   223  		return err
   224  	}
   225  
   226  	if err := i.runHostHook(PostCleanHost, allToDelete); err != nil {
   227  		return err
   228  	}
   229  
   230  	// delete HostAlias
   231  	if err := i.infraDriver.DeleteClusterHostAliases(allToDelete); err != nil {
   232  		return err
   233  	}
   234  
   235  	if err := i.Distributor.Restore(i.infraDriver.GetClusterBasePath(), allToDelete); err != nil {
   236  		return err
   237  	}
   238  
   239  	return nil
   240  }
   241  
   242  func (i *Installer) onlyScaleDown(kubeRuntimeInstaller runtime.Installer, mastersToDelete, workersToDelete []net.IP) error {
   243  	if err := kubeRuntimeInstaller.ScaleDown(mastersToDelete, workersToDelete); err != nil {
   244  		return err
   245  	}
   246  
   247  	return nil
   248  }