New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal for new kubecfg design (kubectl) #1325
Conversation
Looks awesome.
|
Sam, this is exciting stuff. Comments to follow as I read through more closely. |
I like your idea that
|
Wondering if you had thoughts on how submit might interact with version control. And, if there is parameterization of config, as Joe suggested, does parameter substitution happen before commit or before pushing to k8s? Not stuff that this PR needs to address, but would welcome your thoughts. |
I am aiming towards having all the output of the resource commands be parseable in the sed/awk style, e.g. with consistent and parseable whitespace, but in general I believe the kubecfg resource commands (
I think today kubecfg can parse and export both JSON and YAML, so I'd be fine to keep that. Did you mean something else?
I think we can make it really flexible - you can use one file, many files, recursive directories, do selective updates, etc. Mostly will come down to which style we want to prioritize implementing first. Glad to see that I'm heading in the right direction! |
Probably the latter. If anything looks off or doesn't make sense I would expect the user to just run the command again, just as if they were navigating around the REST API.
|
I think we could support many different workflows. Some people may prefer to have a git repo with all their config and have a git hook on receive which runs kubecfg automatically to synchronize the config state with the cluster. Other people may prefer to run all the synchronizing commands manually but keep a record of all changes in a repo somewhere. I think that if we provide the primitive of "take this file and sync it up with the cluster," people can create their own ways of using it that fit them best. For parameter substitution, we can see what needs there are for templating and see if that's best done in kubecfg or directly in the REST API itself. |
wrt machine readable output: while it is possible to hit the k8s API directly from curl, I'd still recommend we (probably via an option) provide easily parseable output:
We can add it later, of course, but I'd love to keep the awk/sed/grep/cut to a minimum. |
@jbeda Fair enough, that makes sense. We can plan to add something like a --parseable flag later. |
If people are running their clusters with duct tape like sed and awk then we're doing something wrong. kubecfg has a nice -template parameter, we should retain that. |
}, | ||
} | ||
|
||
podsListCmd := &cobra.Command{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cobra.Command looks pretty sweet, but I think we can generate these default subcommands programatically given a few strings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I presume you are referring to the List/Get/Create/Delete subcommands, but each resource (Pod/RC/Minion/Service) may want to customize some subset of the subcommand fields (Use/Short/Long/Run/Flags), and if you parameterize all of them I think you end up just as well off writing out the full subcommands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know for sure, but I suspect all the fancy custom things we might want to do ought to be part of config, which has yet to be written. Not duplicating code seems to be my pet issue :)
Overall comments: the cobra command stuff looks pretty awesome, +1 to that. I do not like the List, Get, etc functions in pkg/kubecfg2, though. |
I'm not super excited about 'rc' as the replica controller abbreviation. it's hard to parse for a first time user. Perhaps we could support both "short" ('rc', 'pd' ...) and long ('replicaController', 'pod', ..) names? |
wrt to 'get' vs 'info', I think I'd prefer 'get' and other restful verbs, because it will help people get used to the restful API, but I can be convinced otherwise. I'm happy to pull rollingupdate out into its own binary. |
I'll make comments on the text before I go look at code. On Mon, Sep 15, 2014 at 5:48 PM, Sam Ghods notifications@github.com wrote:
For concrete example, assume 3 output modes: table, key-value, json" $ clitool -t something $ clitool -k something $ clitool -j something Internally the data can all be stored as key-value, but the varying output
What about a generic "select" operation that evaluates a selector? Like: $ kubecfg -k pods select "user in (thockin)" This pattern could apply to all REST resource types.
What about creating and updating a service?
kubecfg -a="/tmp/foo" pods list -l "foo in (bar)" or do flags have to come
|
out = new(tabwriter.Writer) | ||
out.Init(os.Stdout, 0, 8, 1, '\t', 0) | ||
|
||
kubecfg2Cmd := &cobra.Command{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: just call this "cmds" or "cmdTree" :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FTR it will look less ugly when there isn't a 2 in there... but I changed it to cmds anyways. :)
One additional argument for generating the rest interaction code programmatically: I want to add support for k8s plugins. Therefore, kubecfg needs to be able to deal with resource types that weren't compiled into it. |
A lot of really good points have been brought up in this thread. I want to specifically try and resolve one of them: how kubecfg reconciles with the REST data model. (I am only talking about read operations here (like listing, querying and filtering), not updating config - I think config updates and diffs should match 1:1 with the REST API data model.) If I try and look at the raw JSON dump of a Pod (using the latest v1beta3 spec), I get something like this:
OTOH, if I wanted to do something focused on an easy-to-read output for
Basically, to increase readability and usability, I’m doing a number of things to the original parameters:
But all told, what I’m really doing is creating a new Pod data model, which we can call KubecfgPod for convenience, that has all this information in a more user-friendly format. Now, if all I’m doing is printing this out, this is fine. I could print out the above in the key-value textual output I have above, or I can print it in YAML or JSON, no big deal. But if I want kubecfg to become more advanced with querying and filtering (as has been mentioned by @thockin, @bgrant0607 and @smarterclayton) or even more tightly integrated into config, this becomes problematic. What should people refer to, KubecfgPod fields or Pod fields? If they refer to KubecfgPod fields, we would have to publish it and evolve it side by side with Pod fields, and force people to potentially learn two conflicting models, making config management confusing. If we go with Pod fields, then what they see printed out and how they are querying are at odds. The question is, how do we reconcile ease of use with the kubecfg tool compared to what the API is actually outputting and how config is structured? |
Ease of use is choosing the 5 or 6 most important fields and showing those. You can't be full featured and easy to use. On Thu, Sep 18, 2014 at 7:00 PM, Sam Ghods notifications@github.com wrote:
|
@ghodss This is a very nice proposal and thread. In OpenShift we are in the process of writing the very first skeleton proposals for our end-user CLI[1] and we would like to stay in conformance with the design and technology choices of We are also considering codegangsta/cli for cleaner command definitions, specifically the clear separation of arguments and flags, default values and so on. It does appear to support global flags through One feature I didn't find in any of them is flags that accept a list of predefined values, for example something like: For terminal colors I'm considering fatih/color which allows you to integrate nicely with From @thockin's comments, the idea of output formats looks really powerful specially for scripting. |
I thought about --master but I don't know if that's the right word for an end user command. --server seems more appropriate to me. ----- Original Message -----
|
Unless anyone disagrees, I am following @thockin's plan but without adding back run, stop, resize or rollingupdate (as per @bgrant0607's comments).
I anticipate I may have missed something in how to package a brand new binary (kubectl), so I would appreciate comments on that. But otherwise this should be pretty close to merge. |
return nil, fmt.Errorf("Minion %s not found", id) | ||
} | ||
|
||
// Get all replication controllers whose selectors would would match a given |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: double would
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Done
last comment - we've had a lot of "good idea, do it later" stuff - are you keeping track of it all? Can you file issues? We can make a new category for CLI. |
Yes - once this is merged, I will go through the entire thread and create issues for anything relevant and outstanding. |
Okay, I think I've addressed all current comments. |
|
||
func NewCmdDelete(out io.Writer) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "delete ([-f filename] | (<resource> <id>))", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sub "kind" for "resource" - since "kind" is the JSON field? And if so, same with other commands.
LGTM. Fire in the hole! |
Proposal for new kubecfg design (kubectl)
…-release-4.9 [release-4.9] Bug 2106655: UPSTREAM: 109103: cpu/memory manager containerMap memory leak
_UPDATE: This proposal was reworked many times throughout this PR. I am keeping this parent message the same for historical purposes, but you can find the closest description of the final design in this comment (with the exception that
inspect
becamedescribe
)._Intent
The intent of this pull request is to propose a design for the present and future of kubecfg. The conversation from #1167 was the primary input into this design. The idea is to have kubecfg solve two use cases:
The problem with the current design is that it is too generic to effectively support (1). The proposed redesign enables custom commands per resource (e.g. kubecfg pods, kubecfg services, etc.) but generic subcommands to satisfy (2) (kubecfg submit, kubecfg diff, kubecfg reconcile, etc.).
Proposed set of subcommands
Only a subset of these have been implemented in the attached commit.
kubecfg2
- Parent command.pods
list [<id>]
- List pods in a column-oriented view (see Examples below). By default, the first argument passed in acts as a filter by ID.get <id>
- List info about a pod in a row-oriented view. Designed to show more metadata about a given pod, and over time can be enhanced to make navigating the cluster from a given pod very easy. Currently I'm adding a list of any replication controllers whose selectors match (and therefore who control) the selected pod.delete <id>
- Delete a pod.create [-f <filename>]
- In the future we can accept directories or even data from stdin.rc
- For replication controllers. Happy to use a different abbreviation but replicationControllers seemed too long.list [<id>]
get <id>
- RC'sget
command could become extremely rich. For now I've added Pods Status which queries for pods under this replication controller and shows counts for running, waiting and terminated, but in the future you could do diffs against the controller's PodTemplate and show counts for matching and non-matching pods. You could also show the first 3-4 pod ID's per category and then show <X more ...>, making debugging even easier.create [-f <filename>]
update [-f <filename>]
delete <id>
- I have removed the delete/stop/rm replication controller confusion in favor of justdelete
andresize
, where delete takes an optional --force flag if replicas > 0.resize <id> <replicas>
rollingupdate <controller> <image> <time>
- I've included this here for parity but I would like to propose taking it out. This is the one command that I don't think belongs in kubecfg ... it's too long-running, fraught with edge cases, and in reality would probably want to take more into consideration (like fluctuations in metrics, % of pods that come up successfully, etc.). I think this level of functionality belongs in an independent client that uses the API that can look at more components in the infrastructure than just kubernetes.minions
list [<id>]
get <id>
services
list [<id>]
get <id>
create [-f <filename>]
update [-f <filename>]
delete <id>
resolve <id>
- Just an idea, but it could give you a random IP/port combination to connect to. May be useful for quickly locating a node to test for a given service.submit [<filename>...]
- This command exists to satisfy the second use case above. Reconcile and submit any changes from a given set of config(s), from files or from stdin. If you had an entire directory tree of files that had configs that represented your cluster state, you could use this command to submit them all to either create or update your cluster.diff [<filename>...]
- A dry-run version ofsubmit
.run [-p <port spec>] <image> <replicas> <controller>
- Same as today.Examples
Here is what the current commit produces:
These examples are out of date - see this comment for the latest.
Other notes
get
commands that show a lot of info) may result in lots of queries to the server. There are several ways to handle this: (1) don't consider it an issue, (2) offer a "succinct mode" that tries to do as little as possible and (3) over time backport functionality that is particularly useful directly into apiserver as new API endpoints. Especially with (3), you could consider kubecfg a proving ground for new convenience functionality to see whether it's worth implementing in apiserver directly.File layout
Open Questions
get
is not the best name for above.info
anddetails
are other options but ideas here are welcome.