File: README.md
Krew
Krew is the package manager for kubectl plugins.
What does Krew do?
Krew is a tool that makes it easy to use kubectl
plugins. Krew
helps you discover plugins, install and manage them on your machine. It is
similar to tools like apt, dnf or brew. Today, over 200
kubectl plugins are available on Krew.
- For kubectl users: Krew helps you find, install and manage kubectl plugins
in a consistent way. - For plugin developers: Krew helps you package and distribute your plugins
on multiple platforms and makes them discoverable.
[Documentation][website]
Visit the Krew documentation to find Installation
instructions, User Guide and Developer Guide.
You can follow the Quickstart to get started with Krew.
Contributor Documentation
- Releasing Krew: how to release new version of
Krew. - Plugin Lifecycle: how Krew installs/upgrades
plugins and itself. (Not necessarily up-to-date, but it can give a good idea
about how Krew works under the covers.) - Krew Architecture: architectural decisions
behind designing initial versions of Krew. (Not up-to-date.) - Krew Logo: our logo and branding assets.
Visit ./docs for all documentation.
Roadmap
Please check out the Issue
Tracker to see the plan of
record for new features and changes.
Community
Bug reports
- If you have a problem with the Krew itself, please file an
issue in this repository. - If you're having a problem with a particular plugin's installation or
upgrades, file an issue at krew-index repository. - If you're having an issue with an installed plugin, file an issue for the
repository the plugin's source code is hosted at.
Communication channels
Contributing
Interested in contributing to Krew? Please refer to our
Contributing Guidelines for more details.
Code of Conduct
Participation in the Kubernetes community is governed by the Kubernetes Code
of Conduct.
File: docs/CONTRIBUTOR_GUIDE.md
Contributor Guide
This guide is intended for people who want to start working on krew itself. If
you intend to write a new plugin, see the Developer
Guide instead.
Setting up the environment
Krew is built with go 1.10, but newer versions will do as well.
Most toolchains will expect that the krew repository is on the GOPATH.
To set it up correctly, do
mkdir -p $(go env GOPATH)/src/sigs.k8s.io/krew
cd $(go env GOPATH)/src/sigs.k8s.io/krew
git clone https://github.com/kubernetes-sigs/krew .
git remote set-url origin --push no_push # to avoid pushesUsing macOS for development
The tools provided in the hack folder expect you to use GNU binaries, the easiest way to install them is to use brew
brew install coreutils grep gnu-sedAnd remember to add them to your $PATH to make them your default binaries
export PATH=$(brew --prefix coreutils)/libexec/gnubin:$PATH
export PATH="$(brew --prefix grep)/libexec/gnubin:$PATH"
export PATH="$(brew --prefix gnu-sed)/libexec/gnubin:$PATH"Code style
Krew adheres to standard golang code formatting conventions, and also expects
imports sorted properly.
To automatically format code appropriately, installgoimports via:
go get golang.org/x/tools/cmd/goimportsand run:
goimports -local sigs.k8s.io/krew -w cmd pkg integration_testShell scripts are automatically formatted by shfmt, to install and to validate run:
hack/run-lint.shIf format is in expected format, there will be no output.
Otherwise, problematic scripts will be listed and a command will be
provided to format them:
shfmt -w -i=2 hack/In addition, a boilerplate license header is expected in all source files.
All new code should be covered by tests.
Compiling
Use hack/make-binary.sh to make a binary in out/bin/ for your current
platform. You can use hack/make-binaries.sh to build binaries for all
supported platforms.
Running tests
To run tests locally, the easiest way to get started is with
hack/run-tests.shThis will run all unit tests and code quality tools.
To run a single tool independently of the other code checks, have a look at the
other scripts in hack/.
In addition, there are integration tests to cover high-level krew functionality.
To run integration tests, you will need to build the krew binary beforehand:
hack/make-binary.sh
hack/run-integration-tests.shTesting `krew` in a sandbox
After making changes to krew, you should also check that it behaves as expected.
You can do this without messing up the krew installation on the host system by
setting the KREW_ROOT environment variable.
For example:
mkdir playground
KREW_ROOT="$PWD/playground" krew updateAny changes that krew is going to apply will then be applied in theplayground/ folder, instead of the standard ~/.krew folder.
Testing in a docker sandbox
Alternatively, if the isolation provided by KREW_ROOT is not enough, there is
also a script to run krew in a docker sandbox:
hack/run-in-docker.shFile: docs/DEVELOPER_GUIDE.md
Developer Guide
This page has moved from GitHub to our website:
https://krew.sigs.k8s.io/docs/developer-guide/
File: docs/KREW_ARCHITECTURE.md
Architecture
(This guide is intended for developers of krew.)
:warning: The instructions below are not up to date for krew v0.2+. But this
document is still retained as a reference to highlight some original design
decisions behind Krew.
- Krew Plugins location
- Installation Methods
- Krew Itself as a Plugin
- Note on Potential Changes to Kubectl Plugin System
Krew Plugins location
Kubernetes plugins can be installed to:
${KUBECTL_PLUGINS_PATH}If specified.${XDG_DATA_DIRS}/kubectl/plugins~/.kube/plugins
It's up to the user to specify one of the above options. In this document the
path will be referenced as ~/.kube/plugins. This is not implementation
specific. Krew installs itself in the default plugin directory for the user.
Directory structure
Krew installs plugins in its root path under ~/.krew/store. Each
plugin has a directory with its uncompressed content from the URI.
Kubectl will recursively search the plugin path for plugin.yaml files. The
download directory is a temporary directory which only exists during the
execution of the install or upgrade command. Directory structure:
. ($HOME)
βββ .krew/
βββ bin/
| βββ kubectl-foo
βββ index/
| βββ foo.yaml
| βββ krew.yaml
βββ store/
βββ foo/<sha256>/
| βββ plugin.yaml
| βββ foo.sh
βββ krew/<sha256>/
βββ commands/
| βββ install/
| | βββ plugin.yaml
| βββ upgrade/
| βββ plugin.yaml
βββ krew-install
βββ krew-upgrade
${TMPDIR}/krew/
βββ download/ (This directory is only available during installation and upgrade)
βββ foo/<sha256>/
βββ plugin.yaml
βββ foo.shKrew Index
As a starting point, the index holds information about all available plugins.
The index will be synced to a user machine through git. The user operates on
their local index.
The index exists as a git repository, hosted on GitHub. This allows partial
updates of the index, GPG verification of committers and rollbacks.
Index Structure
The repository will hold a directory of yaml files. Each describes a single
plugin. This directory is called Plugin Manifest. The file name must match with
the plugin name .yaml. To avoid conflicting commands, there
should only be one new top level command for each plugin.
Plugin Manifest File Format
The Plugin Manifest for a plugin itself is a yaml file. It describes the plugin
name, plugin download URI, verification hash and plugin version. Plugin manifest
supports having different installation steps to support incompatible platforms
like Unix systems and Windows.
An example Plugin Manifest file of a plugin "foo", named foo.yaml, can look like this:
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: foo
spec:
platforms:
- uri: https://github.com/barbaz/foo/archive/windows-v0.5.0.tar.gz
sha256: 29C9C411AF879AB85049344B81B8E8A9FBC1D657D493694E2783A2D0DB240775
# This is used during installation. It uses file Globs to copy required files.
files:
- from: "/posix/*"
to: "."
selector: # A regular Kubernetes label selector
matchExpressions:
- {key: os, operator: In, values: [macos, linux]}
- uri: https://github.com/barbaz/foo/archive/windows-v0.5.0.tar.gz
sha256: 29C9C411AF879AB85049344B81B8E8A9FBC1D657D493694E2783A2D0DB240775
files:
- from: "/win/utils"
to: "/utils"
selector:
matchLabels:
os: "windows"
# Version does not follow any conventions and is not functional.
version: "v0.5.0"
shortDesciption: Short description of foo!
This is a long description
it will be shown to elaborate
The plugins purpose.
caveats: |
This plugin needs the following programs:
* fzf
* jq
For a better user experience:
export $TERM=vt220Update Index Locally
To sync the index to the user's machine, krew requires that curl and git is installed on the
host machine. Krew is cloning or pulling the index repository to~/.kube/plugins/krew/index on a krew update. The first pull can take some
time due to a long history, but will be fast on incremental changes. We use git
as a backend because it does already implement downloading, incremental updates
with patches and GPG signing.
Plugin Package Format
The plugin package is found under the download URI in the Plugin Manifest.
Currently, krew only supports downloading plugin packages of formats.tar.gz and .zip over HTTP(S) protocol.
Plugins must meet some standards even though kubectl does allow more. Krew
allows to download repositories and later copy only the needed files to a new
directory using File Globs under .spec.platforms[].files[]. The file field
mimics the posix mv command mv <from> <to>. The "to" field will be defaulted
to ".". (See example manifest for a use case.)
- To allow plugin scans and verification, the plugin.yaml file must be present in
the root directory of the package after the files have been moved. - There should also be only one plugin.yaml in the package.
- The plugin.yaml also has to reference an executable that is not in the parent
repository. - A package also should not contain symlinks.
Installation Methods
Krew itself is also a krew plugin. To reduce the total maintenance and setup
procedure, krew is bootstrapping and dogfooding itself.
The installation on windows and linux works as follows:
- Download the krew binary to a temp path
- Run
krew update - Run
krew install krew - Delete current executed krew from the temp path
Why krew should not rely on OS-Package managers
We canβt easily cover all possible package managers. Trying this introduces a
high maintenance overhead and a huge build pipeline. Maintaining many different
packages can also lead to various errors that need domain knowledge to resolve.
Krew Itself as a Plugin
Kubectl Plugin Descriptor (plugin.yaml) File Generation
Krew should be able to generate its own plugin.yaml files in its build pipeline
to reduce human errors and toil work. As a CLI framework krew should use spf13βs
cobra framework. It is possible to parse the cobra command tree and convert it
into a plugin manifest.
Single Binary
To reduce the amount of disk space we compile krew as a single binary and
generate multiple plugin.yaml files with different entry points to the binary.
The binary then uses argv to determine which subcommand is called.
Note on Potential Changes to Kubectl Plugin System
Kubectl Plugin system is currently alpha and is undergoing a lot of change by
SIG CLI.
We are expecting the following changes may impact Krew heavily: Intention to
move away from plugin.yaml: Community is planning to implement Git plugin model
which does not require a plugin.yaml. Intention to move away from~/.kube/plugins: Community is planning to move a $PATH based discovery, like
the Git plugin system. This way the plugin "foo" would be named "kubectl-foo"
and placed in the $PATH. This will break Krew, but can be addressed through
creating a .../krew/bin directory and symlinking the plugin executables there.
This is very similar to what brew does today.
File: docs/KREW_LOGO.md
Krew logo
Krew logo is designed by @iboonox and it is
licensed under Apache 2.0 license.
Krew logo follows the nautical theme of Kubernetes: The tentacles wrapping
around the crate refer to tentacles of a cuttlefish, which is the mascot of
kubectl project, and the crate
represents a kubectl plugin package.
Available logo types
| Type | Preview |
|---|---|
| Horizontal | |
| Stacked | |
| Icon-only |
Logo assets
| Type | Color Scheme | Format |
|---|---|---|
| horizontal (text next to the icon) | colored | [png] [svg] |
| horizontal (text next to the icon) | black | [png] [svg] |
| horizontal (text next to the icon) | white | [png] [svg] |
| stacked (text below the icon) | colored | [png] [svg] |
| stacked (text below the icon) | black | [png] [svg] |
| stacked (text below the icon) | white | [png] [svg] |
| icon-only | colored | [png] [svg] |
| icon-only | black | [png] [svg] |
| icon-only | white | [png] [svg] |
File: docs/NAMING_GUIDE.md
Plugin Naming Style Guide
This page has moved to our website:
https://krew.sigs.k8s.io/docs/developer-guide/develop/naming-guide/
File: docs/PLUGIN_LIFECYCLE.md
Plugin Lifecycle
(This guide is intended for developers of Krew.)
:warning: The instructions below may not be up to date for krew v0.2 and higher.
It is provided as a reference to learn how Krew works under the covers, but
may not be entirely accurate.
Installation
The plugins will be downloaded and checked against its sha256 to verify the
integrity. The package will be uncompressed into a directory called${TMP}/krew/download//<sha256>/. Then the directory will
be renamed (mv) to ~/.krew/store//<sha256>/.
This ensures a partially atomic and idempotent operation on most file systems.
Upgrade
Upgrading is more difficult because we already have a plugin that is working.
Krew should not destroy a working environment. The operations should be
idempotent. If something fails we should be able to recover to the wanted state.
Upgrading works by iterating over the ~/.krew/store/ directory
names and comparing the current hash to the corresponding index file. When a
hash differs the plugin gets installed again.
Install the plugin:
- Delete the old version
- Therefore itβs not possible for plugins to store
data in the plugin directory.
In case any plugin operation does not succeed the plugin directory is not
damaged under the assumption that mv is atomic. If another plugin
upgrade/install command is issued and a directory in download still exists or
two plugin version directories exist in /store//, krew assumes
that the previous operation failed.
Krew informs the user and retries to reinstall the package.
On Windows it is not possible to modify a file/directory which is currently in
use. This requires a special case for upgrading krew, which itself is a plugin,
from krew. If krew upgrades itself, it is installing itself, instead of deleting
the whole old directory it just deletes the old /commands/ directory witch
holds all the plugin descriptor files.
This way only the new krew version is executed. If krew upgrade is executed
again the old version directory gets deleted.
File: docs/RELEASING_KREW.md
Releasing Krew
(This document is intended for maintainers of Krew only.)
Build/Test the release locally
Build krew release assets locally:
texthack/make-all.shTry krew installation on each platform:
shkrew=out/bin/krew-darwin_amd64 # assuming macOS amd64 for osarch in darwin_amd64 darwin_arm64 linux_amd64 linux_arm linux_arm64 linux_ppc64le windows_amd64; do KREW_ROOT="$(mktemp -d --tmpdir krew-XXXXXXXXXX)" KREW_OS="${osarch%_*}" KREW_ARCH="${osarch#*_}" \ $krew install --manifest=out/krew.yaml --archive="out/krew-${osarch}.tar.gz" done
Release a new version
Krew follows Semantic Versioning 2.0.0.
Krew tags versions starting with v. Example: v0.2.0-rc.1.
Decide on a version number: set it to
$TAGvariable:shTAG=v0.3.2-rc.1 # <- change thisCreate a release commit:
shgit commit -am "Release ${TAG:?TAG required}" --allow-empty git push origin master(Only repository administrators can directly push to master branch.)
Wait until the build succeeds: Wait for CI to show green for the
build of the commit you just pushed to master branch.Tag the release:
textgit tag "${TAG:?TAG required}"Push the tag:
textgit push origin "${TAG:?TAG required}"Verify on Releases tab on GitHub: Make sure
krew.yaml,krew.tar.gz
and other release assets show up on "Releases" tab.Make the new version available on krew index: Get the latest
krew.yamlfromtextcurl -LO https://github.com/kubernetes-sigs/krew/releases/download/"${TAG:?TAG required}"/krew.yamland make a pull request to
krew-index repository.
This will make the plugin available to upgrade for users using older versions
of krew.Update krew-index CI: The CI tests for
krew-indexrepository relies on
tools from mainkrewrepository, and they should use the latest version.
When there's a new version, update.github/workflows/ci.ymlinkrew-indexrepo.
Release artifacts
When a tag is pushed to the repository, GitHub workflow will make a release
on GitHub, and upload the release artifacts as files on the release.
File: docs/USER_GUIDE.md
User Guide
This page has moved from GitHub to our website:
https://krew.sigs.k8s.io/docs/user-guide/