Repository: kubeclipper/kubeclipper
Pull request #699 (2024-06-05 10:26:34)

build(deps): bump golang.org/x/oauth2 from 0.10.0 to 0.21.0
Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.10.0 to 0.21.0.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/golang/oauth2/commit/5fd42413edb3b1699004a31b72e485e0e4ba1b13"><code>5fd4241</code></a> google: update compute token refresh</li>
<li><a href="https://github.com/golang/oauth2/commit/84cb9f7f5c5a639955cd501bfdd54f0e63997e61"><code>84cb9f7</code></a> oauth2: fix typo in comment</li>
<li><a href="https://github.com/golang/oauth2/commit/4b7f0bdbc7c30d05383d2597847300fbb870608b"><code>4b7f0bd</code></a> go.mod: update cloud.google.com/go/compute/metadata dependency</li>
<li><a href="https://github.com/golang/oauth2/commit/e11eea88a89331c1fae3d38a37f484363a8d597d"><code>e11eea8</code></a> microsoft: added DeviceAuthURL to AzureADEndpoint</li>
<li><a href="https://github.com/golang/oauth2/commit/d0e617c58cf747cf27df9762003502f814dd524c"><code>d0e617c</code></a> google: add Credentials.UniverseDomainProvider</li>
<li><a href="https://github.com/golang/oauth2/commit/3c9c1f6d00e8761389cd2c50bc4179459d6320b5"><code>3c9c1f6</code></a> oauth2/google: fix the logic of sts 0 value of expires_in</li>
<li><a href="https://github.com/golang/oauth2/commit/5a05c654f92c675eb6bfe782f61b601b0efb77ea"><code>5a05c65</code></a> oauth2/google: fix remove content-type header from idms get requests</li>
<li><a href="https://github.com/golang/oauth2/commit/3a6776ada799d857cee190d6f517c4afee7c3170"><code>3a6776a</code></a> appengine: drop obsolete code for AppEngine envs &lt;=Go 1.11</li>
<li><a href="https://github.com/golang/oauth2/commit/85231f99d65eedc833c8fccfec7fd7d8303c0d3e"><code>85231f9</code></a> go.mod: update golang.org/x dependencies</li>
<li><a href="https://github.com/golang/oauth2/commit/34a7afaa8571b555a177d9bf0360276cbb94f630"><code>34a7afa</code></a> google/externalaccount: add Config.UniverseDomain</li>
<li>Additional commits viewable in <a href="https://github.com/golang/oauth2/compare/v0.10.0...v0.21.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/oauth2&package-manager=go_modules&previous-version=0.10.0&new-version=0.21.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

kubeclipper-bot: @dependabot[bot]: Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our [release note process](https://git.k8s.io/community/contributors/guide/release-notes.md) to remove it.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
kubeclipper-bot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubeclipper/kubeclipper/pull/699#" title="Author self-approved">dependabot[bot]</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **x893675** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @x893675` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubeclipper%2Fkubeclipper).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubeclipper/kubeclipper/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["x893675"]} -->

Patch:
diff --git a/go.mod b/go.mod
index cfb28f1..841047b 100644
--- a/go.mod
+++ b/go.mod
@@ -50,7 +50,7 @@ require (
 	github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
 	go.uber.org/zap v1.24.0
 	golang.org/x/crypto v0.11.0
-	golang.org/x/oauth2 v0.10.0
+	golang.org/x/oauth2 v0.21.0
 	golang.org/x/sys v0.20.0
 	golang.org/x/term v0.20.0
 	golang.org/x/text v0.11.0
@@ -214,7 +214,6 @@ require (
 	golang.org/x/time v0.3.0 // indirect
 	golang.org/x/tools v0.6.0 // indirect
 	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
-	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
 	google.golang.org/grpc v1.56.1 // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
diff --git a/go.sum b/go.sum
index 4c6bb4e..14e9b3c 100644
--- a/go.sum
+++ b/go.sum
@@ -77,12 +77,12 @@ cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x
 cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE=
 cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=
 cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
-cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
+cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ=
 cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU=
 cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
 cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
-cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
 cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
+cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
 cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=
 cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=
 cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg=
@@ -1473,8 +1473,8 @@ golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri
 golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
 golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
 golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
-golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
-golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
+golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
+golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1694,7 +1694,6 @@ google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60c
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
diff --git a/pkg/cli/create/create_cluster.go b/pkg/cli/create/create_cluster.go
index 6e41183..711381e 100644
--- a/pkg/cli/create/create_cluster.go
+++ b/pkg/cli/create/create_cluster.go
@@ -137,30 +137,31 @@ IP6_AUTODETECTION_METHOD=can-reach=www.google.com`
 
 type CreateClusterOptions struct {
 	BaseOptions
-	Masters                   []string
-	Workers                   []string
-	UntaintMaster             bool
-	Offline                   bool
-	LocalRegistry             string
-	InsecureRegistries        []string
-	CRI                       string
-	CRIVersion                string
-	K8sVersion                string
-	CNI                       string
-	CNIVersion                string
-	Name                      string
-	createdByIP               bool
-	CertSans                  []string
-	CaCertFile                string
-	CaKeyFile                 string
-	DNSDomain                 string
-	CalicoNetMode             string
-	IPv4AutoDetection         string
-	ServiceSubnet             string
-	PodSubnet                 string
-	OnlyInstallKubernetesComp bool
-	FeatureGatesString        []string
-	FeatureGates              map[string]bool
+	Masters                          []string
+	Workers                          []string
+	UntaintMaster                    bool
+	Offline                          bool
+	LocalRegistry                    string
+	InsecureRegistries               []string
+	CRI                              string
+	CRIVersion                       string
+	K8sVersion                       string
+	CNI                              string
+	CNIVersion                       string
+	Name                             string
+	createdByIP                      bool
+	CertSans                         []string
+	CaCertFile                       string
+	CaKeyFile                        string
+	DNSDomain                        string
+	CalicoNetMode                    string
+	IPv4AutoDetection                string
+	ServiceSubnet                    string
+	PodSubnet                        string
+	KubeadmInitIgnorePreflightErrors string // kubeadm init --ignore-preflight-errors
+	OnlyInstallKubernetesComp        bool
+	FeatureGatesString               []string
+	FeatureGates                     map[string]bool
 }
 
 var (
@@ -225,6 +226,7 @@ func NewCmdCreateCluster(streams options.IOStreams) *cobra.Command {
 	cmd.Flags().StringVar(&o.CalicoNetMode, "calico.net-mode", o.CalicoNetMode, "calico network mode, support [BGP|Overlay-IPIP-All|Overlay-IPIP-Cross-Subnet|Overlay-Vxlan-All|Overlay-Vxlan-Cross-Subnet] now. \n"+CalicoNetModeDescription)
 	cmd.Flags().StringVar(&o.ServiceSubnet, "service-subnet", o.ServiceSubnet, "serviceSubnet is the subnet used by Kubernetes Services. Defaults to '10.96.0.0/12'")
 	cmd.Flags().StringVar(&o.PodSubnet, "pod-subnet", o.PodSubnet, "podSubnet is the subnet used by Pods. Defaults to '172.25.0.0/16'")
+	cmd.Flags().StringVar(&o.KubeadmInitIgnorePreflightErrors, "kubeadm-init-ignore-preflight-errors", o.KubeadmInitIgnorePreflightErrors, "A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.,kubeadm init --ignore-preflight-errors=xxx")
 	cmd.Flags().BoolVar(&o.OnlyInstallKubernetesComp, "only-install-kubernetes-component", o.OnlyInstallKubernetesComp, "only install kubernetes component, not install cni")
 	cmd.Flags().StringSliceVar(&o.FeatureGatesString, "feature-gates", o.FeatureGatesString, "k8s feature gates, format as: --feature-gates=xxx=true|false")
 	o.CliOpts.AddFlags(cmd.Flags())
@@ -442,6 +444,11 @@ func (l *CreateClusterOptions) newCluster() *v1.Cluster {
 	if l.OnlyInstallKubernetesComp {
 		annotations[common.AnnotationOnlyInstallKubernetesComp] = "true"
 	}
+
+	if l.KubeadmInitIgnorePreflightErrors != "" {
+		annotations[common.AnnotationOnlyIgnorePreflightErrors] = l.KubeadmInitIgnorePreflightErrors
+	}
+
 	if l.ServiceSubnet == "" {
 		l.ServiceSubnet = constatns.ClusterServiceSubnet
 	}
diff --git a/pkg/scheme/common/well_known_labels.go b/pkg/scheme/common/well_known_labels.go
index 96ca617..8d5bc1a 100644
--- a/pkg/scheme/common/well_known_labels.go
+++ b/pkg/scheme/common/well_known_labels.go
@@ -71,6 +71,8 @@ const (
 
 	// AnnotationOnlyInstallKubernetesComp mean not install cni when create cluster
 	AnnotationOnlyInstallKubernetesComp = "kubeclipper.io/only-install-kubernetes-component"
+	// AnnotationOnlyIgnorePreflightErrors specify kubeadm init --ignore-preflight-errors
+	AnnotationOnlyIgnorePreflightErrors = "kubeclipper.io/ignore-preflight-errors"
 )
 
 type NodeRole string // master/worker/ingress(worker)
diff --git a/pkg/scheme/core/v1/k8s/cluster.go b/pkg/scheme/core/v1/k8s/cluster.go
index 97afffe..333b99b 100644
--- a/pkg/scheme/core/v1/k8s/cluster.go
+++ b/pkg/scheme/core/v1/k8s/cluster.go
@@ -29,6 +29,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/kubeclipper/kubeclipper/pkg/scheme/common"
+
 	"github.com/kubeclipper/kubeclipper/pkg/agent/config"
 	"github.com/kubeclipper/kubeclipper/pkg/component"
 	"github.com/kubeclipper/kubeclipper/pkg/component/utils"
@@ -150,6 +152,7 @@ func (stepper *Upgrade) InitStepper(metadata *component.ExtraMetadata, c *v1.Clu
 		CertSANs:                c.GetAllCertSANs(),
 		LocalRegistry:           c.LocalRegistry,
 		FeatureGates:            c.FeatureGates,
+		IgnorePreflightErrors:   parseIgnorePreflightErrors(c.Annotations[common.AnnotationOnlyIgnorePreflightErrors]),
 	}
 	stepper.Offline = metadata.Offline
 	stepper.Version = metadata.KubeVersion
diff --git a/pkg/scheme/core/v1/k8s/kubeadm.go b/pkg/scheme/core/v1/k8s/kubeadm.go
index 6713920..44db596 100644
--- a/pkg/scheme/core/v1/k8s/kubeadm.go
+++ b/pkg/scheme/core/v1/k8s/kubeadm.go
@@ -105,32 +105,34 @@ type KubeadmConfig struct {
 	ClusterConfigAPIVersion string `json:"clusterConfigAPIVersion"`
 	// If both Docker and containerd are detected, Docker takes precedence,so we must specify cri.
 	// https://v1-20.docs.kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-runtime
-	ContainerRuntime     string          `json:"containerRuntime"`
-	Etcd                 v1.Etcd         `json:"etcd"`
-	Networking           v1.Networking   `json:"networking"`
-	KubeProxy            v1.KubeProxy    `json:"kubeProxy"`
-	Kubelet              v1.Kubelet      `json:"kubelet"`
-	ClusterName          string          `json:"clusterName"`
-	KubernetesVersion    string          `json:"kubernetesVersion"`
-	ControlPlaneEndpoint string          `json:"controlPlaneEndpoint"`
-	CertSANs             []string        `json:"certSANs"`
-	LocalRegistry        string          `json:"localRegistry"`
-	Offline              bool            `json:"offline"`
-	IsControlPlane       bool            `json:"isControlPlane,omitempty"`
-	CACertHashes         string          `json:"caCertHashes,omitempty"`
-	BootstrapToken       string          `json:"bootstrapToken,omitempty"`
-	CertificateKey       string          `json:"certificateKey,omitempty"`
-	AdvertiseAddress     string          `json:"advertiseAddress,omitempty"`
-	FeatureGates         map[string]bool `json:"featureGates,omitempty"`
+	ContainerRuntime      string          `json:"containerRuntime"`
+	Etcd                  v1.Etcd         `json:"etcd"`
+	Networking            v1.Networking   `json:"networking"`
+	KubeProxy             v1.KubeProxy    `json:"kubeProxy"`
+	Kubelet               v1.Kubelet      `json:"kubelet"`
+	ClusterName           string          `json:"clusterName"`
+	KubernetesVersion     string          `json:"kubernetesVersion"`
+	ControlPlaneEndpoint  string          `json:"controlPlaneEndpoint"`
+	CertSANs              []string        `json:"certSANs"`
+	LocalRegistry         string          `json:"localRegistry"`
+	Offline               bool            `json:"offline"`
+	IsControlPlane        bool            `json:"isControlPlane,omitempty"`
+	CACertHashes          string          `json:"caCertHashes,omitempty"`
+	BootstrapToken        string          `json:"bootstrapToken,omitempty"`
+	CertificateKey        string          `json:"certificateKey,omitempty"`
+	AdvertiseAddress      string          `json:"advertiseAddress,omitempty"`
+	FeatureGates          map[string]bool `json:"featureGates,omitempty"`
+	IgnorePreflightErrors []string        `json:"ignorePreflightErrors,omitempty"`
 }
 
 type ControlPlane struct {
 	// KubeConfig file
-	APIServerDomainName string
-	EtcdDataPath        string
-	ContainerRuntime    string
-	ExternalCaCert      string
-	ExternalCaKey       string
+	APIServerDomainName   string
+	EtcdDataPath          string
+	ContainerRuntime      string
+	ExternalCaCert        string
+	ExternalCaKey         string
+	IgnorePreflightErrors string
 }
 
 type ClusterNode struct {
diff --git a/pkg/scheme/core/v1/k8s/kubeadm_step.go b/pkg/scheme/core/v1/k8s/kubeadm_step.go
index 4318472..a6a4eee 100644
--- a/pkg/scheme/core/v1/k8s/kubeadm_step.go
+++ b/pkg/scheme/core/v1/k8s/kubeadm_step.go
@@ -25,6 +25,7 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
+	"strings"
 	"time"
 
 	"k8s.io/apimachinery/pkg/util/sets"
@@ -433,10 +434,18 @@ func (stepper *KubeadmConfig) InitStepper(c *v1.Cluster, metadata *component.Ext
 	stepper.FeatureGates = c.FeatureGates
 	// TODO: No vip is currently introduced as controlPlaneEndpoint
 	stepper.AdvertiseAddress = metadata.Masters[0].NodeIPv4
+	stepper.IgnorePreflightErrors = parseIgnorePreflightErrors(c.Annotations[common.AnnotationOnlyIgnorePreflightErrors])
 
 	return stepper
 }
 
+func parseIgnorePreflightErrors(errStr string) []string {
+	if errStr == "" {
+		return nil
+	}
+	return strings.Split(errStr, ",")
+}
+
 func (stepper *KubeadmConfig) InstallSteps(nodes []v1.StepNode) ([]v1.Step, error) {
 	kubeadmBytes, err := json.Marshal(stepper)
 	if err != nil {
@@ -506,6 +515,7 @@ func (stepper *ControlPlane) InitStepper(c *v1.Cluster) *ControlPlane {
 	stepper.ContainerRuntime = c.ContainerRuntime.Type
 	stepper.ExternalCaCert = c.ExternalCaCert
 	stepper.ExternalCaKey = c.ExternalCaKey
+	stepper.IgnorePreflightErrors = c.Annotations[common.AnnotationOnlyIgnorePreflightErrors]
 
 	return stepper
 }
diff --git a/pkg/scheme/core/v1/k8s/template.go b/pkg/scheme/core/v1/k8s/template.go
index c77bff3..445c431 100644
--- a/pkg/scheme/core/v1/k8s/template.go
+++ b/pkg/scheme/core/v1/k8s/template.go
@@ -100,6 +100,10 @@ nodeRegistration:
 {{- if .Kubelet.IPAsName }}
   name: "{{.Kubelet.NodeIP}}"
 {{- end}}
+{{if gt (len .IgnorePreflightErrors) 0}}
+  ignorePreflightErrors:{{range .IgnorePreflightErrors}}
+    - {{.}}{{end}}
+{{- end}}
 {{- if eq .ContainerRuntime  "containerd"}}
   criSocket: /run/containerd/containerd.sock
 {{end}}


Test patch:
diff --git a/pkg/scheme/core/v1/k8s/kubeadm_test.go b/pkg/scheme/core/v1/k8s/kubeadm_test.go
index 94562cf..a29e20e 100644
--- a/pkg/scheme/core/v1/k8s/kubeadm_test.go
+++ b/pkg/scheme/core/v1/k8s/kubeadm_test.go
@@ -53,6 +53,7 @@ func TestKubeadmConfig_renderTo(t *testing.T) {
 		CertSANs                []string
 		LocalRegistry           string
 		FeatureGates            map[string]bool
+		IgnorePreflightErrors   string
 	}
 	tests := []struct {
 		name   string
@@ -73,13 +74,14 @@ func TestKubeadmConfig_renderTo(t *testing.T) {
 					ProxyMode:     "ipvs",
 					WorkerNodeVip: "8.8.8.8",
 				},
-				KubeProxy:            v1.KubeProxy{},
-				Kubelet:              v1.Kubelet{RootDir: "/var/lib/kubelet"},
-				ClusterName:          "test-cluster",
-				KubernetesVersion:    "v1.23.6",
-				ControlPlaneEndpoint: "apiserver.cluster.local:6443",
-				CertSANs:             []string{"127.0.0.1"},
-				LocalRegistry:        "127.0.0.1:5000",
+				KubeProxy:             v1.KubeProxy{},
+				Kubelet:               v1.Kubelet{RootDir: "/var/lib/kubelet"},
+				ClusterName:           "test-cluster",
+				KubernetesVersion:     "v1.23.6",
+				ControlPlaneEndpoint:  "apiserver.cluster.local:6443",
+				CertSANs:              []string{"127.0.0.1"},
+				LocalRegistry:         "127.0.0.1:5000",
+				IgnorePreflightErrors: "",
 			},
 		},
 		{
@@ -96,13 +98,14 @@ func TestKubeadmConfig_renderTo(t *testing.T) {
 					ProxyMode:     "ipvs",
 					WorkerNodeVip: "8.8.8.8",
 				},
-				KubeProxy:            v1.KubeProxy{},
-				Kubelet:              v1.Kubelet{RootDir: "/var/lib/kubelet", NodeIP: "127.0.0.1", IPAsName: true},
-				ClusterName:          "test-cluster",
-				KubernetesVersion:    "v1.23.6",
-				ControlPlaneEndpoint: "apiserver.cluster.local:6443",
-				CertSANs:             []string{"127.0.0.1"},
-				LocalRegistry:        "127.0.0.1:5000",
+				KubeProxy:             v1.KubeProxy{},
+				Kubelet:               v1.Kubelet{RootDir: "/var/lib/kubelet", NodeIP: "127.0.0.1", IPAsName: true},
+				ClusterName:           "test-cluster",
+				KubernetesVersion:     "v1.23.6",
+				ControlPlaneEndpoint:  "apiserver.cluster.local:6443",
+				CertSANs:              []string{"127.0.0.1"},
+				LocalRegistry:         "127.0.0.1:5000",
+				IgnorePreflightErrors: "NumCPU",
 			},
 		},
 		{
@@ -130,6 +133,7 @@ func TestKubeadmConfig_renderTo(t *testing.T) {
 					"AdmissionWebhookMatchConditions": true,
 					"AggregatedDiscoveryEndpoint":     true,
 				},
+				IgnorePreflightErrors: "NumCPU,Swap",
 			},
 		},
 	}
@@ -148,7 +152,9 @@ func TestKubeadmConfig_renderTo(t *testing.T) {
 				CertSANs:                tt.fields.CertSANs,
 				LocalRegistry:           tt.fields.LocalRegistry,
 				FeatureGates:            tt.fields.FeatureGates,
+				IgnorePreflightErrors:   parseIgnorePreflightErrors(tt.fields.IgnorePreflightErrors),
 			}
+			t.Logf("IgnorePreflightErrors %v,len %v", stepper.IgnorePreflightErrors, len(stepper.IgnorePreflightErrors))
 			w := &bytes.Buffer{}
 			err := stepper.renderTo(w)
 			if err != nil {