|
| 1 | +--- |
| 2 | +title: Kubectl Commands In Headers |
| 3 | +authors: |
| 4 | + - "@pwittrock" |
| 5 | +owning-sig: sig-cli |
| 6 | +participating-sigs: |
| 7 | + - sig-api-machinery |
| 8 | +reviewers: |
| 9 | + - "@deads2k" |
| 10 | + - "@kow3ns" |
| 11 | + - "@lavalamp" |
| 12 | +approvers: |
| 13 | + - "@seans3" |
| 14 | + - "@soltysh" |
| 15 | +editor: TBD |
| 16 | +creation-date: 2019-02-22 |
| 17 | +last-updated: 2019-02-22 |
| 18 | +status: implementable |
| 19 | +see-also: |
| 20 | +replaces: |
| 21 | +superseded-by: |
| 22 | +--- |
| 23 | + |
| 24 | +# kubectl-commands-in-headers |
| 25 | + |
| 26 | + |
| 27 | +## Table of Contents |
| 28 | + |
| 29 | +A table of contents is helpful for quickly jumping to sections of a KEP and for highlighting any additional information provided beyond the standard KEP template. |
| 30 | +[Tools for generating][] a table of contents from markdown are available. |
| 31 | + |
| 32 | +- [Table of Contents](#table-of-contents) |
| 33 | +- [Release Signoff Checklist](#release-signoff-checklist) |
| 34 | +- [Summary](#summary) |
| 35 | +- [Motivation](#motivation) |
| 36 | +- [Goals](#goals) |
| 37 | +- [Non-Goals](#non-goals) |
| 38 | +- [Proposal](#proposal) |
| 39 | +- [Risks and Mitigations](#risks-and-mitigations) |
| 40 | +- [Design Details](#design-details) |
| 41 | +- [Test Plan](#test-plan) |
| 42 | +- [Implementation History](#implementation-history) |
| 43 | + |
| 44 | +[Tools for generating]: https://github.com/ekalinin/github-markdown-toc |
| 45 | + |
| 46 | +## Release Signoff Checklist |
| 47 | + |
| 48 | +- [x] kubernetes/enhancements issue in release milestone, which links to KEP (this should be a link to the KEP location in kubernetes/enhancements, not the initial KEP PR) |
| 49 | + - [#859](https://github.com/kubernetes/enhancements/issues/859) |
| 50 | +- [x] KEP approvers have set the KEP status to `implementable` |
| 51 | +- [x] Design details are appropriately documented |
| 52 | +- [x] Test plan is in place, giving consideration to SIG Architecture and SIG Testing input |
| 53 | + - Standard Unit and Integration testing should be sufficient |
| 54 | +- [x] Graduation criteria is in place |
| 55 | + - This is not a user facing API change |
| 56 | +- [ ] "Implementation History" section is up-to-date for milestone |
| 57 | +- [ ] User-facing documentation has been created in [kubernetes/website], for publication to [kubernetes.io] |
| 58 | +- [ ] Supporting documentation e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes |
| 59 | + |
| 60 | +[kubernetes.io]: https://kubernetes.io/ |
| 61 | +[kubernetes/enhancements]: https://github.com/kubernetes/enhancements/issues |
| 62 | +[kubernetes/kubernetes]: https://github.com/kubernetes/kubernetes |
| 63 | +[kubernetes/website]: https://github.com/kubernetes/website |
| 64 | + |
| 65 | +## Summary |
| 66 | + |
| 67 | +Requests sent to the apiserver from kubectl already include a User Agent header with |
| 68 | +information about the kubectl build. This KEP proposes sending http request headers |
| 69 | +with additional context about the kubectl command that created the request. |
| 70 | +This information may be used by operators of clusters for debugging or |
| 71 | +to gather telemetry about how users are interacting with the cluster. |
| 72 | + |
| 73 | + |
| 74 | +## Motivation |
| 75 | + |
| 76 | +Kubectl generates requests sent to the apiserver for commands such as `apply`, `delete`, `edit`, `run`, however |
| 77 | +the context of the command for the requests is lost and unavailable to cluster administrators. Context would be |
| 78 | +useful to cluster admins both for debugging the cause of requests as well as providing telemetry about how users |
| 79 | +are interacting with the cluster, which could be used for various purposes. |
| 80 | + |
| 81 | +### Goals |
| 82 | + |
| 83 | +- Allow cluster administrators to identify how requests in the logs were generated from |
| 84 | + kubectl commands. |
| 85 | + |
| 86 | +Possible applications of this information may include but are not limited to: |
| 87 | + |
| 88 | +- Organizations could learn how users are interacting will their clusters to inform what internal |
| 89 | + tools they build and invest in or what gaps they may need to fill. |
| 90 | +- Organizations could identify if users are running deprecated commands that will be removed |
| 91 | + when the version of kubectl is upgraded. They could do this before upgrading kubectl. |
| 92 | + - SIG-CLI could build tools that cluster admins run and perform this analysis |
| 93 | + to them to help with understanding whether they will be impacted by command deprecation |
| 94 | +- Organizations could identify if users are running kubectl commands that are inconsistent with |
| 95 | + the organization's internal best practices and recommendations. |
| 96 | +- Organizations could voluntarily choose to bring back high-level learnings to SIG-CLI regarding |
| 97 | + which and how commands are used. This could be used by the SIG to inform where to invest resources |
| 98 | + and whether to deprecate functionality that has proven costly to maintain. |
| 99 | +- Cluster admins debugging odd behavior caused by users running kubectl may more easily root cause issues |
| 100 | + (e.g. knowing what commands were being run could make identifying miss-behaving scripts easier) |
| 101 | +- Organizations could build dashboards visualizing which kubectl commands where being run |
| 102 | + against clusters and when. This could be used to identify broader usage patterns within the |
| 103 | + organization. |
| 104 | + |
| 105 | + |
| 106 | +### Non-Goals |
| 107 | + |
| 108 | +*The following are not goals of this KEP, but could be considered in the future.* |
| 109 | + |
| 110 | +- Supply Headers for requests made by kubectl plugins. Enforcing this would not be trivial. |
| 111 | +- Send Headers to the apiserver for kubectl command invocations that don't make requests - |
| 112 | + e.g. `--dry-run` |
| 113 | + |
| 114 | +### Anti-Goals |
| 115 | + |
| 116 | +*The following should be actively discouraged.* |
| 117 | + |
| 118 | +- Make decisions of any sort in the apiserver based on these headers. |
| 119 | + - This information is intended to be used by humans for the purposes of developing a better understanding |
| 120 | + of kubectl usage with their clusters, such as **for debugging and telemetry**. |
| 121 | + |
| 122 | +## Proposal |
| 123 | + |
| 124 | +Include in http requests made from kubectl to the apiserver: |
| 125 | + |
| 126 | +- the kubectl subcommand |
| 127 | +- which flags were specified as well as whitelisted enum values for flags (never arbitrary values) |
| 128 | +- a generated session id |
| 129 | +- never include the flag values directly, only use a predefined enumeration |
| 130 | +- never include arguments to the commands, only the sub commands themselves |
| 131 | +- if the command is deprecated, add a header including when which release it will be removed in (if known) |
| 132 | +- allow users and organizations that compile their own kubectl binaries to define a build metadata header |
| 133 | + |
| 134 | +### X-Kubectl-Command Header |
| 135 | + |
| 136 | +The `X-Kubectl-Command` Header contains the kubectl sub command. |
| 137 | + |
| 138 | +It contains the path to the subcommand (e.g. `create secret tls`) to disambiguate sub commands |
| 139 | +that might have the same name and different paths. |
| 140 | + |
| 141 | +Examples: |
| 142 | + |
| 143 | +- `X-Kubectl-Command: apply` |
| 144 | +- `X-Kubectl-Command: create secret tls` |
| 145 | +- `X-Kubectl-Command: delete` |
| 146 | +- `X-Kubectl-Command: get` |
| 147 | + |
| 148 | +### X-Kubectl-Flags Header |
| 149 | + |
| 150 | +The `X-Kubectl-Flags` Header contains a list of the kubectl flags that were provided to the sub |
| 151 | +command. It does *not* contain the raw flag values, but may contain enumerations for |
| 152 | +whitelisted flag values. (e.g. for `-f` it may contain whether a local file, stdin, or remote file |
| 153 | +was provided). It does not normalize into short or long form. If a flag is |
| 154 | +provided multiple times it will appear multiple times in the list. Flags are sorted |
| 155 | +alpha-numerically and separated by a ',' to simplify human readability. |
| 156 | + |
| 157 | +Examples: |
| 158 | + |
| 159 | +- `X-Kubectl-Flags: --filename=local,--recursive,--context` |
| 160 | +- `X-Kubectl-Flags: -f=local,-f=local,-f=remote,-R` |
| 161 | +- `X-Kubectl-Flags: -f=stdin` |
| 162 | +- `X-Kubectl-Flags: --dry-run,-o=custom-columns` |
| 163 | + |
| 164 | +#### Enumerated Flag Values |
| 165 | + |
| 166 | +- `-f`, `--filename`: `local`, `remote`, `stdin` |
| 167 | +- `-o`, `--output`: `json`,`yaml`,`wide`,`name`,`custom-columns`,`custom-columns-file`,`go-template`,`go-template-file`,`jsonpath`,`jsonpath-file` |
| 168 | +- `--type` (for patch subcommand): `json`, `merge`, `strategic` |
| 169 | + |
| 170 | +### X-Kubectl-Session Header |
| 171 | + |
| 172 | +The `X-Kubectl-Session` Header contains a Session ID that can be used to identify that multiple |
| 173 | +requests which were made from the same kubectl command invocation. The Session Header is generated |
| 174 | +once and used for all requests for each kubectl process. |
| 175 | + |
| 176 | +- `X-Kubectl-Session: 67b540bf-d219-4868-abd8-b08c77fefeca` |
| 177 | + |
| 178 | +### X-Kubectl-Deprecated Header |
| 179 | + |
| 180 | +The `X-Kubectl-Deprecated` Header is set to inform cluster admins that the command being run |
| 181 | +has been deprecated. This may be used by organizations to determine if they are likely |
| 182 | +to be impacted by command deprecation and removal before they upgrade. |
| 183 | + |
| 184 | +The `X-Kubectl-Deprecated` Header is set if the command that was run is marked as deprecated. |
| 185 | + |
| 186 | +- The Header may have a value of `true` if the command has been deprecated, but has no removal date. |
| 187 | +- The Header may have a value of a specific Kubernetes release. If it does, this is the release |
| 188 | + that the command will be removed in. |
| 189 | + |
| 190 | +- `X-Kubectl-Deprecated: true` |
| 191 | +- `X-Kubectl-Deprecated: v1.16` |
| 192 | + |
| 193 | + |
| 194 | +### X-Kubectl-Build Header |
| 195 | + |
| 196 | +The `X-Kubectl-Build` Header may be set by building with a specific `-ldflags` value. By default the Header |
| 197 | +is unset, but may be set if kubectl is built from source, forked, or vendored into another command. |
| 198 | +Organizations that distribute one or more versions of kubectl which they maintain internally may |
| 199 | +set a flag at build time and this header will be populated with the value. |
| 200 | + |
| 201 | +- `X-Kubectl-Build: some-value` |
| 202 | + |
| 203 | +### Example |
| 204 | + |
| 205 | +```sh |
| 206 | +$ kubectl apply -f - -o yaml |
| 207 | +``` |
| 208 | + |
| 209 | +``` |
| 210 | +X-Kubectl-Command: apply |
| 211 | +X-Kubectl-Flags: -f=stdin,-o=yaml |
| 212 | +X-Kubectl-Session: 67b540bf-d219-4868-abd8-b08c77fefeca |
| 213 | +``` |
| 214 | + |
| 215 | + |
| 216 | +```sh |
| 217 | +$ kubectl apply -f ./local/file -o=custom-columns=NAME:.metadata.name |
| 218 | +``` |
| 219 | + |
| 220 | +``` |
| 221 | +X-Kubectl-Command: apply |
| 222 | +X-Kubectl-Flags: -f=local,-o=custom-columns |
| 223 | +X-Kubectl-Session: 0087f200-3079-458e-ae9a-b35305fb7432 |
| 224 | +``` |
| 225 | + |
| 226 | +```sh |
| 227 | +kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new |
| 228 | +image"}]' |
| 229 | +``` |
| 230 | + |
| 231 | +``` |
| 232 | +X-Kubectl-Command: patch |
| 233 | +X-Kubectl-Flags: --type=json,-p |
| 234 | +X-Kubectl-Session: 0087f200-3079-458e-ae9a-b35305fb7432 |
| 235 | +``` |
| 236 | + |
| 237 | + |
| 238 | +```sh |
| 239 | +kubectl run nginx --image nginx |
| 240 | +``` |
| 241 | + |
| 242 | +``` |
| 243 | +X-Kubectl-Command: run |
| 244 | +X-Kubectl-Flags: --image |
| 245 | +X-Kubectl-Session: 0087f200-3079-458e-ae9a-b35305fb7432 |
| 246 | +X-Kubectl-Deprecated: true |
| 247 | +``` |
| 248 | + |
| 249 | +### Risks and Mitigations |
| 250 | + |
| 251 | +Unintentionally including sensitive information in the request headers - such as local directory paths |
| 252 | +or cluster names. This won't be a problem as the command arguments and flag values are never directly |
| 253 | +included. |
| 254 | + |
| 255 | +## Design Details |
| 256 | + |
| 257 | +### Test Plan |
| 258 | + |
| 259 | +- Verify the Command Header is sent for commands and has the correct value |
| 260 | +- Verify the Flags Header is sent for flags and has the correct value |
| 261 | +- Verify the Session Header is sent for the Session and has a legitimate value |
| 262 | +- Verify the Deprecation Header is sent for the deprecated commands and has the correct value |
| 263 | +- Verify the Build Header is sent when the binary is built with the correct ldflags value |
| 264 | + specified and has the correct value |
| 265 | + |
| 266 | +### Graduation Criteria |
| 267 | + |
| 268 | +- Determine if additional information would be valuable to operators of clusters. |
| 269 | +- Consider building and publishing tools for cluster operators to run which make use of the data |
| 270 | + - Look for deprecated command invocations |
| 271 | + - Build graphs of usage |
| 272 | + - Identify most used commands |
| 273 | + |
| 274 | +### Upgrade / Downgrade Strategy |
| 275 | + |
| 276 | +NA |
| 277 | + |
| 278 | +### Version Skew Strategy |
| 279 | + |
| 280 | +NA |
| 281 | + |
| 282 | +## Implementation History |
| 283 | + |
| 284 | + |
0 commit comments