mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-10 13:42:02 +00:00
devel/ tree 80col updates; and other minor edits
Signed-off-by: Mike Brown <brownwm@us.ibm.com>
This commit is contained in:
@@ -32,14 +32,14 @@ Documentation for other releases can be found at
|
||||
|
||||
<!-- END MUNGE: UNVERSIONED_WARNING -->
|
||||
|
||||
Kubectl Conventions
|
||||
===================
|
||||
# Kubectl Conventions
|
||||
|
||||
Updated: 8/27/2015
|
||||
|
||||
**Table of Contents**
|
||||
<!-- BEGIN MUNGE: GENERATED_TOC -->
|
||||
|
||||
- [Kubectl Conventions](#kubectl-conventions)
|
||||
- [Principles](#principles)
|
||||
- [Command conventions](#command-conventions)
|
||||
- [Create commands](#create-commands)
|
||||
@@ -54,45 +54,89 @@ Updated: 8/27/2015
|
||||
## Principles
|
||||
|
||||
* Strive for consistency across commands
|
||||
|
||||
* Explicit should always override implicit
|
||||
|
||||
* Environment variables should override default values
|
||||
|
||||
* Command-line flags should override default values and environment variables
|
||||
* `--namespace` should also override the value specified in a specified resource
|
||||
|
||||
* `--namespace` should also override the value specified in a specified
|
||||
resource
|
||||
|
||||
## Command conventions
|
||||
|
||||
* Command names are all lowercase, and hyphenated if multiple words.
|
||||
|
||||
* kubectl VERB NOUNs for commands that apply to multiple resource types.
|
||||
|
||||
* Command itself should not have built-in aliases.
|
||||
* NOUNs may be specified as `TYPE name1 name2` or `TYPE/name1 TYPE/name2` or `TYPE1,TYPE2,TYPE3/name1`; TYPE is omitted when only a single type is expected.
|
||||
* Resource types are all lowercase, with no hyphens; both singular and plural forms are accepted.
|
||||
* NOUNs may also be specified by one or more file arguments: `-f file1 -f file2 ...`
|
||||
|
||||
* NOUNs may be specified as `TYPE name1 name2` or `TYPE/name1 TYPE/name2` or
|
||||
`TYPE1,TYPE2,TYPE3/name1`; TYPE is omitted when only a single type is expected.
|
||||
|
||||
* Resource types are all lowercase, with no hyphens; both singular and plural
|
||||
forms are accepted.
|
||||
|
||||
* NOUNs may also be specified by one or more file arguments: `-f file1 -f file2
|
||||
...`
|
||||
|
||||
* Resource types may have 2- or 3-letter aliases.
|
||||
* Business logic should be decoupled from the command framework, so that it can be reused independently of kubectl, cobra, etc.
|
||||
* Ideally, commonly needed functionality would be implemented server-side in order to avoid problems typical of "fat" clients and to make it readily available to non-Go clients.
|
||||
* Commands that generate resources, such as `run` or `expose`, should obey specific conventions, see [generators](#generators).
|
||||
* A command group (e.g., `kubectl config`) may be used to group related non-standard commands, such as custom generators, mutations, and computations.
|
||||
|
||||
* Business logic should be decoupled from the command framework, so that it can
|
||||
be reused independently of kubectl, cobra, etc.
|
||||
* Ideally, commonly needed functionality would be implemented server-side in
|
||||
order to avoid problems typical of "fat" clients and to make it readily
|
||||
available to non-Go clients.
|
||||
|
||||
* Commands that generate resources, such as `run` or `expose`, should obey
|
||||
specific conventions, see [generators](#generators).
|
||||
|
||||
* A command group (e.g., `kubectl config`) may be used to group related
|
||||
non-standard commands, such as custom generators, mutations, and computations.
|
||||
|
||||
|
||||
### Create commands
|
||||
|
||||
`kubectl create <resource>` commands fill the gap between "I want to try Kubernetes, but I don't know or care what gets created" (`kubectl run`) and "I want to create exactly this" (author yaml and run `kubectl create -f`).
|
||||
They provide an easy way to create a valid object without having to know the vagaries of particular kinds, nested fields, and object key typos that are ignored by the yaml/json parser.
|
||||
Because editing an already created object is easier than authoring one from scratch, these commands only need to have enough parameters to create a valid object and set common immutable fields. It should default as much as is reasonably possible.
|
||||
Once that valid object is created, it can be further manipulated using `kubectl edit` or the eventual `kubectl set` commands.
|
||||
`kubectl create <resource>` commands fill the gap between "I want to try
|
||||
Kubernetes, but I don't know or care what gets created" (`kubectl run`) and "I
|
||||
want to create exactly this" (author yaml and run `kubectl create -f`). They
|
||||
provide an easy way to create a valid object without having to know the vagaries
|
||||
of particular kinds, nested fields, and object key typos that are ignored by the
|
||||
yaml/json parser. Because editing an already created object is easier than
|
||||
authoring one from scratch, these commands only need to have enough parameters
|
||||
to create a valid object and set common immutable fields. It should default as
|
||||
much as is reasonably possible. Once that valid object is created, it can be
|
||||
further manipulated using `kubectl edit` or the eventual `kubectl set` commands.
|
||||
|
||||
`kubectl create <resource> <special-case>` commands help in cases where you need to perform non-trivial configuration generation/transformation tailored for a common use case.
|
||||
`kubectl create secret` is a good example, there's a `generic` flavor with keys mapping to files, then there's a `docker-registry` flavor that is tailored for creating an image pull secret,
|
||||
and there's a `tls` flavor for creating tls secrets. You create these as separate commands to get distinct flags and separate help that is tailored for the particular usage.
|
||||
`kubectl create <resource> <special-case>` commands help in cases where you need
|
||||
to perform non-trivial configuration generation/transformation tailored for a
|
||||
common use case. `kubectl create secret` is a good example, there's a `generic`
|
||||
flavor with keys mapping to files, then there's a `docker-registry` flavor that
|
||||
is tailored for creating an image pull secret, and there's a `tls` flavor for
|
||||
creating tls secrets. You create these as separate commands to get distinct
|
||||
flags and separate help that is tailored for the particular usage.
|
||||
|
||||
|
||||
## Flag conventions
|
||||
|
||||
* Flags are all lowercase, with words separated by hyphens
|
||||
* Flag names and single-character aliases should have the same meaning across all commands
|
||||
* Command-line flags corresponding to API fields should accept API enums exactly (e.g., `--restart=Always`)
|
||||
* Do not reuse flags for different semantic purposes, and do not use different flag names for the same semantic purpose -- grep for `"Flags()"` before adding a new flag
|
||||
* Use short flags sparingly, only for the most frequently used options, prefer lowercase over uppercase for the most common cases, try to stick to well known conventions for UNIX commands and/or Docker, where they exist, and update this list when adding new short flags
|
||||
|
||||
* Flag names and single-character aliases should have the same meaning across
|
||||
all commands
|
||||
|
||||
* Command-line flags corresponding to API fields should accept API enums
|
||||
exactly (e.g., `--restart=Always`)
|
||||
|
||||
* Do not reuse flags for different semantic purposes, and do not use different
|
||||
flag names for the same semantic purpose -- grep for `"Flags()"` before adding a
|
||||
new flag
|
||||
|
||||
* Use short flags sparingly, only for the most frequently used options, prefer
|
||||
lowercase over uppercase for the most common cases, try to stick to well known
|
||||
conventions for UNIX commands and/or Docker, where they exist, and update this
|
||||
list when adding new short flags
|
||||
|
||||
* `-f`: Resource file
|
||||
* also used for `--follow` in `logs`, but should be deprecated in favor of `-F`
|
||||
* `-l`: Label selector
|
||||
@@ -111,51 +155,116 @@ and there's a `tls` flavor for creating tls secrets. You create these as separa
|
||||
* `-r`: Replicas
|
||||
* `-u`: Unix socket
|
||||
* `-v`: Verbose logging level
|
||||
* `--dry-run`: Don't modify the live state; simulate the mutation and display the output. All mutations should support it.
|
||||
* `--local`: Don't contact the server; just do local read, transformation, generation, etc., and display the output
|
||||
|
||||
|
||||
* `--dry-run`: Don't modify the live state; simulate the mutation and display
|
||||
the output. All mutations should support it.
|
||||
|
||||
* `--local`: Don't contact the server; just do local read, transformation,
|
||||
generation, etc., and display the output
|
||||
|
||||
* `--output-version=...`: Convert the output to a different API group/version
|
||||
|
||||
* `--validate`: Validate the resource schema
|
||||
|
||||
## Output conventions
|
||||
|
||||
* By default, output is intended for humans rather than programs
|
||||
* However, affordances are made for simple parsing of `get` output
|
||||
|
||||
* Only errors should be directed to stderr
|
||||
|
||||
* `get` commands should output one row per resource, and one resource per row
|
||||
* Column titles and values should not contain spaces in order to facilitate commands that break lines into fields: cut, awk, etc. Instead, use `-` as the word separator.
|
||||
|
||||
* Column titles and values should not contain spaces in order to facilitate
|
||||
commands that break lines into fields: cut, awk, etc. Instead, use `-` as the
|
||||
word separator.
|
||||
|
||||
* By default, `get` output should fit within about 80 columns
|
||||
|
||||
* Eventually we could perhaps auto-detect width
|
||||
* `-o wide` may be used to display additional columns
|
||||
* The first column should be the resource name, titled `NAME` (may change this to an abbreviation of resource type)
|
||||
* NAMESPACE should be displayed as the first column when --all-namespaces is specified
|
||||
|
||||
|
||||
* The first column should be the resource name, titled `NAME` (may change this
|
||||
to an abbreviation of resource type)
|
||||
|
||||
* NAMESPACE should be displayed as the first column when --all-namespaces is
|
||||
specified
|
||||
|
||||
* The last default column should be time since creation, titled `AGE`
|
||||
* `-Lkey` should append a column containing the value of label with key `key`, with `<none>` if not present
|
||||
* json, yaml, Go template, and jsonpath template formats should be supported and encouraged for subsequent processing
|
||||
* Users should use --api-version or --output-version to ensure the output uses the version they expect
|
||||
* `describe` commands may output on multiple lines and may include information from related resources, such as events. Describe should add additional information from related resources that a normal user may need to know - if a user would always run "describe resource1" and the immediately want to run a "get type2" or "describe resource2", consider including that info. Examples, persistent volume claims for pods that reference claims, events for most resources, nodes and the pods scheduled on them. When fetching related resources, a targeted field selector should be used in favor of client side filtering of related resources.
|
||||
* For fields that can be explicitly unset (booleans, integers, structs), the output should say `<unset>`. Likewise, for arrays `<none>` should be used. Lastly `<unknown>` should be used where unrecognized field type was specified.
|
||||
* Mutations should output TYPE/name verbed by default, where TYPE is singular; `-o name` may be used to just display TYPE/name, which may be used to specify resources in other commands
|
||||
|
||||
* `-Lkey` should append a column containing the value of label with key `key`,
|
||||
with `<none>` if not present
|
||||
|
||||
* json, yaml, Go template, and jsonpath template formats should be supported
|
||||
and encouraged for subsequent processing
|
||||
|
||||
* Users should use --api-version or --output-version to ensure the output
|
||||
uses the version they expect
|
||||
|
||||
|
||||
* `describe` commands may output on multiple lines and may include information
|
||||
from related resources, such as events. Describe should add additional
|
||||
information from related resources that a normal user may need to know - if a
|
||||
user would always run "describe resource1" and the immediately want to run a
|
||||
"get type2" or "describe resource2", consider including that info. Examples,
|
||||
persistent volume claims for pods that reference claims, events for most
|
||||
resources, nodes and the pods scheduled on them. When fetching related
|
||||
resources, a targeted field selector should be used in favor of client side
|
||||
filtering of related resources.
|
||||
|
||||
* For fields that can be explicitly unset (booleans, integers, structs), the
|
||||
output should say `<unset>`. Likewise, for arrays `<none>` should be used.
|
||||
Lastly `<unknown>` should be used where unrecognized field type was specified.
|
||||
|
||||
* Mutations should output TYPE/name verbed by default, where TYPE is singular;
|
||||
`-o name` may be used to just display TYPE/name, which may be used to specify
|
||||
resources in other commands
|
||||
|
||||
## Documentation conventions
|
||||
|
||||
* Commands are documented using Cobra; docs are then auto-generated by `hack/update-generated-docs.sh`.
|
||||
* Use should contain a short usage string for the most common use case(s), not an exhaustive specification
|
||||
* Commands are documented using Cobra; docs are then auto-generated by
|
||||
`hack/update-generated-docs.sh`.
|
||||
|
||||
* Use should contain a short usage string for the most common use case(s), not
|
||||
an exhaustive specification
|
||||
|
||||
* Short should contain a one-line explanation of what the command does
|
||||
* Long may contain multiple lines, including additional information about input, output, commonly used flags, etc.
|
||||
|
||||
* Long may contain multiple lines, including additional information about
|
||||
input, output, commonly used flags, etc.
|
||||
|
||||
* Example should contain examples
|
||||
* Start commands with `$`
|
||||
* A comment should precede each example command, and should begin with `#`
|
||||
|
||||
|
||||
* Use "FILENAME" for filenames
|
||||
* Use "TYPE" for the particular flavor of resource type accepted by kubectl, rather than "RESOURCE" or "KIND"
|
||||
|
||||
* Use "TYPE" for the particular flavor of resource type accepted by kubectl,
|
||||
rather than "RESOURCE" or "KIND"
|
||||
|
||||
* Use "NAME" for resource names
|
||||
|
||||
## Command implementation conventions
|
||||
|
||||
For every command there should be a `NewCmd<CommandName>` function that creates the command and returns a pointer to a `cobra.Command`, which can later be added to other parent commands to compose the structure tree. There should also be a `<CommandName>Config` struct with a variable to every flag and argument declared by the command (and any other variable required for the command to run). This makes tests and mocking easier. The struct ideally exposes three methods:
|
||||
For every command there should be a `NewCmd<CommandName>` function that creates
|
||||
the command and returns a pointer to a `cobra.Command`, which can later be added
|
||||
to other parent commands to compose the structure tree. There should also be a
|
||||
`<CommandName>Config` struct with a variable to every flag and argument declared
|
||||
by the command (and any other variable required for the command to run). This
|
||||
makes tests and mocking easier. The struct ideally exposes three methods:
|
||||
|
||||
* `Complete`: Completes the struct fields with values that may or may not be directly provided by the user, for example, by flags pointers, by the `args` slice, by using the Factory, etc.
|
||||
* `Validate`: performs validation on the struct fields and returns appropriate errors.
|
||||
* `Run<CommandName>`: runs the actual logic of the command, taking as assumption that the struct is complete with all required values to run, and they are valid.
|
||||
* `Complete`: Completes the struct fields with values that may or may not be
|
||||
directly provided by the user, for example, by flags pointers, by the `args`
|
||||
slice, by using the Factory, etc.
|
||||
|
||||
* `Validate`: performs validation on the struct fields and returns appropriate
|
||||
errors.
|
||||
|
||||
* `Run<CommandName>`: runs the actual logic of the command, taking as assumption
|
||||
that the struct is complete with all required values to run, and they are valid.
|
||||
|
||||
Sample command skeleton:
|
||||
|
||||
@@ -221,19 +330,41 @@ func (o MineConfig) RunMine() error {
|
||||
}
|
||||
```
|
||||
|
||||
The `Run<CommandName>` method should contain the business logic of the command and as noted in [command conventions](#command-conventions), ideally that logic should exist server-side so any client could take advantage of it. Notice that this is not a mandatory structure and not every command is implemented this way, but this is a nice convention so try to be compliant with it. As an example, have a look at how [kubectl logs](../../pkg/kubectl/cmd/logs.go) is implemented.
|
||||
The `Run<CommandName>` method should contain the business logic of the command
|
||||
and as noted in [command conventions](#command-conventions), ideally that logic
|
||||
should exist server-side so any client could take advantage of it. Notice that
|
||||
this is not a mandatory structure and not every command is implemented this way,
|
||||
but this is a nice convention so try to be compliant with it. As an example,
|
||||
have a look at how [kubectl logs](../../pkg/kubectl/cmd/logs.go) is implemented.
|
||||
|
||||
## Generators
|
||||
|
||||
Generators are kubectl commands that generate resources based on a set of inputs (other resources, flags, or a combination of both).
|
||||
Generators are kubectl commands that generate resources based on a set of inputs
|
||||
(other resources, flags, or a combination of both).
|
||||
|
||||
The point of generators is:
|
||||
* to enable users using kubectl in a scripted fashion to pin to a particular behavior which may change in the future. Explicit use of a generator will always guarantee that the expected behavior stays the same.
|
||||
* to enable potential expansion of the generated resources for scenarios other than just creation, similar to how -f is supported for most general-purpose commands.
|
||||
|
||||
* to enable users using kubectl in a scripted fashion to pin to a particular
|
||||
behavior which may change in the future. Explicit use of a generator will always
|
||||
guarantee that the expected behavior stays the same.
|
||||
|
||||
* to enable potential expansion of the generated resources for scenarios other
|
||||
than just creation, similar to how -f is supported for most general-purpose
|
||||
commands.
|
||||
|
||||
Generator commands shoud obey to the following conventions:
|
||||
* A `--generator` flag should be defined. Users then can choose between different generators, if the command supports them (for example, `kubectl run` currently supports generators for pods, jobs, replication controllers, and deployments), or between different versions of a generator so that users depending on a specific behavior may pin to that version (for example, `kubectl expose` currently supports two different versions of a service generator).
|
||||
* Generation should be decoupled from creation. A generator should implement the `kubectl.StructuredGenerator` interface and have no dependencies on cobra or the Factory. See, for example, how the first version of the namespace generator is defined:
|
||||
|
||||
* A `--generator` flag should be defined. Users then can choose between
|
||||
different generators, if the command supports them (for example, `kubectl run`
|
||||
currently supports generators for pods, jobs, replication controllers, and
|
||||
deployments), or between different versions of a generator so that users
|
||||
depending on a specific behavior may pin to that version (for example, `kubectl
|
||||
expose` currently supports two different versions of a service generator).
|
||||
|
||||
* Generation should be decoupled from creation. A generator should implement the
|
||||
`kubectl.StructuredGenerator` interface and have no dependencies on cobra or the
|
||||
Factory. See, for example, how the first version of the namespace generator is
|
||||
defined:
|
||||
|
||||
```go
|
||||
// NamespaceGeneratorV1 supports stable generation of a namespace
|
||||
@@ -264,8 +395,14 @@ func (g *NamespaceGeneratorV1) validate() error {
|
||||
}
|
||||
```
|
||||
|
||||
The generator struct (`NamespaceGeneratorV1`) holds the necessary fields for namespace generation. It also satisfies the `kubectl.StructuredGenerator` interface by implementing the `StructuredGenerate() (runtime.Object, error)` method which configures the generated namespace that callers of the generator (`kubectl create namespace` in our case) need to create.
|
||||
* `--dry-run` should output the resource that would be created, without creating it.
|
||||
The generator struct (`NamespaceGeneratorV1`) holds the necessary fields for
|
||||
namespace generation. It also satisfies the `kubectl.StructuredGenerator`
|
||||
interface by implementing the `StructuredGenerate() (runtime.Object, error)`
|
||||
method which configures the generated namespace that callers of the generator
|
||||
(`kubectl create namespace` in our case) need to create.
|
||||
|
||||
* `--dry-run` should output the resource that would be created, without
|
||||
creating it.
|
||||
|
||||
|
||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||
|
Reference in New Issue
Block a user