SiamCafe.net Blog
Technology

Skaffold Dev Container Orchestration

skaffold dev container orchestration
Skaffold Dev Container Orchestration | SiamCafe Blog
2025-07-31· อ. บอม — SiamCafe.net· 1,531 คำ

Skaffold Dev Container Orchestration คืออะไร

Skaffold เป็น CLI tool จาก Google สำหรับ automate Kubernetes development workflow ครอบคลุม build, push และ deploy containers อัตโนมัติพร้อม hot-reload Container Orchestration คือการจัดการ containers หลายตัวให้ทำงานร่วมกันอย่างมีประสิทธิภาพ ครอบคลุม scheduling, scaling, networking และ health management การรวม Skaffold กับ container orchestration ช่วยให้ developers พัฒนา microservices บน Kubernetes ได้อย่างรวดเร็ว ลด inner loop time จากนาทีเหลือวินาที

Skaffold Architecture

# skaffold_arch.py — Skaffold architecture overview
import json

class SkaffoldArchitecture:
    PIPELINE_STAGES = {
        "build": {
            "name": "Build Stage",
            "description": "สร้าง container images จาก source code",
            "builders": ["Docker", "Jib (Java)", "Buildpacks", "Kaniko (in-cluster)", "Ko (Go)"],
            "optimization": "File sync — sync files เข้า container แทน rebuild ทั้งหมด",
        },
        "tag": {
            "name": "Tag Stage",
            "description": "Tag images ด้วย strategy ที่เลือก",
            "strategies": ["Git commit hash", "DateTime", "SHA256", "Custom template"],
        },
        "push": {
            "name": "Push Stage",
            "description": "Push images ไป container registry",
            "registries": ["Docker Hub", "GCR", "ECR", "ACR", "Local (skip push)"],
        },
        "deploy": {
            "name": "Deploy Stage",
            "description": "Deploy ไป Kubernetes cluster",
            "deployers": ["kubectl", "Helm", "Kustomize", "Cloud Run"],
        },
        "verify": {
            "name": "Verify Stage",
            "description": "รัน tests หลัง deploy สำเร็จ",
            "tools": ["Container structure tests", "Custom test scripts"],
        },
    }

    def show_stages(self):
        print("=== Skaffold Pipeline Stages ===\n")
        for key, stage in self.PIPELINE_STAGES.items():
            print(f"[{stage['name']}]")
            print(f"  {stage['description']}")
            if 'builders' in stage:
                print(f"  Options: {', '.join(stage['builders'][:4])}")
            elif 'deployers' in stage:
                print(f"  Options: {', '.join(stage['deployers'])}")
            print()

arch = SkaffoldArchitecture()
arch.show_stages()

Skaffold Configuration

# skaffold.yaml — Skaffold configuration for microservices
apiVersion: skaffold/v4beta6
kind: Config
metadata:
  name: my-microservices

build:
  artifacts:
    - image: api-gateway
      context: services/api-gateway
      docker:
        dockerfile: Dockerfile
      sync:
        manual:
          - src: "src/**/*.py"
            dest: /app

    - image: user-service
      context: services/user-service
      docker:
        dockerfile: Dockerfile
      sync:
        manual:
          - src: "src/**/*.py"
            dest: /app

    - image: order-service
      context: services/order-service
      docker:
        dockerfile: Dockerfile

    - image: notification-service
      context: services/notification-service
      docker:
        dockerfile: Dockerfile

  local:
    push: false
    useBuildkit: true
    concurrency: 2

deploy:
  helm:
    releases:
      - name: api-gateway
        chartPath: charts/api-gateway
        valuesFiles:
          - charts/api-gateway/values-dev.yaml
        setValues:
          image.tag: "{{.IMAGE_TAG_api_gateway}}"

      - name: user-service
        chartPath: charts/user-service
        valuesFiles:
          - charts/user-service/values-dev.yaml

      - name: order-service
        chartPath: charts/order-service
        valuesFiles:
          - charts/order-service/values-dev.yaml

  statusCheckDeadlineSeconds: 120

portForward:
  - resourceType: service
    resourceName: api-gateway
    port: 8080
    localPort: 8080

  - resourceType: service
    resourceName: user-service
    port: 8081
    localPort: 8081

profiles:
  - name: dev
    activation:
      - command: dev
    patches:
      - op: add
        path: /build/local/push
        value: false

  - name: staging
    build:
      googleCloudBuild:
        projectId: my-project
    deploy:
      kustomize:
        paths:
          - k8s/overlays/staging

  - name: production
    build:
      googleCloudBuild:
        projectId: my-project
    deploy:
      kustomize:
        paths:
          - k8s/overlays/production

Multi-Service Orchestration

# orchestration.py — Multi-service development with Skaffold
import json

class MultiServiceOrchestration:
    CODE = """
# dev_manager.py — Manage multi-service development
import subprocess
import json
import os

class SkaffoldDevManager:
    def __init__(self, project_dir):
        self.project_dir = project_dir
        self.services = []
    
    def discover_services(self):
        '''Discover services from skaffold.yaml'''
        result = subprocess.run(
            ["skaffold", "diagnose", "-o", "json"],
            capture_output=True, text=True, cwd=self.project_dir
        )
        config = json.loads(result.stdout)
        
        self.services = []
        for artifact in config.get("build", {}).get("artifacts", []):
            self.services.append({
                "name": artifact["image"],
                "context": artifact.get("context", "."),
                "has_sync": "sync" in artifact,
            })
        return self.services
    
    def start_dev(self, profile="dev", services=None):
        '''Start Skaffold dev mode'''
        cmd = ["skaffold", "dev", "--profile", profile, "--port-forward"]
        
        if services:
            # Filter specific services
            cmd.extend(["--build-artifacts", ",".join(services)])
        
        return subprocess.Popen(
            cmd, cwd=self.project_dir,
            stdout=subprocess.PIPE, stderr=subprocess.PIPE
        )
    
    def run_single_service(self, service_name):
        '''Dev mode for single service only'''
        cmd = [
            "skaffold", "dev",
            "--build-artifacts", service_name,
            "--port-forward",
            "--cleanup=false",
        ]
        return subprocess.Popen(cmd, cwd=self.project_dir)
    
    def deploy_all(self, profile="staging"):
        '''Deploy all services'''
        result = subprocess.run(
            ["skaffold", "run", "--profile", profile],
            capture_output=True, text=True, cwd=self.project_dir
        )
        return result.returncode == 0
    
    def health_check(self):
        '''Check all deployed services'''
        result = subprocess.run(
            ["kubectl", "get", "pods", "-l", "app.kubernetes.io/managed-by=skaffold",
             "-o", "json"],
            capture_output=True, text=True
        )
        pods = json.loads(result.stdout)
        
        status = []
        for pod in pods.get("items", []):
            name = pod["metadata"]["name"]
            phase = pod["status"]["phase"]
            ready = all(
                c.get("ready", False)
                for c in pod["status"].get("containerStatuses", [])
            )
            status.append({"pod": name, "phase": phase, "ready": ready})
        
        return status

manager = SkaffoldDevManager("/path/to/project")
services = manager.discover_services()
for svc in services:
    print(f"  [{svc['name']}] context: {svc['context']} sync: {svc['has_sync']}")
"""

    def show_code(self):
        print("=== Dev Manager ===")
        print(self.CODE[:600])

    def workflow(self):
        print(f"\n=== Development Workflow ===")
        steps = [
            "1. skaffold dev → build + deploy all services to local K8s",
            "2. Edit code → Skaffold detects changes → auto rebuild/sync",
            "3. File sync: Python/JS files sync instantly (no rebuild)",
            "4. Docker rebuild: Dockerfile changes trigger full rebuild",
            "5. Port forward: access services at localhost:8080, 8081...",
            "6. Logs: skaffold streams all pod logs in terminal",
            "7. Ctrl+C → cleanup all deployed resources",
        ]
        for step in steps:
            print(f"  {step}")

orch = MultiServiceOrchestration()
orch.show_code()
orch.workflow()

Performance Optimization

# optimization.py — Skaffold performance tips
import json
import random

class PerformanceOptimization:
    TIPS = {
        "file_sync": {
            "name": "File Sync (ไม่ต้อง rebuild)",
            "description": "Sync source files เข้า running container — เร็วกว่า rebuild 10-50x",
            "config": "sync: manual: [{src: 'src/**/*.py', dest: /app}]",
            "savings": "Rebuild 30s → Sync 1s",
        },
        "layer_caching": {
            "name": "Docker Layer Caching",
            "description": "จัด Dockerfile ให้ COPY dependencies ก่อน source — cache layers",
            "config": "COPY requirements.txt . → RUN pip install → COPY . .",
            "savings": "Rebuild 60s → 5s (ถ้า deps ไม่เปลี่ยน)",
        },
        "buildkit": {
            "name": "BuildKit",
            "description": "ใช้ BuildKit สำหรับ parallel builds, better caching",
            "config": "build.local.useBuildkit: true",
            "savings": "Build 30-50% เร็วขึ้น",
        },
        "concurrency": {
            "name": "Parallel Builds",
            "description": "Build หลาย services พร้อมกัน",
            "config": "build.local.concurrency: 4 (= 4 services build พร้อมกัน)",
            "savings": "4 services: 120s → 40s",
        },
        "profiles": {
            "name": "Dev Profiles",
            "description": "ใช้ lightweight images สำหรับ dev — skip unnecessary steps",
            "config": "profiles.dev: ใช้ python:slim แทน python:latest, skip tests",
        },
    }

    def show_tips(self):
        print("=== Performance Tips ===\n")
        for key, tip in self.TIPS.items():
            print(f"[{tip['name']}]")
            print(f"  {tip['description']}")
            if 'savings' in tip:
                print(f"  Savings: {tip['savings']}")
            print()

    def benchmark(self):
        print("=== Build Time Benchmark ===")
        services = ["api-gateway", "user-service", "order-service", "notification"]
        print(f"  {'Service':<20} {'No Opt':>8} {'With Opt':>10} {'Savings':>8}")
        for svc in services:
            no_opt = random.uniform(20, 60)
            with_opt = random.uniform(2, 10)
            saving = (1 - with_opt/no_opt) * 100
            print(f"  {svc:<20} {no_opt:>6.1f}s {with_opt:>8.1f}s {saving:>7.0f}%")

opt = PerformanceOptimization()
opt.show_tips()
opt.benchmark()

CI/CD Integration

# cicd.py — Skaffold CI/CD pipeline
import json

class CICDIntegration:
    GITHUB_ACTIONS = """
# .github/workflows/deploy.yml
name: Build & Deploy
on:
  push:
    branches: [main, develop]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Skaffold
        run: |
          curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
          chmod +x skaffold && sudo mv skaffold /usr/local/bin/
      
      - name: Auth to GCP
        uses: google-github-actions/auth@v2
        with:
          credentials_json: }
      
      - name: Setup GKE credentials
        uses: google-github-actions/get-gke-credentials@v2
        with:
          cluster_name: my-cluster
          location: asia-southeast1
      
      - name: Deploy to Staging
        if: github.ref == 'refs/heads/develop'
        run: skaffold run --profile staging
      
      - name: Deploy to Production
        if: github.ref == 'refs/heads/main'
        run: skaffold run --profile production
      
      - name: Verify Deployment
        run: skaffold verify --profile }
"""

    def show_pipeline(self):
        print("=== CI/CD Pipeline ===")
        print(self.GITHUB_ACTIONS[:500])

    def commands(self):
        print(f"\n=== Skaffold Commands ===")
        cmds = [
            ("skaffold dev", "Development mode — watch + rebuild + deploy"),
            ("skaffold run", "One-time build + deploy (CI/CD)"),
            ("skaffold debug", "Dev mode with debugger attached"),
            ("skaffold render", "Generate Kubernetes manifests (dry run)"),
            ("skaffold verify", "Run verification tests after deploy"),
            ("skaffold delete", "Delete all deployed resources"),
        ]
        for cmd, desc in cmds:
            print(f"  {cmd:<25} — {desc}")

cicd = CICDIntegration()
cicd.show_pipeline()
cicd.commands()

FAQ - คำถามที่พบบ่อย

Q: Skaffold กับ Tilt อันไหนดี?

A: Skaffold: CLI-first, config-as-YAML, CI/CD friendly, Google-backed Tilt: UI dashboard, Tiltfile (Starlark), better visualization, Docker Compose-like Skaffold ดีกว่า: CI/CD integration, simple projects, kubectl/Helm/Kustomize users Tilt ดีกว่า: complex microservices, team collaboration, visual debugging ทั้งคู่ฟรี open source — ลองทั้งคู่แล้วเลือก

Q: File sync กับ rebuild ต่างกันอย่างไร?

A: File sync: copy ไฟล์ที่เปลี่ยนเข้า running container → ไม่ต้อง rebuild image (~1 วินาที) Rebuild: build Docker image ใหม่ → push → redeploy pod (~30-60 วินาที) File sync เหมาะ: source code changes (Python, JS, HTML) Rebuild จำเป็น: Dockerfile changes, dependency changes (requirements.txt)

Q: Skaffold ใช้กับ local development ได้ยังไง?

A: ต้องมี local Kubernetes: Minikube, Kind, Docker Desktop K8s, Rancher Desktop skaffold dev → build locally → deploy to local cluster → port forward → access at localhost ใช้ build.local.push: false → ไม่ push to registry (เร็วกว่า) Tips: ใช้ Kind + Skaffold = setup เร็วที่สุด

Q: รองรับกี่ services ได้?

A: ไม่มี limit ทางทฤษฎี — แต่ performance ขึ้นกับ hardware 5-10 services: ทำงานดีบน laptop ทั่วไป 10-20 services: ต้อง RAM 16GB+, SSD, parallel builds 20+ services: แนะนำ remote cluster + Cloud Build แทน local Tips: ใช้ Skaffold modules — dev แค่ services ที่กำลังทำ ไม่ต้อง build ทั้งหมด

📖 บทความที่เกี่ยวข้อง

Skaffold Dev Agile Scrum Kanbanอ่านบทความ → Skaffold Dev Interview Preparationอ่านบทความ → Skaffold Dev Multi-tenant Designอ่านบทความ → Skaffold Dev MLOps Workflowอ่านบทความ → Skaffold Dev AR VR Developmentอ่านบทความ →

📚 ดูบทความทั้งหมด →