diff --git a/.all-contributorsrc b/.all-contributorsrc
index ea78cea7f..ced0e693b 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -796,6 +796,15 @@
"contributions": [
"code"
]
+ },
+ {
+ "login": "knowmost",
+ "name": "knowmost",
+ "avatar_url": "https://avatars.githubusercontent.com/u/167442703?v=4",
+ "profile": "https://github.com/knowmost",
+ "contributions": [
+ "doc"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index d882bdd97..e127b4c01 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -118,6 +118,7 @@ Contributions of any kind are welcome! Thanks goes to these wonderful contributo
Ronald Fletcher 💻 |
baikjy0215 💻 |
+ knowmost 📖 |
diff --git a/README.md b/README.md
index 9600381e6..22df4da32 100644
--- a/README.md
+++ b/README.md
@@ -402,6 +402,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Ronald Fletcher 💻 |
baikjy0215 💻 |
+ knowmost 📖 |
diff --git a/README_zh-CN.md b/README_zh-CN.md
index 39619500c..64f3cced8 100644
--- a/README_zh-CN.md
+++ b/README_zh-CN.md
@@ -419,6 +419,7 @@ kubectl completion bash >/etc/bash_completion.d/kubectl
Ronald Fletcher 💻 |
baikjy0215 💻 |
+ knowmost 📖 |
diff --git a/cmd/kk/apis/kubekey/v1alpha2/addons_types.go b/cmd/kk/apis/kubekey/v1alpha2/addons_types.go
index 5500317b1..8066524cf 100644
--- a/cmd/kk/apis/kubekey/v1alpha2/addons_types.go
+++ b/cmd/kk/apis/kubekey/v1alpha2/addons_types.go
@@ -17,11 +17,13 @@
package v1alpha2
type Addon struct {
- Name string `yaml:"name" json:"name,omitempty"`
- Namespace string `yaml:"namespace" json:"namespace,omitempty"`
- Sources Sources `yaml:"sources" json:"sources,omitempty"`
- Retries int `yaml:"retries" json:"retries,omitempty"`
- Delay int `yaml:"delay" json:"delay,omitempty"`
+ Name string `yaml:"name" json:"name,omitempty"`
+ Namespace string `yaml:"namespace" json:"namespace,omitempty"`
+ PreInstall []CustomScripts `yaml:"preInstall" json:"preInstall,omitempty"`
+ Sources Sources `yaml:"sources" json:"sources,omitempty"`
+ PostInstall []CustomScripts `yaml:"postInstall" json:"postInstall,omitempty"`
+ Retries int `yaml:"retries" json:"retries,omitempty"`
+ Delay int `yaml:"delay" json:"delay,omitempty"`
}
type Sources struct {
diff --git a/cmd/kk/apis/kubekey/v1alpha2/cluster_types.go b/cmd/kk/apis/kubekey/v1alpha2/cluster_types.go
index b5b3bc2af..aca782e7e 100644
--- a/cmd/kk/apis/kubekey/v1alpha2/cluster_types.go
+++ b/cmd/kk/apis/kubekey/v1alpha2/cluster_types.go
@@ -89,18 +89,20 @@ type KubeVip struct {
type CustomScripts struct {
Name string `yaml:"name" json:"name,omitempty"`
Bash string `yaml:"bash" json:"bash,omitempty"`
+ Role string `yaml:"role" json:"role,omitempty"`
Materials []string `yaml:"materials" json:"materials,omitempty"`
}
// System defines the system config for each node in cluster.
type System struct {
- NtpServers []string `yaml:"ntpServers" json:"ntpServers,omitempty"`
- Timezone string `yaml:"timezone" json:"timezone,omitempty"`
- Rpms []string `yaml:"rpms" json:"rpms,omitempty"`
- Debs []string `yaml:"debs" json:"debs,omitempty"`
- PreInstall []CustomScripts `yaml:"preInstall" json:"preInstall,omitempty"`
- PostInstall []CustomScripts `yaml:"postInstall" json:"postInstall,omitempty"`
- SkipConfigureOS bool `yaml:"skipConfigureOS" json:"skipConfigureOS,omitempty"`
+ NtpServers []string `yaml:"ntpServers" json:"ntpServers,omitempty"`
+ Timezone string `yaml:"timezone" json:"timezone,omitempty"`
+ Rpms []string `yaml:"rpms" json:"rpms,omitempty"`
+ Debs []string `yaml:"debs" json:"debs,omitempty"`
+ PreInstall []CustomScripts `yaml:"preInstall" json:"preInstall,omitempty"`
+ PostClusterInstall []CustomScripts `yaml:"postClusterInstall" json:"postClusterInstall,omitempty"`
+ PostInstall []CustomScripts `yaml:"postInstall" json:"postInstall,omitempty"`
+ SkipConfigureOS bool `yaml:"skipConfigureOS" json:"skipConfigureOS,omitempty"`
}
// RegistryConfig defines the configuration information of the image's repository.
diff --git a/cmd/kk/apis/kubekey/v1alpha2/default.go b/cmd/kk/apis/kubekey/v1alpha2/default.go
index 0f802cf7b..b02d41fc9 100644
--- a/cmd/kk/apis/kubekey/v1alpha2/default.go
+++ b/cmd/kk/apis/kubekey/v1alpha2/default.go
@@ -43,6 +43,7 @@ const (
DefaultEtcdPort = "2379"
DefaultDockerVersion = "24.0.9"
DefaultCriDockerdVersion = "0.3.10"
+ DefaultBuildxVersion = "v0.14.0"
DefaultContainerdVersion = "1.7.13"
DefaultRuncVersion = "v1.1.12"
DefaultCrictlVersion = "v1.29.0"
diff --git a/cmd/kk/apis/kubekey/v1alpha2/dns_types.go b/cmd/kk/apis/kubekey/v1alpha2/dns_types.go
index aeaf0081d..dfed3f39f 100644
--- a/cmd/kk/apis/kubekey/v1alpha2/dns_types.go
+++ b/cmd/kk/apis/kubekey/v1alpha2/dns_types.go
@@ -18,6 +18,7 @@ package v1alpha2
type DNS struct {
DNSEtcHosts string `yaml:"dnsEtcHosts" json:"dnsEtcHosts"`
+ NodeEtcHosts string `yaml:"nodeEtcHosts" json:"nodeEtcHosts,omitempty"`
CoreDNS CoreDNS `yaml:"coredns" json:"coredns"`
NodeLocalDNS NodeLocalDNS `yaml:"nodelocaldns" json:"nodelocaldns"`
}
diff --git a/cmd/kk/apis/kubekey/v1alpha2/manifest_types.go b/cmd/kk/apis/kubekey/v1alpha2/manifest_types.go
index 66aab5844..2ba3ee18e 100644
--- a/cmd/kk/apis/kubekey/v1alpha2/manifest_types.go
+++ b/cmd/kk/apis/kubekey/v1alpha2/manifest_types.go
@@ -24,6 +24,7 @@ import (
type Iso struct {
LocalPath string `yaml:"localPath" json:"localPath"`
Url string `yaml:"url" json:"url"`
+ Checksum string `yaml:"checksum" json:"checksum"`
}
type Repository struct {
diff --git a/cmd/kk/cmd/artifact/export.go b/cmd/kk/cmd/artifact/export.go
index 0b8b1d6d6..b5df6b1fc 100644
--- a/cmd/kk/cmd/artifact/export.go
+++ b/cmd/kk/cmd/artifact/export.go
@@ -34,6 +34,8 @@ type ArtifactExportOptions struct {
Output string
CriSocket string
DownloadCmd string
+ ImageStartIndex int
+ ImageTransport string
SkipRemoveArtifact bool
}
@@ -80,6 +82,8 @@ func (o *ArtifactExportOptions) Run() error {
ManifestFile: o.ManifestFile,
Output: o.Output,
CriSocket: o.CriSocket,
+ ImageStartIndex: o.ImageStartIndex,
+ ImageTransport: o.ImageTransport,
Debug: o.CommonOptions.Verbose,
IgnoreErr: o.CommonOptions.IgnoreErr,
SkipRemoveArtifact: o.SkipRemoveArtifact,
@@ -93,6 +97,8 @@ func (o *ArtifactExportOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Output, "output", "o", "", "Path to a output path")
cmd.Flags().StringVarP(&o.DownloadCmd, "download-cmd", "", "curl -L -o %s %s",
`The user defined command to download the necessary binary files. The first param '%s' is output path, the second param '%s', is the URL`)
+ cmd.Flags().IntVarP(&o.ImageStartIndex, "image-start-index", "", 0, "Save images from specific index, default to 0")
+ cmd.Flags().StringVarP(&o.ImageTransport, "image-transport", "", "", "Image transport to pull from, take values from [docker, docker-daemon]")
cmd.Flags().BoolVarP(&o.SkipRemoveArtifact, "skip-remove-artifact", "", false, "Skip remove artifact")
}
diff --git a/cmd/kk/cmd/artifact/images/push.go b/cmd/kk/cmd/artifact/images/push.go
index d337bdd14..3a5f7ad4e 100644
--- a/cmd/kk/cmd/artifact/images/push.go
+++ b/cmd/kk/cmd/artifact/images/push.go
@@ -37,6 +37,7 @@ type ArtifactImagesPushOptions struct {
CommonOptions *options.CommonOptions
ImageDirPath string
+ ImageTransport string
Artifact string
ClusterCfgFile string
}
@@ -89,11 +90,12 @@ func (o *ArtifactImagesPushOptions) Validate(_ []string) error {
func (o *ArtifactImagesPushOptions) Run() error {
arg := common.Argument{
- ImagesDir: o.ImageDirPath,
- Artifact: o.Artifact,
- FilePath: o.ClusterCfgFile,
- Debug: o.CommonOptions.Verbose,
- IgnoreErr: o.CommonOptions.IgnoreErr,
+ ImagesDir: o.ImageDirPath,
+ Artifact: o.Artifact,
+ FilePath: o.ClusterCfgFile,
+ ImageTransport: o.ImageTransport,
+ Debug: o.CommonOptions.Verbose,
+ IgnoreErr: o.CommonOptions.IgnoreErr,
}
return runPush(arg)
}
@@ -102,6 +104,7 @@ func (o *ArtifactImagesPushOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.ImageDirPath, "images-dir", "", "", "Path to a KubeKey artifact images directory")
cmd.Flags().StringVarP(&o.Artifact, "artifact", "a", "", "Path to a KubeKey artifact")
cmd.Flags().StringVarP(&o.ClusterCfgFile, "filename", "f", "", "Path to a configuration file")
+ cmd.Flags().StringVarP(&o.ImageTransport, "image-transport", "", "", "Image transport to push to, take values from [docker, docker-daemon]")
}
func runPush(arg common.Argument) error {
@@ -122,7 +125,8 @@ func newImagesPushPipeline(runtime *common.KubeRuntime) error {
m := []module.Module{
&artifact.UnArchiveModule{Skip: noArtifact},
- &images.CopyImagesToRegistryModule{ImagePath: runtime.Arg.ImagesDir},
+ &images.CopyImagesToRegistryModule{ImagePath: runtime.Arg.ImagesDir,
+ ImageTransport: runtime.Arg.ImageTransport},
&filesystem.ChownWorkDirModule{},
}
diff --git a/cmd/kk/cmd/create/cluster.go b/cmd/kk/cmd/create/cluster.go
index 3ca16ec03..3ba592c43 100644
--- a/cmd/kk/cmd/create/cluster.go
+++ b/cmd/kk/cmd/create/cluster.go
@@ -38,6 +38,7 @@ type CreateClusterOptions struct {
EnableKubeSphere bool
KubeSphere string
LocalStorage bool
+ SkipInstallAddons bool
SkipPullImages bool
SkipPushImages bool
SecurityEnhancement bool
@@ -45,6 +46,7 @@ type CreateClusterOptions struct {
DownloadCmd string
Artifact string
InstallPackages bool
+ WithBuildx bool
localStorageChanged bool
}
@@ -112,6 +114,7 @@ func (o *CreateClusterOptions) Run() error {
KubernetesVersion: o.Kubernetes,
KsEnable: o.EnableKubeSphere,
KsVersion: o.KubeSphere,
+ SkipInstallAddons: o.SkipInstallAddons,
SkipPullImages: o.SkipPullImages,
SkipPushImages: o.SkipPushImages,
SecurityEnhancement: o.SecurityEnhancement,
@@ -122,6 +125,7 @@ func (o *CreateClusterOptions) Run() error {
Artifact: o.Artifact,
InstallPackages: o.InstallPackages,
Namespace: o.CommonOptions.Namespace,
+ WithBuildx: o.WithBuildx,
}
if o.localStorageChanged {
@@ -137,6 +141,7 @@ func (o *CreateClusterOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Kubernetes, "with-kubernetes", "", "", "Specify a supported version of kubernetes")
cmd.Flags().BoolVarP(&o.LocalStorage, "with-local-storage", "", false, "Deploy a local PV provisioner")
cmd.Flags().BoolVarP(&o.EnableKubeSphere, "with-kubesphere", "", false, fmt.Sprintf("Deploy a specific version of kubesphere (default %s)", kubesphere.Latest().Version))
+ cmd.Flags().BoolVarP(&o.SkipInstallAddons, "skip-install-addons", "", false, "Skip install addons")
cmd.Flags().BoolVarP(&o.SkipPullImages, "skip-pull-images", "", false, "Skip pre pull images")
cmd.Flags().BoolVarP(&o.SkipPushImages, "skip-push-images", "", false, "Skip pre push images")
cmd.Flags().BoolVarP(&o.SecurityEnhancement, "with-security-enhancement", "", false, "Security enhancement")
@@ -145,6 +150,7 @@ func (o *CreateClusterOptions) AddFlags(cmd *cobra.Command) {
`The user defined command to download the necessary binary files. The first param '%s' is output path, the second param '%s', is the URL`)
cmd.Flags().StringVarP(&o.Artifact, "artifact", "a", "", "Path to a KubeKey artifact")
cmd.Flags().BoolVarP(&o.InstallPackages, "with-packages", "", false, "install operation system packages by artifact")
+ cmd.Flags().BoolVarP(&o.WithBuildx, "with-buildx", "", false, "install buildx when Container runtime is docker")
}
func completionSetting(cmd *cobra.Command) (err error) {
diff --git a/cmd/kk/cmd/create/phase/addons.go b/cmd/kk/cmd/create/phase/addons.go
new file mode 100644
index 000000000..ead549ccb
--- /dev/null
+++ b/cmd/kk/cmd/create/phase/addons.go
@@ -0,0 +1,49 @@
+package phase
+
+import (
+ "github.com/spf13/cobra"
+
+ "github.com/kubesphere/kubekey/v3/cmd/kk/cmd/options"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/cmd/util"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/common"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/phase/addons"
+)
+
+type ApplyAddonsOptions struct {
+ CommonOptions *options.CommonOptions
+ ClusterCfgFile string
+}
+
+func NewApplyAddonsOptions() *ApplyAddonsOptions {
+ return &ApplyAddonsOptions{
+ CommonOptions: options.NewCommonOptions(),
+ }
+}
+
+func NewCmdApplyAddons() *cobra.Command {
+ o := NewApplyAddonsOptions()
+ cmd := &cobra.Command{
+ Use: "addons",
+ Short: "Apply cluster addons",
+ Run: func(cmd *cobra.Command, args []string) {
+ util.CheckErr(o.Run(args))
+ },
+ }
+
+ o.CommonOptions.AddCommonFlag(cmd)
+ o.AddFlags(cmd)
+ return cmd
+}
+
+func (o *ApplyAddonsOptions) Run(args []string) error {
+ arg := common.Argument{
+ FilePath: o.ClusterCfgFile,
+ Debug: o.CommonOptions.Verbose,
+ EnabledAddons: args,
+ }
+ return addons.ApplyClusterAddons(arg)
+}
+
+func (o *ApplyAddonsOptions) AddFlags(cmd *cobra.Command) {
+ cmd.Flags().StringVarP(&o.ClusterCfgFile, "filename", "f", "", "Path to a configuration file")
+}
diff --git a/cmd/kk/cmd/create/phase/init.go b/cmd/kk/cmd/create/phase/init.go
index 60f5c83b3..abcc2fd8a 100644
--- a/cmd/kk/cmd/create/phase/init.go
+++ b/cmd/kk/cmd/create/phase/init.go
@@ -39,7 +39,7 @@ func NewCreateInitClusterOptions() *CreateInitClusterOptions {
}
}
-// NewCmdUpgrade creates a new upgrade command
+// NewCmdCreateInitCluster creates a new upgrade command
func NewCmdCreateInitCluster() *cobra.Command {
o := NewCreateInitClusterOptions()
cmd := &cobra.Command{
diff --git a/cmd/kk/cmd/create/phase/phase.go b/cmd/kk/cmd/create/phase/phase.go
index 655fddeae..862a8a346 100755
--- a/cmd/kk/cmd/create/phase/phase.go
+++ b/cmd/kk/cmd/create/phase/phase.go
@@ -34,6 +34,7 @@ func NewPhaseCommand() *cobra.Command {
cmds.AddCommand(NewCmdCreateJoinNodes())
cmds.AddCommand(NewCmdCreateConfigureKubernetes())
cmds.AddCommand(NewCmdCreateKubeSphere())
+ cmds.AddCommand(NewCmdApplyAddons())
return cmds
}
diff --git a/cmd/kk/cmd/upgrade/phase/images.go b/cmd/kk/cmd/upgrade/phase/images.go
index 86bd97a44..a726f7265 100755
--- a/cmd/kk/cmd/upgrade/phase/images.go
+++ b/cmd/kk/cmd/upgrade/phase/images.go
@@ -39,7 +39,7 @@ func NewUpgradeImagesOptions() *UpgradeImagesOptions {
}
}
-// NewCmdUpgrade creates a new upgrade command
+// NewCmdUpgradeImages creates a new upgrade command
func NewCmdUpgradeImages() *cobra.Command {
o := NewUpgradeImagesOptions()
cmd := &cobra.Command{
diff --git a/cmd/kk/cmd/upgrade/phase/nodes.go b/cmd/kk/cmd/upgrade/phase/nodes.go
index 83b0eaa29..b00d54ee4 100755
--- a/cmd/kk/cmd/upgrade/phase/nodes.go
+++ b/cmd/kk/cmd/upgrade/phase/nodes.go
@@ -39,7 +39,7 @@ func NewUpgradeNodesOptions() *UpgradeNodesOptions {
}
}
-// NewCmdUpgrade creates a new upgrade command
+// NewCmdUpgradeNodes creates a new upgrade command
func NewCmdUpgradeNodes() *cobra.Command {
o := NewUpgradeNodesOptions()
cmd := &cobra.Command{
diff --git a/cmd/kk/pkg/addons/module.go b/cmd/kk/pkg/addons/module.go
index ab833c23e..4b08fede1 100644
--- a/cmd/kk/pkg/addons/module.go
+++ b/cmd/kk/pkg/addons/module.go
@@ -17,6 +17,9 @@
package addons
import (
+ "fmt"
+
+ kubekeyapiv1alpha2 "github.com/kubesphere/kubekey/v3/cmd/kk/apis/kubekey/v1alpha2"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/common"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/task"
)
@@ -44,3 +47,23 @@ func (a *AddonsModule) Init() {
install,
}
}
+
+type AddonModule struct {
+ common.KubeModule
+ addon *kubekeyapiv1alpha2.Addon
+}
+
+func (s *AddonModule) Init() {
+ s.Name = "AddonModule"
+ s.Desc = fmt.Sprintf("Install addon %s", s.addon.Name)
+
+ install := &task.LocalTask{
+ Name: "InstallAddon",
+ Desc: fmt.Sprintf("Install addon %s", s.addon.Name),
+ Action: &InstallAddon{addon: s.addon},
+ }
+
+ s.Tasks = []task.Interface{
+ install,
+ }
+}
diff --git a/cmd/kk/pkg/addons/tasks.go b/cmd/kk/pkg/addons/tasks.go
index cd79d589f..547796410 100644
--- a/cmd/kk/pkg/addons/tasks.go
+++ b/cmd/kk/pkg/addons/tasks.go
@@ -19,10 +19,17 @@ package addons
import (
"fmt"
"path/filepath"
+ "strings"
+ "github.com/pkg/errors"
+
+ kubekeyapiv1alpha2 "github.com/kubesphere/kubekey/v3/cmd/kk/apis/kubekey/v1alpha2"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/bootstrap/customscripts"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/common"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/connector"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/logger"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/module"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/pipeline"
)
type Install struct {
@@ -31,11 +38,81 @@ type Install struct {
func (i *Install) Execute(runtime connector.Runtime) error {
nums := len(i.KubeConf.Cluster.Addons)
+
+ enabledAddons, err := i.enabledAddons()
+ if err != nil {
+ return err
+ }
+
+ logger.Log.Messagef(runtime.RemoteHost().GetName(), "[%v/%v] enabled addons", len(enabledAddons), nums)
+
for index, addon := range i.KubeConf.Cluster.Addons {
+ if _, ok := enabledAddons[addon.Name]; !ok {
+ continue
+ }
logger.Log.Messagef(runtime.RemoteHost().GetName(), "Install addon [%v-%v]: %s", nums, index, addon.Name)
- if err := InstallAddons(i.KubeConf, &addon, filepath.Join(runtime.GetWorkDir(), fmt.Sprintf("config-%s", runtime.GetObjName()))); err != nil {
+
+ m := []module.Module{
+ &customscripts.CustomScriptsModule{Phase: "PreInstall", Scripts: addon.PreInstall},
+ &AddonModule{addon: &addon},
+ &customscripts.CustomScriptsModule{Phase: "PostInstall", Scripts: addon.PostInstall},
+ }
+ p := pipeline.Pipeline{
+ Name: "InstallAddonsPipeline",
+ Modules: m,
+ Runtime: runtime,
+ SkipPrintLogo: true,
+ }
+ if err := p.Start(); err != nil {
return err
}
}
return nil
}
+
+func (i *Install) enabledAddons() (map[string]struct{}, error) {
+ enabledAddons := make(map[string]struct{}, len(i.KubeConf.Cluster.Addons))
+ for _, addon := range i.KubeConf.Cluster.Addons {
+ enabledAddons[addon.Name] = struct{}{}
+ }
+
+ if len(i.KubeConf.Arg.EnabledAddons) == 0 {
+ return enabledAddons, nil
+ }
+
+ enabledAddonsConfig := make(map[string]struct{}, len(i.KubeConf.Arg.EnabledAddons))
+ for _, config := range i.KubeConf.Arg.EnabledAddons {
+ enabledAddonsConfig[config] = struct{}{}
+ }
+
+ for addon := range enabledAddons {
+ if _, ok := enabledAddonsConfig[addon]; !ok {
+ // drop addons not in input args
+ delete(enabledAddons, addon)
+ } else {
+ // drop input args validated
+ delete(enabledAddonsConfig, addon)
+ }
+ }
+ if len(enabledAddonsConfig) > 0 {
+ // exists invalid input args
+ keys := make([]string, 0, len(enabledAddonsConfig))
+ for key := range enabledAddonsConfig {
+ keys = append(keys, key)
+ }
+ return nil, errors.New(fmt.Sprintf("Addons not exists: %s", strings.Join(keys, ",")))
+ }
+ return enabledAddons, nil
+}
+
+type InstallAddon struct {
+ common.KubeAction
+ addon *kubekeyapiv1alpha2.Addon
+}
+
+func (i *InstallAddon) Execute(runtime connector.Runtime) error {
+ if err := InstallAddons(i.KubeConf, i.addon, filepath.Join(runtime.GetWorkDir(), fmt.Sprintf("config-%s", runtime.GetObjName()))); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/cmd/kk/pkg/artifact/tasks.go b/cmd/kk/pkg/artifact/tasks.go
index a10889961..180b9ef09 100644
--- a/cmd/kk/pkg/artifact/tasks.go
+++ b/cmd/kk/pkg/artifact/tasks.go
@@ -30,6 +30,7 @@ import (
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/connector"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/logger"
coreutil "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/util"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/files"
)
type DownloadISOFile struct {
@@ -44,6 +45,17 @@ func (d *DownloadISOFile) Execute(runtime connector.Runtime) error {
fileName := fmt.Sprintf("%s-%s-%s.iso", sys.Id, sys.Version, sys.Arch)
filePath := filepath.Join(runtime.GetWorkDir(), fileName)
+
+ checksumEqual, err := files.SHA256CheckEqual(filePath, sys.Repository.Iso.Checksum)
+ if err != nil {
+ return err
+ }
+ if checksumEqual {
+ logger.Log.Infof("Skip download exists iso file %s", fileName)
+ d.Manifest.Spec.OperatingSystems[i].Repository.Iso.LocalPath = filePath
+ continue
+ }
+
getCmd := d.Manifest.Arg.DownloadCommand(filePath, sys.Repository.Iso.Url)
cmd := exec.Command("/bin/sh", "-c", getCmd)
diff --git a/cmd/kk/pkg/binaries/kubernetes.go b/cmd/kk/pkg/binaries/kubernetes.go
index 5f16c9c98..832183e59 100644
--- a/cmd/kk/pkg/binaries/kubernetes.go
+++ b/cmd/kk/pkg/binaries/kubernetes.go
@@ -45,6 +45,8 @@ func K8sFilesDownloadHTTP(kubeConf *common.KubeConf, path, version, arch string,
runc := files.NewKubeBinary("runc", arch, kubekeyapiv1alpha2.DefaultRuncVersion, path, kubeConf.Arg.DownloadCommand)
calicoctl := files.NewKubeBinary("calicoctl", arch, kubekeyapiv1alpha2.DefaultCalicoVersion, path, kubeConf.Arg.DownloadCommand)
+ buildx := files.NewKubeBinary(common.Buildx, arch, kubekeyapiv1alpha2.DefaultBuildxVersion, path, kubeConf.Arg.DownloadCommand)
+
binaries := []*files.KubeBinary{kubeadm, kubelet, kubectl, helm, kubecni, crictl, etcd}
if kubeConf.Cluster.Kubernetes.ContainerManager == kubekeyapiv1alpha2.Docker {
@@ -52,6 +54,9 @@ func K8sFilesDownloadHTTP(kubeConf *common.KubeConf, path, version, arch string,
if kubeConf.Cluster.Kubernetes.IsAtLeastV124() && kubeConf.Cluster.Kubernetes.ContainerManager == common.Docker {
binaries = append(binaries, criDockerd)
}
+ if kubeConf.Arg.WithBuildx {
+ binaries = append(binaries, buildx)
+ }
} else if kubeConf.Cluster.Kubernetes.ContainerManager == kubekeyapiv1alpha2.Containerd {
binaries = append(binaries, containerd, runc)
}
diff --git a/cmd/kk/pkg/bootstrap/confirm/tasks.go b/cmd/kk/pkg/bootstrap/confirm/tasks.go
index 74227cb12..0e4da5508 100644
--- a/cmd/kk/pkg/bootstrap/confirm/tasks.go
+++ b/cmd/kk/pkg/bootstrap/confirm/tasks.go
@@ -23,6 +23,9 @@ import (
"regexp"
"strings"
+ versionK8S "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/version/kubernetes"
+
+ kubekeyapiv1alpha2 "github.com/kubesphere/kubekey/v3/cmd/kk/apis/kubekey/v1alpha2"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/common"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/action"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/connector"
@@ -32,6 +35,7 @@ import (
"github.com/modood/table"
"github.com/pkg/errors"
versionutil "k8s.io/apimachinery/pkg/util/version"
+ "k8s.io/utils/strings/slices"
)
// PreCheckResults defines the items to be checked.
@@ -106,6 +110,27 @@ func (i *InstallationConfirm) Execute(runtime connector.Runtime) error {
fmt.Println("https://github.com/kubesphere/kubekey#requirements-and-recommendations")
fmt.Println("")
+ // check k8s version is supported
+ k8sVersion := i.KubeConf.Cluster.Kubernetes.Version
+ if k8sVersion != kubekeyapiv1alpha2.DefaultKubeVersion {
+ suppportVersions := versionK8S.SupportedK8sVersionList()
+ if !strings.HasPrefix(k8sVersion, "v") {
+ k8sVersion = "v" + k8sVersion
+ }
+ if !slices.Contains(suppportVersions, k8sVersion) {
+ fmt.Printf("The Kubernetes version: %s isn't supported.\n", k8sVersion)
+ fmt.Println("Use kk version --show-supported-k8s,show supported k8s versions")
+ fmt.Println("")
+ stopFlag = true
+ } else {
+ fmt.Println("Install k8s with specify version: ", k8sVersion)
+ fmt.Println("")
+ }
+ } else {
+ fmt.Println("Install k8s with default version: ", kubekeyapiv1alpha2.DefaultKubeVersion)
+ fmt.Println("")
+ }
+
if i.KubeConf.Cluster.Kubernetes.IsAtLeastV124() && i.KubeConf.Cluster.Kubernetes.ContainerManager == common.Docker {
fmt.Println("[Notice]")
fmt.Println("For Kubernetes v1.24 and later, dockershim has been deprecated.")
diff --git a/cmd/kk/pkg/bootstrap/customscripts/module.go b/cmd/kk/pkg/bootstrap/customscripts/module.go
index 1c98a178d..336d35d9b 100644
--- a/cmd/kk/pkg/bootstrap/customscripts/module.go
+++ b/cmd/kk/pkg/bootstrap/customscripts/module.go
@@ -20,6 +20,7 @@ import (
"fmt"
kubekeyapiv1alpha2 "github.com/kubesphere/kubekey/v3/cmd/kk/apis/kubekey/v1alpha2"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/connector"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/module"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/task"
)
@@ -38,10 +39,18 @@ func (m *CustomScriptsModule) Init() {
taskName := fmt.Sprintf("Phase:%s(%d/%d) script:%s", m.Phase, idx, len(m.Scripts), script.Name)
taskDir := fmt.Sprintf("%s-%d-script", m.Phase, idx)
+
+ var hosts []connector.Host
+ if len(script.Role) > 0 {
+ hosts = m.Runtime.GetHostsByRole(script.Role)
+ } else {
+ hosts = m.Runtime.GetAllHosts()
+ }
+
task := &task.RemoteTask{
Name: taskName,
Desc: taskName,
- Hosts: m.Runtime.GetAllHosts(),
+ Hosts: hosts,
Action: &CustomScriptTask{taskDir: taskDir, script: script},
Parallel: true,
Retry: 1,
diff --git a/cmd/kk/pkg/bootstrap/customscripts/tasks.go b/cmd/kk/pkg/bootstrap/customscripts/tasks.go
index 439e4dc0d..314698f9d 100644
--- a/cmd/kk/pkg/bootstrap/customscripts/tasks.go
+++ b/cmd/kk/pkg/bootstrap/customscripts/tasks.go
@@ -96,8 +96,9 @@ func (t *CustomScriptTask) Execute(runtime connector.Runtime) error {
RunBash = "/bin/bash " + targetPath
}
+ cd_cmd := fmt.Sprintf("cd %s;", remoteTaskHome)
start := time.Now()
- out, err := runtime.GetRunner().SudoCmd(RunBash, false)
+ out, err := runtime.GetRunner().SudoCmd(cd_cmd+RunBash, false)
if err != nil {
return errors.Errorf("Exec Bash: %s err:%s", RunBash, err)
}
diff --git a/cmd/kk/pkg/bootstrap/os/templates/init_script.go b/cmd/kk/pkg/bootstrap/os/templates/init_script.go
index 327fad661..d9042eff2 100644
--- a/cmd/kk/pkg/bootstrap/os/templates/init_script.go
+++ b/cmd/kk/pkg/bootstrap/os/templates/init_script.go
@@ -18,6 +18,7 @@ package templates
import (
"fmt"
+ "strings"
"text/template"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/bootstrap/registry"
@@ -81,8 +82,8 @@ echo 'net.ipv4.tcp_keepalive_intvl = 30' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_keepalive_probes = 10' >> /etc/sysctl.conf
echo 'net.ipv4.udp_rmem_min = 131072' >> /etc/sysctl.conf
echo 'net.ipv4.udp_wmem_min = 131072' >> /etc/sysctl.conf
-echo 'net.ipv4.conf.all.rp_filter = 1' >> /etc/sysctl.conf
-echo 'net.ipv4.conf.default.rp_filter = 1' >> /etc/sysctl.conf
+echo 'net.ipv4.conf.all.rp_filter = 0' >> /etc/sysctl.conf
+echo 'net.ipv4.conf.default.rp_filter = 0' >> /etc/sysctl.conf
echo 'net.ipv4.conf.all.arp_accept = 1' >> /etc/sysctl.conf
echo 'net.ipv4.conf.default.arp_accept = 1' >> /etc/sysctl.conf
echo 'net.ipv4.conf.all.arp_ignore = 1' >> /etc/sysctl.conf
@@ -107,8 +108,8 @@ echo 'net.ipv6.conf.all.forwarding=1' >> /etc/sysctl.conf
#See https://help.aliyun.com/document_detail/118806.html#uicontrol-e50-ddj-w0y
sed -r -i "s@#{0,}?net.ipv4.tcp_tw_recycle ?= ?(0|1|2)@net.ipv4.tcp_tw_recycle = 0@g" /etc/sysctl.conf
sed -r -i "s@#{0,}?net.ipv4.tcp_tw_reuse ?= ?(0|1)@net.ipv4.tcp_tw_reuse = 0@g" /etc/sysctl.conf
-sed -r -i "s@#{0,}?net.ipv4.conf.all.rp_filter ?= ?(0|1|2)@net.ipv4.conf.all.rp_filter = 1@g" /etc/sysctl.conf
-sed -r -i "s@#{0,}?net.ipv4.conf.default.rp_filter ?= ?(0|1|2)@net.ipv4.conf.default.rp_filter = 1@g" /etc/sysctl.conf
+sed -r -i "s@#{0,}?net.ipv4.conf.all.rp_filter ?= ?(0|1|2)@net.ipv4.conf.all.rp_filter = 0@g" /etc/sysctl.conf
+sed -r -i "s@#{0,}?net.ipv4.conf.default.rp_filter ?= ?(0|1|2)@net.ipv4.conf.default.rp_filter = 0@g" /etc/sysctl.conf
sed -r -i "s@#{0,}?net.ipv4.ip_forward ?= ?(0|1)@net.ipv4.ip_forward = 1@g" /etc/sysctl.conf
sed -r -i "s@#{0,}?net.bridge.bridge-nf-call-arptables ?= ?(0|1)@net.bridge.bridge-nf-call-arptables = 1@g" /etc/sysctl.conf
sed -r -i "s@#{0,}?net.bridge.bridge-nf-call-ip6tables ?= ?(0|1)@net.bridge.bridge-nf-call-ip6tables = 1@g" /etc/sysctl.conf
@@ -272,6 +273,17 @@ func GenerateHosts(runtime connector.ModuleRuntime, kubeConf *common.KubeConf) [
}
+ nodeEtcHosts := kubeConf.Cluster.DNS.NodeEtcHosts
+ if len(nodeEtcHosts) > 0 {
+ lines := strings.Split(strings.TrimSpace(nodeEtcHosts), "\n")
+ for i := range lines {
+ line := strings.TrimSpace(lines[i])
+ if line != "" {
+ hostsList = append(hostsList, line)
+ }
+ }
+ }
+
hostsList = append(hostsList, lbHost)
return hostsList
}
diff --git a/cmd/kk/pkg/bootstrap/precheck/tasks.go b/cmd/kk/pkg/bootstrap/precheck/tasks.go
index 5517228a9..868517eb2 100644
--- a/cmd/kk/pkg/bootstrap/precheck/tasks.go
+++ b/cmd/kk/pkg/bootstrap/precheck/tasks.go
@@ -335,8 +335,10 @@ func (g *GetKubernetesNodesStatus) Execute(runtime connector.Runtime) error {
featureGates, err := runtime.GetRunner().SudoCmd("cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep feature-gates", false)
if err != nil {
- return err
+ g.PipelineCache.Set(common.ClusterFeatureGates, "")
+ } else {
+ g.PipelineCache.Set(common.ClusterFeatureGates, featureGates)
}
- g.PipelineCache.Set(common.ClusterFeatureGates, featureGates)
+
return nil
}
diff --git a/cmd/kk/pkg/common/artifact_runtime.go b/cmd/kk/pkg/common/artifact_runtime.go
index c9ad51170..2ab4e8afe 100644
--- a/cmd/kk/pkg/common/artifact_runtime.go
+++ b/cmd/kk/pkg/common/artifact_runtime.go
@@ -35,6 +35,8 @@ type ArtifactArgument struct {
Debug bool
IgnoreErr bool
DownloadCommand func(path, url string) string
+ ImageStartIndex int
+ ImageTransport string
SkipRemoveArtifact bool
}
diff --git a/cmd/kk/pkg/common/common.go b/cmd/kk/pkg/common/common.go
index a57ee1ec2..f2cf19170 100644
--- a/cmd/kk/pkg/common/common.go
+++ b/cmd/kk/pkg/common/common.go
@@ -69,6 +69,8 @@ const (
Isula = "isula"
Runc = "runc"
+ Buildx = "buildx"
+
// global cache key
// PreCheckModule
NodePreCheck = "nodePreCheck"
@@ -97,4 +99,7 @@ const (
// Artifact pipeline
Artifact = "artifact"
+
+ // Image Copy Transports
+ DockerDaemon = "docker-daemon"
)
diff --git a/cmd/kk/pkg/common/kube_runtime.go b/cmd/kk/pkg/common/kube_runtime.go
index c7727474b..b500a3f06 100644
--- a/cmd/kk/pkg/common/kube_runtime.go
+++ b/cmd/kk/pkg/common/kube_runtime.go
@@ -37,6 +37,8 @@ type Argument struct {
KsVersion string
Debug bool
IgnoreErr bool
+ SkipInstallAddons bool
+ EnabledAddons []string
SkipPullImages bool
SkipPushImages bool
SkipDependencyCheck bool
@@ -48,6 +50,7 @@ type Argument struct {
FromCluster bool
KubeConfig string
Artifact string
+ ImageTransport string
InstallPackages bool
ImagesDir string
Namespace string
@@ -55,6 +58,7 @@ type Argument struct {
Role string
Type string
EtcdUpgrade bool
+ WithBuildx bool
}
func NewKubeRuntime(flag string, arg Argument) (*KubeRuntime, error) {
diff --git a/cmd/kk/pkg/container/docker.go b/cmd/kk/pkg/container/docker.go
index 94641b167..cbe8de6e6 100644
--- a/cmd/kk/pkg/container/docker.go
+++ b/cmd/kk/pkg/container/docker.go
@@ -30,6 +30,39 @@ import (
"github.com/pkg/errors"
)
+type SyncDockerBuildxPluginBinaries struct {
+ common.KubeAction
+}
+
+func (s *SyncDockerBuildxPluginBinaries) Execute(runtime connector.Runtime) error {
+ if err := utils.ResetTmpDir(runtime); err != nil {
+ return err
+ }
+
+ binariesMapObj, ok := s.PipelineCache.Get(common.KubeBinaries + "-" + runtime.RemoteHost().GetArch())
+ if !ok {
+ return errors.New("get KubeBinary by pipeline cache failed")
+ }
+ binariesMap := binariesMapObj.(map[string]*files.KubeBinary)
+
+ buildx, ok := binariesMap[common.Buildx]
+ if !ok {
+ return errors.New("get KubeBinary key buildx by pipeline cache failed")
+ }
+
+ dst := filepath.Join(common.TmpDir, buildx.FileName)
+ if err := runtime.GetRunner().Scp(buildx.Path(), dst); err != nil {
+ return errors.Wrap(errors.WithStack(err), fmt.Sprintf("sync docker binaries failed"))
+ }
+
+ if _, err := runtime.GetRunner().SudoCmd(
+ fmt.Sprintf("mkdir -p /usr/local/lib/docker/cli-plugins && mv %s /usr/local/lib/docker/cli-plugins/docker-buildx && chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx && rm -rf %s", dst, dst),
+ false); err != nil {
+ return errors.Wrap(errors.WithStack(err), fmt.Sprintf("install docker-buildx binaries failed"))
+ }
+ return nil
+}
+
type SyncDockerBinaries struct {
common.KubeAction
}
diff --git a/cmd/kk/pkg/container/module.go b/cmd/kk/pkg/container/module.go
index 36eaddeac..a432eb4dc 100644
--- a/cmd/kk/pkg/container/module.go
+++ b/cmd/kk/pkg/container/module.go
@@ -60,6 +60,19 @@ func (i *InstallContainerModule) Init() {
}
func InstallDocker(m *InstallContainerModule) []task.Interface {
+
+ syncBuildxPluginBinaries := &task.RemoteTask{
+ Name: "SyncDockerBuildxBinaries",
+ Desc: "Sync docker buildx binaries",
+ Hosts: m.Runtime.GetHostsByRole(common.K8s),
+ Prepare: &prepare.PrepareCollection{
+ &WithBuildxPlugin{},
+ },
+ Action: new(SyncDockerBuildxPluginBinaries),
+ Parallel: true,
+ Retry: 2,
+ }
+
syncBinaries := &task.RemoteTask{
Name: "SyncDockerBinaries",
Desc: "Sync docker binaries",
@@ -169,6 +182,7 @@ func InstallDocker(m *InstallContainerModule) []task.Interface {
enableContainerdForDocker,
enableDocker,
dockerLoginRegistry,
+ syncBuildxPluginBinaries,
}
}
diff --git a/cmd/kk/pkg/container/prepares.go b/cmd/kk/pkg/container/prepares.go
index d0f0ba829..4e6782bcb 100644
--- a/cmd/kk/pkg/container/prepares.go
+++ b/cmd/kk/pkg/container/prepares.go
@@ -23,6 +23,18 @@ import (
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/connector"
)
+type WithBuildxPlugin struct {
+ common.KubePrepare
+}
+
+func (w *WithBuildxPlugin) PreCheck(runtime connector.Runtime) (bool, error) {
+ if w.KubeConf.Arg.WithBuildx {
+ return true, nil
+ } else {
+ return false, nil
+ }
+}
+
type DockerExist struct {
common.KubePrepare
Not bool
diff --git a/cmd/kk/pkg/core/pipeline/pipeline.go b/cmd/kk/pkg/core/pipeline/pipeline.go
index 9afce39d9..0f6525560 100644
--- a/cmd/kk/pkg/core/pipeline/pipeline.go
+++ b/cmd/kk/pkg/core/pipeline/pipeline.go
@@ -51,10 +51,13 @@ type Pipeline struct {
PipelineCache *cache.Cache
ModuleCachePool sync.Pool
ModulePostHooks []module.PostHookInterface
+ SkipPrintLogo bool
}
func (p *Pipeline) Init() error {
- fmt.Print(logo)
+ if !p.SkipPrintLogo {
+ fmt.Print(logo)
+ }
p.PipelineCache = cache.NewCache()
p.SpecHosts = len(p.Runtime.GetAllHosts())
//if err := p.Runtime.GenerateWorkDir(); err != nil {
diff --git a/cmd/kk/pkg/files/file.go b/cmd/kk/pkg/files/file.go
index 9079837ad..dfc298ad8 100644
--- a/cmd/kk/pkg/files/file.go
+++ b/cmd/kk/pkg/files/file.go
@@ -52,6 +52,7 @@ const (
containerd = "containerd"
runc = "runc"
calicoctl = "calicoctl"
+ buildx = "buildx"
)
// KubeBinary Type field const
@@ -66,6 +67,7 @@ const (
REGISTRY = "registry"
CONTAINERD = "containerd"
RUNC = "runc"
+ BUILD = "buildx"
)
var (
@@ -225,6 +227,10 @@ func NewKubeBinary(name, arch, version, prePath string, getCmd func(path, url st
if component.Zone == "cn" {
component.Url = fmt.Sprintf("https://kubernetes-release.pek3b.qingstor.com/projectcalico/calico/releases/download/%s/calicoctl-linux-%s", version, arch)
}
+ case buildx:
+ component.Type = BUILD
+ component.FileName = fmt.Sprintf("buildx-%s.linux-%s", version, arch)
+ component.Url = fmt.Sprintf("https://github.com/docker/buildx/releases/download/%s/buildx-%s.linux-%s", version, version, arch)
default:
logger.Log.Fatalf("unsupported kube binaries %s", name)
}
@@ -322,6 +328,23 @@ func (b *KubeBinary) SHA256Check() error {
return nil
}
+func SHA256CheckEqual(filePath string, checksum string) (bool, error) {
+ if strings.TrimSpace(checksum) == "" {
+ return false, nil
+ }
+
+ if !util.IsExist(filePath) {
+ return false, nil
+ }
+
+ output, err := sha256sum(filePath)
+ if err != nil {
+ return false, errors.Wrap(err, fmt.Sprintf("Failed to check SHA256 of %s", filePath))
+ }
+
+ return output == checksum, nil
+}
+
func sha256sum(path string) (string, error) {
file, err := os.Open(path)
if err != nil {
diff --git a/cmd/kk/pkg/images/module.go b/cmd/kk/pkg/images/module.go
index cc4843e02..361371746 100644
--- a/cmd/kk/pkg/images/module.go
+++ b/cmd/kk/pkg/images/module.go
@@ -49,6 +49,8 @@ func (p *PullModule) Init() {
type CopyImagesToLocalModule struct {
common.ArtifactModule
+ ImageStartIndex int
+ ImageTransport string
}
func (c *CopyImagesToLocalModule) Init() {
@@ -58,7 +60,7 @@ func (c *CopyImagesToLocalModule) Init() {
copyImage := &task.LocalTask{
Name: "SaveImages",
Desc: "Copy images to a local OCI path from registries",
- Action: new(SaveImages),
+ Action: &SaveImages{ImageStartIndex: c.ImageStartIndex, ImageTransport: c.ImageTransport},
}
c.Tasks = []task.Interface{
@@ -68,8 +70,9 @@ func (c *CopyImagesToLocalModule) Init() {
type CopyImagesToRegistryModule struct {
common.KubeModule
- Skip bool
- ImagePath string
+ Skip bool
+ ImagePath string
+ ImageTransport string
}
func (c *CopyImagesToRegistryModule) IsSkip() bool {
@@ -83,13 +86,14 @@ func (c *CopyImagesToRegistryModule) Init() {
copyImage := &task.LocalTask{
Name: "CopyImagesToRegistry",
Desc: "Copy images to a private registry from an artifact OCI Path",
- Action: &CopyImagesToRegistry{ImagesPath: c.ImagePath},
+ Action: &CopyImagesToRegistry{ImagesPath: c.ImagePath, ImageTransport: c.ImageTransport},
}
pushManifest := &task.LocalTask{
- Name: "PushManifest",
- Desc: "Push multi-arch manifest to private registry",
- Action: new(PushManifest),
+ Name: "PushManifest",
+ Desc: "Push multi-arch manifest to private registry",
+ Prepare: &ShouldPushManifest{ImageTransport: c.ImageTransport},
+ Action: new(PushManifest),
}
c.Tasks = []task.Interface{
diff --git a/cmd/kk/pkg/images/prepares.go b/cmd/kk/pkg/images/prepares.go
new file mode 100644
index 000000000..a61c2dde4
--- /dev/null
+++ b/cmd/kk/pkg/images/prepares.go
@@ -0,0 +1,34 @@
+/*
+ Copyright 2024 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 images
+
+import (
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/common"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/connector"
+)
+
+type ShouldPushManifest struct {
+ common.KubePrepare
+ ImageTransport string
+}
+
+func (m *ShouldPushManifest) PreCheck(_ connector.Runtime) (bool, error) {
+ if m.ImageTransport != common.DockerDaemon {
+ return true, nil
+ }
+ return false, nil
+}
diff --git a/cmd/kk/pkg/images/tasks.go b/cmd/kk/pkg/images/tasks.go
index f431b51db..a9c088efb 100644
--- a/cmd/kk/pkg/images/tasks.go
+++ b/cmd/kk/pkg/images/tasks.go
@@ -155,6 +155,8 @@ func GetImage(runtime connector.ModuleRuntime, kubeConf *common.KubeConf, name s
type SaveImages struct {
common.ArtifactAction
+ ImageStartIndex int
+ ImageTransport string
}
func (s *SaveImages) Execute(runtime connector.Runtime) error {
@@ -164,7 +166,10 @@ func (s *SaveImages) Execute(runtime connector.Runtime) error {
if err := coreutil.Mkdir(dirName); err != nil {
return errors.Wrapf(errors.WithStack(err), "mkdir %s failed", dirName)
}
- for _, image := range s.Manifest.Spec.Images {
+ for index, image := range s.Manifest.Spec.Images {
+ if s.ImageStartIndex > index {
+ continue
+ }
if err := validateImageName(image); err != nil {
return err
}
@@ -175,7 +180,7 @@ func (s *SaveImages) Execute(runtime connector.Runtime) error {
auth = v
}
- srcName := fmt.Sprintf("docker://%s", image)
+ srcName := formatImageName(s.ImageTransport, image)
for _, platform := range s.Manifest.Spec.Arches {
arch, variant := ParseArchVariant(platform)
// placeholder
@@ -183,11 +188,11 @@ func (s *SaveImages) Execute(runtime connector.Runtime) error {
variant = "-" + variant
}
// Ex:
- // oci:./kubekey/artifact/images:kubesphere:kube-apiserver:v1.21.5-amd64
- // oci:./kubekey/artifact/images:kubesphere:kube-apiserver:v1.21.5-arm-v7
- destName := fmt.Sprintf("oci:%s:%s:%s-%s%s", dirName, imageFullName[1], suffixImageName(imageFullName[2:]), arch, variant)
- logger.Log.Infof("Source: %s", srcName)
- logger.Log.Infof("Destination: %s", destName)
+ // oci:./kubekey/artifact/images:docker.io/kubesphere/kube-apiserver:v1.21.5-amd64
+ // oci:./kubekey/artifact/images:docker.io/kubesphere/kube-apiserver:v1.21.5-arm-v7
+ destName := fmt.Sprintf("oci:%s:%s-%s%s", dirName, image, arch, variant)
+ logger.Log.Infof("[%d]Source: %s", index, srcName)
+ logger.Log.Infof("[%d]Destination: %s", index, destName)
o := &CopyImageOptions{
srcImage: &srcImageOptions{
@@ -232,7 +237,8 @@ func (s *SaveImages) Execute(runtime connector.Runtime) error {
type CopyImagesToRegistry struct {
common.KubeAction
- ImagesPath string
+ ImagesPath string
+ ImageTransport string
}
func (c *CopyImagesToRegistry) Execute(runtime connector.Runtime) error {
@@ -260,18 +266,21 @@ func (c *CopyImagesToRegistry) Execute(runtime connector.Runtime) error {
ref := m.Annotations.RefName
// Ex:
- // calico:cni:v3.20.0-amd64
- nameArr := strings.Split(ref, ":")
- if len(nameArr) != 3 {
+ // docker.io/calico/cni:v3.20.0-amd64
+ repoAddr, namespace, imageName, imageTag, err := parseImageFullName(ref)
+ if err != nil {
return errors.Errorf("invalid ref name: %s", ref)
}
+ if c.ImageTransport != common.DockerDaemon {
+ repoAddr = c.KubeConf.Cluster.Registry.PrivateRegistry
+ }
image := Image{
- RepoAddr: c.KubeConf.Cluster.Registry.PrivateRegistry,
- Namespace: nameArr[0],
+ RepoAddr: repoAddr,
+ Namespace: namespace,
NamespaceOverride: c.KubeConf.Cluster.Registry.NamespaceOverride,
- Repo: nameArr[1],
- Tag: nameArr[2],
+ Repo: imageName,
+ Tag: imageTag,
}
uniqueImage, p := ParseImageWithArchTag(image.ImageName())
@@ -305,7 +314,7 @@ func (c *CopyImagesToRegistry) Execute(runtime connector.Runtime) error {
}
srcName := fmt.Sprintf("oci:%s:%s", imagesPath, ref)
- destName := fmt.Sprintf("docker://%s", image.ImageName())
+ destName := formatImageName(c.ImageTransport, uniqueImage)
logger.Log.Infof("Source: %s", srcName)
logger.Log.Infof("Destination: %s", destName)
diff --git a/cmd/kk/pkg/images/utils.go b/cmd/kk/pkg/images/utils.go
index 7e7a3ea66..ad35edd95 100644
--- a/cmd/kk/pkg/images/utils.go
+++ b/cmd/kk/pkg/images/utils.go
@@ -26,6 +26,7 @@ import (
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/common"
"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/logger"
)
@@ -182,9 +183,32 @@ func validateImageName(imageFullName string) error {
return nil
}
-func suffixImageName(imageFullName []string) string {
+func parseImageFullName(imageFullName string) (string, string, string, string, error) {
+ if err := validateImageName(imageFullName); err != nil {
+ return "", "", "", "", err
+ }
+ image := strings.Split(imageFullName, "/")
+ partsNum := len(image)
+ repoAddr := image[0]
+ namespace := concatImageName(image[1 : partsNum-1])
+ nameAndTag := strings.Split(image[partsNum-1], ":")
+ return repoAddr, namespace, nameAndTag[0], nameAndTag[1], nil
+}
+
+func concatImageName(imageFullName []string) string {
if len(imageFullName) >= 2 {
return strings.Join(imageFullName, "/")
}
return imageFullName[0]
}
+
+func formatImageName(transport string, imageFullName string) string {
+ switch transport {
+ case common.DockerDaemon:
+ return fmt.Sprintf("docker-daemon:%s", imageFullName)
+ case common.Docker:
+ fallthrough
+ default:
+ return fmt.Sprintf("docker://%s", imageFullName)
+ }
+}
diff --git a/cmd/kk/pkg/kubernetes/kubernetes_status.go b/cmd/kk/pkg/kubernetes/kubernetes_status.go
index 582d5f596..3853f5bf4 100644
--- a/cmd/kk/pkg/kubernetes/kubernetes_status.go
+++ b/cmd/kk/pkg/kubernetes/kubernetes_status.go
@@ -55,6 +55,11 @@ func (k *KubernetesStatus) SearchVersion(runtime connector.Runtime) error {
}
func (k *KubernetesStatus) SearchJoinInfo(runtime connector.Runtime) error {
+ // check if the cluster status contain initial data
+ if k.BootstrapToken != "" && k.CertificateKey != "" {
+ return nil
+ }
+
checkKubeadmConfig, err := runtime.GetRunner().SudoCmd("cat /etc/kubernetes/kubeadm-config.yaml", false)
if err != nil {
return err
diff --git a/cmd/kk/pkg/phase/addons/addons.go b/cmd/kk/pkg/phase/addons/addons.go
new file mode 100644
index 000000000..ee2660d00
--- /dev/null
+++ b/cmd/kk/pkg/phase/addons/addons.go
@@ -0,0 +1,57 @@
+package addons
+
+import (
+ "github.com/pkg/errors"
+
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/addons"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/bootstrap/precheck"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/common"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/module"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/pipeline"
+ "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/kubernetes"
+)
+
+func ApplyClusterAddons(args common.Argument) error {
+
+ var loaderType string
+ if args.FilePath != "" {
+ loaderType = common.File
+ } else {
+ loaderType = common.AllInOne
+ }
+
+ runtime, err := common.NewKubeRuntime(loaderType, args)
+ if err != nil {
+ return err
+ }
+
+ switch runtime.Cluster.Kubernetes.Type {
+ case common.Kubernetes:
+ if err := ApplyClusterAddonsPipeline(runtime); err != nil {
+ return err
+ }
+ default:
+ return errors.New("unsupported cluster kubernetes type")
+ }
+
+ return nil
+}
+
+func ApplyClusterAddonsPipeline(runtime *common.KubeRuntime) error {
+ m := []module.Module{
+ &precheck.GreetingsModule{},
+ &precheck.NodePreCheckModule{},
+ &kubernetes.StatusModule{},
+ &addons.AddonsModule{},
+ }
+
+ p := pipeline.Pipeline{
+ Name: "ApplyClusterAddonsPipeline",
+ Modules: m,
+ Runtime: runtime,
+ }
+ if err := p.Start(); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/cmd/kk/pkg/pipelines/artifact_export.go b/cmd/kk/pkg/pipelines/artifact_export.go
index a47db6857..d09adb4bb 100644
--- a/cmd/kk/pkg/pipelines/artifact_export.go
+++ b/cmd/kk/pkg/pipelines/artifact_export.go
@@ -34,7 +34,7 @@ import (
func NewArtifactExportPipeline(runtime *common.ArtifactRuntime) error {
m := []module.Module{
&confirm.CheckFileExistModule{FileName: runtime.Arg.Output},
- &images.CopyImagesToLocalModule{},
+ &images.CopyImagesToLocalModule{ImageStartIndex: runtime.Arg.ImageStartIndex, ImageTransport: runtime.Arg.ImageTransport},
&binaries.ArtifactBinariesModule{},
&artifact.RepositoryModule{},
&artifact.ArchiveModule{},
@@ -58,7 +58,7 @@ func NewArtifactExportPipeline(runtime *common.ArtifactRuntime) error {
func NewK3sArtifactExportPipeline(runtime *common.ArtifactRuntime) error {
m := []module.Module{
&confirm.CheckFileExistModule{FileName: runtime.Arg.Output},
- &images.CopyImagesToLocalModule{},
+ &images.CopyImagesToLocalModule{ImageStartIndex: runtime.Arg.ImageStartIndex},
&binaries.K3sArtifactBinariesModule{},
&artifact.RepositoryModule{},
&artifact.ArchiveModule{},
@@ -82,7 +82,7 @@ func NewK3sArtifactExportPipeline(runtime *common.ArtifactRuntime) error {
func NewK8eArtifactExportPipeline(runtime *common.ArtifactRuntime) error {
m := []module.Module{
&confirm.CheckFileExistModule{FileName: runtime.Arg.Output},
- &images.CopyImagesToLocalModule{},
+ &images.CopyImagesToLocalModule{ImageStartIndex: runtime.Arg.ImageStartIndex},
&binaries.K8eArtifactBinariesModule{},
&artifact.RepositoryModule{},
&artifact.ArchiveModule{},
diff --git a/cmd/kk/pkg/pipelines/create_cluster.go b/cmd/kk/pkg/pipelines/create_cluster.go
index 4f5935f6c..a083d290b 100644
--- a/cmd/kk/pkg/pipelines/create_cluster.go
+++ b/cmd/kk/pkg/pipelines/create_cluster.go
@@ -92,7 +92,8 @@ func NewCreateClusterPipeline(runtime *common.KubeRuntime) error {
&kubernetes.SecurityEnhancementModule{Skip: !runtime.Arg.SecurityEnhancement},
&kubernetes.SaveKubeConfigModule{},
&plugins.DeployPluginsModule{},
- &addons.AddonsModule{},
+ &customscripts.CustomScriptsModule{Phase: "PostClusterInstall", Scripts: runtime.Cluster.System.PostClusterInstall},
+ &addons.AddonsModule{Skip: runtime.Arg.SkipInstallAddons},
&storage.DeployLocalVolumeModule{Skip: skipLocalStorage},
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
&kubesphere.CheckResultModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
@@ -166,7 +167,8 @@ func NewK3sCreateClusterPipeline(runtime *common.KubeRuntime) error {
&filesystem.ChownModule{},
&certs.AutoRenewCertsModule{Skip: !runtime.Cluster.Kubernetes.EnableAutoRenewCerts()},
&k3s.SaveKubeConfigModule{},
- &addons.AddonsModule{},
+ &customscripts.CustomScriptsModule{Phase: "PostClusterInstall", Scripts: runtime.Cluster.System.PostClusterInstall},
+ &addons.AddonsModule{Skip: runtime.Arg.SkipInstallAddons},
&storage.DeployLocalVolumeModule{Skip: skipLocalStorage},
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
&kubesphere.CheckResultModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
@@ -240,7 +242,8 @@ func NewK8eCreateClusterPipeline(runtime *common.KubeRuntime) error {
&filesystem.ChownModule{},
&certs.AutoRenewCertsModule{Skip: !runtime.Cluster.Kubernetes.EnableAutoRenewCerts()},
&k8e.SaveKubeConfigModule{},
- &addons.AddonsModule{},
+ &customscripts.CustomScriptsModule{Phase: "PostClusterInstall", Scripts: runtime.Cluster.System.PostClusterInstall},
+ &addons.AddonsModule{Skip: runtime.Arg.SkipInstallAddons},
&storage.DeployLocalVolumeModule{Skip: skipLocalStorage},
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
&kubesphere.CheckResultModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
diff --git a/docs/kubernetes-versions.md b/docs/kubernetes-versions.md
index d98d3982a..fe36a8ac9 100644
--- a/docs/kubernetes-versions.md
+++ b/docs/kubernetes-versions.md
@@ -123,6 +123,9 @@
| v1.27.10 | :white_check_mark: |
| v1.27.11 | :white_check_mark: |
| v1.27.12 | :white_check_mark: |
+| v1.27.13 | :white_check_mark: |
+| v1.27.14 | :white_check_mark: |
+| v1.27.15 | :white_check_mark: |
| v1.28.0 | :white_check_mark: |
| v1.28.1 | :white_check_mark: |
| v1.28.2 | :white_check_mark: |
@@ -132,7 +135,16 @@
| v1.28.6 | :white_check_mark: |
| v1.28.7 | :white_check_mark: |
| v1.28.8 | :white_check_mark: |
+| v1.28.9 | :white_check_mark: |
+| v1.28.10 | :white_check_mark: |
+| v1.28.11 | :white_check_mark: |
| v1.29.0 | :white_check_mark: |
| v1.29.1 | :white_check_mark: |
| v1.29.2 | :white_check_mark: |
| v1.29.3 | :white_check_mark: |
+| v1.29.4 | :white_check_mark: |
+| v1.29.5 | :white_check_mark: |
+| v1.29.6 | :white_check_mark: |
+| v1.30.0 | :white_check_mark: |
+| v1.30.1 | :white_check_mark: |
+| v1.30.2 | :white_check_mark: |
diff --git a/pkg/service/operation/file/template.go b/pkg/service/operation/file/template.go
index 500a5ce05..46c8b1833 100644
--- a/pkg/service/operation/file/template.go
+++ b/pkg/service/operation/file/template.go
@@ -71,6 +71,7 @@ func (t *Template) RenderToLocal() error {
if err != nil {
return err
}
+ defer f.Close()
if err := t.template.Execute(f, t.data); err != nil {
return err
diff --git a/version/components.json b/version/components.json
index 84a22b92c..01ce11386 100644
--- a/version/components.json
+++ b/version/components.json
@@ -123,6 +123,9 @@
"v1.27.10": "23985e958443ac1aabdbeeedc675358abc0638eb580707829fd42b0996a0aae5",
"v1.27.11": "31bf446a712fb08190838c35d1f4c93b0f975708c59634a5dc3d8915a241c83e",
"v1.27.12": "06ee36cc80cfdfc01c937d750783d3ca6169a3da76382c7af3dd172d9f6bfa4e",
+ "v1.27.13": "b88c30b7067f095b7fa02c5560cc50d6e69a5a9fecc606ef477dc7efc86453b9",
+ "v1.27.14": "1ce264643e521494e111b1c9ee59694a54d1f2464bbac3a7a531324ffeae0182",
+ "v1.27.15": "e6f8313e213a8a75deda81edf445d0d785493f6a0a0caadf31e88d173b607943",
"v1.28.0": "12ea68bfef0377ccedc1a7c98a05ea76907decbcf1e1ec858a60a7b9b73211bb",
"v1.28.1": "6134dbc92dcb83c3bae1a8030f7bb391419b5d13ea94badd3a79b7ece75b2736",
"v1.28.2": "6a4808230661c69431143db2e200ea2d021c7f1b1085e6353583075471310d00",
@@ -132,10 +135,19 @@
"v1.28.6": "bda3eda8d51e8746a42b535b7eab7df52b091a796227c3212dc30909a8f1b431",
"v1.28.7": "8aa005bdf6af43e47fc818b26f4cb9f361aae8ec4390519e8d4033be65fbef2b",
"v1.28.8": "c11946cbfd962e1197062534514226cfd70230349e6343ff3ecebfca5476ee64",
+ "v1.28.9": "a4d8acf0a74cb1d07d96a1a34148f54c6420874221af16d8ec902d9bffc7ef89",
+ "v1.28.10": "1a344d34755c5f005120308f09a730e7564c8f857de6606b6bc5f18a69606e5a",
+ "v1.28.11": "1f2c7c69736698aa13a59c6705ac26b7b6752d9651330605369357c1ac99c7c6",
"v1.29.0": "629d4630657caace9c819fd3797f4a70c397fbd41a2a7e464a0507dad675d52c",
"v1.29.1": "d4d81d9020b550c896376fb9e0586a9f15a332175890d061619b52b3e9bc6cbd",
"v1.29.2": "2d4e4fa8685bcbfb661cb41050cd4756f50a7aa147f68492d51a99f9cdfd69ac",
- "v1.29.3": "6abaa1208bf40b6d1f49e518bd68c8ae4a1be0c5b7d3e45d87979999ab070d8b"
+ "v1.29.3": "6abaa1208bf40b6d1f49e518bd68c8ae4a1be0c5b7d3e45d87979999ab070d8b",
+ "v1.29.4": "ea20ab064f716ab7f69a36d72df340257b31c9721ea86e1cf9d70b35999ddeea",
+ "v1.29.5": "e424dcdbe661314b6ca1fcc94726eb554bc3f4392b060b9626f9df8d7d44d42c",
+ "v1.29.6": "8f1e04079e614dd549e36be8114ee7022517d646ea715b5778e7c6ab353eb354",
+ "v1.30.0": "29f4232c50e6524abba3443ff3b9948d386964d79eb8dfefb409e1f8a8434c14",
+ "v1.30.1": "651faa3bbbfb368ed00460e4d11732614310b690b767c51810a7b638cc0961a2",
+ "v1.30.2": "672b0cae2accce5eac10a1fe4ea6b166e5b518c79ccf71a2fbe7b53c2ca74062"
},
"arm64": {
"v1.19.0": "db1c432646e6e6484989b6f7191f3610996ac593409f12574290bfc008ea11f5",
@@ -260,6 +272,9 @@
"v1.27.10": "ed0447155a7e967ae23480b06b31b2c0aaa871e7c59dfd82ae25b03a1eccf6e6",
"v1.27.11": "b8452d6c3f1331beb3d5fa42466a9bc96638a76c40980dba9822300f230c0858",
"v1.27.12": "e74d47c14b5a251cff961dcce92cd632abcfd0fba4a07e78f0a5a5b2796e4b84",
+ "v1.27.13": "f334ba0612fada50e98a7ea56b686b35c22f0e3243ec2210f2a6a87e841a139f",
+ "v1.27.14": "cb840eb83404047cdafec0b15054023c90a47491b56d2dceba1050040f37cc7e",
+ "v1.27.15": "577630b65c54ba9b629c9c42e35ba0939ce03dcb8f38fb79583ec3c9db9141a7",
"v1.28.0": "b9b473d2d9136559b19eb465006af77df45c09862cd7ce6673a33aae517ff5ab",
"v1.28.1": "7d2f68917470a5d66bd2a7d62897f59cb4afaeffb2f26c028afa119acd8c3fc8",
"v1.28.2": "010789a94cf512d918ec4a3ef8ec734dea0061d89a8293059ef9101ca1bf6bff",
@@ -269,10 +284,19 @@
"v1.28.6": "4298cad464e92eec19cdf3e6a607a82a1d626ae70fedba7956175152ab983457",
"v1.28.7": "f556e49494737f97a15bf15bb4b27d45f8747b477302cdfd22dd61816bc02203",
"v1.28.8": "e0f47adc69ef84e2f6c42cc341b8a790904a929ad10ed1c23c2e822ec804e247",
+ "v1.28.9": "cd6aefad8144a9771fd470529ff14be2675df7b561f7c56dee3fed4f81332dc4",
+ "v1.28.10": "f6809d72ed1bf6fde460e48e5c714c3bc92f680e328defa9bd592a796347b644",
+ "v1.28.11": "15a021fdecf08989d6b64af873d89c61750d3a0564bee58c248eafe5cc4df433",
"v1.29.0": "bbddee2d46d2e1643ae3623698b45b13aa2e858616d61c642f2f49e5bb14c980",
"v1.29.1": "3bff8c50c104c45e416cce9991706c6ac46365f0defbcd54f8cf4ace0fa68dcf",
"v1.29.2": "e05720feb9d2d67eff25b0156a5c22e2de37be2ffab4e1f4d31e8c526fafd0e1",
- "v1.29.3": "ce2e4c230f954e59ae77e34c4ff2ae08cad3970505ae1e21b6337e6d83b21682"
+ "v1.29.3": "ce2e4c230f954e59ae77e34c4ff2ae08cad3970505ae1e21b6337e6d83b21682",
+ "v1.29.4": "438287a91e08cbefecab79be8ac893a935c3dbf6e87bea895fb99f2bc38cf06e",
+ "v1.29.5": "d4db8c514f2764edc039462c218dbcd316577f76f21b209b76e9a4b1f08e3100",
+ "v1.29.6": "3ba6879ef491cdd8433647020d345d86c0ea8e77f726375bc4b5495888bbf778",
+ "v1.30.0": "c36afd28921303e6db8e58274de16c60a80a1e75030fc3c4e9c4ed6249b6b696",
+ "v1.30.1": "bda423cb4b9d056f99a2ef116bdf227fadbc1c3309fa3d76da571427a7f41478",
+ "v1.30.2": "7268762b7afd44bf07619985dd52c376b63e47d73b8f9a3b08cc49624a8fbd55"
}
},
"kubelet": {
@@ -399,6 +423,9 @@
"v1.27.10": "25a34bf98bb8a296ea07f1ebbcb496b1e6b6c6da3247695288a7c99fc8c1be2c",
"v1.27.11": "2ce92a5d8985b93bd8ffc4f5519cd79bf2f844590aa38228a3d809c5bf5986e0",
"v1.27.12": "aae861a21913c274228ccdad1609b370e5198c9f4b39b8924b20a7ffe7f148e0",
+ "v1.27.13": "ed68df2a77f3057ab47f57eacb6e9310e91731e4f43c58a3c3b5c857d78d0080",
+ "v1.27.14": "f28defa43f80f82ce909940c1b57b71cba1fcf0de6fc4723e798ef5c72376c28",
+ "v1.27.15": "c0ab414cdd116e9644c8c154ae4a6565c75c2605e2c7b6a5a04b56037ef2ba88",
"v1.28.0": "bfb6b977100963f2879a33e5fbaa59a5276ba829a957a6819c936e9c1465f981",
"v1.28.1": "2bc22332f44f8fcd3fce57879fd873f977949ebd261571fbae31fbb2713a5dd3",
"v1.28.2": "17edb866636f14eceaad58c56eab12af7ab3be3c78400aff9680635d927f1185",
@@ -408,10 +435,19 @@
"v1.28.6": "8506df1f20a5f8bba0592f5a4cf5d0cc541047708e664cb88580735400d0b26f",
"v1.28.7": "120b1495babc4364f7e16a9d0f8b8e6b6f78316d047e4f6de77b5569b05813c7",
"v1.28.8": "049b412a5861255cd3922f612acb79ab51135e166c5d80acf12fba9179eebf0c",
+ "v1.28.9": "f3af46cff11c675a80d91ebb38ebc4e85a9f813ce93e56ee131e7fea1491b786",
+ "v1.28.10": "a361e744aaeef4539f0636ecd1827c85207a5f2b0c2b0a98dbbce1498061f509",
+ "v1.28.11": "230f0634ea42a54a6c96771f12eecd6cadfe0b76ab41c3bc39aa7cbbe4dfb12e",
"v1.29.0": "e1c38137db8d8777eed8813646b59bf4d22d19b9011ab11dc28e2e34f6b80a05",
"v1.29.1": "1b1975c58d38be1a99a8bcba4564ac489afd223b0abe9f2ab08bbde89d2412a3",
"v1.29.2": "f71a85039b71fe08f1c063a93d61a1c952dc8f9a8c6be9b13fbdac8f0d9ff960",
- "v1.29.3": "d8b55a2f8a87c8cd2cbf867d76d1d7f98b7198a740db19bad6ed7b8b813de771"
+ "v1.29.3": "d8b55a2f8a87c8cd2cbf867d76d1d7f98b7198a740db19bad6ed7b8b813de771",
+ "v1.29.4": "58571f0ed62543a9bbac541e52c15d8385083113a463e23aec1341d0b5043939",
+ "v1.29.5": "261dc3f3c384d138835fe91a02071c642af94abb0cca56ebc04719240440944c",
+ "v1.29.6": "a946789d4fef64e6f5905dbd7dca01d4c3abd302d0da7958fdaa924fe2729c0b",
+ "v1.30.0": "32a32ec3d7e7f8b2648c9dd503ce9ef63b4af1d1677f5b5aed7846fb02d66f18",
+ "v1.30.1": "87bd6e5de9c0769c605da5fedb77a35c8b764e3bda1632447883c935dcf219d3",
+ "v1.30.2": "6923abe67ef069afca61c71c585023840426e802b198298055af3a82e11a4e52"
},
"arm64": {
"v1.19.0": "d8fa5a9739ecc387dfcc55afa91ac6f4b0ccd01f1423c423dbd312d787bbb6bf",
@@ -536,6 +572,9 @@
"v1.27.10": "0edadc44ef36be8d8106cad9972360c0477540e2d8c0bbeb38fd97fd1d7801d5",
"v1.27.11": "e81987a864fb47afe14f65fa4e93760bc19c424335e0f0540c6c725b727ce22a",
"v1.27.12": "0d7d2d25c8b909d6cec7c1c2a5bfe51428ec33eaa5e8b209c718b77983e9dcba",
+ "v1.27.13": "d7bfb14d0b0fc2c41074baf02617cf98589fd029fb3539ea017825e36371f19c",
+ "v1.27.14": "31c97a723021ccc90a47a15ad1de1ffdf58ba109aea922eb359ad2fcb8e8ce4b",
+ "v1.27.15": "ac8abb249dd78a22d92e28306ce9823f7e3ce23cd4ba8dbb0f3bd34f48b6c12b",
"v1.28.0": "05dd12e35783cab4960e885ec0e7d0e461989b94297e7bea9018ccbd15c4dce9",
"v1.28.1": "9b7fa64b2785da4a38768377961e227f8da629c56a5df43ca1b665dd07b56f3c",
"v1.28.2": "32269e9ec38c561d028b65c3048ea6a100e1292cbe9e505565222455c8096577",
@@ -545,10 +584,19 @@
"v1.28.6": "ee2c060deff330d3338e24aec9734c9e5d5aea4fea1905c0795bccff6997a65e",
"v1.28.7": "e2c98b39b0b0745ef3e30febaeb8eaaf31ec721012405bd0dcf25e84026c221e",
"v1.28.8": "90d61f40b7bb061b0fc6d08b8b9ddae51f90863c899b098e19eaa89dc855f2c0",
+ "v1.28.9": "312471ad255acfcdeea2c5849b171467af4518e96d69d727a3197ff334e9299d",
+ "v1.28.10": "feae161e374ee0155b5263cda339f30f16b525631535a003be7aa437661e1580",
+ "v1.28.11": "0e01c1393f8746965994431b70a20c32b8547dfb1dcf2770cb692990fc65ba5f",
"v1.29.0": "0e0e4544c2a0a3475529154b7534d0d58683466efa04a2bb2e763b476db0bb16",
"v1.29.1": "e46417ab1ceae995f0e00d4177959a36ed34b807829422bc9dda70b263fe5c5d",
"v1.29.2": "9b4aa572d4cd51a41b1067161d961423d0d12b120fb636ea887a12a975d4b19a",
- "v1.29.3": "891dce19ed0eae34050c2eca0454204892e97bfe1a926f988cd044a987a9c7c9"
+ "v1.29.3": "891dce19ed0eae34050c2eca0454204892e97bfe1a926f988cd044a987a9c7c9",
+ "v1.29.4": "dc4bb6ea6cd35b024d63cc20d1c1800a9c695bd6f70411c57358d7c407513b00",
+ "v1.29.5": "0d4328a3c67e4f0dbf270fa49343f3eab9316adde1a1bd2a857fa56876a9aff1",
+ "v1.29.6": "0f0fa9429d0bcf04f271dcf4f666582dd4a4b15d6f116a45f17b5fcda90c2d2c",
+ "v1.30.0": "fa887647422d34f3c7cc5b30fefcf97084d2c3277eff237c5808685ba8e4b15a",
+ "v1.30.1": "c45049b829af876588ec1a30def3884ce77c2c175cd77485d49c78d2064a38fb",
+ "v1.30.2": "72ceb082311b42032827a936f80cd2437b8eee03053d05dbe36ba48585febfb8"
}
},
"kubectl": {
@@ -675,6 +723,9 @@
"v1.27.10": "bfb219643c28d9842fceae51590776f06987835d93fc3cb9b0149c9111c741ac",
"v1.27.11": "7ae327978a1edb43700070c86f5fd77215792c6b58a7ea70192647e0da848e29",
"v1.27.12": "d639eda39be2dce42fbec21e038942ab5734541715e3ea5fb29c9ad76686bd7f",
+ "v1.27.13": "e991f163197cbd85bbff22f656a74d48b69db5addfa43cc04cca0cf5328f57f1",
+ "v1.27.14": "1d2431c68bb6dfa9de3cd40fd66d97a9ac73593c489f9467249eea43e9c16a1e",
+ "v1.27.15": "c12cf17ec30fb162f8f5fb168e67d4e5b7d6826e08c7648a5f1c6b4e9ba23f39",
"v1.28.0": "4717660fd1466ec72d59000bb1d9f5cdc91fac31d491043ca62b34398e0799ce",
"v1.28.1": "e7a7d6f9d06fab38b4128785aa80f65c54f6675a0d2abef655259ddd852274e1",
"v1.28.2": "c922440b043e5de1afa3c1382f8c663a25f055978cbc6e8423493ec157579ec5",
@@ -684,10 +735,19 @@
"v1.28.6": "c8351fe0611119fd36634dd3f53eb94ec1a2d43ef9e78b92b4846df5cc7aa7e3",
"v1.28.7": "aff42d3167685e4d8e86fda0ad9c6ce6ec6c047bc24d608041d54717a18192ba",
"v1.28.8": "e02aad5c0bac52c970700b814645b62c4f18b634144398ac344875dbaf1072f8",
+ "v1.28.9": "b4693d0b22f509250694b10c7727c42b427d570af04f2065fe23a55d6c0051f1",
+ "v1.28.10": "389c17a9700a4b01ebb055e39b8bc0886330497440dde004b5ed90f2a3a028db",
+ "v1.28.11": "1dba63e1a5c9520fc516c6e817924d927b9b83b8e08254c8fe2a2edb65da7a9c",
"v1.29.0": "0e03ab096163f61ab610b33f37f55709d3af8e16e4dcc1eb682882ef80f96fd5",
"v1.29.1": "69ab3a931e826bf7ac14d38ba7ca637d66a6fcb1ca0e3333a2cafdf15482af9f",
"v1.29.2": "7816d067740f47f949be826ac76943167b7b3a38c4f0c18b902fffa8779a5afa",
- "v1.29.3": "89c0435cec75278f84b62b848b8c0d3e15897d6947b6c59a49ddccd93d7312bf"
+ "v1.29.3": "89c0435cec75278f84b62b848b8c0d3e15897d6947b6c59a49ddccd93d7312bf",
+ "v1.29.4": "10e343861c3cb0010161e703307ba907add2aeeeaffc6444779ad915f9889c88",
+ "v1.29.5": "603c8681fc0d8609c851f9cc58bcf55eeb97e2934896e858d0232aa8d1138366",
+ "v1.29.6": "339553c919874ebe3b719e9e1fcd68b55bc8875f9b5a005cf4c028738d54d309",
+ "v1.30.0": "7c3807c0f5c1b30110a2ff1e55da1d112a6d0096201f1beb81b269f582b5d1c5",
+ "v1.30.1": "5b86f0b06e1a5ba6f8f00e2b01e8ed39407729c4990aeda961f83a586f975e8a",
+ "v1.30.2": "c6e9c45ce3f82c90663e3c30db3b27c167e8b19d83ed4048b61c1013f6a7c66e"
},
"arm64": {
"v1.19.0": "d4adf1b6b97252025cb2f7febf55daa3f42dc305822e3da133f77fd33071ec2f",
@@ -812,6 +872,9 @@
"v1.27.10": "2e1996379d5a8b132e0606fcd3df3c8689e11882630b75cca3b7135126847871",
"v1.27.11": "d30e1aa873e78eb376ddee3c785aa78c44eddc56ce2ef901dac1ce0c2c4f50b0",
"v1.27.12": "bfc6cb71041ebc0f048402988eccc107cfff2b866c864231c9ada05ab328e5bf",
+ "v1.27.13": "4838ad8f3902c928f6139d69eba962b1cc2471511c828885650d728d970594d1",
+ "v1.27.14": "29f3a1f520d929df38873c68dec73519c1e5e521140e01cf9d7701f7b5ffe4f3",
+ "v1.27.15": "6bd6bd3092c0a8e536e8e5a56b22aaab87ab1e54a4556ce4d1bff2493180fb8c",
"v1.28.0": "f5484bd9cac66b183c653abed30226b561f537d15346c605cc81d98095f1717c",
"v1.28.1": "46954a604b784a8b0dc16754cfc3fa26aabca9fd4ffd109cd028bfba99d492f6",
"v1.28.2": "ea6d89b677a8d9df331a82139bb90d9968131530b94eab26cee561531eff4c53",
@@ -821,10 +884,19 @@
"v1.28.6": "0de705659a80c3fef01df43cc0926610fe31482f728b0f992818abd9bdcd2cb9",
"v1.28.7": "13d547495bdea49b223fe06bffb6d2bef96436634847f759107655aa80fc990e",
"v1.28.8": "93d60dd36093b4c719f1f1bafcf59437c17cb2209341c7c94771e7dd9acdab33",
+ "v1.28.9": "e0341d3973213f8099e7fcbbf6d1d506967bc2b7a4faac3fb3b4340f226e9b2f",
+ "v1.28.10": "e659d23d442c2706debe5b96742326c0a1e1d7b5c695a9fe7dfe8ea7402caee8",
+ "v1.28.11": "7984a98d52365d190b6f56caa962339a7228b6f432e58ba5f1b1e60dbedac275",
"v1.29.0": "8f7a4bd6bae900a4ddab12bd1399aa652c0d59ea508f39b910e111d248893ff7",
"v1.29.1": "96d6dc7b2bdcd344ce58d17631c452225de5bbf59b83fd3c89c33c6298fb5d8b",
"v1.29.2": "3507ecb4224cf05ae2151a98d4932253624e7762159936d5347b19fe037655ca",
- "v1.29.3": "191a96b27e3c6ae28b330da4c9bfefc9592762670727df4fcf124c9f1d5a466a"
+ "v1.29.3": "191a96b27e3c6ae28b330da4c9bfefc9592762670727df4fcf124c9f1d5a466a",
+ "v1.29.4": "61537408eedcad064d7334384aed508a8aa1ea786311b87b505456a2e0535d36",
+ "v1.29.5": "9ee9168def12ac6a6c0c6430e0f73175e756ed262db6040f8aa2121ad2c1f62e",
+ "v1.29.6": "21816488cf3af4cf2b956ee58f7afc5b4964c29488f63756f5ddcf09b0df5be9",
+ "v1.30.0": "669af0cf520757298ea60a8b6eb6b719ba443a9c7d35f36d3fb2fd7513e8c7d2",
+ "v1.30.1": "d90446719b815e3abfe7b2c46ddf8b3fda17599f03ab370d6e47b1580c0e869e",
+ "v1.30.2": "56becf07105fbacd2b70f87f3f696cfbed226cb48d6d89ed7f65ba4acae3f2f8"
}
},
"etcd": {
@@ -1058,5 +1130,13 @@
"v3.27.2": "0fd1f65a511338cf9940835987d420c94ab95b5386288ba9673b736a4d347463",
"v3.27.3": "1fc5f58a18d8b1c487b4663fc5cbe23b45bd9d31617debd309f6dfac7c11a8ef"
}
+ },
+ "buildx": {
+ "amd64": {
+ "v0.14.0": "32f8f17eca35bf2efe6c0e47f40e4692a876f34531b421efc984799a5b41226e"
+ },
+ "arm64": {
+ "v0.14.0": "38bf0ea9c48743edb8243f14272be65a2bad7092228068337aea584309ea664c"
+ }
}
-}
+}
\ No newline at end of file