mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-09 21:21:14 +00:00
replace contents of docs/devel with stubs
This commit is contained in:
@@ -1,411 +1 @@
|
||||
# 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)
|
||||
- [Rules for extending special resource alias - "all"](#rules-for-extending-special-resource-alias---all)
|
||||
- [Flag conventions](#flag-conventions)
|
||||
- [Output conventions](#output-conventions)
|
||||
- [Documentation conventions](#documentation-conventions)
|
||||
- [Command implementation conventions](#command-implementation-conventions)
|
||||
- [Generators](#generators)
|
||||
|
||||
<!-- END MUNGE: GENERATED_TOC -->
|
||||
|
||||
## 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
|
||||
|
||||
## 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
|
||||
...`
|
||||
|
||||
* 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.
|
||||
|
||||
|
||||
### 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> <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.
|
||||
|
||||
|
||||
### Rules for extending special resource alias - "all"
|
||||
|
||||
Here are the rules to add a new resource to the `kubectl get all` output.
|
||||
|
||||
* No cluster scoped resources
|
||||
|
||||
* No namespace admin level resources (limits, quota, policy, authorization
|
||||
rules)
|
||||
|
||||
* No resources that are potentially unrecoverable (secrets and pvc)
|
||||
|
||||
* Resources that are considered "similar" to #3 should be grouped
|
||||
the same (configmaps)
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
* Flag descriptions should start with an uppercase letter and not have a
|
||||
period at the end of a sentence
|
||||
|
||||
* 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`
|
||||
* `-n`: Namespace scope
|
||||
* `-l`: Label selector
|
||||
* also used for `--labels` in `expose`, but should be deprecated
|
||||
* `-L`: Label columns
|
||||
* `-c`: Container
|
||||
* also used for `--client` in `version`, but should be deprecated
|
||||
* `-i`: Attach stdin
|
||||
* `-t`: Allocate TTY
|
||||
* `-w`: Watch (currently also used for `--www` in `proxy`, but should be deprecated)
|
||||
* `-p`: Previous
|
||||
* also used for `--pod` in `exec`, but deprecated
|
||||
* also used for `--patch` in `patch`, but should be deprecated
|
||||
* also used for `--port` in `proxy`, but should be deprecated
|
||||
* `-P`: Static file prefix in `proxy`, but should be deprecated
|
||||
* `-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
|
||||
|
||||
* `--output-version=...`: Convert the output to a different API group/version
|
||||
|
||||
* `--short`: Output a compact summary of normal output; the format is subject
|
||||
to change and is optimizied for reading not parsing.
|
||||
|
||||
* `--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.
|
||||
|
||||
* 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 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; for
|
||||
external IP, `<nodes>` should be used; for load balancer, `<pending>` 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
|
||||
|
||||
* Short should contain a one-line explanation of what the command does
|
||||
* Short descriptions should start with an uppercase case letter and not
|
||||
have a period at the end of a sentence
|
||||
* Short descriptions should (if possible) start with a first person
|
||||
(singular present tense) verb
|
||||
|
||||
* Long may contain multiple lines, including additional information about
|
||||
input, output, commonly used flags, etc.
|
||||
* Long descriptions should use proper grammar, start with an uppercase
|
||||
letter and have a period at the end of a sentence
|
||||
|
||||
|
||||
* 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 "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:
|
||||
|
||||
* `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:
|
||||
|
||||
```go
|
||||
// MineRecommendedName is the recommended command name for kubectl mine.
|
||||
const MineRecommendedName = "mine"
|
||||
|
||||
// Long command description and examples.
|
||||
var (
|
||||
mineLong = templates.LongDesc(`
|
||||
mine which is described here
|
||||
with lots of details.`)
|
||||
|
||||
mineExample = templates.Examples(`
|
||||
# Run my command's first action
|
||||
kubectl mine first_action
|
||||
|
||||
# Run my command's second action on latest stuff
|
||||
kubectl mine second_action --flag`)
|
||||
)
|
||||
|
||||
// MineConfig contains all the options for running the mine cli command.
|
||||
type MineConfig struct {
|
||||
mineLatest bool
|
||||
}
|
||||
|
||||
// NewCmdMine implements the kubectl mine command.
|
||||
func NewCmdMine(parent, name string, f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
opts := &MineConfig{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: fmt.Sprintf("%s [--latest]", name),
|
||||
Short: "Run my command",
|
||||
Long: mineLong,
|
||||
Example: fmt.Sprintf(mineExample, parent+" "+name),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := opts.Complete(f, cmd, args, out); err != nil {
|
||||
cmdutil.CheckErr(err)
|
||||
}
|
||||
if err := opts.Validate(); err != nil {
|
||||
cmdutil.CheckErr(cmdutil.UsageError(cmd, err.Error()))
|
||||
}
|
||||
if err := opts.RunMine(); err != nil {
|
||||
cmdutil.CheckErr(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVar(&options.mineLatest, "latest", false, "Use latest stuff")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Complete completes all the required options for mine.
|
||||
func (o *MineConfig) Complete(f *cmdutil.Factory, cmd *cobra.Command, args []string, out io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates all the required options for mine.
|
||||
func (o MineConfig) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunMine implements all the necessary functionality for mine.
|
||||
func (o MineConfig) RunMine() error {
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
```go
|
||||
// NamespaceGeneratorV1 supports stable generation of a namespace
|
||||
type NamespaceGeneratorV1 struct {
|
||||
// Name of namespace
|
||||
Name string
|
||||
}
|
||||
|
||||
// Ensure it supports the generator pattern that uses parameters specified during construction
|
||||
var _ StructuredGenerator = &NamespaceGeneratorV1{}
|
||||
|
||||
// StructuredGenerate outputs a namespace object using the configured fields
|
||||
func (g *NamespaceGeneratorV1) StructuredGenerate() (runtime.Object, error) {
|
||||
if err := g.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
namespace := &api.Namespace{}
|
||||
namespace.Name = g.Name
|
||||
return namespace, nil
|
||||
}
|
||||
|
||||
// validate validates required fields are set to support structured generation
|
||||
func (g *NamespaceGeneratorV1) validate() error {
|
||||
if len(g.Name) == 0 {
|
||||
return fmt.Errorf("name must be specified")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
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 -->
|
||||
[]()
|
||||
<!-- END MUNGE: GENERATED_ANALYTICS -->
|
||||
This file has moved to [https://github.com/kubernetes/community/blob/master/contributors/devel/kubectl-conventions.md](https://github.com/kubernetes/community/blob/master/contributors/devel/kubectl-conventions.md)
|
||||
|
Reference in New Issue
Block a user