diff --git a/inventory/sample/group_vars/k8s_cluster/addons.yml b/inventory/sample/group_vars/k8s_cluster/addons.yml
index 05d9a4b08b9d2327291322e21fd46965396525a2..cee77d634422a01518c5c8f023bc04e2f2661f4f 100644
--- a/inventory/sample/group_vars/k8s_cluster/addons.yml
+++ b/inventory/sample/group_vars/k8s_cluster/addons.yml
@@ -175,3 +175,7 @@ metallb_enabled: false
 #   - peer_address: 192.0.2.2
 #     peer_asn: 64513
 #     my_asn: 4200000000
+
+# The plugin manager for kubectl
+krew_enabled: false
+krew_root_dir: "/usr/local/krew"
diff --git a/roles/download/defaults/main.yml b/roles/download/defaults/main.yml
index 61005a2fb81e5a8efe3d1b127185548d2f07d172..2c680cf52d94e7ed5b0dc3b7ab6fab2283e2ebf6 100644
--- a/roles/download/defaults/main.yml
+++ b/roles/download/defaults/main.yml
@@ -85,6 +85,7 @@ ovn4nfv_ovn_image_version: "v1.0.0"
 ovn4nfv_k8s_plugin_image_version: "v1.1.0"
 helm_version: "v3.5.4"
 nerdctl_version: "0.8.0"
+krew_version: "v0.4.1"
 
 # Get kubernetes major version (i.e. 1.17.4 => 1.17)
 kube_major_version: "{{ kube_version | regex_replace('^v([0-9])+\\.([0-9]+)\\.[0-9]+', 'v\\1.\\2') }}"
@@ -107,6 +108,7 @@ helm_download_url: "https://get.helm.sh/helm-{{ helm_version }}-linux-{{ image_a
 crun_download_url: "https://github.com/containers/crun/releases/download/{{ crun_version }}/crun-{{ crun_version }}-linux-{{ image_arch }}"
 kata_containers_download_url: "https://github.com/kata-containers/runtime/releases/download/{{ kata_containers_version }}/kata-static-{{ kata_containers_version }}-{{ ansible_architecture }}.tar.xz"
 nerdctl_download_url: "https://github.com/containerd/nerdctl/releases/download/v{{ nerdctl_version }}/nerdctl-{{ nerdctl_version }}-{{ ansible_system | lower }}-{{ image_arch }}.tar.gz"
+krew_download_url: "https://github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew.tar.gz"
 
 crictl_checksums:
   arm:
@@ -336,6 +338,9 @@ calico_crds_archive_checksums:
   v3.17.4: 92b9d37dcebe382a8e43d4384cfcceb5c9bc22459a2f8cdd89ab7c41b09a7532
   v3.16.10: a4627285afe5761a2681452bfcc858ec998ba2dae3060283b81b5ae3f7ea386b
 
+krew_archive_checksums:
+  v0.4.1: a26deea175f70264260d59a4e061778a892f8a8e301ac261660dd7d24c551c99
+
 helm_archive_checksums:
   arm:
     v3.5.4: 1a9cc09ef06db29a0232d265f73625056a0cb089e5a16b0a5ef8e810e0533157
@@ -388,6 +393,7 @@ helm_archive_checksum: "{{ helm_archive_checksums[image_arch][helm_version] }}"
 crun_binary_checksum: "{{ crun_checksums[image_arch][crun_version] }}"
 kata_containers_binary_checksum: "{{ kata_containers_binary_checksums[image_arch][kata_containers_version] }}"
 nerdctl_archive_checksum: "{{ nerdctl_archive_checksums[image_arch][nerdctl_version] }}"
+krew_archive_checksum: "{{ krew_archive_checksums[krew_version] }}"
 
 # Containers
 # In some cases, we need a way to set --registry-mirror or --insecure-registry for docker,
@@ -923,6 +929,19 @@ downloads:
     groups:
     - kube_control_plane
 
+  krew:
+    enabled: "{{ krew_enabled }}"
+    file: true
+    version: "{{ krew_version }}"
+    dest: "{{ local_release_dir }}/krew.tar.gz"
+    sha256: "{{ krew_archive_checksum }}"
+    url: "{{ krew_download_url }}"
+    unarchive: true
+    owner: "root"
+    mode: "0755"
+    groups:
+    - kube_control_plane
+
   registry:
     enabled: "{{ registry_enabled }}"
     container: true
diff --git a/roles/kubernetes-apps/krew/defaults/main.yml b/roles/kubernetes-apps/krew/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d0de6b14f4bd3b9af515f9303fcb15a60094c982
--- /dev/null
+++ b/roles/kubernetes-apps/krew/defaults/main.yml
@@ -0,0 +1,4 @@
+---
+krew_enabled: false
+krew_root_dir: "/usr/local/krew"
+krew_default_index_uri: https://github.com/kubernetes-sigs/krew-index.git
diff --git a/roles/kubernetes-apps/krew/tasks/krew.yml b/roles/kubernetes-apps/krew/tasks/krew.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ebd98212090b36c803c5682b252c63f019820f40
--- /dev/null
+++ b/roles/kubernetes-apps/krew/tasks/krew.yml
@@ -0,0 +1,21 @@
+---
+- name: Krew | Download krew
+  include_tasks: "../../../download/tasks/download_file.yml"
+  vars:
+    download: "{{ download_defaults | combine(downloads.krew) }}"
+
+- name: Krew | krew env
+  template:
+    src: krew.j2
+    dest: /etc/bash_completion.d/krew
+
+- name: Krew | Copy krew manifest
+  template:
+    src: krew.yml.j2
+    dest: "{{ local_release_dir }}/krew.yml"
+
+- name: Krew | Install krew  # noqa 301 305
+  shell: "{{ local_release_dir }}/krew-linux_{{ image_arch }} install --archive={{ local_release_dir }}/krew.tar.gz --manifest={{ local_release_dir }}/krew.yml"
+  environment:
+    KREW_ROOT: "{{ krew_root_dir }}"
+    KREW_DEFAULT_INDEX_URI: "{{ krew_default_index_uri | default('') }}"
diff --git a/roles/kubernetes-apps/krew/tasks/main.yml b/roles/kubernetes-apps/krew/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..40729e88090117cf99bd150a57dd5c643cf944a1
--- /dev/null
+++ b/roles/kubernetes-apps/krew/tasks/main.yml
@@ -0,0 +1,10 @@
+---
+- name: Krew | install krew on kube_control_plane
+  import_tasks: krew.yml
+
+- name: Krew | install krew on localhost
+  import_tasks: krew.yml
+  delegate_to: localhost
+  connection: local
+  run_once: true
+  when: kubectl_localhost
diff --git a/roles/kubernetes-apps/krew/templates/krew.j2 b/roles/kubernetes-apps/krew/templates/krew.j2
new file mode 100644
index 0000000000000000000000000000000000000000..a666f6e2c78623510a2f77af219c667b6927908f
--- /dev/null
+++ b/roles/kubernetes-apps/krew/templates/krew.j2
@@ -0,0 +1,6 @@
+# krew bash env(kubespray)
+export KREW_ROOT="{{ krew_root_dir }}"
+{% if krew_default_index_uri is defined %}
+export KREW_DEFAULT_INDEX_URI='{{ krew_default_index_uri }}'
+{% endif %}
+export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
diff --git a/roles/kubernetes-apps/krew/templates/krew.yml.j2 b/roles/kubernetes-apps/krew/templates/krew.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..9c036a9310948efb3d580544e7d831b470002939
--- /dev/null
+++ b/roles/kubernetes-apps/krew/templates/krew.yml.j2
@@ -0,0 +1,100 @@
+apiVersion: krew.googlecontainertools.github.com/v1alpha2
+kind: Plugin
+metadata:
+  name: krew
+spec:
+  version: "{{ krew_version }}"
+  homepage: https://krew.sigs.k8s.io/
+  shortDescription: Package manager for kubectl plugins.
+  caveats: |
+    krew is now installed! To start using kubectl plugins, you need to add
+    krew's installation directory to your PATH:
+
+      * macOS/Linux:
+        - Add the following to your ~/.bashrc or ~/.zshrc:
+            export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
+        - Restart your shell.
+
+      * Windows: Add %USERPROFILE%\.krew\bin to your PATH environment variable
+
+    To list krew commands and to get help, run:
+      $ kubectl krew
+    For a full list of available plugins, run:
+      $ kubectl krew search
+
+    You can find documentation at
+      https://krew.sigs.k8s.io/docs/user-guide/quickstart/.
+
+  platforms:
+  - uri: https://github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew.tar.gz
+    sha256: {{ krew_archive_checksum }}
+    bin: krew
+    files:
+    - from: ./krew-darwin_amd64
+      to: krew
+    - from: ./LICENSE
+      to: .
+    selector:
+      matchLabels:
+        os: darwin
+        arch: amd64
+  - uri: https://github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew.tar.gz
+    sha256: {{ krew_archive_checksum }}
+    bin: krew
+    files:
+    - from: ./krew-darwin_arm64
+      to: krew
+    - from: ./LICENSE
+      to: .
+    selector:
+      matchLabels:
+        os: darwin
+        arch: arm64
+  - uri: https://github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew.tar.gz
+    sha256: {{ krew_archive_checksum }}
+    bin: krew
+    files:
+    - from: ./krew-linux_amd64
+      to: krew
+    - from: ./LICENSE
+      to: .
+    selector:
+      matchLabels:
+        os: linux
+        arch: amd64
+  - uri: https://github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew.tar.gz
+    sha256: {{ krew_archive_checksum }}
+    bin: krew
+    files:
+    - from: ./krew-linux_arm
+      to: krew
+    - from: ./LICENSE
+      to: .
+    selector:
+      matchLabels:
+        os: linux
+        arch: arm
+  - uri: https://github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew.tar.gz
+    sha256: {{ krew_archive_checksum }}
+    bin: krew
+    files:
+    - from: ./krew-linux_arm64
+      to: krew
+    - from: ./LICENSE
+      to: .
+    selector:
+      matchLabels:
+        os: linux
+        arch: arm64
+  - uri: https://github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew.tar.gz
+    sha256: {{ krew_archive_checksum }}
+    bin: krew.exe
+    files:
+    - from: ./krew-windows_amd64.exe
+      to: krew.exe
+    - from: ./LICENSE
+      to: .
+    selector:
+      matchLabels:
+        os: windows
+        arch: amd64
diff --git a/roles/kubernetes-apps/meta/main.yml b/roles/kubernetes-apps/meta/main.yml
index a3b1f1dfe9125d9ce37f422e8b5482caff387de7..a4faa32ff1a7347b6d49dd50029c9341a3c8eebe 100644
--- a/roles/kubernetes-apps/meta/main.yml
+++ b/roles/kubernetes-apps/meta/main.yml
@@ -10,6 +10,12 @@ dependencies:
     tags:
       - helm
 
+  - role: kubernetes-apps/krew
+    when:
+      - krew_enabled
+    tags:
+      - krew
+
   - role: kubernetes-apps/registry
     when:
       - registry_enabled
diff --git a/roles/kubespray-defaults/defaults/main.yaml b/roles/kubespray-defaults/defaults/main.yaml
index edafbe56745e6621c4b7be38646185985061d533..1546833f55a04f1cdab42a33fbceb78fc4e79da2 100644
--- a/roles/kubespray-defaults/defaults/main.yaml
+++ b/roles/kubespray-defaults/defaults/main.yaml
@@ -340,6 +340,7 @@ dashboard_enabled: false
 
 # Addons which can be enabled
 helm_enabled: false
+krew_enabled: false
 registry_enabled: false
 metrics_server_enabled: false
 enable_network_policy: true
diff --git a/roles/reset/tasks/main.yml b/roles/reset/tasks/main.yml
index 735dd4c320b62906e17814cd6ab55d2cd53f0cb2..848497556b3d79cc2670056315e795b255dbb232 100644
--- a/roles/reset/tasks/main.yml
+++ b/roles/reset/tasks/main.yml
@@ -300,6 +300,7 @@
     - /etc/bash_completion.d/kubectl.sh
     - /etc/bash_completion.d/crictl
     - /etc/bash_completion.d/nerdctl
+    - "{{ krew_root_dir }}"
   ignore_errors: yes
   tags:
     - files
diff --git a/tests/files/packet_centos7-flannel-containerd-addons-ha.yml b/tests/files/packet_centos7-flannel-containerd-addons-ha.yml
index fa5fff1a7129140b1ecc55bb18aa063b5dd3f442..2657cf5d184e83a3e9355d428bf7df3861a625c7 100644
--- a/tests/files/packet_centos7-flannel-containerd-addons-ha.yml
+++ b/tests/files/packet_centos7-flannel-containerd-addons-ha.yml
@@ -10,6 +10,7 @@ kube_network_plugin: flannel
 download_localhost: false
 download_run_once: true
 helm_enabled: true
+krew_enabled: true
 kubernetes_audit: true
 container_manager: containerd
 etcd_events_cluster_enabled: true
diff --git a/tests/files/packet_debian10-containerd.yml b/tests/files/packet_debian10-containerd.yml
index a6725bcb6405814ac4beab6ffc7ad14f18baff7a..d08477a5b0c7463edeaeefdac4db5a8fb396fc62 100644
--- a/tests/files/packet_debian10-containerd.yml
+++ b/tests/files/packet_debian10-containerd.yml
@@ -10,6 +10,7 @@ deploy_netchecker: true
 dns_min_replicas: 1
 
 helm_enabled: true
+krew_enabled: true
 
 # https://gitlab.com/miouge/kubespray-ci/-/blob/a4fd5ed6857807f1c353cb60848aedebaf7d2c94/manifests/http-proxy.yml#L42
 http_proxy: http://172.30.30.30:8888
diff --git a/tests/files/packet_ubuntu18-flannel-containerd-ha-once.yml b/tests/files/packet_ubuntu18-flannel-containerd-ha-once.yml
index 67b0ff963125254c83a7db5a1e015063af8f7ef8..2537168ec56d2e07fef21fcd8c40578a48d11edc 100644
--- a/tests/files/packet_ubuntu18-flannel-containerd-ha-once.yml
+++ b/tests/files/packet_ubuntu18-flannel-containerd-ha-once.yml
@@ -9,6 +9,7 @@ kubeadm_certificate_key: 3998c58db6497dd17d909394e62d515368c06ec617710d02edea31c
 kube_proxy_mode: iptables
 kube_network_plugin: flannel
 helm_enabled: true
+krew_enabled: true
 kubernetes_audit: true
 container_manager: containerd
 etcd_events_cluster_enabled: true
diff --git a/tests/files/packet_ubuntu18-flannel-containerd-ha.yml b/tests/files/packet_ubuntu18-flannel-containerd-ha.yml
index 67b0ff963125254c83a7db5a1e015063af8f7ef8..2537168ec56d2e07fef21fcd8c40578a48d11edc 100644
--- a/tests/files/packet_ubuntu18-flannel-containerd-ha.yml
+++ b/tests/files/packet_ubuntu18-flannel-containerd-ha.yml
@@ -9,6 +9,7 @@ kubeadm_certificate_key: 3998c58db6497dd17d909394e62d515368c06ec617710d02edea31c
 kube_proxy_mode: iptables
 kube_network_plugin: flannel
 helm_enabled: true
+krew_enabled: true
 kubernetes_audit: true
 container_manager: containerd
 etcd_events_cluster_enabled: true