Skip to content

Latest commit

 

History

History
242 lines (164 loc) · 8.12 KB

File metadata and controls

242 lines (164 loc) · 8.12 KB

Deploying Kubernetes MCP Server in a Kubernetes Cluster

This guide walks you through setting up the Kubernetes MCP Server for deployment in a Kubernetes cluster. You'll create a dedicated, read-only ServiceAccount and generate a secure kubeconfig file that can be used with various MCP clients.

Note: This setup is recommended for production use but not strictly required. The MCP Server can use your existing kubeconfig file (e.g., ~/.kube/config), but using a dedicated ServiceAccount with limited permissions follows the principle of least privilege and is more secure.

Next: After completing this guide, continue with the Claude Code CLI guide. See the docs README for all available guides.

What You'll Create

By the end of this guide, you'll have:

  • A dedicated mcp-viewer ServiceAccount with read-only cluster access
  • A secure, time-bound authentication token
  • A dedicated kubeconfig file (~/.kube/mcp-viewer.kubeconfig)

Prerequisites

  • A running Kubernetes cluster
  • kubectl CLI installed and configured
  • Cluster admin permissions to create ServiceAccounts and RBAC bindings

1. Create a Read-Only ServiceAccount and RBAC

A ServiceAccount represents a non-human identity. Binding it to a read-only role lets tools query the cluster safely without using administrator credentials.

Step 1.1: Create the Namespace and ServiceAccount

First, create a Namespace for the ServiceAccount:

# Create or pick a Namespace for the ServiceAccount
kubectl create namespace mcp

# Create the ServiceAccount
kubectl create serviceaccount mcp-viewer -n mcp

Step 1.2: Grant Read-Only Access (RBAC)

Use a ClusterRoleBinding or RoleBinding to grant read-only permissions.

Option A: Cluster-Wide Read-Only (Most Common)

This binds the ServiceAccount to the built-in view ClusterRole, which provides read-only access across the whole cluster.

# Binds the view ClusterRole to the ServiceAccount
kubectl create clusterrolebinding mcp-viewer-crb \
    --clusterrole=view \
    --serviceaccount=mcp:mcp-viewer

Option B: Namespace-Scoped Only (Tighter Scope)

This limits read access to the mcp namespace only, using the built-in view Role.

# Binds the view role to the ServiceAccount within the 'mcp' namespace
kubectl create rolebinding mcp-viewer-rb \
    --role=view \
    --serviceaccount=mcp:mcp-viewer \
    -n mcp

Quick Verification (Optional)

Verify the permissions granted to the ServiceAccount:

# Check if the ServiceAccount can list pods cluster-wide
# Expect 'yes' if you used the view ClusterRole (Option A)
kubectl auth can-i list pods --as=system:serviceaccount:mcp:mcp-viewer --all-namespaces

2. Mint a ServiceAccount Token

Tools authenticate via a bearer token. We use the TokenRequest API (kubectl create token) to generate a secure, short-lived token.

# Create a time-bound token (choose a duration, e.g., 2 hours)
TOKEN="$(kubectl create token mcp-viewer --duration=2h -n mcp)"

# Verify the token was generated (Optional)
echo "$TOKEN"

Note: The kubectl create token command requires Kubernetes v1.24+. For older versions, you'll need to extract the token from the ServiceAccount's secret.

3. Build a Dedicated Kubeconfig

A dedicated kubeconfig file isolates this ServiceAccount's credentials from your personal admin credentials, making it easy to point external tools at.

Step 3.1: Get Cluster Details

Get the API server address and certificate authority from your current active context:

# 1. Get the current cluster API server address
API_SERVER="$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')"

# 2. Get the cluster's Certificate Authority (CA) file path or data
# First, try to get the CA file path
CA_FILE="$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.certificate-authority}')"

# If CA file is not set, extract the CA data and write it to a temp file
if [ -z "$CA_FILE" ]; then
    CA_FILE="/tmp/k8s-ca-$$.crt"
    kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d > "$CA_FILE"
fi

# 3. Define the desired context name
CONTEXT_NAME="mcp-viewer-context"
KUBECONFIG_FILE="$HOME/.kube/mcp-viewer.kubeconfig"

Step 3.2: Create and Configure the Kubeconfig File

Create the new kubeconfig file by defining the cluster, user (the ServiceAccount), and context:

# Create a new kubeconfig file with cluster configuration
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-cluster mcp-viewer-cluster \
    --server="$API_SERVER" \
    --certificate-authority="$CA_FILE" \
    --embed-certs=true

# Set the ServiceAccount token as the user credential
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-credentials mcp-viewer \
    --token="$TOKEN"

# Define the context (links the cluster and user)
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-context "$CONTEXT_NAME" \
    --cluster=mcp-viewer-cluster \
    --user=mcp-viewer

# Set the new context as current
kubectl config --kubeconfig="$KUBECONFIG_FILE" use-context "$CONTEXT_NAME"

# Secure the file permissions
chmod 600 "$KUBECONFIG_FILE"

# Clean up temporary CA file if we created one
if [[ "$CA_FILE" == /tmp/k8s-ca-*.crt ]]; then
    rm -f "$CA_FILE"
fi

Quick Sanity Check

You can now use this new file to verify access:

# Run a command using the dedicated kubeconfig file
kubectl --kubeconfig="$KUBECONFIG_FILE" get pods -A

This command should successfully list all Pods if you chose Option A: Cluster-Wide Read-Only, proving the ServiceAccount and its token are correctly configured.

4. Use with Kubernetes MCP Server

Now that you have a dedicated kubeconfig file, you can use it with the Kubernetes MCP Server:

# Run the MCP server with the dedicated kubeconfig
./kubernetes-mcp-server --kubeconfig="$HOME/.kube/mcp-viewer.kubeconfig"

# Or use npx
npx -y kubernetes-mcp-server@latest --kubeconfig="$HOME/.kube/mcp-viewer.kubeconfig"

# Or use uvx
uvx kubernetes-mcp-server@latest --kubeconfig="$HOME/.kube/mcp-viewer.kubeconfig"

Alternatively, you can set the KUBECONFIG environment variable:

export KUBECONFIG="$HOME/.kube/mcp-viewer.kubeconfig"
./kubernetes-mcp-server

Token Expiration and Renewal

The token created in Step 2 has a limited lifetime (2 hours in the example). When it expires, you'll need to:

  1. Generate a new token:

    TOKEN="$(kubectl create token mcp-viewer --duration=2h -n mcp)"
  2. Update the kubeconfig file:

    kubectl config --kubeconfig="$KUBECONFIG_FILE" set-credentials mcp-viewer --token="$TOKEN"

For long-running applications, consider:

  • Using a longer token duration (up to the cluster's maximum, typically 24h)
  • Implementing automatic token renewal in your application
  • Using a different authentication method (e.g., client certificates)

Cleanup

To remove the ServiceAccount and associated RBAC bindings:

# Delete the ClusterRoleBinding (if using Option A)
kubectl delete clusterrolebinding mcp-viewer-crb

# Delete the RoleBinding (if using Option B)
kubectl delete rolebinding mcp-viewer-rb -n mcp

# Delete the ServiceAccount
kubectl delete serviceaccount mcp-viewer -n mcp

# Delete the namespace (optional - only if you created it specifically for this)
kubectl delete namespace mcp

# Remove the kubeconfig file
rm "$HOME/.kube/mcp-viewer.kubeconfig"

Troubleshooting

kubectl create token: command not found

This command requires Kubernetes v1.24+. For older versions, you'll need to extract the token from the ServiceAccount's secret manually.

Permission denied errors

Ensure you're using the correct kubeconfig file and that the ServiceAccount has the necessary RBAC permissions. Verify with:

kubectl auth can-i list pods --as=system:serviceaccount:mcp:mcp-viewer --all-namespaces

Next Steps

Now that you have a working kubeconfig with read-only access, configure Claude Code CLI:

You can also:

  • Explore the main README for more MCP server capabilities