mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-03 23:40:03 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			443 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			443 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
 | 
						|
 | 
						|
<!-- BEGIN STRIP_FOR_RELEASE -->
 | 
						|
 | 
						|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
 | 
						|
     width="25" height="25">
 | 
						|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
 | 
						|
     width="25" height="25">
 | 
						|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
 | 
						|
     width="25" height="25">
 | 
						|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
 | 
						|
     width="25" height="25">
 | 
						|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
 | 
						|
     width="25" height="25">
 | 
						|
 | 
						|
<h2>PLEASE NOTE: This document applies to the HEAD of the source tree</h2>
 | 
						|
 | 
						|
If you are using a released version of Kubernetes, you should
 | 
						|
refer to the docs that go with that version.
 | 
						|
 | 
						|
<!-- TAG RELEASE_LINK, added by the munger automatically -->
 | 
						|
<strong>
 | 
						|
The latest release of this document can be found
 | 
						|
[here](http://releases.k8s.io/release-1.4/docs/devel/kubectl-conventions.md).
 | 
						|
 | 
						|
Documentation for other releases can be found at
 | 
						|
[releases.k8s.io](http://releases.k8s.io).
 | 
						|
</strong>
 | 
						|
--
 | 
						|
 | 
						|
<!-- END STRIP_FOR_RELEASE -->
 | 
						|
 | 
						|
<!-- END MUNGE: UNVERSIONED_WARNING -->
 | 
						|
 | 
						|
# 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
 | 
						|
 | 
						|
* `--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 -->
 |