Skip to content

Latest commit

 

History

History
1188 lines (885 loc) · 48 KB

File metadata and controls

1188 lines (885 loc) · 48 KB

KEP-3104: Introduce kuberc

Release Signoff Checklist

Items marked with (R) are required prior to targeting to a milestone / release.

  • (R) Enhancement issue in release milestone, which links to KEP dir in kubernetes/enhancements (not the initial KEP PR)
  • (R) KEP approvers have approved the KEP status as implementable
  • (R) Design details are appropriately documented
  • (R) Test plan is in place, giving consideration to SIG Architecture and SIG Testing input (including test refactors)
    • e2e Tests for all Beta API Operations (endpoints)
    • (R) Ensure GA e2e tests for meet requirements for Conformance Tests
    • (R) Minimum Two Week Window for GA e2e tests to prove flake free
  • (R) Graduation criteria is in place
  • (R) Production readiness review completed
  • (R) Production readiness review approved
  • "Implementation History" section is up-to-date for milestone
  • User-facing documentation has been created in kubernetes/website, for publication to kubernetes.io
  • Supporting documentation—e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes

Summary

This proposal introduces an optional kuberc file that is used to separate cluster credentials and server configuration from user preferences.

Motivation

kubectl is one of the oldest parts of the Kubernetes project and has a strong guarantee on backwards compatibility. We want users to be able to opt in to new behaviors (like delete confirmation) that may be considered breaking changes for existing CI jobs and scripts.

kubeconfig already has a field for preferences that is currently underutilized. The reason for not using this existing field is that creating a new cluster generally yields a new kubeconfig file which contains credentials and host information. While kubeconfigs can be merged and specified by path, we feel there should be a clear separation between server configuration and user preferences.

Additionally, users can split kubeconfig files into various locations, while maintaining a single preference file that will apply no matter which --kubeconfig flag or $KUBECONFIG env var is pointing to.

Goals

  • Introduce a kuberc file as a place for client preferences.
  • Version and structure this file in a way that makes it easy to introduce new behaviors and settings for users.
  • Enable users to define kubectl command aliases.
  • Enable users to define kubectl default options.
  • Deprecate kubeconfig Preferences field.

Non-Goals

Proposal

We propose introducing a new file that will be versioned and intended for user provided preferences. This new file is entirely opt-in.

User Stories (Optional)

Story 1

As a user I would like to specify preferences per client (device) without my kubeconfig overriding them when I access different clusters.

Story 2

As a user I would like to opt in to enforcing delete confirmation or colored output on my local client but not disrupt my CI pipeline with unexpected prompts or output.

https://groups.google.com/g/kubernetes-dev/c/y4Q20V3dyOk

kubernetes/kubectl#524

Story 3

[UNRESOLVED] As a user I would like to use different preferences per context.

Story 4

As a user I would like to be able to opt out of deprecation warnings.

kubernetes/kubectl#1317

Story 5

As a user I would like to be able to prevent the execution of untrusted binaries by the client-go credential plugin system.

Notes/Constraints/Caveats (Optional)

Open Questions

  1. How are subcommands indicated for command overrides?
  2. How are subcommand aliases indicated?
  3. How do we handle tying these settings to cluster contexts?
  4. Do we want this file to live elsewhere i.e. XDG_CONFIG?
  5. How do we execute subcommands and do we want to support variable substitution i.e. $1

Risks and Mitigations

Risk Impact Mitigation
Confusing users with a new config file Low Documentation and education

Design Details

For beta this feature will be enabled by default. However, users can disable it by setting the KUBECTL_KUBERC environment variable to false. Additionally, users can always set the KUBERC environment variable to off, which disables the preference mechanism at any point in time.

By default, the configuration file will be located in ~/.kube/kuberc. A flag will allow overriding this default location with a specific path, for example: kubectl --kuberc /var/kube/rc.

The following top-level keys are proposed, alongside the kubernetes metav1.TypeMeta fields (apiVersion, kind):

  • aliases Allows users to declare their own command aliases, including options and values.
  • defaults Enables users to set default options to be applied to commands.
  • credentialPluginPolicy (available in kubectl.config.k8s.io/v1beta1) Allows users to deny all, alow all, or allow some client-go credential plugins.
  • credentialPluginAllowlist (available in kubectl.config.k8s.io/v1beta1) Enables users to specify criteria for trusting binaries to be executed by the client-go credential plugin system.

aliases will not be permitted to override built-in commands but will take precedence over plugins (builtins -> aliases -> plugins). Any additional options and values will be appended to the end of the aliased command. Users are responsible for defining aliases with this behavior in mind.

defaults is designed based on the principle that all configurable behavior is initially implemented as options. This design decision was made after analyzing the intended behavior and realizing that targeting options effectively addresses the use cases. During command execution, a merge will be occur, with inline overrides taking precedence over the defaults.

apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference

aliases:
  - name: getdbprod
    command: get
    prependArgs:
    - pods
    options:
    - name: labels
      default: what=database
    - name: namespace
      default: us-2-production

defaults:
  - command: apply
    options:
      - name: server-side
        default: "true"
  - command: delete
    options:
      - name: interactive
        default: "true"

credentialPluginPolicy: Allowlist
credentialPluginAllowlist:
    - command: cloudplatform-credential-helper
    - command: custom-credential-script

Kubectl Kuberc Management Command (kubectl kuberc)

In alpha (and initially in beta), users are expected to generate their kuberc files manually. However, this operation is error-prone and cumbersome. The lack of kubectl command which operates on kuberc file makes the adoption of this feature significantly difficult. Therefore, this section proposes new kubectl command, namely kubectl kuberc.

kubectl kuberc is the main command serving as an entry point to the subcommands similar to how kubectl create is designed. Invocation of kubectl kuberc prints the subcommands. Currently, there are two subcommands (but this can be extended in the future, when more functionality is added to kuberc). All the subcommands accept kuberc flag to explicitly specify the kuberc file to be updated. File priority order is the same with kuberc execution:

  • If --kuberc flag is specified, operate on this file
  • If KUBERC environment variable is specified, operate on this file
  • If none, operate on default kuberc (i.e. $HOME/.kube/kuberc).

kubectl kuberc view

kubectl kuberc view subcommand prints the defined kuberc file content in the given format via --output flag (default is yaml).

kubectl kuberc set --section defaults

kubectl kuberc set --section defaults subcommand creates/updates the default values of commands. It has the following flags;

command

kubectl kuberc set --section defaults command validates the presence of the command given via flag --command. This flag can contain subcommands as well. Examples might be --command=apply, --command="create role".

option

--option flag accepts list of options. We may or may not validate the presence of the flag name in the given command. But it is up to user to set the correct default value in correct type. Therefore, default field of the options is arbitrary. Examples might be --option="server-side=true", --option="namespace=test".

Although kuberc supports short versions of flags (e.g. -n test), this flag forces users to enter options in standardized format --option=$flag_name=$flag_value. This gives us the opportunity to standardize kuberc files.

overwrite

By default, this command errors out, if it finds a section of same command and same flag that is executed. --overwrite flag is used to update this section.

kubectl kuberc set --section aliases

kubectl kuberc set --section aliases defines alias definitions of a command and a set of flag options. It has these flags;

name

This required field is to define the name of the alias. This is inherently arbitrary field based on the preferences of the user.

command

kubectl kuberc set --section aliases command validates the presence of the command given via flag --command. This flag can contain subcommands as well. Examples might be --command=apply, --command="create role".

option

--option flag accepts list of options. We may or may not validate the presence of the flag name in the given command. But it is up to user setting the correct default value in correct type. Therefore, default field of the options is arbitrary. Examples might be --option="server-side=true", --option="namespace=test".

Although kuberc supports short versions of flags (e.g. -n test), this flag forces users to enter options in opinionated format --option=$flag_name=$flag_value. This gives us the opportunity to standardize kuberc files.

prependarg

--prependarg is an arbitrary list of strings that accepts anything in a string array format.

appendarg

--appendarg is an arbitrary list of strings that accepts anything in string array format.

kubectl kuberc set --section credentialplugin

kubectl kuberc set --section credentialplugin sets values in the top-level credentialPluginPolicy and credentialPluginPolicyAllowlist fields, according to the given options.

policy

The required --policy flag sets the credential plugin policy. The value must be one of AllowAll, DenyAll, or AllowList (case-insensitive). If --policy=Allowlist is used, it must be accompanied by the --allowlist-entry flag.

allowlist-entry

--allowlist-entry may be supplied one or multiple times if (and only if) the --policy flag is set to Allowlist. In order to build an allowlist with multiple entries, you must supply the flag multiple times. The argument to --allowlist-entry is a list of key=value pairs separated by a comma. In the below example, we add two entries to the allowlist, one with command cloudplatform-credential-helper, and another with command custom-credential-script:

kubectl kuberc set --section credentialplugin \
    --policy=Allowlist \
    --allowlist-entry="command=cloudplatform-credential-helper" \
    --allowlist-entry="command=custom-credential-script"

Allowlist Design Details

credentialPluginAllowlist allows the end-user to provide an array of objects describing required conditions for executing a credential plugin binary. The overall result of a check against the allowlist will be the logical OR of the individual checks against the allowlist's entries. Each allowlist entry MUST have at least one nonempty field describing the conditions required for the plugin's execution. If multiple fields are specified within an entry, the binary in question must meet all of the required conditions in that entry in order to be executed (i.e. they are combined with logical AND).

Each element in the allowlist is a set of criteria; if the binary in question meets all of the criteria in at least one set of criteria, the plugin will be allowed to execute. If no criteria set succeeds after comparing the binary to all sets of criteria, the operation will be immediately aborted and an error returned.

At the outset, the entry object will have only one field, command. The path of the binary specified in the kubeconfig will be compared against that named in the command field. This field may contain a basename, or the full path of a plugin. To ensure an exact match, exec.LookPath will be called on both the command field and the binary named in the kubeconfig. The resulting absolute paths must match. The following table illustrates this:

Scenario PATH= Allowlist command exec.LookPath(allowlist.Command) kubeconfig command exec.LookPath(execConfig.Command) success?
kubeconfig lists full path; my-binary is in both /usr/local/bin and /usr/bin PATH=/usr/local/bin:/usr/bin:<...> my-binary /usr/local/bin/my-binary /usr/bin/my-binary /usr/bin/my-binary false
kubeconfig lists full path; my-binary is only in /usr/local/bin PATH=/usr/local/bin:/usr/bin:<...> my-binary /usr/local/bin/my-binary /usr/bin/my-binary /usr/bin/my-binary false
kubeconfig lists full path; my-binary is only in /usr/bin PATH=/usr/local/bin:/usr/bin:<...> my-binary /usr/bin/my-binary /usr/bin/my-binary /usr/bin/my-binary true
kubeconfig lists full path; my-binary is only in /usr/bin PATH=/usr/local/bin:/usr/bin:<...> /usr/bin/my-binary /usr/bin/my-binary /usr/bin/my-binary /usr/bin/my-binary true
kuberc lists full path; my-binary is only in /usr/bin PATH=/usr/local/bin:/usr/bin:<...> /usr/bin/my-binary /usr/bin/my-binary my-binary /usr/bin/my-binary true
kuberc lists full path; my-binary is in /usr/local/bin PATH=/usr/local/bin:/usr/bin:<...> /usr/bin/my-binary /usr/bin/my-binary my-binary /usr/local/bin/my-binary false
neither lists full path; my-binary is in /usr/bin; equivalent to basename match PATH=/usr/local/bin:/usr/bin:<...> my-binary /usr/bin/my-binary my-binary /usr/bin/my-binary true

If credentialPluginPolicy is set to Allowlist, but a credentialPluginAllowlist is not provided, it will be considered an configuration error. Rather than guess at what the user intended, the operation will be aborted just before the exec call. An error describing the misconfiguration will be returned. This is because the allowlist is a security control, and it is likely the user has made a mistake. Since the output may be long, it would be easy for a security warning to be lost at the beginning of the output. An explicitly empty allowlist (i.e. credentialPluginAllowlist: []), in combination with credentialPluginPolicy: Allowlist will be considered an error for the same reason. The user should instead use credentialPluginPolicy: DisableAll in this case.

Commands that don't create a client, such as kubectl config view will not be affected by the allowlist. Additionally, commands that create but do not use a client (such as commands run with --dry-run) will likewise remain unaffected.

In future updates, other allowlist entry fields MAY be added. Specifically, fields allowing for verification by digest or public key have been discussed. The initial design MUST accommodate such future additions.

note: While kuberc is in beta, name may be used as an alias for command. From 1.36 onward, name will be considered deprecated in favor of command. Because these are security knobs, supplying both name and command will be considered an error until name is removed entirely at promotion to GA.

Test Plan

[x] I/we understand the owners of the involved components may require updates to existing tests to make this code solid enough prior to committing the changes necessary to implement this enhancement.

Prerequisite testing updates

We're planning to expand tests adding:

  • config API fuzzy tests
  • cross API config loading
  • input validation and correctness
  • simple e2e using kuberc
Unit tests
  • k8s.io/kubectl/pkg/cmd/: 2025-05-13 - 57.0%
  • k8s.io/kubectl/pkg/config/: 2025-05-13 - 0.0%
  • k8s.io/kubectl/pkg/kuberc/: 2025-05-13 - 64.5%
Integration tests
e2e tests
  • :

Graduation Criteria

Alpha

  • Initial implementation behind KUBECTL_KUBERC environment variable.

Beta

  • Gather feedback from developers and shape API appropriately.
  • Decide if we want to do support configs per context.

GA

  • Address feedback.

Upgrade / Downgrade Strategy

Version Skew Strategy

This feature will follow the version skew policy of kubectl.

Furthermore, kubectl will be equipped with a mechanism which will allow it to read all past versions of the kuberc file, and pick the latest known one. This mechanism will ensure that users can continue using whatever version of kuberc they started with, unless they are interested in newer feature available only in newer releases.

Production Readiness Review Questionnaire

Feature Enablement and Rollback

How can this feature be enabled / disabled in a live cluster?
  • Feature gate (also fill in values in kep.yaml)
    • Feature gate name:
    • Components depending on the feature gate:
  • Other
    • Describe the mechanism: The environment variable KUBECTL_KUBERC=true.
    • Will enabling / disabling the feature require downtime of the control plane? No.
    • Will enabling / disabling the feature require downtime or reprovisioning of a node? No.
Does enabling the feature change any default behavior?

No.

Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)?

Yes the environment variable can be unset and ~/.kube/kuberc can be removed.

What happens if we reenable the feature if it was previously rolled back?

The new feature is enabled.

Are there any tests for feature enablement/disablement?

Yes, there is a kuberc CLI test, which verifies that --kuberc is used when the KUBECTL_KUBERC is on, and is ignored when it's turned off.

Rollout, Upgrade and Rollback Planning

How can a rollout or rollback fail? Can it impact already running workloads?

Not applicable.

What specific metrics should inform a rollback?

Not applicable.

Were upgrade and rollback tested? Was the upgrade->downgrade->upgrade path tested?

Not applicable.

Is the rollout accompanied by any deprecations and/or removals of features, APIs, fields of API types, flags, etc.?

Not applicable.

Monitoring Requirements

How can an operator determine if the feature is in use by workloads?

Not applicable.

How can someone using this feature know that it is working for their instance?
  • Events
    • Event Reason:
  • API .status
    • Condition name:
    • Other field:
  • Other (treat as last resort)
    • Details: The command will be logged with kubectl -v 2
What are the reasonable SLOs (Service Level Objectives) for the enhancement?

Not applicable.

What are the SLIs (Service Level Indicators) an operator can use to determine the health of the service?

Not applicable.

Are there any missing metrics that would be useful to have to improve observability of this feature?

Dependencies

Does this feature depend on any specific services running in the cluster?

Not applicable.

Scalability

Will enabling / using this feature result in any new API calls?

No.

Will enabling / using this feature result in introducing new API types?

There will be a new type similar to a kubeconfig - not in the API server.

Will enabling / using this feature result in any new calls to the cloud provider?

No.

Will enabling / using this feature result in increasing size or count of the existing API objects?

No.

Will enabling / using this feature result in increasing time taken by any operations covered by existing SLIs/SLOs?

No.

Will enabling / using this feature result in non-negligible increase of resource usage (CPU, RAM, disk, IO, ...) in any components?

No.

Can enabling / using this feature result in resource exhaustion of some node resources (PIDs, sockets, inodes, etc.)?

No.

Troubleshooting

How does this feature react if the API server and/or etcd is unavailable?

kubectl is not resilient to API server unavailability.

What are other known failure modes?

Not applicable.

What steps should be taken if SLOs are not being met to determine the problem?

Not applicable.

Implementation History

  • 2021-06-02: Proposal to add delete confirmation
  • 2022-06-13: This KEP created.
  • 2024-06-07: Update KEP with new env var name and template.
  • 2025-05-13: Update KEP for beta promotion.

Drawbacks

None considered.

Alternatives

None considered.

Infrastructure Needed (Optional)

Not applicable.