Slide 1

Slide 1 text

Building kubectl plugins like a pro Ahmet Alp Balkan @ahmetb

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Outline ● kubectl plugin machinery ● Krew plugin manager ● Writing idiomatic kubectl CLIs ○ Generic CLI flags ○ Resource builder ● Bonus: Favorite kubectl plugins

Slide 4

Slide 4 text

Is this talk just about kubectl? Many non-kubectl CLIs interact with Kubernetes API! ● helm ● istioctl ● karmadactl ● OpenKruise ● openebsctl ● kn (Knative) ● …

Slide 5

Slide 5 text

kubectl plugin machinery

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Krew plugin manager

Slide 9

Slide 9 text

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!

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Developing idiomatic Kubernetes CLIs

Slide 12

Slide 12 text

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 4. Common way of specifying resources: ○ deploy/foo == deployment foo == deployments.v1.apps/foo ○ -f deployment.yaml Writing idiomatic kubectl plugins

Slide 13

Slide 13 text

Generic CLI flags Add all “kubectl options” to your command

Slide 14

Slide 14 text

Initializing a typed Kubernetes client

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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.

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

Working with printers The usual -o=yaml|json|custom-columns|name|... flag you’re familiar with to print objects from your plugin.

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

Left as an exercise to the listener ● Select resources via -f/-k/-R ● Select resources via -l/--selector

Slide 21

Slide 21 text

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).[...]

Slide 22

Slide 22 text

Recommended resources Ivan Velichko (@iximiuz)’s blog + https://github.com/iximiuz/client-go-examples

Slide 23

Slide 23 text

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”

Slide 24

Slide 24 text

Useful kubectl plugins

Slide 25

Slide 25 text

kubectl who-can

Slide 26

Slide 26 text

kubectl get-all Queries all API groups

Slide 27

Slide 27 text

kubectl tree / lineage Show ownerResource hierarchy

Slide 28

Slide 28 text

kubectl foreach / mc Run a command against multiple clusters in parallel.

Slide 29

Slide 29 text

kubectl images

Slide 30

Slide 30 text

kubectl neat / eksporter Tidy up a resource for saving the manifest locally

Slide 31

Slide 31 text

kubectl cond Render resource conditions as table.

Slide 32

Slide 32 text

kubectl blame / fields Show which controller/actor updated which field/when

Slide 33

Slide 33 text

Thank you! tw/gh: @ahmetb 🦋: @ahmet.dev