mcpField
S
skaffold-orbstack

skaffold-orbstack

github.com/laurigatesCloud & DevOps5960 installsUpdated 1d ago
Repository

About skaffold-orbstack

A skill for developers using Skaffold with an OrbStack local Kubernetes cluster, explaining how to access services without port forwarding. It covers LoadBalancer, Ingress, cluster DNS, migration steps, and troubleshooting.

Key features

  1. 01Configure Skaffold for OrbStack clusters
  2. 02Access services through LoadBalancer
  3. 03Use wildcard DNS and Ingress
  4. 04Migrate away from port forwarding
  5. 05Troubleshoot services and DNS

Use cases

  1. 01Reach local cluster services from macOS
  2. 02Set up local service addresses with Ingress
  3. 03Move a Skaffold project off port forwarding
  4. 04Connect local tools to a cluster database

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/laurigates/claude-plugins --skill skaffold-orbstack

After installing, type/skaffold-orbstackin Claude Code to confirm it loaded.

Details

From the project README

Skaffold with OrbStack - Port-Forward-Free Development

When to Use This Skill

Use this skill when...Use a sibling Skaffold/container skill instead when...
Wiring Skaffold against the OrbStack local Kubernetes clusterDefining file-sync rules for the inner dev loop (skaffold-filesync)
Reaching services via *.k8s.orb.local, LoadBalancer, or Ingress without port-forwardAdding pre-deploy test or post-deploy verify stages (skaffold-testing)
Migrating an existing project off kubectl port-forward onto OrbStack networkingHardening or shrinking the container image itself (container-development)

Overview

OrbStack provides superior local Kubernetes networking compared to other tools (minikube, kind, Docker Desktop). Services are accessible directly from macOS without port-forward.

Key OrbStack Advantages

FeatureOrbStackminikube/kind
LoadBalancer auto-provision✅ Yes❌ Needs MetalLB
Wildcard DNS (*.k8s.orb.local)✅ Yes❌ No
cluster.local from host✅ Yes❌ No
Pod IP direct access✅ Yes❌ No
Auto HTTPS certificates✅ Yes❌ No

Service Access Methods

Method 1: LoadBalancer Services (Simplest)

Change service type from ClusterIP to LoadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: LoadBalancer  # OrbStack auto-provisions external IP
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: my-app

Access: curl http://my-app.default.svc.cluster.local from macOS

Method 2: Ingress with Wildcard DNS (Recommended)

One-time setup - Install Ingress controller:

# Ingress-NGINX (recommended)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

# OR Traefik
helm repo add traefik https://traefik.github.io/charts
helm install traefik traefik/traefik

Create Ingress for your service:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app
spec:
  ingressClassName: nginx
  rules:
    - host: my-app.k8s.orb.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app
                port:
                  number: 80

Access: http://my-app.k8s.orb.local (auto-resolves)

Method 3: Direct Service DNS (cluster.local)

OrbStack exposes cluster DNS to macOS:

# Access any service directly
curl http://my-app.default.svc.cluster.local:8080

# Full DNS pattern
curl http://<service>.<namespace>.svc.cluster.local:<port>

Skaffold Configuration for OrbStack

Minimal skaffold.yaml (No Port-Forward Needed)
apiVersion: skaffold/v4beta11
kind: Config
metadata:
  name: my-app

build:
  local:
    push: false
    useBuildkit: true
  artifacts:
    - image: my-app
      docker:
        dockerfile: Dockerfile

deploy:
  kubeContext: orbstack
  kubectl:
    manifests:
      - k8s/*.yaml
  statusCheck: true
  statusCheckDeadlineSeconds: 180

# Port-forward REMOVED - use LoadBalancer/Ingress instead
Profile: Local with Ingress
profiles:
  - name: local-ingress
    deploy:
      kubeContext: orbstack
      kubectl:
        manifests:
          - k8s/base/*.yaml
          - k8s/ingress/*.yaml  # Ingress resources
Profile: Services-Only (Frontend Local Dev)
profiles:
  - name: services-only
    build:
      artifacts: []  # Don't build frontend
    deploy:
      kubeContext: orbstack
      kubectl:
        manifests:
          - k8s/namespace.yaml
          - k8s/database/*.yaml
          - k8s/api/*.yaml

Access backend at http://api.k8s.orb.local while running npm run dev locally.

Kubernetes Manifest Templates

LoadBalancer Service Template
# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .name }}
  labels:
    app: {{ .name }}
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: {{ .containerPort | default 8080 }}
  selector:
    app: {{ .name }}
Ingress Template
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ .name }}
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: {{ .name }}.k8s.orb.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: {{ .name }}
                port:
                  number: 80

Migration: Port-Forward to LoadBalancer

Before (Traditional)
# skaffold.yaml with port-forward
portForward:
  - resourceType: service
    resourceName: api
    port: 8080
    localPort: 8080
    address: 127.0.0.1
  - resourceType: service
    resourceName: frontend
    port: 3000
    localPort: 3000
    address: 127.0.0.1
skaffold dev  # Services at localhost:8080, localhost:3000
After (OrbStack Native)
# k8s/services.yaml - Change service types
apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  type: LoadBalancer  # Changed from ClusterIP
  ports:
    - port: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  type: LoadBalancer  # Changed from ClusterIP
  ports:
    - port: 3000
# skaffold.yaml - Remove portForward section entirely
deploy:
  kubeContext: orbstack
  kubectl:
    manifests:
      - k8s/*.yaml
# No portForward needed!
skaffold dev  # Services at api.default.svc.cluster.local:8080
              #            frontend.default.svc.cluster.local:3000

Common Patterns

Database Access
# k8s/postgresql.yaml
apiVersion: v1
kind: Service
metadata:
  name: postgresql
spec:
  type: LoadBalancer  # Access from local tools (DBeaver, pgAdmin)
  ports:
    - port: 5432

Connection string: postgres://user:[email protected]:5432/db

Multi-Service Application
# k8s/ingress.yaml - Single Ingress for all services
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  ingressClassName: nginx
  rules:
    - host: api.k8s.orb.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api
                port:
                  number: 8080
    - host: web.k8s.orb.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend
                port:
                  number: 3000
    - host: admin.k8s.orb.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: admin-panel
                port:
                  number: 8000

Security Considerations

Default: Localhost Only

OrbStack restricts services to localhost by default - safe on untrusted networks.

Expose to LAN (Use with Caution)

Settings → Kubernetes → "Expose services to local network devices"

Only enable when:

  • Testing from mobile devices on same network
  • Sharing local environment with team
  • On trusted network

Troubleshooting

Service Not Accessible
  1. Check service type: kubectl get svc
  2. Verify LoadBalancer has EXTERNAL-IP (not <pending>)
  3. Test DNS: nslookup my-app.default.svc.cluster.local
Ingress Not Working
  1. Verify Ingress controller is running:
    kubectl -n ingress-nginx get pods
    
  2. Check Ingress controller has LoadBalancer IP:
    kubectl -n ingress-nginx get svc
    
  3. Verify Ingress resource:
    kubectl describe ingress my-app
    
DNS Resolution Issues
# Test cluster DNS from macOS
nslookup my-service.default.svc.cluster.local

# If short names fail, use full domain
# ❌ my-service.default.svc
# ✅ my-service.default.svc.cluster.local
Pod IP Direct Access (Debugging)
# Get pod IP
kubectl get pods -o wide

# Connect directly (OrbStack routes pod network to macOS)
curl http://10.42.0.15:8080

Agentic Optimizations

ContextCommand
Start dev (no port-forward)skaffold dev --kube-context=orbstack
Check service IPskubectl get svc -o wide
Verify Ingresskubectl get ingress
Test DNS resolutionnslookup my-app.default.svc.cluster.local
Check Ingress controllerkubectl -n ingress-nginx get pods
Get pod IPskubectl get pods -o wide
Run specific profileskaffold dev -p services-only --kube-context=orbstack
Describe Ingresskubectl describe ingress my-app

Quick Setup Checklist

  1. Install Ingress controller (one-time)
  2. Change service types to LoadBalancer
  3. Create Ingress resources for pretty URLs
  4. Remove portForward from skaffold.yaml
  5. Set kubeContext: orbstack in deploy config
  6. Update local .env/config to use .k8s.orb.local URLs

Commands Reference

# Start development (no --port-forward needed)
skaffold dev --kube-context=orbstack

# Run specific profile
skaffold dev -p services-only --kube-context=orbstack

# Check service accessibility
kubectl get svc -o wide

# Verify Ingress
kubectl get ingress

Comments

Markdown supported