Prerequisites
Before installing kubectl-mtv, ensure your environment meets the following requirements:
System Requirements
- Operating System: Linux, macOS, or Windows (Linux and macOS are primarily supported)
- Architecture: amd64 (x86_64) and arm64 architectures supported
Kubernetes Environment
- Kubernetes Cluster: Version 1.23 or higher
- Forklift/MTV Installation: Either upstream Forklift or downstream Migration Toolkit for Virtualization (MTV) must be installed in your cluster
- kubectl: Latest stable version installed and configured to access your cluster
- Cluster Access: Appropriate RBAC permissions to access MTV/Forklift resources
Development Prerequisites (Method 4 Only)
If building from source, you’ll need:
- Go: Version 1.24 or higher (current requirement based on go.mod)
- Git: For cloning the repository
- Make: For using the build system
Installation Methods
Method 1: Quick Install Script (Recommended)
Download the latest release, verify its checksum, install the binary and shell completion helpers:
1
curl -sSL https://raw.githubusercontent.com/yaacov/kubectl-mtv/main/install.sh | bash
By default the script installs to ~/.local/bin. Override with environment variables:
1
2
3
4
5
# Install a specific version
curl -sSL https://raw.githubusercontent.com/yaacov/kubectl-mtv/main/install.sh | VERSION=v0.1.0 bash
# Install to a different directory
curl -sSL https://raw.githubusercontent.com/yaacov/kubectl-mtv/main/install.sh | INSTALL_DIR=/usr/local/bin bash
Note: System directories like /usr/local/bin may require elevated permissions. Either prefix the command with sudo or use a user-writable directory such as INSTALL_DIR=$HOME/bin.
The script installs three files:
| File | Purpose |
|---|---|
kubectl-mtv |
Main binary (kubectl plugin) |
kubectl_complete-mtv |
Shell completion helper for kubectl mtv |
oc_complete-mtv |
Shell completion helper for oc mtv |
If the install directory is not in your PATH, the script prints instructions for adding it.
Method 2: Krew Plugin Manager
Krew is the kubectl plugin manager. If you already use Krew, you can install kubectl-mtv through it. See the Krew installation guide if you don’t have Krew yet.
1
2
3
4
kubectl krew install mtv
# Verify installation
kubectl mtv --help
Note: Available for Linux (amd64, arm64), macOS (amd64, arm64), and Windows (amd64). Krew does not set up shell completion helpers automatically; see the Shell Completion section below.
Method 3: Downloading Release Binaries
Download pre-built binaries directly from the GitHub Releases page. Archives are available for:
| OS | Architecture | Archive |
|---|---|---|
| Linux | amd64 | kubectl-mtv-VERSION-linux-amd64.tar.gz |
| Linux | arm64 | kubectl-mtv-VERSION-linux-arm64.tar.gz |
| macOS | amd64 | kubectl-mtv-VERSION-darwin-amd64.tar.gz |
| macOS | arm64 | kubectl-mtv-VERSION-darwin-arm64.tar.gz |
| Windows | amd64 | kubectl-mtv-VERSION-windows-amd64.zip |
Extract and install:
Linux / macOS:
1
2
3
4
5
6
VERSION=v0.1.0 # replace with desired version
OS=darwin # linux or darwin
ARCH=arm64 # amd64 or arm64
tar -xzf kubectl-mtv-${VERSION}-${OS}-${ARCH}.tar.gz
install -m 0755 kubectl-mtv-${OS}-${ARCH} ~/.local/bin/kubectl-mtv
Windows (PowerShell):
1
2
3
4
5
6
$VERSION = "v0.1.0" # replace with desired version
$ARCH = "amd64"
Expand-Archive "kubectl-mtv-${VERSION}-windows-${ARCH}.zip" -DestinationPath .
New-Item -ItemType Directory -Force "$HOME\.local\bin" | Out-Null
Move-Item "kubectl-mtv-windows-${ARCH}.exe" "$HOME\.local\bin\kubectl-mtv.exe"
Method 4: Building from Source
For development, customization, or platforms without pre-built binaries.
Step 1: Install Prerequisites
On Ubuntu/Debian:
1
2
3
4
5
6
7
8
# Install Go 1.24+
wget https://go.dev/dl/go1.24.7.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.24.7.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
# Install build tools
sudo apt-get update
sudo apt-get install git make
On Fedora/RHEL:
1
2
3
4
5
# Install Go and build tools
sudo dnf install golang git make
# Verify Go version
go version # Should be 1.24+
On macOS:
1
2
3
4
5
# Using Homebrew
brew install go git
# Verify Go version
go version # Should be 1.24+
Step 2: Build the Binary
1
2
3
4
5
6
7
8
9
10
11
12
# Clone the repository
git clone https://github.com/yaacov/kubectl-mtv.git
cd kubectl-mtv
# Build the binary
make
# Install to GOPATH/bin (ensure it's in your PATH)
cp kubectl-mtv $(go env GOPATH)/bin/
# Or install to /usr/local/bin
sudo cp kubectl-mtv /usr/local/bin/
Step 3: Build Static Binary (Optional)
The default build already produces static binaries (CGO is disabled), but you can verify:
1
2
3
4
5
# The default make already creates a static binary
make
# Verify it's statically linked
ldd kubectl-mtv # Should show "not a dynamic executable"
Cross-compilation
Build for different platforms:
1
2
3
4
5
6
7
8
9
10
11
12
# Build for different platforms
make build-linux-amd64
make build-linux-arm64
make build-darwin-amd64
make build-darwin-arm64
make build-windows-amd64
# Build all platforms
make build-all
# Create distribution archives
make dist-all
Verification and Configuration
Basic Verification
After installation, verify that kubectl-mtv is working correctly:
1
2
3
4
5
6
7
8
9
10
11
# Check if kubectl recognizes the plugin
kubectl plugin list | grep mtv
# Test the plugin
kubectl mtv version
# Check help and available commands
kubectl mtv --help
# List available subcommands
kubectl mtv
Expected output should show the version information and available commands.
Shell Completion
Enable tab completion for commands, flags, and resource names. Setup depends on how you invoke the tool.
As a kubectl / oc plugin (kubectl mtv <TAB> or oc mtv <TAB>)
kubectl 1.26+ and oc 4.x delegate completion to plugins, but they expect a helper
executable named kubectl_complete-mtv or oc_complete-mtv (note the
underscore) to be in your PATH. Create them once:
1
2
3
4
5
6
7
d="$(dirname "$(which kubectl-mtv)")"
cat > "$d/kubectl_complete-mtv" << 'SCRIPT'
#!/usr/bin/env bash
kubectl-mtv __complete "$@"
SCRIPT
chmod +x "$d/kubectl_complete-mtv"
ln -sf "$d/kubectl_complete-mtv" "$d/oc_complete-mtv"
As a standalone binary (kubectl-mtv <TAB>)
If you invoke the binary directly as kubectl-mtv, install its own completion
script.
Bash:
1
d="$(pkg-config --variable=completionsdir bash-completion 2>/dev/null || echo "${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions")" && mkdir -p "$d" && kubectl-mtv completion bash > "$d/kubectl-mtv"
Or source it manually in the current session:
1
source <(kubectl-mtv completion bash)
Zsh:
1
d="${fpath[1]:-${XDG_DATA_HOME:-$HOME/.local/share}/zsh/completions}" && mkdir -p "$d" && kubectl-mtv completion zsh > "$d/_kubectl-mtv"
If completions don’t appear, ensure the directory is in your fpath and run compinit:
1
2
echo 'fpath=(~/.local/share/zsh/completions $fpath)' >> ~/.zshrc
echo 'autoload -Uz compinit && compinit' >> ~/.zshrc
Fish:
1
kubectl-mtv completion fish > ~/.config/fish/completions/kubectl-mtv.fish
Kubeconfig Configuration
kubectl-mtv uses the same kubeconfig as kubectl. Ensure your kubeconfig is properly configured:
1
2
3
4
5
6
7
8
9
10
11
12
# Check current context
kubectl config current-context
# List available contexts
kubectl config get-contexts
# Switch context if needed
kubectl config use-context <your-context>
# Verify cluster connectivity
kubectl cluster-info
kubectl get nodes
Global Flags Reference
kubectl-mtv provides several global flags that can be used with any command:
Kubernetes Connection Flags
These flags are inherited from kubectl and control cluster connectivity:
--kubeconfig string: Path to kubeconfig file (default:$HOME/.kube/config)--context string: The name of the kubeconfig context to use--namespace string, -n: Namespace to use for the operation--server string: Kubernetes API server address--token string: Bearer token for authentication--user string: The name of the kubeconfig user to use
Output and Formatting Flags
Control how command output is displayed:
--output string, -o: Output format (json, yaml, table)--use-utc: Format timestamps in UTC instead of local timezone
Operational Flags
Control command behavior and scope:
--verbose int, -v: Verbose output level (0=silent, 1=info, 2=debug, 3=trace)--all-namespaces, -A: List resources across all namespaces
Examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Use a specific kubeconfig file
kubectl mtv --kubeconfig=/path/to/kubeconfig get providers
# Operate in a specific namespace
kubectl mtv --namespace migration-ns get plans
# Enable debug logging
kubectl mtv -v=2 get inventory vms --provider vsphere-01
# List resources across all namespaces
kubectl mtv get plans --all-namespaces
# Output in JSON format with UTC timestamps
kubectl mtv get plan --name migration-1 --output json --use-utc
Environment Variables
Configure kubectl-mtv behavior using environment variables:
Core Configuration
MTV_VDDK_INIT_IMAGE: Default VDDK initialization image for VMware providers1
export MTV_VDDK_INIT_IMAGE=quay.io/your-registry/vddk:8.0.1
MTV_INVENTORY_URL: Base URL for the inventory service (required for Kubernetes, auto-discovered on OpenShift)1
export MTV_INVENTORY_URL=http://inventory-service-ip:port
Kubernetes Configuration
KUBECONFIG: Path to kubeconfig file (if not using default location)1
export KUBECONFIG=/path/to/your/kubeconfig
Setting Environment Variables Permanently
Add environment variables to your shell profile for persistence:
1
2
3
4
# Add to ~/.bashrc, ~/.zshrc, or equivalent
echo 'export MTV_VDDK_INIT_IMAGE=quay.io/your-registry/vddk:8.0.1' >> ~/.bashrc
echo 'export MTV_INVENTORY_URL=http://inventory-service-ip:port' >> ~/.bashrc
source ~/.bashrc
Cluster Requirements and Setup
Forklift/MTV Installation
kubectl-mtv requires either Forklift (upstream) or Migration Toolkit for Virtualization (downstream) to be installed in your cluster.
Option A: Install Forklift (Upstream - Any Kubernetes)
1
2
3
4
5
6
7
8
9
10
11
12
# Install Forklift operator
kubectl apply -f https://github.com/kubev2v/forklift/releases/latest/download/forklift-operator.yaml
# Wait for operator to be ready
kubectl wait --for=condition=Available deployment/forklift-operator \
-n forklift-operator --timeout=300s
# Create Forklift controller
kubectl apply -f https://github.com/kubev2v/forklift/releases/latest/download/forklift-controller.yaml
# Verify installation
kubectl get pods -n konveyor-forklift
Option B: Install MTV (Downstream - OpenShift)
For OpenShift environments, install MTV through the Operator Hub:
Using OpenShift Console:
- Navigate to Operators - OperatorHub
- Search for “Migration Toolkit for Virtualization”
- Install the operator
- Create an MTV instance
Using CLI:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Create subscription for MTV operator
cat <<EOF | oc apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: mtv-operator
namespace: openshift-migration
spec:
channel: release-v2.6
name: mtv-operator
source: redhat-operators
sourceNamespace: openshift-marketplace
EOF
# Verify installation
oc get pods -n openshift-migration
RBAC Permissions
Ensure your user or service account has appropriate permissions to access MTV/Forklift resources.
Required Permissions
Create a ClusterRole with necessary permissions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: mtv-user
rules:
# Forklift/MTV resources
- apiGroups: ["forklift.konveyor.io"]
resources: ["*"]
verbs: ["get", "list", "create", "update", "patch", "delete", "watch"]
# Core Kubernetes resources
- apiGroups: [""]
resources: ["secrets", "configmaps", "namespaces"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
# For inventory access
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list"]
# For route discovery (OpenShift)
- apiGroups: ["route.openshift.io"]
resources: ["routes"]
verbs: ["get", "list"]
Bind Permissions to User
1
2
3
4
5
6
7
8
9
# Bind to a user
kubectl create clusterrolebinding mtv-user-binding \
--clusterrole=mtv-user \
--user=your-username
# Or bind to a service account
kubectl create clusterrolebinding mtv-serviceaccount-binding \
--clusterrole=mtv-user \
--serviceaccount=namespace:serviceaccount-name
Verify Permissions
1
2
3
4
5
6
7
# Check if you can access MTV resources
kubectl auth can-i get plans.forklift.konveyor.io
kubectl auth can-i list providers.forklift.konveyor.io
kubectl auth can-i create mappings.forklift.konveyor.io
# Check specific namespace permissions
kubectl auth can-i create secrets -n migration-namespace
Service Account Setup (Optional)
For automated operations or CI/CD, create a dedicated service account:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Create namespace and service account
kubectl create namespace migration-ops
kubectl create serviceaccount mtv-operator -n migration-ops
# Bind the ClusterRole
kubectl create clusterrolebinding mtv-operator-binding \
--clusterrole=mtv-user \
--serviceaccount=migration-ops:mtv-operator
# Generate a token (Kubernetes 1.24+)
kubectl create token mtv-operator -n migration-ops --duration=24h
# For long-term tokens, create a secret
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: mtv-operator-token
namespace: migration-ops
annotations:
kubernetes.io/service-account.name: mtv-operator
type: kubernetes.io/service-account-token
EOF
# Retrieve the token
kubectl get secret mtv-operator-token -n migration-ops \
-o go-template='{{ .data.token | base64decode }}'
Uninstall
Remove the three installed files:
1
2
3
rm -f ~/.local/bin/kubectl-mtv
rm -f ~/.local/bin/kubectl_complete-mtv
rm -f ~/.local/bin/oc_complete-mtv
If you installed to a different directory, replace ~/.local/bin with that path.
Troubleshooting Installation
Common Issues and Solutions
Issue: Plugin Not Found
Error: plugin "mtv" not found
Solutions:
1
2
3
4
5
6
7
8
9
# Ensure binary is in PATH
which kubectl-mtv
echo $PATH
# Make binary executable
chmod +x $(which kubectl-mtv)
# Verify kubectl can find plugins
kubectl plugin list
Issue: Permission Denied
Error: User cannot list resources
Solutions:
1
2
3
4
5
6
7
8
9
10
11
# Check RBAC permissions
kubectl auth can-i get plans.forklift.konveyor.io
kubectl auth can-i list providers.forklift.konveyor.io
# Verify current user
kubectl config current-context
kubectl config view --minify
# Check if Forklift/MTV is installed
kubectl get crd | grep forklift
kubectl get pods -n konveyor-forklift
Issue: Connection Issues
Error: Unable to connect to cluster
Solutions:
1
2
3
4
5
6
7
8
9
10
# Verify cluster connectivity
kubectl cluster-info
kubectl get nodes
# Check kubeconfig
kubectl config current-context
kubectl config get-contexts
# Test with specific kubeconfig
kubectl mtv --kubeconfig=/path/to/config get providers
Issue: MTV_INVENTORY_URL Not Set (Kubernetes)
Error: Commands hang or fail when querying inventory
Solutions:
1
2
3
4
5
6
7
8
9
# Find inventory service
kubectl get service -n konveyor-forklift forklift-inventory
# Set environment variable
export MTV_INVENTORY_URL=http://<service-ip>:<port>
# Or use port-forward for testing
kubectl port-forward -n konveyor-forklift svc/forklift-inventory 8080:8080 &
export MTV_INVENTORY_URL=http://localhost:8080
Debug Mode
Enable verbose output for troubleshooting:
1
2
3
4
5
6
7
# Use debug verbosity levels
kubectl mtv -v=1 get providers # Info level
kubectl mtv -v=2 get providers # Debug level
kubectl mtv -v=3 get providers # Trace level
# Check cluster connectivity with debug
kubectl mtv -v=2 --kubeconfig=/path/to/config get providers
Getting Help
- Documentation: Check the complete documentation
- Issues: Open an issue on GitHub
- Community: Join discussions on the Forklift community channels
Next Steps
After successful installation and verification:
- Follow the Quick Start in Chapter 3: Quick Start - First Migration Workflow
- Set up providers for your source virtualization platforms
- Create your first migration plan using the simplified workflow
- Explore advanced features like VDDK optimization and migration hooks
Previous: Chapter 1: Overview of kubectl-mtv
Next: Chapter 3: Quick Start - First Migration Workflow