Skaffold with OrbStack - Port-Forward-Free 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 Feature OrbStack minikube/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:pass@postgresql.default.svc.cluster.local: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
Check service type:
kubectl get svc
Verify LoadBalancer has EXTERNAL-IP (not
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 Quick Setup Checklist Install Ingress controller (one-time) Change service types to LoadBalancer Create Ingress resources for pretty URLs Remove portForward from skaffold.yaml Set kubeContext: orbstack in deploy config 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