Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building kubectl plugins like a pro

Building kubectl plugins like a pro

Let’s talk about how to build idiomatic CLI tools that look and feel like kubectl, using the libraries and techniques from SIG CLI. In this talk, we’ll also talk about Krew kubectl plugin manager (a SIG CLI project) and showcase some useful popular plugins.

For almost a decade now, Kubectl has supported a plugin extension mechanism. Today, the Krew plugin manager distributes over 275 open source kubectl plugins that the community uses every day to take their Kubernetes experience to the next level.
In this talk, we will
* Show some techniques and libraries to build your own CLI tools that look and feel like kubectl itself, using some building blocks that SIG CLI provides (that you probably didn’t know about)
* Talk about idioms to pay attention to while building and distributing your own plugins
* Some new features in kubectl plugin machinery introduced in Kubernetes v1.31
* Talk about the brief history of the Krew project, how it got started and became a SIG CLI subproject, how it grew to 275+ plugins
* Showcase some of the cool kubectl plugins from the open source.

Ahmet Alp Balkan

November 12, 2024
Tweet

More Decks by Ahmet Alp Balkan

Other Decks in Technology

Transcript

  1. Developed a few kubectl tools: • kubectx / kubens •

    krew • kubectl tree • kubectl pods-on • kubectl foreach • kubectl cond About me Sr. Staff Engineer at LinkedIn. Prev: • Twitter • Google Cloud • Microsoft Azure
  2. Outline • kubectl plugin machinery • Krew plugin manager •

    Writing idiomatic kubectl CLIs ◦ Generic CLI flags ◦ Resource builder • Bonus: Favorite kubectl plugins
  3. Is this talk just about kubectl? Many non-kubectl CLIs interact

    with Kubernetes API! • helm • istioctl • karmadactl • OpenKruise • openebsctl • kn (Knative) • …
  4. kubectl plugins primer • Introduced in Kubernetes as alpha v1.8

    (2017) • Allows adding new plugins to kubectl ◦ Can’t replace existing commands with a plugin • Place an executable in $PATH named: kubectl-foo ⇒ kubectl foo kubectl-foo-bar ⇒ kubectl foo bar (or kubectl foo-bar) kubectl-foo_bar ⇒ kubectl foo-bar
  5. Normally you can’t shadow the builtin “create” command. But now:

    kubectl-create-couchbase ⇒ kubectl create couchbase Caveat: “kubectl create -h” won’t show your plugin New in v1.31: “create” plugins
  6. Krew (krew.sigs.k8s.io) • Started as an intern project at Google

    in 2018 • Accepted into SIG CLI in 2019 • Maintains a curated plugin list (krew-index) • Distributes 275+ plugins in OSS • Looking for maintainers and plugin curators!
  7. Look and feel like kubectl 1. Same set of CLI

    options (flags) ◦ -n/--namespace/-A/--all-namespaces ◦ -l/--selector 2. Configuration and context awareness ◦ --context flag, reading from the right $KUBECONFIG file (merging, overrides…) 3. Subcommand organization: kubectl <verb> <resource> 4. Common way of specifying resources: ◦ deploy/foo == deployment foo == deployments.v1.apps/foo ◦ -f deployment.yaml Writing idiomatic kubectl plugins
  8. resource.Builder from k8s.io/cli-runtime/pkg/resource! resource.NewBuilder(configFlags) Use positional args (e.g. “pod/foo”, “pods

    foo”): builder.ResourceTypeOrNameArgs(true, os.Args[1:]) or a specific type of resource: builder.ResourceNames("pods", podNames...) Selecting resources
  9. Working with builtin vs dynamic types If you’re only using

    builtin types: builder.WithScheme(scheme.Scheme, …). If you’re working with custom resources: builder.Unstructured() …or register your own scheme.
  10. Multiple namespace sources: 1. -n/--namespace: defaults to “” ◦ but

    in Kubernetes API “” means all namespaces! 2. --all-namespaces/-A: need to define yourself 3. namespace configured for context (kubens) in the ~/.kube/config file (cli-runtime doesn’t help you with this part) Working with namespace flags
  11. Server-side printing As of v1.15 the columns printed and their

    values are decided on the API server. You can get server side printing in your CLIs with request header: Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json
  12. Left as an exercise to the listener • Select resources

    via -f/-k/-R • Select resources via -l/--selector
  13. More tips • If you make a lot of requests,

    adjust client-side rate-limiting: ◦ restConfig.QPS ◦ restConfig.Burst • If you make large list calls, use pagination. ◦ builder.RequestChunksOf(1000).[...]
  14. Recommended resources • Read the cli-runtime/builder pkg • Demo code:

    https://github.com/ahmetb/rejekts-kubectl-demo • Server printer example: “kubectl pods-on” • Resource builder example: “kubectl cond”