krew Documentation

Find and install kubectl plugins

6,965 stars Go Go 1 file Β· ~5,346 tokens #k8s-sig-cli#kubectl#kubectl-plugins
RAW Doc

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

bash
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 pushes

Using 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

bash
brew install coreutils grep gnu-sed

And remember to add them to your $PATH to make them your default binaries

bash
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, install
goimports via:

bash
go get golang.org/x/tools/cmd/goimports

and run:

bash
goimports -local sigs.k8s.io/krew -w cmd pkg integration_test

Shell scripts are automatically formatted by shfmt, to install and to validate run:

bash
hack/run-lint.sh

If 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:

bash
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

bash
hack/run-tests.sh

This 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:

bash
hack/make-binary.sh
hack/run-integration-tests.sh

Testing `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:

bash
mkdir playground
KREW_ROOT="$PWD/playground" krew update

Any changes that krew is going to apply will then be applied in the
playground/ 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:

bash
hack/run-in-docker.sh

File: 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

Kubernetes plugins can be installed to:

  1. ${KUBECTL_PLUGINS_PATH} If specified.
  2. ${XDG_DATA_DIRS}/kubectl/plugins
  3. ~/.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:

text
. ($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.sh

Krew 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:

yaml
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=vt220

Update 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:

  1. Download the krew binary to a temp path
  2. Run krew update
  3. Run krew install krew
  4. 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 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:

  1. Delete the old version
  2. 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

  1. Build krew release assets locally:

    text
    hack/make-all.sh
  2. Try krew installation on each platform:

    sh
    krew=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.

  1. Decide on a version number: set it to $TAG variable:

    sh
    TAG=v0.3.2-rc.1 # <- change this
  2. Create a release commit:

    sh
    git commit -am "Release ${TAG:?TAG required}" --allow-empty
    git push origin master

    (Only repository administrators can directly push to master branch.)

  3. Wait until the build succeeds: Wait for CI to show green for the
    build of the commit you just pushed to master branch.

  4. Tag the release:

    text
    git tag "${TAG:?TAG required}"
  5. Push the tag:

    text
    git push origin "${TAG:?TAG required}"
  6. Verify on Releases tab on GitHub: Make sure krew.yaml, krew.tar.gz
    and other release assets show up on "Releases" tab.

  7. Make the new version available on krew index: Get the latest krew.yaml from

    text
    curl -LO https://github.com/kubernetes-sigs/krew/releases/download/"${TAG:?TAG required}"/krew.yaml

    and make a pull request to
    krew-index repository.
    This will make the plugin available to upgrade for users using older versions
    of krew.

  8. Update krew-index CI: The CI tests for krew-index repository relies on
    tools from main krew repository, and they should use the latest version.
    When there's a new version, update .github/workflows/ci.yml in krew-index repo.

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/