github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/pkg/runtime/kubernetes/runtime.go (about) 1 // Copyright © 2021 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 "bytes" 19 "context" 20 "fmt" 21 "net" 22 "os" 23 "path" 24 "path/filepath" 25 26 "github.com/sirupsen/logrus" 27 corev1 "k8s.io/api/core/v1" 28 apierrors "k8s.io/apimachinery/pkg/api/errors" 29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 30 k8snet "k8s.io/utils/net" 31 runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" 32 33 "github.com/sealerio/sealer/common" 34 containerruntime "github.com/sealerio/sealer/pkg/container-runtime" 35 "github.com/sealerio/sealer/pkg/infradriver" 36 "github.com/sealerio/sealer/pkg/registry" 37 "github.com/sealerio/sealer/pkg/runtime" 38 "github.com/sealerio/sealer/pkg/runtime/kubernetes/kubeadm" 39 "github.com/sealerio/sealer/utils" 40 utilsnet "github.com/sealerio/sealer/utils/net" 41 ) 42 43 type Config struct { 44 Vlog int 45 VIP string 46 RegistryInfo registry.Info 47 containerRuntimeInfo containerruntime.Info 48 KubeadmConfigFromClusterFile kubeadm.KubeadmConfig 49 APIServerDomain string 50 } 51 52 // Runtime struct is the runtime interface for kubernetes 53 type Runtime struct { 54 infra infradriver.InfraDriver 55 Config *Config 56 } 57 58 func NewKubeadmRuntime(clusterFileKubeConfig kubeadm.KubeadmConfig, infra infradriver.InfraDriver, containerRuntimeInfo containerruntime.Info, registryInfo registry.Info) (runtime.Installer, error) { 59 k := &Runtime{ 60 infra: infra, 61 Config: &Config{ 62 KubeadmConfigFromClusterFile: clusterFileKubeConfig, 63 APIServerDomain: common.DefaultAPIserverDomain, 64 VIP: common.DefaultVIP, 65 RegistryInfo: registryInfo, 66 containerRuntimeInfo: containerRuntimeInfo, 67 }, 68 } 69 70 if hosts := infra.GetHostIPList(); len(hosts) > 0 && k8snet.IsIPv6(hosts[0]) { 71 k.Config.VIP = common.DefaultVIPForIPv6 72 } 73 74 if ipv4, ok := infra.GetClusterEnv()[common.EnvIPvsVIPForIPv4]; ok { 75 k.Config.VIP = ipv4 76 } 77 78 if ipv6, ok := infra.GetClusterEnv()[common.EnvIPvsVIPForIPv6]; ok { 79 k.Config.VIP = ipv6 80 } 81 82 if logrus.GetLevel() == logrus.DebugLevel { 83 k.Config.Vlog = 6 84 } 85 86 return k, nil 87 } 88 89 func (k *Runtime) Install() error { 90 masters := k.infra.GetHostIPListByRole(common.MASTER) 91 workers := k.infra.GetHostIPListByRole(common.NODE) 92 93 kubeadmConf, err := k.initKubeadmConfig(masters) 94 if err != nil { 95 return err 96 } 97 98 if err = k.generateCert(kubeadmConf, masters[0]); err != nil { 99 return err 100 } 101 102 if err = k.createKubeConfig(masters[0]); err != nil { 103 return err 104 } 105 106 if err = k.copyStaticFiles(masters[0:1]); err != nil { 107 return err 108 } 109 110 token, certKey, err := k.initMaster0(masters[0]) 111 if err != nil { 112 return err 113 } 114 115 if err = k.joinMasters(masters[1:], masters[0], kubeadmConf, token, certKey); err != nil { 116 return err 117 } 118 119 if err = k.joinNodes(workers, masters, kubeadmConf, token); err != nil { 120 return err 121 } 122 123 driver, err := k.GetCurrentRuntimeDriver() 124 if err != nil { 125 return err 126 } 127 128 if err := k.dumpKubeConfigIntoCluster(driver, masters[0]); err != nil { 129 return err 130 } 131 132 logrus.Info("succeeded in creating a new cluster.") 133 return nil 134 } 135 136 func (k *Runtime) GetCurrentRuntimeDriver() (runtime.Driver, error) { 137 return NewKubeDriver(AdminKubeConfPath) 138 } 139 140 func (k *Runtime) Upgrade() error { 141 panic("now not support upgrade") 142 } 143 144 func (k *Runtime) Reset() error { 145 masters := k.infra.GetHostIPListByRole(common.MASTER) 146 workers := k.infra.GetHostIPListByRole(common.NODE) 147 return k.reset(masters, workers) 148 } 149 150 func (k *Runtime) ScaleUp(newMasters, newWorkers []net.IP) error { 151 masters := k.infra.GetHostIPListByRole(common.MASTER) 152 workers := k.infra.GetHostIPListByRole(common.NODE) 153 154 kubeadmConfig, err := kubeadm.LoadKubeadmConfigs(path.Join(k.infra.GetClusterRootfsPath(), "kubeadm.yaml"), utils.DecodeCRDFromFile) 155 if err != nil { 156 return err 157 } 158 159 token, certKey, err := k.getJoinTokenHashAndKey(masters[0]) 160 if err != nil { 161 return err 162 } 163 164 if err = k.joinMasters(newMasters, masters[0], kubeadmConfig, token, certKey); err != nil { 165 return err 166 } 167 168 if len(newMasters) > 0 { 169 oldWorkers := utilsnet.RemoveIPs(workers, newWorkers) 170 if err := k.configureLvs(masters, oldWorkers); err != nil { 171 return err 172 } 173 } 174 175 if err = k.joinNodes(newWorkers, masters, kubeadmConfig, token); err != nil { 176 return err 177 } 178 179 logrus.Info("cluster scale up succeeded!") 180 return nil 181 } 182 183 func (k *Runtime) ScaleDown(mastersToDelete, workersToDelete []net.IP) error { 184 masters := k.infra.GetHostIPListByRole(common.MASTER) 185 workers := k.infra.GetHostIPListByRole(common.NODE) 186 187 remainMasters := utilsnet.RemoveIPs(masters, mastersToDelete) 188 if len(remainMasters) == 0 { 189 return fmt.Errorf("cleaning up all masters is illegal, unless you give the --all flag, which will delete the entire cluster") 190 } 191 192 if len(workersToDelete) > 0 { 193 if err := k.deleteNodes(workersToDelete, remainMasters); err != nil { 194 return err 195 } 196 } 197 198 if len(mastersToDelete) > 0 { 199 remainWorkers := utilsnet.RemoveIPs(workers, workersToDelete) 200 if err := k.deleteMasters(mastersToDelete, remainMasters); err != nil { 201 return err 202 } 203 if err := k.configureLvs(remainMasters, remainWorkers); err != nil { 204 return err 205 } 206 } 207 208 logrus.Info("cluster scale down succeeded!") 209 return nil 210 } 211 212 // dumpKubeConfigIntoCluster save AdminKubeConf to cluster as secret resource. 213 func (k *Runtime) dumpKubeConfigIntoCluster(driver runtime.Driver, master0 net.IP) error { 214 kubeConfigContent, err := os.ReadFile(AdminKubeConfPath) 215 if err != nil { 216 return err 217 } 218 219 kubeConfigContent = bytes.ReplaceAll(kubeConfigContent, []byte("apiserver.cluster.local"), []byte(master0.String())) 220 221 secret := &corev1.Secret{ 222 ObjectMeta: metav1.ObjectMeta{ 223 Name: "admin.conf", 224 Namespace: metav1.NamespaceSystem, 225 }, 226 Type: corev1.SecretTypeOpaque, 227 Data: map[string][]byte{ 228 "admin.conf": kubeConfigContent, 229 }, 230 } 231 232 if err := driver.Create(context.Background(), secret, &runtimeClient.CreateOptions{}); err != nil { 233 if !apierrors.IsAlreadyExists(err) { 234 return fmt.Errorf("unable to create secret: %v", err) 235 } 236 237 if err := driver.Update(context.Background(), secret, &runtimeClient.UpdateOptions{}); err != nil { 238 return fmt.Errorf("unable to update secret: %v", err) 239 } 240 } 241 242 return nil 243 } 244 245 // /var/lib/sealer/data/my-cluster/pki 246 func (k *Runtime) getPKIPath() string { 247 return filepath.Join(k.infra.GetClusterRootfsPath(), "pki") 248 } 249 250 // /var/lib/sealer/data/my-cluster/pki/etcd 251 func (k *Runtime) getEtcdCertPath() string { 252 return filepath.Join(k.getPKIPath(), "etcd") 253 } 254 255 // /var/lib/sealer/data/my-cluster/rootfs/statics 256 func (k *Runtime) getStaticFileDir() string { 257 return filepath.Join(k.infra.GetClusterRootfsPath(), "statics") 258 } 259 260 // /var/lib/sealer/data/my-cluster/mount/etc/kubeadm.yml 261 func (k *Runtime) getDefaultKubeadmConfig() string { 262 return filepath.Join(k.infra.GetClusterRootfsPath(), "etc", "kubeadm.yml") 263 } 264 265 func (k *Runtime) getAPIServerDomain() string { 266 return k.Config.APIServerDomain 267 } 268 269 func (k *Runtime) getAPIServerVIP() net.IP { 270 return net.ParseIP(k.Config.VIP) 271 }