From eec6f05ce0a1fbe0e8e9d20c44a98c1c1f506922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Tue, 16 Mar 2021 07:15:05 +0100 Subject: [PATCH 1/6] Don't use the generic path name for a variable It conflicts with the system "path" in module --- cmd/minikube/cmd/generate-docs.go | 12 ++++++------ cmd/minikube/cmd/kubectl.go | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/minikube/cmd/generate-docs.go b/cmd/minikube/cmd/generate-docs.go index 046b29ca5b..406c173bdf 100644 --- a/cmd/minikube/cmd/generate-docs.go +++ b/cmd/minikube/cmd/generate-docs.go @@ -27,7 +27,7 @@ import ( "k8s.io/minikube/pkg/minikube/style" ) -var path string +var docsPath string // generateDocs represents the generate-docs command var generateDocs = &cobra.Command{ @@ -38,20 +38,20 @@ var generateDocs = &cobra.Command{ Hidden: true, Run: func(cmd *cobra.Command, args []string) { // if directory does not exist - docsPath, err := os.Stat(path) - if err != nil || !docsPath.IsDir() { + st, err := os.Stat(docsPath) + if err != nil || !st.IsDir() { exit.Message(reason.Usage, "Unable to generate the documentation. Please ensure that the path specified is a directory, exists & you have permission to write to it.") } // generate docs - if err := generate.Docs(RootCmd, path); err != nil { + if err := generate.Docs(RootCmd, docsPath); err != nil { exit.Error(reason.InternalGenerateDocs, "Unable to generate docs", err) } - out.Step(style.Documentation, "Docs have been saved at - {{.path}}", out.V{"path": path}) + out.Step(style.Documentation, "Docs have been saved at - {{.path}}", out.V{"path": docsPath}) }, } func init() { - generateDocs.Flags().StringVar(&path, "path", "", "The path on the file system where the docs in markdown need to be saved") + generateDocs.Flags().StringVar(&docsPath, "path", "", "The path on the file system where the docs in markdown need to be saved") RootCmd.AddCommand(generateDocs) } diff --git a/cmd/minikube/cmd/kubectl.go b/cmd/minikube/cmd/kubectl.go index 6e37d88de7..c1df7d751b 100644 --- a/cmd/minikube/cmd/kubectl.go +++ b/cmd/minikube/cmd/kubectl.go @@ -66,7 +66,7 @@ minikube kubectl -- get pods --namespace kube-system`, waitStatus := exitError.Sys().(syscall.WaitStatus) rc = waitStatus.ExitStatus() } else { - fmt.Fprintf(os.Stderr, "Error running %s: %v\n", path, err) + fmt.Fprintf(os.Stderr, "Error running %s: %v\n", c.Path, err) rc = 1 } os.Exit(rc) From 78bc248a89c8824f60138c59a428e1e6e7f94b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Tue, 16 Mar 2021 07:44:47 +0100 Subject: [PATCH 2/6] Allow running kubectl over the ssh connection The default is to run kubernetes client locally --- cmd/minikube/cmd/kubectl.go | 45 +++++++++++++++++++++++- site/content/en/docs/commands/kubectl.md | 6 ++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/cmd/minikube/cmd/kubectl.go b/cmd/minikube/cmd/kubectl.go index c1df7d751b..1891607360 100644 --- a/cmd/minikube/cmd/kubectl.go +++ b/cmd/minikube/cmd/kubectl.go @@ -20,14 +20,22 @@ import ( "fmt" "os" "os/exec" + "path" "syscall" "github.com/spf13/cobra" "k8s.io/klog/v2" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/minikube/machine" + "k8s.io/minikube/pkg/minikube/mustload" "k8s.io/minikube/pkg/minikube/node" "k8s.io/minikube/pkg/minikube/out" + "k8s.io/minikube/pkg/minikube/vmpath" +) + +var ( + useSSH bool ) // kubectlCmd represents the kubectl command @@ -47,7 +55,28 @@ minikube kubectl -- get pods --namespace kube-system`, version = cc.KubernetesConfig.KubernetesVersion } - cluster := []string{"--cluster", ClusterFlagValue()} + cname := ClusterFlagValue() + + if useSSH { + co := mustload.Running(cname) + n := co.CP.Node + + kc := []string{"sudo"} + kc = append(kc, kubectlPath(*co.Config)) + kc = append(kc, "--kubeconfig") + kc = append(kc, kubeconfigPath(*co.Config)) + args = append(kc, args...) + + klog.Infof("Running SSH %v", args) + err := machine.CreateSSHShell(co.API, *co.Config, *n, args, false) + if err != nil { + fmt.Fprintf(os.Stderr, "Error running kubectl: %v", err) + os.Exit(1) + } + return + } + + cluster := []string{"--cluster", cname} args = append(cluster, args...) c, err := KubectlCommand(version, args...) @@ -74,6 +103,16 @@ minikube kubectl -- get pods --namespace kube-system`, }, } +// kubectlPath returns the path to kubectl +func kubectlPath(cfg config.ClusterConfig) string { + return path.Join(vmpath.GuestPersistentDir, "binaries", cfg.KubernetesConfig.KubernetesVersion, "kubectl") +} + +// kubeconfigPath returns the path to kubeconfig +func kubeconfigPath(cfg config.ClusterConfig) string { + return "/etc/kubernetes/admin.conf" +} + // KubectlCommand will return kubectl command with a version matching the cluster func KubectlCommand(version string, args ...string) (*exec.Cmd, error) { if version == "" { @@ -87,3 +126,7 @@ func KubectlCommand(version string, args ...string) (*exec.Cmd, error) { return exec.Command(path, args...), nil } + +func init() { + kubectlCmd.Flags().BoolVar(&useSSH, "ssh", false, "Use SSH for running kubernetes client") +} diff --git a/site/content/en/docs/commands/kubectl.md b/site/content/en/docs/commands/kubectl.md index 5d96e314c0..b4c4b91379 100644 --- a/site/content/en/docs/commands/kubectl.md +++ b/site/content/en/docs/commands/kubectl.md @@ -21,6 +21,12 @@ minikube kubectl -- get pods --namespace kube-system minikube kubectl [flags] ``` +### Options + +``` + --ssh Use SSH for running kubernetes client +``` + ### Options inherited from parent commands ``` From 2df5215960cbf0c0c51d0d9db6b37c4a11285a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Wed, 17 Mar 2021 20:17:56 +0100 Subject: [PATCH 3/6] Add more help text about using the ssh option --- cmd/minikube/cmd/kubectl.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/minikube/cmd/kubectl.go b/cmd/minikube/cmd/kubectl.go index 1891607360..33c2e22579 100644 --- a/cmd/minikube/cmd/kubectl.go +++ b/cmd/minikube/cmd/kubectl.go @@ -44,9 +44,13 @@ var kubectlCmd = &cobra.Command{ Short: "Run a kubectl binary matching the cluster version", Long: `Run the Kubernetes client, download it if necessary. Remember -- after kubectl! -Examples: -minikube kubectl -- --help -minikube kubectl -- get pods --namespace kube-system`, +This will run the Kubernetes client (kubectl) with the same version as the cluster + +Normally it will download a binary matching the host operating system and architecture, +but optionally you can also run it directly on the control plane over the ssh connection. +This can be useful if you cannot run kubectl locally for some reason, like unsupported +host. Please be aware that when using --ssh all paths will apply to the remote machine.`, + Example: "minikube kubectl -- --help\nminikube kubectl -- get pods --namespace kube-system", Run: func(cmd *cobra.Command, args []string) { cc, err := config.Load(ClusterFlagValue()) @@ -128,5 +132,5 @@ func KubectlCommand(version string, args ...string) (*exec.Cmd, error) { } func init() { - kubectlCmd.Flags().BoolVar(&useSSH, "ssh", false, "Use SSH for running kubernetes client") + kubectlCmd.Flags().BoolVar(&useSSH, "ssh", false, "Use SSH for running kubernetes client on the node") } From c552a1e754c4e334e919195302a9d9b73b7ac84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Wed, 17 Mar 2021 20:22:16 +0100 Subject: [PATCH 4/6] Make the example with --help not broken again --- cmd/minikube/cmd/kubectl.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/minikube/cmd/kubectl.go b/cmd/minikube/cmd/kubectl.go index 33c2e22579..9472caf8a1 100644 --- a/cmd/minikube/cmd/kubectl.go +++ b/cmd/minikube/cmd/kubectl.go @@ -80,8 +80,10 @@ host. Please be aware that when using --ssh all paths will apply to the remote m return } - cluster := []string{"--cluster", cname} - args = append(cluster, args...) + if len(args) > 1 && args[0] != "--help" { + cluster := []string{"--cluster", cname} + args = append(cluster, args...) + } c, err := KubectlCommand(version, args...) if err != nil { From e7f568a9d22d327fcb1ae56256ac048285fc0342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Thu, 18 Mar 2021 07:17:50 +0100 Subject: [PATCH 5/6] Make --help work when running minikube as kubectl Avoid the "magic" cobra.Command parsing of --help, and pass all flags as-is to the kubectl command. Use "minikube kubectl" if you want to set flags, and "kubectl" if you just want to run Kubernetes. --- cmd/minikube/main.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cmd/minikube/main.go b/cmd/minikube/main.go index d4a79f76eb..56536ef264 100644 --- a/cmd/minikube/main.go +++ b/cmd/minikube/main.go @@ -61,7 +61,10 @@ func main() { bridgeLogMessages() defer klog.Flush() - setFlags() + // Don't parse flags when running as kubectl + _, callingCmd := filepath.Split(os.Args[0]) + parse := callingCmd != "kubectl" + setFlags(parse) s := stacklog.MustStartFromEnv("STACKLOG_PATH") defer s.Stop() @@ -124,14 +127,16 @@ func (lb machineLogBridge) Write(b []byte) (n int, err error) { } // setFlags sets the flags -func setFlags() { +func setFlags(parse bool) { // parse flags beyond subcommand - get aroung go flag 'limitations': // "Flag parsing stops just before the first non-flag argument" (ref: https://pkg.go.dev/flag#hdr-Command_line_flag_syntax) pflag.CommandLine.ParseErrorsWhitelist.UnknownFlags = true pflag.CommandLine.AddGoFlagSet(flag.CommandLine) // avoid 'pflag: help requested' error, as help will be defined later by cobra cmd.Execute() pflag.BoolP("help", "h", false, "") - pflag.Parse() + if parse { + pflag.Parse() + } // set default flag value for logtostderr and alsologtostderr but don't override user's preferences if !pflag.CommandLine.Changed("logtostderr") { From 15e422d79ba8397318a29e02e5353f524861a80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Thu, 18 Mar 2021 07:20:33 +0100 Subject: [PATCH 6/6] Generate docs for commands to make test happy --- site/content/en/docs/commands/kubectl.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/site/content/en/docs/commands/kubectl.md b/site/content/en/docs/commands/kubectl.md index b4c4b91379..34e7975402 100644 --- a/site/content/en/docs/commands/kubectl.md +++ b/site/content/en/docs/commands/kubectl.md @@ -13,18 +13,28 @@ Run a kubectl binary matching the cluster version Run the Kubernetes client, download it if necessary. Remember -- after kubectl! -Examples: -minikube kubectl -- --help -minikube kubectl -- get pods --namespace kube-system +This will run the Kubernetes client (kubectl) with the same version as the cluster + +Normally it will download a binary matching the host operating system and architecture, +but optionally you can also run it directly on the control plane over the ssh connection. +This can be useful if you cannot run kubectl locally for some reason, like unsupported +host. Please be aware that when using --ssh all paths will apply to the remote machine. ```shell minikube kubectl [flags] ``` +### Examples + +``` +minikube kubectl -- --help +minikube kubectl -- get pods --namespace kube-system +``` + ### Options ``` - --ssh Use SSH for running kubernetes client + --ssh Use SSH for running kubernetes client on the node ``` ### Options inherited from parent commands