This guide is intended for plugin developers. If you are not developing kubectl plugins, read the User Guide to learn how to use krew.
This guide explains how to package, test, run plugins locally and make them available on the krew index.
Before creating a plugin, read the Kubernetes Plugins documentation.
If you are writing a plugin in Go: Consider using the cli-runtime project which is designed to provide the same command-line arguments, kubeconfig parser, Kubernetes API REST client, and printing logic.
Unofficial Quickstart for Go: For Go plugins, there's a GitHub template repo that implements these best practices and also configures GoReleaser and a GitHub Action to create releases when a tag is pushed. Note: this template repo is not maintained by the Krew project.
Below you will create a small plugin named foo
which prints the environment
variables to the screen and exits.
Read the Naming Guide for choosing a name for your plugin.
Create an executable file named kubectl-foo
with the following contents:
#!/usr/bin/env bash
env
Then make this script executable:
chmod +x ./kubectl-foo
(Since this plugin requires bash
, it will only work on Unix platforms. If you
need to support windows, develop a kubectl-foo.exe
executable.)
Now, if you place this plugin to anywhere in your $PATH
directories, you
should be able to call it like:
kubectl foo
To package a plugin via krew, you need to:
- Develop a plugin and archive it into a
.zip
or.tar.gz
. - Write a plugin manifest file.
- Test installation locally with the archive and the manifest file.
To publish a plugin in krew-index
to make it available via krew, you need to:
- Make the plugin source code publicly available.
- Make the archive file (
.zip
or.tar.gz
) publicly downloadable on a URL (you can host it yourself or use GitHub releases feature). - Submit the plugin manifest file to the krew index repository.
Plugin packages need to be available to download from the public Internet. A service like GitHub Releases is recommended.
Each krew plugin has a "plugin manifest" file that lives in the krew index repository.
This file describes which files krew must copy out of your plugin archive and how to run your plugin. It is also used to determine if an upgrade to your plugin is available and how to install it.
For a plugin named foo
, the plugin manifest file should be named foo.yaml
.
An example manifest for this plugin that runs only on Linux and macOS looks
like this (see krew index for
all plugin manifests):
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: foo # plugin name must match your manifest file name (e.g. foo.yaml)
spec:
version: "v0.0.1" # required, must be in semver format, prefixed with "v"
platforms:
# specify installation script for linux and darwin (macOS)
- selector: # a regular Kubernetes selector
matchExpressions:
- {key: os, operator: In, values: [darwin, linux]}
# url for downloading the package archive:
uri: https://github.com/example/foo/releases/v1.0.zip
# sha256sum of the above archive file:
sha256: "208fde0b9f42ef71f79864b1ce594a70832c47dc5426e10ca73bf02e54d499d0"
# copy the used files out of the zip archive, defaults to `[{from: "*", to: "."}]`
files:
- from: "foo-*/unix/*.sh" # path to the files extracted from archive
to: "." # '.' refers to the root of plugin install directory
- from: "foo-*/LICENSE" # always install your LICENSE file
to: "."
bin: "kubectl-foo" # path to the plugin executable after copying files above
shortDescription: >- # short description gets truncated at ~50 chars
Prints the environment variables.
# (optional) url of the project homepage
homepage: https://github.com/kubernetes-sigs/krew
# (optional) use caveats field to show post-installation recommendations
caveats: |
This plugin needs the following programs:
* env(1)
description: | # should print nicely on standard 80 char wide terminals
This plugin shows all environment variables that get injected when
launching a program as a plugin. You can use this field for longer
description and example usages.
krew makes it possible to install the same plugin on different operating systems
(like windows
, darwin
(macOS), and linux
) and different architectures
(like amd64
, 386
, arm
).
To support multiple platforms, you may need to define multiple platforms
in
the plugin manifest. The selector
field matches to operating systems and
architectures using the keys os
and arch
respectively.
Example: Match to Linux:
platforms:
- selector:
matchLabels:
os: linux
Example: Match to a Linux or macOS platform, any architecture:
...
platforms:
- selector: # A regular Kubernetes label selector
matchExpressions:
- {key: os, operator: In, values: [darwin, linux]}
Example: Match to Windows 64-bit:
platforms:
- selector:
matchLabels:
os: windows
arch: amd64
The possible values for os
and arch
come from the Go runtime. Run
go tool dist list
to see all possible platforms and architectures.
Each operating system may require a different set of files from the archive to
be installed. You can use the files
field in the plugin manifest to specify
which files should be copied into the plugin directory after extracting the
plugin archive.
The files:
list specifies the copy operations (like mv(1) <from> <to>
) to
the files from
the archive to
the installation destination. If the files
list is unspecified, it defaults to [{from: "*", to: "."}]
. Mind that a
wildcard may install more files than desired.
Example: Consider a plugin whose extracted archive looks like
.
├── README.txt
├── README.txt
└── bin
│ └── kubectl-foo-linux
└── kubectl-foo-windows.exe
-
To copy all files in the
bin/
directory of the extracted archive to the root of your plugin, leave out thefiles:
field, which is equivalent tofiles: [{from: "*", to: "."}]
This copies out binaries for both platforms to the installation directory onto the user’s machine, despite only one of them will be used:
. └── krew-foo-windows.exe └── krew-foo-linux
-
For a more fine-grained control, specify each copy operation:
files: - from: bin/*.exe to: .
This will result in the following files in the installation directory:
. └── krew-foo-windows.exe
Each platform
field requires a path to the plugin executable in the plugin's
installation directory.
krew creates a symbolic link to the plugin executable specified in the bin
field in $HOME/.krew/bin/
(which all krew users need to add to their $PATH
).
For example, if your plugin executable is named start-foo.sh
, specify:
platforms:
- bin: "./start-foo.sh"
...
krew will create a symbolic link
named kubectl-foo
(and kubectl-foo.exe
on Windows) to your plugin executable
after installation is complete. The name of the symbolic link comes from the
plugin name.
Note on underscore conversion: If your plugin name contains dashes, krew will automatically convert them to underscores for kubectl to be able to find your plugin.
For example, if your is named
view-logs
and your plugin binary is namedrun.sh
, krew will create a symbolic namedkubectl-view_logs
automatically.
krew plugins must be packaged as .zip
or .tar.gz
archives and should be made
available for download publicly.
Downloading from a URL also requires a checksum of the downloaded content:
uri
: URL to the archive file (.zip
or.tar.gz
)sha256
: sha256 sum of the archive file
platforms:
- uri: https://github.com/barbaz/foo/archive/v1.2.3.zip
sha256: "29C9C411AF879AB85049344B81B8E8A9FBC1D657D493694E2783A2D0DB240775"
...
After you have:
- written your
<PLUGIN>.yaml
- archived your plugin into a
.zip
or.tar.gz
file
you can now test whether your plugin installs correctly on krew by running:
kubectl krew install --manifest=foo.yaml --archive=foo.tar.gz
--manifest
flag specifies a custom manifest rather than picking it up from the default krew index--archive
overrides the downloadurl
specified in the plugin manifest and uses a local file instead.
If the installation fails, run the command with -v=4
flag for verbose logs.
If your installation has succeeded, you should be able to run:
kubectl foo
If you made your archive file available to download on the Internet, run the
same command without --archive
and actually test downloading the file from
url
.
If you need other platforms
definitions that don't match your current machine,
you can use KREW_OS
and/or KREW_ARCH
environment variables. For example,
if you're on a Linux machine, you can test Windows installation with:
KREW_OS=windows krew install --manifest=[...]
After you have tested your plugin, uninstall it with kubectl krew uninstall foo
.
After you have tested that the plugin can be installed and works you should
create a pull request to the Krew Index with your <PLUGIN>.yaml
manifest file.
The new plugin file should be submitted to the plugins/
directory in the
index repository.
After the pull request gets accepted into the main index, the plugin will be available for all users.
Please make sure to include dependencies of your plugin and extra configuration
needed to run the plugin in the caveats:
field.
When you have a newer version of your plugin, create a new pull request that
updates thew version
, uri
and sha256
fields of the plugin manifest file.
Ideally, the version
specified should match the release tag of the plugin.
This helps users and maintainers to easily identify which version of the plugin
they have installed.