mirror of
https://github.com/kubesphere/kubekey.git
synced 2025-12-26 01:22:51 +00:00
refactor deploy ks
Signed-off-by: pixiake <guofeng@yunify.com>
This commit is contained in:
parent
2ec9b7c5fe
commit
45cd5b549b
|
|
@ -21,7 +21,7 @@ import (
|
|||
)
|
||||
|
||||
// clusterCmd represents the cluster command
|
||||
var ksCmd = &cobra.Command{
|
||||
var deployKsCmd = &cobra.Command{
|
||||
Use: "kubesphere",
|
||||
Short: "Deploy KubeSphere on the existing K8s",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
@ -30,9 +30,9 @@ var ksCmd = &cobra.Command{
|
|||
}
|
||||
|
||||
func init() {
|
||||
deployCmd.AddCommand(ksCmd)
|
||||
deployCmd.AddCommand(deployKsCmd)
|
||||
|
||||
ksCmd.Flags().StringVarP(&opt.Kubeconfig, "kubeconfig", "", "", "Specify a kubeconfig file")
|
||||
ksCmd.Flags().StringVarP(&opt.KsVersion, "version", "v", "v3.0.0", "Specify a supported version of kubesphere")
|
||||
ksCmd.Flags().StringVarP(&opt.Registry, "registry", "", "", "Specify a image registry address")
|
||||
deployKsCmd.Flags().StringVarP(&opt.Kubeconfig, "kubeconfig", "", "", "Specify a kubeconfig file")
|
||||
deployKsCmd.Flags().StringVarP(&opt.KsVersion, "version", "v", "v3.0.0", "Specify a supported version of kubesphere")
|
||||
deployKsCmd.Flags().StringVarP(&opt.Registry, "registry", "", "", "Specify a image registry address")
|
||||
}
|
||||
|
|
@ -208,4 +208,4 @@ func serveCRMetrics(cfg *rest.Config, operatorNs string) error {
|
|||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/kubesphere/kubekey/pkg/upgrade"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// clusterCmd represents the cluster command
|
||||
var upgradeKsCmd = &cobra.Command{
|
||||
Use: "kubesphere",
|
||||
Short: "Deploy KubeSphere on the existing K8s",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return upgrade.KsToV3(opt.KsVersion, opt.Registry, opt.Kubeconfig)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
upgradeCmd.AddCommand(upgradeKsCmd)
|
||||
|
||||
upgradeKsCmd.Flags().StringVarP(&opt.Kubeconfig, "kubeconfig", "", "", "Specify a kubeconfig file")
|
||||
upgradeKsCmd.Flags().StringVarP(&opt.KsVersion, "version", "v", "v3.0.0", "Specify a supported version of kubesphere")
|
||||
upgradeKsCmd.Flags().StringVarP(&opt.Registry, "registry", "", "", "Specify a image registry address")
|
||||
}
|
||||
|
|
@ -89,7 +89,6 @@ type HostCfg struct {
|
|||
IsEtcd bool `json:"-"`
|
||||
IsMaster bool `json:"-"`
|
||||
IsWorker bool `json:"-"`
|
||||
IsClient bool `json:"-"`
|
||||
}
|
||||
|
||||
type RoleGroups struct {
|
||||
|
|
|
|||
|
|
@ -19,14 +19,13 @@ var (
|
|||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
// SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(addKnownTypes)
|
||||
}
|
||||
|
||||
|
||||
// Kind takes an unqualified kind and returns GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
|
|
@ -41,7 +40,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
|||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Cluster{},
|
||||
&ClusterList{},
|
||||
)
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,11 @@ import (
|
|||
"encoding/base64"
|
||||
"fmt"
|
||||
kubekeyapi "github.com/kubesphere/kubekey/pkg/apis/kubekey/v1alpha1"
|
||||
"github.com/kubesphere/kubekey/pkg/kubesphere"
|
||||
"github.com/kubesphere/kubekey/pkg/util"
|
||||
"github.com/lithammer/dedent"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
|
@ -78,9 +75,6 @@ spec:
|
|||
registry:
|
||||
privateRegistry: ""
|
||||
|
||||
{{ if .Options.KubeSphereEnabled }}
|
||||
{{ .Options.KubeSphereConfigMap }}
|
||||
{{ end }}
|
||||
`)))
|
||||
)
|
||||
|
||||
|
|
@ -108,28 +102,10 @@ type OptionsCluster struct {
|
|||
ControlPlaneEndpointDomain string
|
||||
ControlPlaneEndpointAddress string
|
||||
ControlPlaneEndpointPort string
|
||||
KubeSphereConfigMap string
|
||||
KubeSphereEnabled bool
|
||||
}
|
||||
|
||||
func GetInfoFromCluster(config, name string) (*OptionsCluster, error) {
|
||||
var kubeconfig string
|
||||
if config != "" {
|
||||
config, err := filepath.Abs(config)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to look up current directory")
|
||||
}
|
||||
kubeconfig = config
|
||||
} else {
|
||||
kubeconfig = filepath.Join(homeDir(), ".kube", "config")
|
||||
}
|
||||
// use the current context in kubeconfig
|
||||
configCluster, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// create the clientset
|
||||
clientset, err := kubernetes.NewForConfig(configCluster)
|
||||
clientset, err := util.NewClient(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -213,6 +189,9 @@ func GetInfoFromCluster(config, name string) (*OptionsCluster, error) {
|
|||
}
|
||||
|
||||
pods, err := clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, pod := range pods.Items {
|
||||
if strings.Contains(pod.Name, "calico") {
|
||||
opt.NetworkPlugin = "calico"
|
||||
|
|
@ -242,27 +221,12 @@ func GetInfoFromCluster(config, name string) (*OptionsCluster, error) {
|
|||
return &opt, nil
|
||||
}
|
||||
|
||||
func GenerateConfigFromCluster(cfgPath, kubeconfig, name, ksVersion string, ksEnabled bool) error {
|
||||
func GenerateConfigFromCluster(cfgPath, kubeconfig, name string) error {
|
||||
opt, err := GetInfoFromCluster(kubeconfig, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ksEnabled {
|
||||
switch strings.TrimSpace(ksVersion) {
|
||||
case "":
|
||||
opt.KubeSphereConfigMap = kubesphere.V3_0_0
|
||||
case "v3.0.0":
|
||||
opt.KubeSphereConfigMap = kubesphere.V3_0_0
|
||||
case "v2.1.1":
|
||||
opt.KubeSphereConfigMap = kubesphere.V2_1_1
|
||||
default:
|
||||
return errors.New(fmt.Sprintf("Unsupported version: %s", strings.TrimSpace(ksVersion)))
|
||||
}
|
||||
}
|
||||
|
||||
opt.KubeSphereEnabled = ksEnabled
|
||||
|
||||
ClusterCfgStr, err := GenerateClusterCfgStr(opt)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Faild to generate cluster config")
|
||||
|
|
@ -291,10 +255,3 @@ func GenerateConfigFromCluster(cfgPath, kubeconfig, name, ksVersion string, ksEn
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func homeDir() string {
|
||||
if h := os.Getenv("HOME"); h != "" {
|
||||
return h
|
||||
}
|
||||
return os.Getenv("USERPROFILE") // windows
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ func GenerateClusterObjStr(opt *Options, storageNum int) (string, error) {
|
|||
|
||||
func GenerateClusterObj(addons, k8sVersion, ksVersion, name, kubeconfig, clusterCfgPath string, ksEnabled, fromCluster bool) error {
|
||||
if fromCluster {
|
||||
err := GenerateConfigFromCluster(clusterCfgPath, kubeconfig, name, ksVersion, ksEnabled)
|
||||
err := GenerateConfigFromCluster(clusterCfgPath, kubeconfig, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ func ParseClusterCfg(clusterCfgPath, k8sVersion, ksVersion string, ksEnabled boo
|
|||
}
|
||||
clusterCfg = AllinoneCfg(user, k8sVersion, ksVersion, ksEnabled, logger)
|
||||
} else {
|
||||
cfg, err := ParseCfg(clusterCfgPath, k8sVersion)
|
||||
cfg, err := ParseCfg(clusterCfgPath, k8sVersion, ksVersion, ksEnabled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ func ParseClusterCfg(clusterCfgPath, k8sVersion, ksVersion string, ksEnabled boo
|
|||
return clusterCfg, nil
|
||||
}
|
||||
|
||||
func ParseCfg(clusterCfgPath, k8sVersion string) (*kubekeyapi.Cluster, error) {
|
||||
func ParseCfg(clusterCfgPath, k8sVersion, ksVersion string, ksEnabled bool) (*kubekeyapi.Cluster, error) {
|
||||
clusterCfg := kubekeyapi.Cluster{}
|
||||
fp, err := filepath.Abs(clusterCfgPath)
|
||||
if err != nil {
|
||||
|
|
@ -106,6 +106,24 @@ func ParseCfg(clusterCfgPath, k8sVersion string) (*kubekeyapi.Cluster, error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ksEnabled {
|
||||
clusterCfg.Spec.KubeSphere.Enabled = true
|
||||
switch strings.TrimSpace(ksVersion) {
|
||||
case "":
|
||||
clusterCfg.Spec.KubeSphere.Version = "v3.0.0"
|
||||
clusterCfg.Spec.KubeSphere.Configurations = kubesphere.V3_0_0
|
||||
case "v3.0.0":
|
||||
clusterCfg.Spec.KubeSphere.Version = "v3.0.0"
|
||||
clusterCfg.Spec.KubeSphere.Configurations = kubesphere.V3_0_0
|
||||
case "v2.1.1":
|
||||
clusterCfg.Spec.KubeSphere.Version = "v2.1.1"
|
||||
clusterCfg.Spec.KubeSphere.Configurations = kubesphere.V2_1_1
|
||||
default:
|
||||
return nil, errors.New(fmt.Sprintf("Unsupported version: %s", strings.TrimSpace(ksVersion)))
|
||||
}
|
||||
}
|
||||
|
||||
return &clusterCfg, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/kubesphere/kubekey/pkg/kubesphere"
|
||||
"github.com/kubesphere/kubekey/pkg/util"
|
||||
"github.com/pkg/errors"
|
||||
kubeErr "k8s.io/apimachinery/pkg/api/errors"
|
||||
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
|
@ -32,16 +33,21 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
customResourceDefinition = "/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions"
|
||||
namespaces = "/api/v1/namespaces"
|
||||
serviceAccount = "/api/v1/namespaces/kubesphere-system/serviceaccounts"
|
||||
clusterRole = "/apis/rbac.authorization.k8s.io/v1/clusterroles"
|
||||
clusterRoleBinding = "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings"
|
||||
deployment = "/apis/apps/v1/namespaces/kubesphere-system/deployments"
|
||||
clusterConfiguration = "/apis/installer.kubesphere.io/v1alpha1/namespaces/kubesphere-system/clusterconfigurations"
|
||||
CustomResourceDefinition = "/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions"
|
||||
Namespaces = "/api/v1/namespaces"
|
||||
ServiceAccount = "/api/v1/namespaces/kubesphere-system/serviceaccounts"
|
||||
ClusterRole = "/apis/rbac.authorization.k8s.io/v1/clusterroles"
|
||||
ClusterRoleBinding = "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings"
|
||||
Deployment = "/apis/apps/v1/namespaces/kubesphere-system/deployments"
|
||||
ClusterConfiguration = "/apis/installer.kubesphere.io/v1alpha1/namespaces/kubesphere-system/clusterconfigurations"
|
||||
)
|
||||
|
||||
func DeployKubeSphere(version, repo, kubeconfig string) error {
|
||||
clientset, err := util.NewClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var kubesphereConfig, installerYaml string
|
||||
|
||||
switch version {
|
||||
|
|
@ -70,11 +76,6 @@ func DeployKubeSphere(version, repo, kubeconfig string) error {
|
|||
return errors.New(fmt.Sprintf("Unsupported version: %s", strings.TrimSpace(version)))
|
||||
}
|
||||
|
||||
clientset, err := newClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b1 := bufio.NewReader(bytes.NewReader([]byte(installerYaml)))
|
||||
for {
|
||||
result := make(map[string]interface{})
|
||||
|
|
@ -98,7 +99,7 @@ func DeployKubeSphere(version, repo, kubeconfig string) error {
|
|||
|
||||
switch result["kind"] {
|
||||
case "CustomResourceDefinition":
|
||||
if err := createObject(clientset, j2, customResourceDefinition); err != nil {
|
||||
if err := CreateObject(clientset, j2, CustomResourceDefinition); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
|
@ -108,7 +109,7 @@ func DeployKubeSphere(version, repo, kubeconfig string) error {
|
|||
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "Namespace":
|
||||
if err := createObject(clientset, j2, namespaces); err != nil {
|
||||
if err := CreateObject(clientset, j2, Namespaces); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
|
@ -117,7 +118,7 @@ func DeployKubeSphere(version, repo, kubeconfig string) error {
|
|||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "ServiceAccount":
|
||||
if err := createObject(clientset, j2, serviceAccount); err != nil {
|
||||
if err := CreateObject(clientset, j2, ServiceAccount); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
|
@ -126,7 +127,7 @@ func DeployKubeSphere(version, repo, kubeconfig string) error {
|
|||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "ClusterRole":
|
||||
if err := createObject(clientset, j2, clusterRole); err != nil {
|
||||
if err := CreateObject(clientset, j2, ClusterRole); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
|
@ -135,7 +136,7 @@ func DeployKubeSphere(version, repo, kubeconfig string) error {
|
|||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "ClusterRoleBinding":
|
||||
if err := createObject(clientset, j2, clusterRoleBinding); err != nil {
|
||||
if err := CreateObject(clientset, j2, ClusterRoleBinding); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
|
@ -144,7 +145,7 @@ func DeployKubeSphere(version, repo, kubeconfig string) error {
|
|||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "Deployment":
|
||||
if err := createObject(clientset, j2, deployment); err != nil {
|
||||
if err := CreateObject(clientset, j2, Deployment); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
|
@ -173,7 +174,7 @@ func DeployKubeSphere(version, repo, kubeconfig string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := createObject(clientset, modified, clusterConfiguration); err != nil {
|
||||
if err := CreateObject(clientset, modified, ClusterConfiguration); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
|
@ -188,7 +189,7 @@ func DeployKubeSphere(version, repo, kubeconfig string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func createObject(clientset *kubernetes.Clientset, body []byte, request string) error {
|
||||
func CreateObject(clientset *kubernetes.Clientset, body []byte, request string) error {
|
||||
if err := clientset.
|
||||
RESTClient().Post().
|
||||
AbsPath(request).
|
||||
|
|
|
|||
|
|
@ -165,7 +165,11 @@ EOF
|
|||
caFile := "/etc/ssl/etcd/ssl/ca.pem"
|
||||
certFile := fmt.Sprintf("/etc/ssl/etcd/ssl/node-%s.pem", mgr.EtcdNodes[0].Name)
|
||||
keyFile := fmt.Sprintf("/etc/ssl/etcd/ssl/node-%s-key.pem", mgr.EtcdNodes[0].Name)
|
||||
_, _ = mgr.Runner.ExecuteCmd(fmt.Sprintf("sudo -E /bin/sh -c \"/usr/local/bin/kubectl -n kubesphere-monitoring-system create secret generic kube-etcd-client-certs --from-file=etcd-client-ca.crt=%s --from-file=etcd-client.crt=%s --from-file=etcd-client.key=%s\"", caFile, certFile, keyFile), 5, true)
|
||||
if output, err := mgr.Runner.ExecuteCmd(fmt.Sprintf("sudo -E /bin/sh -c \"/usr/local/bin/kubectl -n kubesphere-monitoring-system create secret generic kube-etcd-client-certs --from-file=etcd-client-ca.crt=%s --from-file=etcd-client.crt=%s --from-file=etcd-client.key=%s\"", caFile, certFile, keyFile), 1, true); err != nil {
|
||||
if !strings.Contains(output, "AlreadyExists") {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
deployKubesphereCmd := "sudo -E /bin/sh -c \"/usr/local/bin/kubectl apply -f /etc/kubernetes/addons/kubesphere.yaml\""
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
|
||||
type V2 struct {
|
||||
Persistence Persistence `yaml:"persistence"`
|
||||
Common Common `yaml:"common"`
|
||||
Etcd Etcd `yaml:"etcd"`
|
||||
MetricsServerOld MetricsServerOld `yaml:"metrics-server"`
|
||||
MetricsServerNew MetricsServerNew `yaml:"metrics_server"`
|
||||
Console Console `yaml:"console"`
|
||||
Monitoring Monitoring `yaml:"monitoring"`
|
||||
Logging Logging `yaml:"logging"`
|
||||
Openpitrix Openpitrix `yaml:"openpitrix"`
|
||||
Devops Devops `yaml:"devops"`
|
||||
Servicemesh Servicemesh `yaml:"servicemesh"`
|
||||
Notification Notification `yaml:"notification"`
|
||||
Alerting Alerting `yaml:"alerting"`
|
||||
LocalRegistry string `yaml:"local_registry"`
|
||||
}
|
||||
|
||||
type Persistence struct {
|
||||
StorageClass string `yaml:"storageClass"`
|
||||
}
|
||||
type Etcd struct {
|
||||
Monitoring bool `yaml:"monitoring"`
|
||||
EndpointIps string `yaml:"endpointIps"`
|
||||
Port int `yaml:"port"`
|
||||
TlsEnable bool `yaml:"tlsEnable"`
|
||||
}
|
||||
|
||||
type Common struct {
|
||||
MysqlVolumeSize string `yaml:"mysqlVolumeSize"`
|
||||
MinioVolumeSize string `yaml:"minioVolumeSize"`
|
||||
EtcdVolumeSize string `yaml:"etcdVolumeSize"`
|
||||
OpenldapVolumeSize string `yaml:"openldapVolumeSize"`
|
||||
RedisVolumSize string `yaml:"redisVolumSize"`
|
||||
}
|
||||
|
||||
type MetricsServerOld struct {
|
||||
Enabled string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type MetricsServerNew struct {
|
||||
Enabled string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Console struct {
|
||||
EnableMultiLogin bool `yaml:"enableMultiLogin"`
|
||||
Port int `yaml:"port"`
|
||||
}
|
||||
|
||||
type Monitoring struct {
|
||||
PrometheusReplicas int `yaml:"prometheusReplicas"`
|
||||
PrometheusMemoryRequest string `yaml:"prometheusMemoryRequest"`
|
||||
PrometheusVolumeSize string `yaml:"prometheusVolumeSize"`
|
||||
}
|
||||
|
||||
type Logging struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
ElasticsearchMasterReplicas int `yaml:"elasticsearchMasterReplicas"`
|
||||
ElasticsearchDataReplicas int `yaml:"elasticsearchDataReplicas"`
|
||||
LogsidecarReplicas int `yaml:"logsidecarReplicas"`
|
||||
ElasticsearchVolumeSize string `yaml:"elasticsearchVolumeSize"`
|
||||
ElasticsearchMasterVolumeSize string `yaml:"elasticsearchMasterVolumeSize"`
|
||||
ElasticsearchDataVolumeSize string `yaml:"elasticsearchDataVolumeSize"`
|
||||
LogMaxAge int `yaml:"logMaxAge"`
|
||||
ElkPrefix string `yaml:"elkPrefix"`
|
||||
}
|
||||
|
||||
type Openpitrix struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Devops struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
JenkinsMemoryLim string `yaml:"jenkinsMemoryLim"`
|
||||
JenkinsMemoryReq string `yaml:"jenkinsMemoryReq"`
|
||||
JenkinsVolumeSize string `yaml:"jenkinsVolumeSize"`
|
||||
JenkinsjavaoptsXms string `yaml:"jenkinsJavaOpts_Xms"`
|
||||
JenkinsjavaoptsXmx string `yaml:"jenkinsJavaOpts_Xmx"`
|
||||
JenkinsjavaoptsMaxram string `yaml:"jenkinsJavaOpts_MaxRAM"`
|
||||
}
|
||||
|
||||
type Servicemesh struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Alerting struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v3
|
||||
|
||||
type ClusterConfig struct {
|
||||
ApiVersion string `yaml:"apiVersion"`
|
||||
Kind string `yaml:"kind"`
|
||||
Metadata Metadata `yaml:"metadata"`
|
||||
Spec *V3 `yaml:"spec"`
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
Name string `yaml:"name"`
|
||||
Namespace string `yaml:"namespace"`
|
||||
Label Label `yaml:"labels"`
|
||||
}
|
||||
|
||||
type Label struct {
|
||||
Version string `yaml:"version"`
|
||||
}
|
||||
|
||||
type V3 struct {
|
||||
Persistence Persistence `yaml:"persistence"`
|
||||
Authentication Authentication `yaml:"authentication"`
|
||||
Common Common `yaml:"common"`
|
||||
Etcd Etcd `yaml:"etcd"`
|
||||
MetricsServer MetricsServer `yaml:"metrics_server"`
|
||||
Console Console `yaml:"console"`
|
||||
Monitoring Monitoring `yaml:"monitoring"`
|
||||
Logging Logging `yaml:"logging"`
|
||||
Openpitrix Openpitrix `yaml:"openpitrix"`
|
||||
Devops Devops `yaml:"devops"`
|
||||
Servicemesh Servicemesh `yaml:"servicemesh"`
|
||||
Notification Notification `yaml:"notification"`
|
||||
Alerting Alerting `yaml:"alerting"`
|
||||
Auditing Auditing `yaml:"auditing"`
|
||||
Events Events `yaml:"events"`
|
||||
Multicluster Multicluster `yaml:"multicluster"`
|
||||
Networkpolicy Networkpolicy `yaml:"networkpolicy"`
|
||||
LocalRegistry string `yaml:"local_registry"`
|
||||
}
|
||||
|
||||
type Persistence struct {
|
||||
StorageClass string `yaml:"storageClass"`
|
||||
}
|
||||
|
||||
type MetricsServer struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Authentication struct {
|
||||
JwtSecret string `yaml:"jwtSecret"`
|
||||
}
|
||||
type Etcd struct {
|
||||
Monitoring bool `yaml:"monitoring"`
|
||||
EndpointIps string `yaml:"endpointIps"`
|
||||
Port int `yaml:"port"`
|
||||
TlsEnable bool `yaml:"tlsEnable"`
|
||||
}
|
||||
|
||||
type Common struct {
|
||||
MysqlVolumeSize string `yaml:"mysqlVolumeSize"`
|
||||
MinioVolumeSize string `yaml:"minioVolumeSize"`
|
||||
EtcdVolumeSize string `yaml:"etcdVolumeSize"`
|
||||
OpenldapVolumeSize string `yaml:"openldapVolumeSize"`
|
||||
RedisVolumSize string `yaml:"redisVolumSize"`
|
||||
ES ES `yaml:"es"`
|
||||
}
|
||||
|
||||
type ES struct {
|
||||
ElasticsearchMasterReplicas int `yaml:"elasticsearchMasterReplicas"`
|
||||
ElasticsearchDataReplicas int `yaml:"elasticsearchDataReplicas"`
|
||||
ElasticsearchMasterVolumeSize string `yaml:"elasticsearchMasterVolumeSize"`
|
||||
ElasticsearchDataVolumeSize string `yaml:"elasticsearchDataVolumeSize"`
|
||||
LogMaxAge int `yaml:"logMaxAge"`
|
||||
ElkPrefix string `yaml:"elkPrefix"`
|
||||
}
|
||||
|
||||
type Console struct {
|
||||
EnableMultiLogin bool `yaml:"enableMultiLogin"`
|
||||
Port int `yaml:"port"`
|
||||
}
|
||||
|
||||
type Alerting struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Auditing struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Devops struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
JenkinsMemoryLim string `yaml:"jenkinsMemoryLim"`
|
||||
JenkinsMemoryReq string `yaml:"jenkinsMemoryReq"`
|
||||
JenkinsVolumeSize string `yaml:"jenkinsVolumeSize"`
|
||||
JenkinsjavaoptsXms string `yaml:"jenkinsJavaOpts_Xms"`
|
||||
JenkinsjavaoptsXmx string `yaml:"jenkinsJavaOpts_Xmx"`
|
||||
JenkinsjavaoptsMaxram string `yaml:"jenkinsJavaOpts_MaxRAM"`
|
||||
}
|
||||
|
||||
type Events struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Ruler Ruler `yaml:"ruler"`
|
||||
}
|
||||
|
||||
type Ruler struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Replicas int `yaml:"replicas"`
|
||||
}
|
||||
|
||||
type Logging struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
LogsidecarReplicas int `yaml:"logsidecarReplicas"`
|
||||
}
|
||||
|
||||
type Metrics struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Monitoring struct {
|
||||
AlertmanagerReplicas int `yaml:"alertmanagerReplicas"`
|
||||
PrometheusReplicas int `yaml:"prometheusReplicas"`
|
||||
PrometheusMemoryRequest string `yaml:"prometheusMemoryRequest"`
|
||||
PrometheusVolumeSize string `yaml:"prometheusVolumeSize"`
|
||||
}
|
||||
|
||||
type Multicluster struct {
|
||||
ClusterRole string `yaml:"clusterRole"`
|
||||
}
|
||||
|
||||
type Networkpolicy struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Openpitrix struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
type Servicemesh struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package upgrade
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package kubernetes
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
kubekeyapi "github.com/kubesphere/kubekey/pkg/apis/kubekey/v1alpha1"
|
||||
"github.com/kubesphere/kubekey/pkg/cluster/kubernetes"
|
||||
"github.com/kubesphere/kubekey/pkg/cluster/kubernetes/tmpl"
|
||||
"github.com/kubesphere/kubekey/pkg/cluster/preinstall"
|
||||
"github.com/kubesphere/kubekey/pkg/files"
|
||||
|
|
@ -98,7 +99,7 @@ func upgradeKubeMasters(mgr *manager.Manager, node *kubekeyapi.HostCfg) error {
|
|||
return errors.Wrap(err, "Failed to get current kubelet version")
|
||||
}
|
||||
if strings.Split(kubeletVersion, " ")[1] != mgr.Cluster.Kubernetes.Version {
|
||||
if err := SyncKubeBinaries(mgr, node); err != nil {
|
||||
if err := kubernetes.SyncKubeBinaries(mgr, node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +133,7 @@ func upgradeKubeMasters(mgr *manager.Manager, node *kubekeyapi.HostCfg) error {
|
|||
return errors.Wrap(errors.WithStack(err2), fmt.Sprintf("Failed to upgrade master: %s", node.Name))
|
||||
}
|
||||
|
||||
if err := SetKubelet(mgr, node); err != nil {
|
||||
if err := kubernetes.SetKubelet(mgr, node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -151,11 +152,11 @@ func upgradeKubeWorkers(mgr *manager.Manager, node *kubekeyapi.HostCfg) error {
|
|||
}
|
||||
if strings.Split(kubeletVersion, " ")[1] != mgr.Cluster.Kubernetes.Version {
|
||||
|
||||
if err := SyncKubeBinaries(mgr, node); err != nil {
|
||||
if err := kubernetes.SyncKubeBinaries(mgr, node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := SetKubelet(mgr, node); err != nil {
|
||||
if err := kubernetes.SetKubelet(mgr, node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/ghodss/yaml"
|
||||
kubekeyapi "github.com/kubesphere/kubekey/pkg/apis/kubekey/v1alpha1"
|
||||
"github.com/kubesphere/kubekey/pkg/deploy"
|
||||
"github.com/kubesphere/kubekey/pkg/kubesphere"
|
||||
ksv2 "github.com/kubesphere/kubekey/pkg/kubesphere/v2"
|
||||
ksv3 "github.com/kubesphere/kubekey/pkg/kubesphere/v3"
|
||||
"github.com/kubesphere/kubekey/pkg/util"
|
||||
"github.com/kubesphere/kubekey/pkg/util/manager"
|
||||
"github.com/pkg/errors"
|
||||
yamlV2 "gopkg.in/yaml.v2"
|
||||
kubeErr "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func KsToV3(version, repo, kubeconfig string) error {
|
||||
clientset, err := util.NewClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clusterConfigMap, err1 := clientset.CoreV1().ConfigMaps("kubesphere-system").Get(context.TODO(), "ks-installer", metav1.GetOptions{})
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
|
||||
clusterCfgV2 := ksv2.V2{}
|
||||
clusterCfgV3 := ksv3.V3{}
|
||||
if err := yamlV2.Unmarshal([]byte(clusterConfigMap.Data["ks-config.yaml"]), &clusterCfgV2); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
configV3, err := MigrateConfig2to3(&clusterCfgV2, &clusterCfgV3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(configV3)
|
||||
|
||||
var kubesphereConfig, installerYaml string
|
||||
|
||||
switch version {
|
||||
case "":
|
||||
kubesphereConfig = configV3
|
||||
str, err := kubesphere.GenerateKubeSphereYaml(repo, "latest")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
installerYaml = str
|
||||
case "v3.0.0":
|
||||
kubesphereConfig = configV3
|
||||
str, err := kubesphere.GenerateKubeSphereYaml(repo, "latest")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
installerYaml = str
|
||||
default:
|
||||
return errors.New(fmt.Sprintf("Unsupported version: %s", strings.TrimSpace(version)))
|
||||
}
|
||||
|
||||
b1 := bufio.NewReader(bytes.NewReader([]byte(installerYaml)))
|
||||
for {
|
||||
result := make(map[string]interface{})
|
||||
content, err := k8syaml.NewYAMLReader(b1).Read()
|
||||
if len(content) == 0 {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to read the manifests")
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(content, &result)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to unmarshal the manifests")
|
||||
}
|
||||
|
||||
j2, err1 := yaml.YAMLToJSON(content)
|
||||
if err1 != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch result["kind"] {
|
||||
case "CustomResourceDefinition":
|
||||
if err := deploy.CreateObject(clientset, j2, deploy.CustomResourceDefinition); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
metadata := result["metadata"].(map[string]interface{})
|
||||
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "Namespace":
|
||||
if err := deploy.CreateObject(clientset, j2, deploy.Namespaces); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "ServiceAccount":
|
||||
if err := deploy.CreateObject(clientset, j2, deploy.ServiceAccount); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "ClusterRole":
|
||||
if err := deploy.CreateObject(clientset, j2, deploy.ClusterRole); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "ClusterRoleBinding":
|
||||
if err := deploy.CreateObject(clientset, j2, deploy.ClusterRoleBinding); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
case "Deployment":
|
||||
if err := deploy.CreateObject(clientset, j2, deploy.Deployment); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
}
|
||||
}
|
||||
|
||||
j2, err1 := yaml.YAMLToJSON([]byte(kubesphereConfig))
|
||||
if err1 != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := deploy.CreateObject(clientset, j2, deploy.ClusterConfiguration); err != nil {
|
||||
if !kubeErr.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
result := make(map[string]interface{})
|
||||
err = yaml.Unmarshal([]byte(kubesphereConfig), &result)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to unmarshal the manifests")
|
||||
}
|
||||
metadata := result["metadata"].(map[string]interface{})
|
||||
fmt.Printf("%s/%s created\n", result["kind"], metadata["name"])
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func MigrateConfig2to3(v2 *ksv2.V2, v3 *ksv3.V3) (string, error) {
|
||||
v3.Etcd = ksv3.Etcd(v2.Etcd)
|
||||
v3.Persistence = ksv3.Persistence(v2.Persistence)
|
||||
v3.Alerting = ksv3.Alerting(v2.Alerting)
|
||||
v3.Notification = ksv3.Notification(v2.Notification)
|
||||
v3.LocalRegistry = v2.LocalRegistry
|
||||
v3.Servicemesh = ksv3.Servicemesh(v2.Servicemesh)
|
||||
v3.Devops = ksv3.Devops(v2.Devops)
|
||||
v3.Openpitrix = ksv3.Openpitrix(v2.Openpitrix)
|
||||
v3.Console = ksv3.Console(v2.Console)
|
||||
|
||||
if v2.MetricsServerNew.Enabled == "" {
|
||||
if v2.MetricsServerOld.Enabled == "true" || v2.MetricsServerOld.Enabled == "True" {
|
||||
v3.MetricsServer.Enabled = true
|
||||
} else {
|
||||
v3.MetricsServer.Enabled = false
|
||||
}
|
||||
} else {
|
||||
if v2.MetricsServerNew.Enabled == "true" || v2.MetricsServerNew.Enabled == "True" {
|
||||
v3.MetricsServer.Enabled = true
|
||||
} else {
|
||||
v3.MetricsServer.Enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
v3.Monitoring.PrometheusMemoryRequest = v2.Monitoring.PrometheusMemoryRequest
|
||||
v3.Monitoring.PrometheusReplicas = v2.Monitoring.PrometheusReplicas
|
||||
v3.Monitoring.PrometheusVolumeSize = v2.Monitoring.PrometheusVolumeSize
|
||||
v3.Monitoring.AlertmanagerReplicas = 1
|
||||
|
||||
v3.Common.EtcdVolumeSize = v2.Common.EtcdVolumeSize
|
||||
v3.Common.MinioVolumeSize = v2.Common.MinioVolumeSize
|
||||
v3.Common.MysqlVolumeSize = v2.Common.MysqlVolumeSize
|
||||
v3.Common.OpenldapVolumeSize = v2.Common.OpenldapVolumeSize
|
||||
v3.Common.RedisVolumSize = v2.Common.RedisVolumSize
|
||||
v3.Common.ES.ElasticsearchDataReplicas = v2.Logging.ElasticsearchDataReplicas
|
||||
v3.Common.ES.ElasticsearchMasterReplicas = v2.Logging.ElasticsearchMasterReplicas
|
||||
v3.Common.ES.ElkPrefix = v2.Logging.ElkPrefix
|
||||
v3.Common.ES.LogMaxAge = v2.Logging.LogMaxAge
|
||||
if v2.Logging.ElasticsearchVolumeSize == "" {
|
||||
v3.Common.ES.ElasticsearchDataVolumeSize = v2.Logging.ElasticsearchDataVolumeSize
|
||||
v3.Common.ES.ElasticsearchMasterVolumeSize = v2.Logging.ElasticsearchMasterVolumeSize
|
||||
} else {
|
||||
v3.Common.ES.ElasticsearchMasterVolumeSize = "4Gi"
|
||||
v3.Common.ES.ElasticsearchDataVolumeSize = v2.Logging.ElasticsearchVolumeSize
|
||||
}
|
||||
|
||||
v3.Logging.Enabled = v2.Logging.Enabled
|
||||
v3.Logging.LogsidecarReplicas = v2.Logging.LogsidecarReplicas
|
||||
|
||||
v3.Authentication.JwtSecret = ""
|
||||
v3.Multicluster.ClusterRole = "none"
|
||||
v3.Events.Ruler.Replicas = 2
|
||||
|
||||
var clusterConfiguration = ksv3.ClusterConfig{
|
||||
ApiVersion: "installer.kubesphere.io/v1alpha1",
|
||||
Kind: "ClusterConfiguration",
|
||||
Metadata: ksv3.Metadata{
|
||||
Name: "ks-installer",
|
||||
Namespace: "kubesphere-system",
|
||||
Label: ksv3.Label{Version: "v3.0.0"},
|
||||
},
|
||||
Spec: v3,
|
||||
}
|
||||
|
||||
configV3, err := yamlV2.Marshal(clusterConfiguration)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(configV3), nil
|
||||
}
|
||||
|
||||
func SyncConfiguration(mgr *manager.Manager) error {
|
||||
if err := mgr.RunTaskOnMasterNodes(syncConfiguration, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncConfiguration(mgr *manager.Manager, _ *kubekeyapi.HostCfg) error {
|
||||
if mgr.Runner.Index == 0 {
|
||||
configV2Str, err := mgr.Runner.ExecuteCmd("sudo -E /bin/sh -c \"/usr/local/bin/kubectl get cm -n kubesphere-system ks-installer -o jsonpath='{.data.ks-config\\.yaml}'\"", 2, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clusterCfgV2 := ksv2.V2{}
|
||||
clusterCfgV3 := ksv3.V3{}
|
||||
if err := yamlV2.Unmarshal([]byte(configV2Str), &clusterCfgV2); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
configV3, err := MigrateConfig2to3(&clusterCfgV2, &clusterCfgV3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mgr.Cluster.KubeSphere.Configurations = "---\n" + configV3
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
kubekeyapi "github.com/kubesphere/kubekey/pkg/apis/kubekey/v1alpha1"
|
||||
"github.com/kubesphere/kubekey/pkg/util/manager"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func GetClusterInfo(mgr *manager.Manager) error {
|
||||
return mgr.RunTaskOnMasterNodes(getClusterInfo, true)
|
||||
}
|
||||
|
||||
func getClusterInfo(mgr *manager.Manager, node *kubekeyapi.HostCfg) error {
|
||||
if mgr.Runner.Index == 0 {
|
||||
componentstatus, err := mgr.Runner.ExecuteCmd("sudo -E /bin/bash -c \"/usr/local/bin/kubectl get componentstatus\"", 2, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Cluster components status:")
|
||||
fmt.Println(componentstatus + "\n")
|
||||
nodestatus, err := mgr.Runner.ExecuteCmd("sudo -E /bin/sh -c \"/usr/local/bin/kubectl get node -o wide\"", 2, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Cluster nodes status:")
|
||||
fmt.Println(nodestatus + "\n\n")
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
Loop:
|
||||
for {
|
||||
fmt.Printf("Continue upgrading cluster? [yes/no]: ")
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
mgr.Logger.Fatal(err)
|
||||
}
|
||||
input = strings.TrimSpace(input)
|
||||
|
||||
switch input {
|
||||
case "yes":
|
||||
break Loop
|
||||
case "no":
|
||||
os.Exit(0)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
kubekeyapi "github.com/kubesphere/kubekey/pkg/apis/kubekey/v1alpha1"
|
||||
"github.com/kubesphere/kubekey/pkg/util/manager"
|
||||
"github.com/pkg/errors"
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var versionCheck = map[string]map[string]map[string]bool{
|
||||
"v3.0.0": {
|
||||
"k8s": {
|
||||
"v1.18": true,
|
||||
"v1.17": true,
|
||||
"v1.16": true,
|
||||
"v1.15": true,
|
||||
},
|
||||
"ks": {
|
||||
"v2.1.0": true,
|
||||
"v2.1.1": true,
|
||||
},
|
||||
},
|
||||
"v2.1.1": {
|
||||
"k8s": {
|
||||
"v1.18": true,
|
||||
"v1.17": true,
|
||||
"v1.16": true,
|
||||
"v1.15": true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func GetClusterInfo(mgr *manager.Manager) error {
|
||||
return mgr.RunTaskOnMasterNodes(getClusterInfo, true)
|
||||
}
|
||||
|
||||
func getClusterInfo(mgr *manager.Manager, _ *kubekeyapi.HostCfg) error {
|
||||
if mgr.Runner.Index == 0 {
|
||||
|
||||
k8sVersionStr, err := mgr.Runner.ExecuteCmd("sudo -E /bin/sh -c \"cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep 'image:' | cut -d ':' -f 3\"", 3, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to get current kube-apiserver version")
|
||||
}
|
||||
|
||||
ksVersion, err := mgr.Runner.ExecuteCmd("sudo -E /bin/sh -c \"/usr/local/bin/kubectl get deploy -n kubesphere-system ks-console -o jsonpath='{.metadata.labels.version}'\"", 2, false)
|
||||
if err != nil {
|
||||
if mgr.Cluster.KubeSphere.Enabled {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if mgr.Cluster.KubeSphere.Enabled {
|
||||
if _, ok := versionCheck[mgr.Cluster.KubeSphere.Version]; !ok {
|
||||
return errors.New(fmt.Sprintf("Unsupported version: %s", mgr.Cluster.KubeSphere.Version))
|
||||
}
|
||||
if _, ok := versionCheck[mgr.Cluster.KubeSphere.Version]["ks"][ksVersion]; !ok {
|
||||
return errors.New(fmt.Sprintf("Unsupported upgrade plan: %s to %s", strings.TrimSpace(ksVersion), mgr.Cluster.KubeSphere.Version))
|
||||
}
|
||||
K8sTargetVersion := versionutil.MustParseSemantic(mgr.Cluster.Kubernetes.Version)
|
||||
if _, ok := versionCheck[mgr.Cluster.KubeSphere.Version]["k8s"][fmt.Sprintf("v%v.%v", K8sTargetVersion.Major(), K8sTargetVersion.Minor())]; !ok {
|
||||
return errors.New(fmt.Sprintf("KubeSphere %s does not support running on Kubernetes %s", mgr.Cluster.KubeSphere.Version, fmt.Sprintf("v%v.%v", K8sTargetVersion.Major(), K8sTargetVersion.Minor())))
|
||||
}
|
||||
} else {
|
||||
if _, ok := versionCheck[ksVersion]; !ok {
|
||||
return errors.New(fmt.Sprintf("Unsupported version: %s", ksVersion))
|
||||
}
|
||||
K8sTargetVersion := versionutil.MustParseSemantic(mgr.Cluster.Kubernetes.Version)
|
||||
if _, ok := versionCheck[ksVersion]["k8s"][fmt.Sprintf("v%v.%v", K8sTargetVersion.Major(), K8sTargetVersion.Minor())]; !ok {
|
||||
return errors.New(fmt.Sprintf("KubeSphere %s does not support running on Kubernetes %s", ksVersion, fmt.Sprintf("v%v.%v", K8sTargetVersion.Major(), K8sTargetVersion.Minor())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := getNodestatus(mgr); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := getComponentStatus(mgr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Upgrade Confirmation:")
|
||||
fmt.Printf("kubernetes version: %s to %s\n", k8sVersionStr, mgr.Cluster.Kubernetes.Version)
|
||||
if mgr.Cluster.KubeSphere.Enabled {
|
||||
fmt.Printf("kubesphere version: %s to %s\n\n", ksVersion, mgr.Cluster.KubeSphere.Version)
|
||||
} else {
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
Loop:
|
||||
for {
|
||||
fmt.Printf("Continue upgrading cluster? [yes/no]: ")
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
mgr.Logger.Fatal(err)
|
||||
}
|
||||
input = strings.TrimSpace(input)
|
||||
|
||||
switch input {
|
||||
case "yes":
|
||||
break Loop
|
||||
case "no":
|
||||
os.Exit(0)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getComponentStatus(mgr *manager.Manager) error {
|
||||
componentStatusStr, err := mgr.Runner.ExecuteCmd("sudo -E /bin/bash -c \"/usr/local/bin/kubectl get componentstatus -o go-template='{{range .items}}{{ printf \\\"%s: \\\" .metadata.name}}{{range .conditions}}{{ printf \\\"%v\\n\\\" .message }}{{end}}{{end}}'\"", 1, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Components Status:")
|
||||
fmt.Println(componentStatusStr + "\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
func getNodestatus(mgr *manager.Manager) error {
|
||||
nodestatus, err := mgr.Runner.ExecuteCmd("sudo -E /bin/sh -c \"/usr/local/bin/kubectl get node\"", 2, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Cluster nodes status:")
|
||||
fmt.Println(nodestatus + "\n")
|
||||
return nil
|
||||
}
|
||||
|
|
@ -18,7 +18,6 @@ package upgrade
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kubesphere/kubekey/pkg/cluster/kubernetes"
|
||||
"github.com/kubesphere/kubekey/pkg/config"
|
||||
"github.com/kubesphere/kubekey/pkg/kubesphere"
|
||||
"github.com/kubesphere/kubekey/pkg/util"
|
||||
|
|
@ -52,8 +51,9 @@ func ExecTasks(mgr *manager.Manager) error {
|
|||
{Task: GetClusterInfo, ErrMsg: "Failed to get cluster info"},
|
||||
//{Task: preinstall.InitOS, ErrMsg: "Failed to download kube binaries"},
|
||||
//{Task: preinstall.PrePullImages, ErrMsg: "Failed to pre-pull images"},
|
||||
{Task: kubernetes.GetCurrentVersions, ErrMsg: "Failed to get current version"},
|
||||
{Task: kubernetes.UpgradeKubeCluster, ErrMsg: "Failed to upgrade kube cluster"},
|
||||
{Task: GetCurrentVersions, ErrMsg: "Failed to get current version"},
|
||||
{Task: UpgradeKubeCluster, ErrMsg: "Failed to upgrade kube cluster"},
|
||||
{Task: SyncConfiguration, ErrMsg: "Failed to sync configuration"},
|
||||
{Task: kubesphere.DeployKubeSphere, ErrMsg: "Failed to upgrade kubesphere"},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package deploy
|
||||
package util
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
|
|
@ -24,7 +24,7 @@ import (
|
|||
"path/filepath"
|
||||
)
|
||||
|
||||
func newClient(config string) (*kubernetes.Clientset, error) {
|
||||
func NewClient(config string) (*kubernetes.Clientset, error) {
|
||||
var kubeconfig string
|
||||
if config != "" {
|
||||
config, err := filepath.Abs(config)
|
||||
Loading…
Reference in New Issue