Merge pull request #53733 from neolit123/kubeadm-01

Automatic merge from submit-queue (batch tested with PRs 55265, 54092, 55353, 53733, 55385). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

kubadm/cmd: wording and punctuation fixes

**What this PR does / why we need it**:
This is a follow-up PR from me fixing more wording & punctuation in the `kubeadm/app/cmd` namespace. I think it makes the output shown to the user clearer and better formatted.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #
NONE

**Special notes for your reviewer**:
Please let me know if you want anything amended. Certain things might be a subject to an argument, so if the maintainers want them kept the way they are ATM, i would comply.

**Release note**:

```release-note
NONE
```

Lubomir (VMware)
This commit is contained in:
Kubernetes Submit Queue 2017-11-10 01:30:27 -08:00 committed by GitHub
commit 96dbf02406
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 115 additions and 116 deletions

View File

@ -42,7 +42,7 @@ func NewKubeadmCommand(_ io.Reader, out, err io.Writer) *cobra.Command {
KUBEADM IS BETA, DO NOT USE IT FOR PRODUCTION CLUSTERS!
But, please try it out! Give us feedback at:
But please, try it out and give us feedback at:
https://github.com/kubernetes/kubeadm/issues │
and at-mention @kubernetes/sig-cluster-lifecycle-bugs
or @kubernetes/sig-cluster-lifecycle-feature-requests
@ -54,13 +54,13 @@ func NewKubeadmCommand(_ io.Reader, out, err io.Writer) *cobra.Command {
and one node (where your workloads, like Pods and Deployments run).
On the first machine
On the first machine:
master# kubeadm init
On the second machine
On the second machine:
node# kubeadm join <arguments-returned-from-init>

View File

@ -97,7 +97,7 @@ func NewCmdCompletion(out io.Writer, boilerPlate string) *cobra.Command {
cmd := &cobra.Command{
Use: "completion SHELL",
Short: i18n.T("Output shell completion code for the specified shell (bash or zsh)"),
Short: i18n.T("Output shell completion code for the specified shell (bash or zsh)."),
Long: completionLong,
Example: completionExample,
Run: func(cmd *cobra.Command, args []string) {

View File

@ -45,9 +45,9 @@ func NewCmdConfig(out io.Writer) *cobra.Command {
Short: "Manage configuration for a kubeadm cluster persisted in a ConfigMap in the cluster.",
Long: fmt.Sprintf(dedent.Dedent(`
There is a ConfigMap in the %s namespace called %q that kubeadm uses to store internal configuration about the
cluster. kubeadm CLI v1.8.0+ automatically creates this ConfigMap with used config on 'kubeadm init', but if you
cluster. kubeadm CLI v1.8.0+ automatically creates this ConfigMap with the config used with 'kubeadm init', but if you
initialized your cluster using kubeadm v1.7.x or lower, you must use the 'config upload' command to create this
ConfigMap in order for 'kubeadm upgrade' to be able to configure your upgraded cluster correctly.
ConfigMap. This is required so that 'kubeadm upgrade' can configure your upgraded cluster correctly.
`), metav1.NamespaceSystem, constants.MasterConfigurationConfigMap),
// Without this callback, if a user runs just the "upload"
// command without a subcommand, or with an invalid subcommand,
@ -57,7 +57,7 @@ func NewCmdConfig(out io.Writer) *cobra.Command {
RunE: cmdutil.SubCmdRunE("config"),
}
cmd.PersistentFlags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster.")
cmd.PersistentFlags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use when talking to the cluster.")
cmd.AddCommand(NewCmdConfigUpload(out, &kubeConfigFile))
cmd.AddCommand(NewCmdConfigView(out, &kubeConfigFile))
@ -69,7 +69,7 @@ func NewCmdConfig(out io.Writer) *cobra.Command {
func NewCmdConfigUpload(out io.Writer, kubeConfigFile *string) *cobra.Command {
cmd := &cobra.Command{
Use: "upload",
Short: "Upload configuration about the current state so 'kubeadm upgrade' later can know how to configure the upgraded cluster.",
Short: "Upload configuration about the current state, so that 'kubeadm upgrade' can later know how to configure the upgraded cluster.",
RunE: cmdutil.SubCmdRunE("upload"),
}
@ -106,8 +106,8 @@ func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Co
Use: "from-file",
Short: "Upload a configuration file to the in-cluster ConfigMap for kubeadm configuration.",
Long: fmt.Sprintf(dedent.Dedent(`
Using from-file, you can upload configuration to the ConfigMap in the cluster using the same config file you gave to kubeadm init.
If you initialized your cluster using a v1.7.x or lower kubeadm client and used the --config option; you need to run this command with the
Using this command, you can upload configuration to the ConfigMap in the cluster using the same config file you gave to 'kubeadm init'.
If you initialized your cluster using a v1.7.x or lower kubeadm client and used the --config option, you need to run this command with the
same config file before upgrading to v1.8 using 'kubeadm upgrade'.
The configuration is located in the %q namespace in the %q ConfigMap.
@ -142,8 +142,8 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C
Use: "from-flags",
Short: "Create the in-cluster configuration file for the first time from using flags.",
Long: fmt.Sprintf(dedent.Dedent(`
Using from-flags, you can upload configuration to the ConfigMap in the cluster using the same flags you'd give to kubeadm init.
If you initialized your cluster using a v1.7.x or lower kubeadm client and set some flag; you need to run this command with the
Using this command, you can upload configuration to the ConfigMap in the cluster using the same flags you gave to 'kubeadm init'.
If you initialized your cluster using a v1.7.x or lower kubeadm client and set certain flags, you need to run this command with the
same flags before upgrading to v1.8 using 'kubeadm upgrade'.
The configuration is located in the %q namespace in the %q ConfigMap.

View File

@ -66,7 +66,7 @@ var (
initDoneTempl = template.Must(template.New("init").Parse(dedent.Dedent(`
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run (as a regular user):
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i {{.KubeConfigPath}} $HOME/.kube/config
@ -87,15 +87,15 @@ var (
Unfortunately, an error has occurred:
{{ .Error }}
This error is likely caused by that:
This error is likely caused by:
- The kubelet is not running
- The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)
- There is no internet connection; so the kubelet can't pull the following control plane images:
- There is no internet connection, so the kubelet cannot pull the following control plane images:
- {{ .APIServerImage }}
- {{ .ControllerManagerImage }}
- {{ .SchedulerImage }}
You can troubleshoot this for example with the following commands if you're on a systemd-powered system:
If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
- 'systemctl status kubelet'
- 'journalctl -xeu kubelet'
`)))
@ -115,7 +115,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "init",
Short: "Run this in order to set up the Kubernetes master",
Short: "Run this command in order to set up the Kubernetes master.",
Run: func(cmd *cobra.Command, args []string) {
var err error
if cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil {
@ -143,7 +143,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfiguration, featureGatesString *string) {
flagSet.StringVar(
&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress,
"The IP address the API Server will advertise it's listening on. 0.0.0.0 means the default network interface's address.",
"The IP address the API Server will advertise it's listening on. Specify '0.0.0.0' to use the address of the default network interface.",
)
flagSet.Int32Var(
&cfg.API.BindPort, "apiserver-bind-port", cfg.API.BindPort,
@ -155,7 +155,7 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfigur
)
flagSet.StringVar(
&cfg.Networking.PodSubnet, "pod-network-cidr", cfg.Networking.PodSubnet,
"Specify range of IP addresses for the pod network; if set, the control plane will automatically allocate CIDRs for every node.",
"Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node.",
)
flagSet.StringVar(
&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain,
@ -171,7 +171,7 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfigur
)
flagSet.StringSliceVar(
&cfg.APIServerCertSANs, "apiserver-cert-extra-sans", cfg.APIServerCertSANs,
`Optional extra altnames to use for the API Server serving cert. Can be both IP addresses and dns names.`,
`Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names.`,
)
flagSet.StringVar(
&cfg.NodeName, "node-name", cfg.NodeName,
@ -183,7 +183,7 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfigur
)
flagSet.DurationVar(
&cfg.TokenTTL.Duration, "token-ttl", cfg.TokenTTL.Duration,
"The duration before the bootstrap token is automatically deleted. 0 means 'never expires'.",
"The duration before the bootstrap token is automatically deleted. If set to '0', the token will never expire.",
)
flagSet.StringVar(featureGatesString, "feature-gates", *featureGatesString, "A set of key=value pairs that describe feature gates for various features. "+
"Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n"))
@ -198,7 +198,7 @@ func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, sk
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
flagSet.BoolVar(
skipPreFlight, "skip-preflight-checks", *skipPreFlight,
"Skip preflight checks normally run before modifying the system.",
"Skip preflight checks which normally run before modifying the system.",
)
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
flagSet.BoolVar(
@ -219,7 +219,7 @@ func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, sk
// NewInit validates given arguments and instantiates Init struct with provided information.
func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight, skipTokenPrint, dryRun bool, criSocket string) (*Init, error) {
fmt.Println("[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.")
fmt.Println("[kubeadm] WARNING: kubeadm is in beta. Please do not use it for production clusters!")
if cfgPath != "" {
b, err := ioutil.ReadFile(cfgPath)
@ -417,7 +417,7 @@ func (i *Init) Run(out io.Writer) error {
if features.Enabled(i.cfg.FeatureGates, features.SelfHosting) {
// Temporary control plane is up, now we create our self hosted control
// plane components and remove the static manifests:
fmt.Println("[self-hosted] Creating self-hosted control plane...")
fmt.Println("[self-hosted] Creating self-hosted control plane.")
if err := selfhostingphase.CreateSelfHostedControlPlane(manifestDir, kubeConfigDir, i.cfg, client, waiter); err != nil {
return fmt.Errorf("error creating self hosted control plane: %v", err)
}
@ -425,7 +425,7 @@ func (i *Init) Run(out io.Writer) error {
// Exit earlier if we're dryrunning
if i.dryRun {
fmt.Println("[dryrun] Finished dry-running successfully; above are the resources that would be created.")
fmt.Println("[dryrun] Finished dry-running successfully. Above are the resources that would be created.")
return nil
}
@ -487,9 +487,9 @@ func printFilesIfDryRunning(dryRun bool, manifestDir string) error {
return nil
}
fmt.Printf("[dryrun] Wrote certificates, kubeconfig files and control plane manifests to %q\n", manifestDir)
fmt.Println("[dryrun] Won't print certificates or kubeconfig files due to the sensitive nature of them")
fmt.Printf("[dryrun] Please go and examine the %q directory for details about what would be written\n", manifestDir)
fmt.Printf("[dryrun] Wrote certificates, kubeconfig files and control plane manifests to the %q directory.\n", manifestDir)
fmt.Println("[dryrun] The certificates or kubeconfig files would not be printed due to their sensitive nature.")
fmt.Printf("[dryrun] Please examine the %q directory for details about what would be written.\n", manifestDir)
// Print the contents of the upgraded manifests and pretend like they were in /etc/kubernetes/manifests
files := []dryrunutil.FileToPrint{}
@ -517,7 +517,7 @@ func waitForAPIAndKubelet(waiter apiclient.Waiter) error {
errorChan := make(chan error)
fmt.Printf("[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory %q.\n", kubeadmconstants.GetStaticPodDirectory())
fmt.Println("[init] This often takes around a minute; or longer if the control plane images have to be pulled.")
fmt.Println("[init] This might take a minute or longer if the control plane images have to be pulled.")
go func(errC chan error, waiter apiclient.Waiter) {
// This goroutine can only make kubeadm init fail. If this check succeeds, it won't do anything special

View File

@ -43,12 +43,12 @@ import (
var (
joinDoneMsgf = dedent.Dedent(`
Node join complete:
* Certificate signing request sent to master and response
received.
* Kubelet informed of new secure connection details.
This node has joined the cluster:
* Certificate signing request was sent to master and a response
was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this machine join.
Run 'kubectl get nodes' on the master to see this node join the cluster.
`)
joinLongDescription = dedent.Dedent(`
@ -59,13 +59,14 @@ var (
There are 2 main schemes for discovery. The first is to use a shared
token along with the IP address of the API server. The second is to
provide a file (a subset of the standard kubeconfig file). This file
provide a file - a subset of the standard kubeconfig file. This file
can be a local file or downloaded via an HTTPS URL. The forms are
kubeadm join --discovery-token abcdef.1234567890abcdef 1.2.3.4:6443,
kubeadm join --discovery-file path/to/file.conf, or kubeadm join
--discovery-file https://url/file.conf. Only one form can be used. If
the discovery information is loaded from a URL, HTTPS must be used and
the host installed CA bundle is used to verify the connection.
the discovery information is loaded from a URL, HTTPS must be used.
Also, in that case the host installed CA bundle is used to verify
the connection.
If you use a shared token for discovery, you should also pass the
--discovery-token-ca-cert-hash flag to validate the public key of the
@ -85,7 +86,7 @@ var (
The TLS bootstrap mechanism is also driven via a shared token. This is
used to temporarily authenticate with the Kubernetes Master to submit a
certificate signing request (CSR) for a locally created key pair. By
default kubeadm will set up the Kubernetes Master to automatically
default, kubeadm will set up the Kubernetes Master to automatically
approve these signing requests. This token is passed in with the
--tls-bootstrap-token abcdef.1234567890abcdef flag.
@ -160,7 +161,7 @@ func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight *bo
flagSet.BoolVar(
skipPreFlight, "skip-preflight-checks", false,
"Skip preflight checks normally run before modifying the system.",
"Skip preflight checks which normally run before modifying the system.",
)
flagSet.StringVar(
criSocket, "cri-socket", "/var/run/dockershim.sock",
@ -175,7 +176,7 @@ type Join struct {
// NewJoin instantiates Join struct with given arguments
func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, skipPreFlight bool, criSocket string) (*Join, error) {
fmt.Println("[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.")
fmt.Println("[kubeadm] WARNING: kubeadm is in beta. Please do not use it for production clusters!")
if cfg.NodeName == "" {
cfg.NodeName = nodeutil.GetHostname("")

View File

@ -79,7 +79,7 @@ func getAddonsSubCommands() []*cobra.Command {
}{
{
use: "all",
short: "Install all addons to a Kubernetes cluster",
short: "Install all addons to a Kubernetes cluster.",
cmdFunc: EnsureAllAddons,
},
{
@ -103,15 +103,15 @@ func getAddonsSubCommands() []*cobra.Command {
}
// Add flags to the command
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use when talking to the cluster")
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental!")
cmd.Flags().StringVar(&cfg.KubernetesVersion, "kubernetes-version", cfg.KubernetesVersion, `Choose a specific Kubernetes version for the control plane.`)
cmd.Flags().StringVar(&cfg.ImageRepository, "image-repository", cfg.ImageRepository, `Choose a container registry to pull control plane images from.`)
if properties.use == "all" || properties.use == "kube-proxy" {
cmd.Flags().StringVar(&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, `The IP address the API Server will advertise it's listening on. 0.0.0.0 means the default network interface's address.`)
cmd.Flags().StringVar(&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, `The IP address the API Server will advertise it's listening on. Specify '0.0.0.0' to use the address of the default network interface.`)
cmd.Flags().Int32Var(&cfg.API.BindPort, "apiserver-bind-port", cfg.API.BindPort, `Port for the API Server to bind to.`)
cmd.Flags().StringVar(&cfg.Networking.PodSubnet, "pod-network-cidr", cfg.Networking.PodSubnet, `Specify range of IP addresses for the pod network; if set, the control plane will automatically allocate CIDRs for every node.`)
cmd.Flags().StringVar(&cfg.Networking.PodSubnet, "pod-network-cidr", cfg.Networking.PodSubnet, `Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node.`)
}
if properties.use == "all" || properties.use == "kube-dns" {

View File

@ -35,12 +35,12 @@ func NewCmdBootstrapToken() *cobra.Command {
var kubeConfigFile string
cmd := &cobra.Command{
Use: "bootstrap-token",
Short: "Manage kubeadm-specific Bootstrap Token functions.",
Short: "Manage kubeadm-specific bootstrap token functions.",
Aliases: []string{"bootstraptoken"},
RunE: cmdutil.SubCmdRunE("bootstrap-token"),
}
cmd.PersistentFlags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
cmd.PersistentFlags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use when talking to the cluster.")
// Add subcommands
cmd.AddCommand(NewSubCmdClusterInfo(&kubeConfigFile))
@ -53,7 +53,7 @@ func NewCmdBootstrapToken() *cobra.Command {
func NewSubCmdClusterInfo(kubeConfigFile *string) *cobra.Command {
cmd := &cobra.Command{
Use: "cluster-info <clusterinfo-file>",
Short: "Uploads and exposes the cluster-info ConfigMap publicly from the given cluster-info file",
Short: "Uploads and exposes the cluster-info ConfigMap publicly from the given cluster-info file.",
Aliases: []string{"clusterinfo"},
Run: func(cmd *cobra.Command, args []string) {
err := cmdutil.ValidateExactArgNumber(args, []string{"clusterinfo-file"})
@ -80,7 +80,7 @@ func NewSubCmdClusterInfo(kubeConfigFile *string) *cobra.Command {
func NewSubCmdNodeBootstrapToken(kubeConfigFile *string) *cobra.Command {
cmd := &cobra.Command{
Use: "node",
Short: "Manages Node Bootstrap Tokens",
Short: "Manages node bootstrap tokens.",
Aliases: []string{"clusterinfo"},
RunE: cmdutil.SubCmdRunE("node"),
}
@ -95,7 +95,7 @@ func NewSubCmdNodeBootstrapToken(kubeConfigFile *string) *cobra.Command {
func NewSubCmdNodeBootstrapTokenPostCSRs(kubeConfigFile *string) *cobra.Command {
cmd := &cobra.Command{
Use: "allow-post-csrs",
Short: "Configure RBAC to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials",
Short: "Configure RBAC to allow node bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials.",
Run: func(cmd *cobra.Command, args []string) {
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
kubeadmutil.CheckErr(err)
@ -114,7 +114,7 @@ func NewSubCmdNodeBootstrapTokenPostCSRs(kubeConfigFile *string) *cobra.Command
func NewSubCmdNodeBootstrapTokenAutoApprove(kubeConfigFile *string) *cobra.Command {
cmd := &cobra.Command{
Use: "allow-auto-approve",
Short: "Configure RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token",
Short: "Configure RBAC rules to allow the csrapprover controller automatically approve CSRs from a node bootstrap token.",
Run: func(cmd *cobra.Command, args []string) {
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
kubeadmutil.CheckErr(err)

View File

@ -111,13 +111,13 @@ func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command {
}
// Add flags to the command
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, "The path where to save and store the certificates")
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental!")
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, "The path where to save and store the certificates.")
if properties.use == "all" || properties.use == "apiserver" {
cmd.Flags().StringVar(&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, "Use alternative domain for services, e.g. \"myorg.internal\"")
cmd.Flags().StringVar(&cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet, "Use alternative range of IP address for service VIPs")
cmd.Flags().StringSliceVar(&cfg.APIServerCertSANs, "apiserver-cert-extra-sans", []string{}, "Optional extra altnames to use for the API Server serving cert. Can be both IP addresses and dns names.")
cmd.Flags().StringVar(&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, "The IP address the API Server will advertise it's listening on. 0.0.0.0 means the default network interface's address.")
cmd.Flags().StringVar(&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, "Use alternative domain for services, e.g. \"myorg.internal\".")
cmd.Flags().StringVar(&cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet, "Use alternative range of IP address for service VIPs.")
cmd.Flags().StringSliceVar(&cfg.APIServerCertSANs, "apiserver-cert-extra-sans", []string{}, "Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names.")
cmd.Flags().StringVar(&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, "The IP address the API Server will advertise it is listening on. Specify '0.0.0.0' to use the address of the default network interface.")
}
subCmds = append(subCmds, cmd)

View File

@ -107,7 +107,7 @@ func getControlPlaneSubCommands(outDir, defaultKubernetesVersion string) []*cobr
cmd.Flags().StringVar(&cfg.Networking.PodSubnet, "pod-network-cidr", cfg.Networking.PodSubnet, "The range of IP addresses used for the pod network.")
}
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental!")
subCmds = append(subCmds, cmd)
}

View File

@ -72,12 +72,12 @@ func getKubeConfigSubCommands(out io.Writer, outDir, defaultKubernetesVersion st
},
{
use: "admin",
short: "Generate a kubeconfig file for the admin to use and for kubeadm itself.",
short: "Generate a kubeconfig file for the administrator to use and for kubeadm itself.",
cmdFunc: kubeconfigphase.CreateAdminKubeConfigFile,
},
{
use: "kubelet",
short: "Generate a kubeconfig file for the Kubelet to use. Please note that this should *only* be used for bootstrapping purposes. After your control plane is up, you should request all kubelet credentials from the CSR API.",
short: "Generate a kubeconfig file for the Kubelet to use. Please note that this should *only* be used for bootstrapping purposes! After your control plane is up, you should request all kubelet credentials from the CSR API.",
cmdFunc: kubeconfigphase.CreateKubeletKubeConfigFile,
},
{
@ -119,7 +119,7 @@ func getKubeConfigSubCommands(out io.Writer, outDir, defaultKubernetesVersion st
// Add flags to the command
if properties.use != "user" {
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental!")
}
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, "The path where certificates are stored.")
cmd.Flags().StringVar(&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, "The IP address or DNS name the API Server is accessible on.")

View File

@ -44,6 +44,6 @@ func NewCmdMarkMaster() *cobra.Command {
},
}
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use when talking to the cluster")
return cmd
}

View File

@ -42,7 +42,7 @@ func NewCmdPreFlight() *cobra.Command {
func NewCmdPreFlightMaster() *cobra.Command {
cmd := &cobra.Command{
Use: "master",
Short: "Run master pre-flight checks",
Short: "Run master pre-flight checks.",
RunE: func(cmd *cobra.Command, args []string) error {
cfg := &kubeadmapi.MasterConfiguration{}
criSocket := ""
@ -57,7 +57,7 @@ func NewCmdPreFlightMaster() *cobra.Command {
func NewCmdPreFlightNode() *cobra.Command {
cmd := &cobra.Command{
Use: "node",
Short: "Run node pre-flight checks",
Short: "Run node pre-flight checks.",
RunE: func(cmd *cobra.Command, args []string) error {
cfg := &kubeadmapi.NodeConfiguration{}
criSocket := ""

View File

@ -90,14 +90,14 @@ func getSelfhostingSubCommand() *cobra.Command {
// Add flags to the command
// flags bound to the configuration object
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`)
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored.`)
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental!")
cmd.Flags().StringVar(&featureGatesString, "feature-gates", featureGatesString, "A set of key=value pairs that describe feature gates for various features."+
"Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n"))
// flags that are not bound to the configuration object
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use when talking to the cluster.")
return cmd
}

View File

@ -51,8 +51,8 @@ func NewCmdUploadConfig() *cobra.Command {
},
}
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
cmd.Flags().StringVar(&cfgPath, "config", "", "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use when talking to the cluster")
cmd.Flags().StringVar(&cfgPath, "config", "", "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental!")
return cmd
}

View File

@ -54,7 +54,7 @@ func NewCmdReset(out io.Writer) *cobra.Command {
cmd.PersistentFlags().BoolVar(
&skipPreFlight, "skip-preflight-checks", false,
"Skip preflight checks normally run before modifying the system.",
"Skip preflight checks which normally run before modifying the system.",
)
cmd.PersistentFlags().StringVar(
@ -100,12 +100,12 @@ func (r *Reset) Run(out io.Writer) error {
// Try to stop the kubelet service
initSystem, err := initsystem.GetInitSystem()
if err != nil {
fmt.Println("[reset] WARNING: The kubelet service couldn't be stopped by kubeadm because no supported init system was detected.")
fmt.Println("[reset] WARNING: The kubelet service could not be stopped by kubeadm. Unable to detect a supported init system!")
fmt.Println("[reset] WARNING: Please ensure kubelet is stopped manually.")
} else {
fmt.Println("[reset] Stopping the kubelet service.")
if err := initSystem.ServiceStop("kubelet"); err != nil {
fmt.Printf("[reset] WARNING: The kubelet service couldn't be stopped by kubeadm: [%v]\n", err)
fmt.Printf("[reset] WARNING: The kubelet service could not be stopped by kubeadm: [%v]\n", err)
fmt.Println("[reset] WARNING: Please ensure kubelet is stopped manually.")
}
}
@ -132,7 +132,7 @@ func (r *Reset) Run(out io.Writer) error {
if _, err := os.Stat(etcdManifestPath); err == nil {
dirsToClean = append(dirsToClean, "/var/lib/etcd")
} else {
fmt.Printf("[reset] No etcd manifest found in %q, assuming external etcd.\n", etcdManifestPath)
fmt.Printf("[reset] No etcd manifest found in %q. Assuming external etcd.\n", etcdManifestPath)
}
// Then clean contents from the stateful kubelet, etcd and cni directories

View File

@ -54,23 +54,21 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
Use: "token",
Short: "Manage bootstrap tokens.",
Long: dedent.Dedent(`
This command will manage Bootstrap Token for you.
Please note this usage of this command is optional, and mostly for advanced users.
This command manages bootstrap tokens. It is optional and needed only for advanced use cases.
In short, Bootstrap Tokens are used for establishing bidirectional trust between a client and a server.
A Bootstrap Token can be used when a client (for example a node that's about to join the cluster) needs
to trust the server it is talking to. Then a Bootstrap Token with the "signing" usage can be used.
Bootstrap Tokens can also function as a way to allow short-lived authentication to the API Server
In short, bootstrap tokens are used for establishing bidirectional trust between a client and a server.
A bootstrap token can be used when a client (for example a node that is about to join the cluster) needs
to trust the server it is talking to. Then a bootstrap token with the "signing" usage can be used.
bootstrap tokens can also function as a way to allow short-lived authentication to the API Server
(the token serves as a way for the API Server to trust the client), for example for doing the TLS Bootstrap.
What is a Bootstrap Token more exactly?
What is a bootstrap token more exactly?
- It is a Secret in the kube-system namespace of type "bootstrap.kubernetes.io/token".
- A Bootstrap Token must be of the form "[a-z0-9]{6}.[a-z0-9]{16}"; the former part is the public Token ID,
and the latter is the Token Secret, which must be kept private at all circumstances.
- A bootstrap token must be of the form "[a-z0-9]{6}.[a-z0-9]{16}". The former part is the public token ID,
while the latter is the Token Secret and it must be kept private at all circumstances!
- The name of the Secret must be named "bootstrap-token-(token-id)".
You can read more about Bootstrap Tokens here:
You can read more about bootstrap tokens here:
https://kubernetes.io/docs/admin/bootstrap-tokens/
`),
@ -83,7 +81,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
}
tokenCmd.PersistentFlags().StringVar(&kubeConfigFile,
"kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
"kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use when talking to the cluster")
tokenCmd.PersistentFlags().BoolVar(&dryRun,
"dry-run", dryRun, "Whether to enable dry-run mode or not")
@ -95,8 +93,8 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
Use: "create [token]",
Short: "Create bootstrap tokens on the server.",
Long: dedent.Dedent(`
This command will create a Bootstrap Token for you.
You can specify the usages for this token, the time to live and an optional human friendly description.
This command will create a bootstrap token for you.
You can specify the usages for this token, the "time to live" and an optional human friendly description.
The [token] is the actual token to write.
This should be a securely generated random token of the form "[a-z0-9]{6}.[a-z0-9]{16}".
@ -115,9 +113,9 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
},
}
createCmd.Flags().DurationVar(&tokenDuration,
"ttl", kubeadmconstants.DefaultTokenDuration, "The duration before the token is automatically deleted (e.g. 1s, 2m, 3h). 0 means 'never expires'.")
"ttl", kubeadmconstants.DefaultTokenDuration, "The duration before the token is automatically deleted (e.g. 1s, 2m, 3h). If set to '0', the token will never expire.")
createCmd.Flags().StringSliceVar(&usages,
"usages", kubeadmconstants.DefaultTokenUsages, fmt.Sprintf("The ways in which this token can be used. Valid options: [%s].", strings.Join(kubeadmconstants.DefaultTokenUsages, ",")))
"usages", kubeadmconstants.DefaultTokenUsages, fmt.Sprintf("Describes the ways in which this token can be used. You can pass --usages multiple times or provide a comma separated list of options. Valid options: [%s].", strings.Join(kubeadmconstants.DefaultTokenUsages, ",")))
createCmd.Flags().StringSliceVar(&extraGroups,
"groups", []string{kubeadmconstants.NodeBootstrapTokenAuthGroup},
fmt.Sprintf("Extra groups that this token will authenticate as when used for authentication. Must match %q.", bootstrapapi.BootstrapGroupPattern))
@ -131,7 +129,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
Use: "list",
Short: "List bootstrap tokens on the server.",
Long: dedent.Dedent(`
This command will list all Bootstrap Tokens for you.
This command will list all bootstrap tokens for you.
`),
Run: func(tokenCmd *cobra.Command, args []string) {
client, err := getClientset(kubeConfigFile, dryRun)
@ -147,7 +145,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
Use: "delete [token-value]",
Short: "Delete bootstrap tokens on the server.",
Long: dedent.Dedent(`
This command will delete a given Bootstrap Token for you.
This command will delete a given bootstrap token for you.
The [token-value] is the full Token of the form "[a-z0-9]{6}.[a-z0-9]{16}" or the
Token ID of the form "[a-z0-9]{6}" to delete.
@ -178,10 +176,10 @@ func NewCmdTokenGenerate(out io.Writer) *cobra.Command {
the "init" and "join" commands.
You don't have to use this command in order to generate a token. You can do so
yourself as long as it's in the format "[a-z0-9]{6}.[a-z0-9]{16}". This
command is provided for convenience to generate tokens in that format.
yourself as long as it is in the format "[a-z0-9]{6}.[a-z0-9]{16}". This
command is provided for convenience to generate tokens in the given format.
You can also use "kubeadm init" without specifying a token, and it will
You can also use "kubeadm init" without specifying a token and it will
generate and print one for you.
`),
Run: func(cmd *cobra.Command, args []string) {

View File

@ -66,7 +66,7 @@ func NewCmdApply(parentFlags *cmdUpgradeFlags) *cobra.Command {
cmd := &cobra.Command{
Use: "apply [version]",
Short: "Upgrade your Kubernetes cluster to the specified version",
Short: "Upgrade your Kubernetes cluster to the specified version.",
Run: func(cmd *cobra.Command, args []string) {
// Ensure the user is root
err := runPreflightChecks(flags.parent.skipPreFlight)
@ -90,7 +90,7 @@ func NewCmdApply(parentFlags *cmdUpgradeFlags) *cobra.Command {
// Specify the valid flags specific for apply
cmd.Flags().BoolVarP(&flags.nonInteractiveMode, "yes", "y", flags.nonInteractiveMode, "Perform the upgrade and do not prompt for confirmation (non-interactive mode).")
cmd.Flags().BoolVarP(&flags.force, "force", "f", flags.force, "Force upgrading although some requirements might not be met. This also implies non-interactive mode.")
cmd.Flags().BoolVar(&flags.dryRun, "dry-run", flags.dryRun, "Do not change any state, just output what actions would be applied.")
cmd.Flags().BoolVar(&flags.dryRun, "dry-run", flags.dryRun, "Do not change any state, just output what actions would be performed.")
cmd.Flags().DurationVar(&flags.imagePullTimeout, "image-pull-timeout", flags.imagePullTimeout, "The maximum amount of time to wait for the control plane pods to be downloaded.")
return cmd
@ -105,7 +105,7 @@ func NewCmdApply(parentFlags *cmdUpgradeFlags) *cobra.Command {
// - Makes sure the control plane images are available locally on the master(s)
// - Upgrades the control plane components
// - Applies the other resources that'd be created with kubeadm init as well, like
// - Creating the RBAC rules for the Bootstrap Tokens and the cluster-info ConfigMap
// - Creating the RBAC rules for the bootstrap tokens and the cluster-info ConfigMap
// - Applying new kube-dns and kube-proxy manifests
// - Uploads the newly used configuration to the cluster ConfigMap
func RunApply(flags *applyFlags) error {

View File

@ -99,11 +99,11 @@ func printConfiguration(cfg *kubeadmapiext.MasterConfiguration, w io.Writer) {
// runPreflightChecks runs the root preflight check
func runPreflightChecks(skipPreFlight bool) error {
if skipPreFlight {
fmt.Println("[preflight] Skipping pre-flight checks")
fmt.Println("[preflight] Skipping pre-flight checks.")
return nil
}
fmt.Println("[preflight] Running pre-flight checks")
fmt.Println("[preflight] Running pre-flight checks.")
return preflight.RunRootCheckOnly()
}

View File

@ -33,7 +33,7 @@ import (
func NewCmdPlan(parentFlags *cmdUpgradeFlags) *cobra.Command {
cmd := &cobra.Command{
Use: "plan",
Short: "Check which versions are available to upgrade to and validate whether your current cluster is upgradeable",
Short: "Check which versions are available to upgrade to and validate whether your current cluster is upgradeable.",
Run: func(_ *cobra.Command, _ []string) {
// Ensure the user is root
err := runPreflightChecks(parentFlags.skipPreFlight)
@ -83,7 +83,7 @@ func printAvailableUpgrades(upgrades []upgrade.Upgrade, w io.Writer) {
for _, upgrade := range upgrades {
if upgrade.CanUpgradeKubelets() {
fmt.Fprintln(w, "Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':")
fmt.Fprintln(w, "Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':")
fmt.Fprintln(tabw, "COMPONENT\tCURRENT\tAVAILABLE")
firstPrinted := false
@ -122,7 +122,7 @@ func printAvailableUpgrades(upgrades []upgrade.Upgrade, w io.Writer) {
fmt.Fprintln(w, "")
if upgrade.Before.KubeadmVersion != upgrade.After.KubeadmVersion {
fmt.Fprintf(w, "Note: Before you can perform this upgrade, you have to update kubeadm to %s\n", upgrade.After.KubeadmVersion)
fmt.Fprintf(w, "Note: Before you can perform this upgrade, you have to update kubeadm to %s.\n", upgrade.After.KubeadmVersion)
fmt.Fprintln(w, "")
}

View File

@ -89,7 +89,7 @@ func TestPrintAvailableUpgrades(t *testing.T) {
},
},
},
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.7.1 v1.7.3
@ -106,7 +106,7 @@ You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.7.3
Note: Before you can perform this upgrade, you have to update kubeadm to v1.7.3
Note: Before you can perform this upgrade, you have to update kubeadm to v1.7.3.
_____________________________________________________________________
@ -131,7 +131,7 @@ _____________________________________________________________________
},
},
},
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.7.3 v1.8.0
@ -187,7 +187,7 @@ _____________________________________________________________________
},
},
},
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.7.3 v1.7.5
@ -206,7 +206,7 @@ You can now apply the upgrade by executing the following command:
_____________________________________________________________________
Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.7.3 v1.8.2
@ -223,7 +223,7 @@ You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.8.2
Note: Before you can perform this upgrade, you have to update kubeadm to v1.8.2
Note: Before you can perform this upgrade, you have to update kubeadm to v1.8.2.
_____________________________________________________________________
@ -248,7 +248,7 @@ _____________________________________________________________________
},
},
},
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.7.5 v1.8.0-beta.1
@ -265,7 +265,7 @@ You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.8.0-beta.1
Note: Before you can perform this upgrade, you have to update kubeadm to v1.8.0-beta.1
Note: Before you can perform this upgrade, you have to update kubeadm to v1.8.0-beta.1.
_____________________________________________________________________
@ -290,7 +290,7 @@ _____________________________________________________________________
},
},
},
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.7.5 v1.8.0-rc.1
@ -307,7 +307,7 @@ You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.8.0-rc.1
Note: Before you can perform this upgrade, you have to update kubeadm to v1.8.0-rc.1
Note: Before you can perform this upgrade, you have to update kubeadm to v1.8.0-rc.1.
_____________________________________________________________________

View File

@ -50,12 +50,12 @@ func NewCmdUpgrade(out io.Writer) *cobra.Command {
RunE: cmdutil.SubCmdRunE("upgrade"),
}
cmd.PersistentFlags().StringVar(&flags.kubeConfigPath, "kubeconfig", flags.kubeConfigPath, "The KubeConfig file to use for talking to the cluster.")
cmd.PersistentFlags().StringVar(&flags.cfgPath, "config", flags.cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental).")
cmd.PersistentFlags().StringVar(&flags.kubeConfigPath, "kubeconfig", flags.kubeConfigPath, "The KubeConfig file to use when talking to the cluster.")
cmd.PersistentFlags().StringVar(&flags.cfgPath, "config", flags.cfgPath, "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental!")
cmd.PersistentFlags().BoolVar(&flags.allowExperimentalUpgrades, "allow-experimental-upgrades", flags.allowExperimentalUpgrades, "Show unstable versions of Kubernetes as an upgrade alternative and allow upgrading to an alpha/beta/release candidate versions of Kubernetes.")
cmd.PersistentFlags().BoolVar(&flags.allowRCUpgrades, "allow-release-candidate-upgrades", flags.allowRCUpgrades, "Show release candidate versions of Kubernetes as an upgrade alternative and allow upgrading to a release candidate versions of Kubernetes.")
cmd.PersistentFlags().BoolVar(&flags.printConfig, "print-config", flags.printConfig, "Whether the configuration file that will be used in the upgrade should be printed or not.")
cmd.PersistentFlags().BoolVar(&flags.skipPreFlight, "skip-preflight-checks", flags.skipPreFlight, "Skip preflight checks normally run before modifying the system")
cmd.PersistentFlags().BoolVar(&flags.printConfig, "print-config", flags.printConfig, "Specifies whether the configuration file that will be used in the upgrade should be printed or not.")
cmd.PersistentFlags().BoolVar(&flags.skipPreFlight, "skip-preflight-checks", flags.skipPreFlight, "Skip preflight checks that normally run before modifying the system.")
cmd.AddCommand(NewCmdApply(flags))
cmd.AddCommand(NewCmdPlan(flags))