Skip to main content

Kubernetes Deployment with Helm

Deploy FastSkill as a production-ready service in Kubernetes using the official Helm chart. The chart supports two deployment modes: simple proxy-only for small teams, or full registry with S3 backend for advanced use cases.

Overview

This chart supports two deployment modes:
  1. Proxy Only - Simple deployment, no external dependencies
  2. Full Registry + Proxy - Advanced deployment with S3 backend and Git-based registry index

Prerequisites

Common (Both Modes)

  • Kubernetes 1.19+
  • Helm 3.0+
  • Persistent storage

Proxy Only Mode

  • No additional requirements

Full Registry Mode

  • S3-compatible storage (AWS S3, MinIO, DigitalOcean Spaces, etc.)
  • GitHub Personal Access Token (repo scope)
  • Git repository for registry index
  • OpenAI API key (optional, for semantic search)

What You Get

  • Proxy server that intercepts Anthropic API calls and injects skills
  • Skills loaded from local directory/PVC
  • No S3 or GitHub setup required
  • Simple, fast deployment

Installation Steps

  1. Create namespace
  2. Install chart with registry disabled
  3. Populate skills directory
  4. Verify deployment

Complete Example

# Step 1: Create namespace
kubectl create namespace fastskill

# Step 2: Install chart (proxy only)
helm install fastskill ./tools/fastskill/helm/fastskill \
  --namespace fastskill \
  --set registry.enabled=false \
  --set proxy.enabled=true \
  --set persistence.skills.size=5Gi

# Step 3: Populate skills directory
# Option A: Copy skills from local directory
# First, get the pod name
POD_NAME=$(kubectl get pods -n fastskill -l app.kubernetes.io/component=proxy -o jsonpath='{.items[0].metadata.name}')
kubectl cp ./my-skills fastskill/$POD_NAME:/app/skills

# Option B: Use existing PVC with pre-populated skills
helm upgrade fastskill ./tools/fastskill/helm/fastskill \
  --namespace fastskill \
  --set registry.enabled=false \
  --set proxy.enabled=true \
  --set persistence.skills.existingClaim=my-skills-pvc

# Step 4: Verify deployment
kubectl get pods -n fastskill
kubectl port-forward -n fastskill svc/fastskill-proxy 8081:8081

# Test health endpoint
curl http://localhost:8081/health

# Test proxy with Anthropic API call
curl -X POST http://localhost:8081/v1/messages \
  -H "x-api-key: YOUR_ANTHROPIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "claude-3-sonnet-20240229", "messages": [{"role": "user", "content": "Hello"}]}'

Configuration Options

Use values-proxy-only.yaml or set values directly:
registry:
  enabled: false

proxy:
  enabled: true
  replicaCount: 1
  resources:
    limits:
      cpu: "500m"
      memory: "512Mi"
    requests:
      cpu: "250m"
      memory: "256Mi"

persistence:
  skills:
    enabled: true
    size: 5Gi
    # Option: Use existing PVC with pre-populated skills
    # existingClaim: "my-skills-pvc"
  registryIndex:
    enabled: false

fastskill:
  logLevel: INFO
Install with custom values:
helm install fastskill ./tools/fastskill/helm/fastskill \
  -f ./tools/fastskill/helm/fastskill/values-proxy-only.yaml \
  --namespace fastskill

Deployment Mode 2: Full Registry with S3 Backend (Advanced)

What You Get

  • Registry server with web UI for skill management
  • Skill publishing via REST API
  • S3 blob storage for skill packages
  • Git-based registry index for version control
  • Proxy server with skill injection
  • Optional semantic search with OpenAI

Installation Steps

  1. Create S3 bucket and IAM credentials
  2. Create GitHub repository for registry index
  3. Create Kubernetes secrets
  4. Install chart with registry enabled
  5. Verify deployment

Complete Example

# Step 1: Create S3 bucket (AWS example)
aws s3 mb s3://my-fastskill-registry --region us-east-1
aws s3api put-public-access-block \
  --bucket my-fastskill-registry \
  --public-access-block-configuration \
  "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

# Create IAM user with S3 access
aws iam create-user --user-name fastskill-registry
aws iam attach-user-policy \
  --user-name fastskill-registry \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
aws iam create-access-key --user-name fastskill-registry
# Save the AccessKeyId and SecretAccessKey

# Step 2: Create GitHub repository for registry index
# Create empty repo: https://github.com/your-org/fastskill-registry-index
# Create GitHub PAT with repo scope: https://github.com/settings/tokens

# Step 3: Create Kubernetes secrets
kubectl create namespace fastskill

kubectl create secret generic fastskill-github-token \
  --from-literal=GITHUB_TOKEN=ghp_your_token_here \
  --namespace fastskill

kubectl create secret generic fastskill-s3-credentials \
  --from-literal=AWS_ACCESS_KEY_ID=AKIA... \
  --from-literal=AWS_SECRET_ACCESS_KEY=secret... \
  --namespace fastskill

# Optional: OpenAI API key for semantic search
kubectl create secret generic fastskill-openai-key \
  --from-literal=OPENAI_API_KEY=sk-... \
  --namespace fastskill

# Step 4: Install chart with registry enabled
helm install fastskill ./tools/fastskill/helm/fastskill \
  --namespace fastskill \
  --set s3.bucket=my-fastskill-registry \
  --set s3.region=us-east-1 \
  --set s3.blobBaseUrl=https://my-fastskill-registry.s3.amazonaws.com/skills \
  --set registryIndex.url=https://github.com/your-org/fastskill-registry-index.git

# Or use values file
helm install fastskill ./tools/fastskill/helm/fastskill \
  -f ./tools/fastskill/helm/fastskill/values-registry-s3.yaml \
  --namespace fastskill

# Step 5: Verify deployment
kubectl get pods -n fastskill
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=registry -n fastskill --timeout=300s
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=proxy -n fastskill --timeout=300s

# Test registry API
kubectl port-forward -n fastskill svc/fastskill-registry 8080:8080
curl http://localhost:8080/api/status

# Access web UI
open http://localhost:8080/registry

# Test proxy
kubectl port-forward -n fastskill svc/fastskill-proxy 8081:8081
curl http://localhost:8081/health

S3-Compatible Storage Options

AWS S3 (Default)

s3:
  bucket: "my-fastskill-registry"
  region: "us-east-1"
  endpoint: ""  # Leave empty for AWS S3
  blobBaseUrl: "https://my-fastskill-registry.s3.amazonaws.com/skills"

MinIO (Self-hosted)

s3:
  bucket: "fastskill-registry"
  region: "us-east-1"
  endpoint: "http://minio.example.com:9000"
  blobBaseUrl: "http://minio.example.com:9000/fastskill-registry/skills"

DigitalOcean Spaces

s3:
  bucket: "my-space-name"
  region: "nyc3"
  endpoint: "https://nyc3.digitaloceanspaces.com"
  blobBaseUrl: "https://my-space-name.nyc3.digitaloceanspaces.com/skills"

Cloudflare R2

s3:
  bucket: "my-r2-bucket"
  region: "auto"
  endpoint: "https://ACCOUNT_ID.r2.cloudflarestorage.com"
  blobBaseUrl: "https://ACCOUNT_ID.r2.cloudflarestorage.com/my-r2-bucket/skills"

Configuration Options

Use values-registry-s3.yaml or set values directly:
registry:
  enabled: true
  replicaCount: 1
  resources:
    limits:
      cpu: "1"
      memory: "1Gi"
    requests:
      cpu: "500m"
      memory: "512Mi"

proxy:
  enabled: true
  replicaCount: 1

persistence:
  skills:
    enabled: true
    size: 10Gi
  registryIndex:
    enabled: true
    size: 5Gi

s3:
  bucket: "my-fastskill-registry"
  region: "us-east-1"
  endpoint: ""  # Leave empty for AWS S3
  blobBaseUrl: "https://my-fastskill-registry.s3.amazonaws.com/skills"

registryIndex:
  url: "https://github.com/your-org/fastskill-registry-index.git"
  branch: main

openai:
  enabled: false  # Enable for semantic search

fastskill:
  logLevel: INFO

Values Reference

Component Toggles

ParameterDescriptionDefault
registry.enabledEnable registry servertrue
proxy.enabledEnable proxy servertrue

Resource Configuration

ParameterDescriptionDefault
registry.replicaCountNumber of registry replicas1
registry.resources.limits.cpuRegistry CPU limit"1"
registry.resources.limits.memoryRegistry memory limit"1Gi"
registry.resources.requests.cpuRegistry CPU request"500m"
registry.resources.requests.memoryRegistry memory request"512Mi"
proxy.replicaCountNumber of proxy replicas1
proxy.resources.limits.cpuProxy CPU limit"500m"
proxy.resources.limits.memoryProxy memory limit"512Mi"
proxy.resources.requests.cpuProxy CPU request"250m"
proxy.resources.requests.memoryProxy memory request"256Mi"

Storage Configuration

ParameterDescriptionDefault
persistence.skills.enabledEnable skills PVCtrue
persistence.skills.sizeSkills storage size10Gi
persistence.skills.existingClaimUse existing PVC""
persistence.registryIndex.enabledEnable registry index PVCtrue
persistence.registryIndex.sizeRegistry index storage size5Gi

S3 Configuration (Registry Mode Only)

ParameterDescriptionDefault
s3.bucketS3 bucket name"" (required for registry)
s3.regionAWS regionus-east-1
s3.endpointS3-compatible service endpoint""
s3.blobBaseUrlBase URL for published packages""

Registry Index Configuration (Registry Mode Only)

ParameterDescriptionDefault
registryIndex.urlGit repository URL"" (required for registry)
registryIndex.branchGit branchmain

Optional Configuration

ParameterDescriptionDefault
openai.enabledEnable OpenAI integrationfalse
fastskill.logLevelLogging levelINFO
ingress.enabledEnable ingressfalse

Environment-Specific Values

Development (values-dev.yaml)

  • Lower resource limits
  • Debug logging
  • Smaller storage sizes
  • Ingress disabled (use port-forward)

Staging (values-staging.yaml)

  • Production-like resources
  • Info logging
  • Standard storage sizes
  • Ingress with staging certificates

Production (values-prod.yaml)

  • Higher resource limits
  • Multiple replicas for HA
  • Warn/Error logging
  • Larger storage sizes
  • Production ingress with TLS

Accessing Services

Port Forwarding (Development)

# Registry server
kubectl port-forward -n fastskill svc/fastskill-registry 8080:8080

# Proxy server
kubectl port-forward -n fastskill svc/fastskill-proxy 8081:8081

Ingress (Production)

  • Registry UI: https://fastskill.example.com/registry
  • Registry API: https://fastskill.example.com/api/*
  • Proxy: https://fastskill.example.com/proxy/*

Health Checks

Registry Server

  • Readiness: GET /api/status
  • Liveness: GET /api/status
  • Returns JSON with service status

Proxy Server

  • Readiness: GET /health
  • Liveness: GET /health
  • Returns plain text “Proxy server is running”

API Endpoints

Registry Server

  • GET /api/status - Service status
  • GET /api/skills - List all skills
  • GET /api/skills/:id - Get skill details
  • POST /api/search - Search skills
  • POST /api/registry/publish - Publish skill package
  • GET /registry - Web UI

Proxy Server

  • GET /health - Health check
  • POST /v1/messages - Proxy Anthropic API calls

Upgrading

# Upgrade with new values
helm upgrade fastskill ./tools/fastskill/helm/fastskill \
  -f ./tools/fastskill/helm/fastskill/values-prod.yaml \
  --namespace fastskill

# Upgrade with new image tag
helm upgrade fastskill ./tools/fastskill/helm/fastskill \
  --set image.tag=v0.2.0 \
  --namespace fastskill

Uninstalling

helm uninstall fastskill --namespace fastskill
This does not delete PVCs. To remove storage:
kubectl delete pvc -n fastskill -l app.kubernetes.io/name=fastskill

Architecture

Components

  1. Registry Deployment: Runs fastskill serve --enable-registry
    • Requires: S3 storage, GitHub token, registry index path
    • Provides: REST API, Web UI, skill publishing
  2. Proxy Deployment: Runs fastskill proxy
    • Requires: Skills directory (read-only)
    • Provides: Anthropic API proxy with skill injection
  3. Init Container: Clones registry index Git repository
    • Runs only if registry index path is empty
    • Uses GitHub token for authentication

Storage

  • Skills PVC: Shared between registry and proxy
    • Mount path: /app/skills
    • Access mode: ReadWriteOnce (or ReadWriteMany for scaling)
  • Registry Index PVC: Registry server only
    • Mount path: /app/registry-index
    • Access mode: ReadWriteOnce

Networking

  • Registry Service: ClusterIP on port 8080
  • Proxy Service: ClusterIP on port 8081
  • Ingress: Optional, for external access

Troubleshooting

Registry Server Won’t Start

Error: “Registry enabled but blob storage not configured” Solution: Ensure S3 configuration is set:
s3:
  bucket: your-bucket
  region: us-east-1
Error: “Registry enabled but registry index path not configured” Solution: Ensure registry index URL is set:
registryIndex:
  url: "https://github.com/org/repo.git"

Init Container Fails

Error: “Failed to clone registry index” Solution:
  1. Verify GitHub token has repository access
  2. Check registry index URL is correct
  3. Ensure network connectivity to GitHub

Storage Issues

Error: “PVC not found” Solution:
  1. Check storage class exists: kubectl get storageclass
  2. Verify PVC was created: kubectl get pvc -n fastskill
  3. Check storage class in values.yaml matches cluster

Secret Access Issues

Error: “Secret not found” Solution:
  1. Verify secrets exist: kubectl get secrets -n fastskill
  2. Check secret names match values.yaml
  3. Ensure secrets are in the correct namespace

Health Check Failures

Error: “Readiness probe failed” Solution:
  1. Check pod logs: kubectl logs -n fastskill <pod-name>
  2. Verify service is listening on correct port
  3. Check network policies allow health check traffic
  4. Increase initialDelaySeconds if service takes longer to start

S3 Connection Issues

Error: “Failed to connect to S3” Solution:
  1. Verify AWS credentials are correct
  2. Check S3 bucket exists and is accessible
  3. For S3-compatible services, ensure s3.endpoint is set
  4. Verify network connectivity to S3 endpoint

Security Considerations

  1. Secrets Management: Never commit secrets to version control. Use Kubernetes secrets or external secret management.
  2. Network Policies: Consider implementing network policies to restrict pod-to-pod communication.
  3. RBAC: Service account has minimal permissions. Adjust as needed for your environment.
  4. TLS: Always use TLS in production. Configure ingress with valid certificates.
  5. Image Security: Use specific image tags (not latest) in production. Scan images for vulnerabilities.

Chart Location

The Helm chart is located at:
tools/fastskill/helm/fastskill/
For detailed chart documentation, see the chart README.