SiamCafe · Blog
Kustomize Overlay Freelance IT Career — จัดการ
บทความ

Kustomize Overlay Freelance IT Career — จัดการ

เผยแพร่ 28 พฤษภาคม 2569

Kustomize Overlay

Kustomize Overlay Kubernetes Configuration Template-free Base Overlay Environment GitOps ArgoCD Flux kubectl Freelance IT Career Multi-client Portfolio

ToolApproachComplexityBuilt-in kubectlเหมาะกับ
KustomizeOverlay/Patchง่ายใช่Internal Apps
HelmGo Templateปานกลางไม่Shared Charts
JsonnetData Templateสูงไม่Complex Config
cdk8sCode (TypeScript)ปานกลางไม่Developer-friendly
TimoniCUE Languageปานกลางไม่Type-safe

Kustomize Structure

=== Kustomize Base + Overlay ===

Directory Structure

my-app/

├── base/

│ ├── kustomization.yaml

│ ├── deployment.yaml

│ ├── service.yaml

│ └── configmap.yaml

├── overlays/

│ ├── dev/

│ │ ├── kustomization.yaml

│ │ ├── replica-patch.yaml

│ │ └── env-patch.yaml

│ ├── staging/

│ │ ├── kustomization.yaml

│ │ └── replica-patch.yaml

│ └── production/

│ ├── kustomization.yaml

│ ├── replica-patch.yaml

│ ├── resource-patch.yaml

│ └── hpa.yaml

base/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1

kind: Kustomization

resources:

  • deployment.yaml
  • service.yaml
  • configmap.yaml

commonLabels:

app: my-app

managed-by: kustomize

base/deployment.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

name: my-app

spec:

replicas: 1

selector:

matchLabels:

app: my-app

template:

metadata:

labels:

app: my-app

spec:

containers:

  • name: app

image: my-app:latest

ports:

  • containerPort: 8080

resources:

requests:

cpu: 100m

memory: 128Mi

limits:

cpu: 500m

memory: 512Mi

overlays/production/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1

kind: Kustomization

resources:

  • ../../base
  • hpa.yaml

namespace: production

namePrefix: prod-

images:

  • name: my-app

newTag: v1.5.0

patches:

  • path: replica-patch.yaml
  • path: resource-patch.yaml

configMapGenerator:

  • name: app-config

literals:

  • ENV=production
  • LOG_LEVEL=warn
  • DB_HOST=prod-db.example.com

Commands

kubectl apply -k overlays/dev/ # Deploy to dev

kubectl apply -k overlays/staging/ # Deploy to staging

kubectl apply -k overlays/production/ # Deploy to production

kubectl kustomize overlays/production/ # Preview output

from dataclasses import dataclass

@dataclass

class KustomizeFeature:

feature: str

syntax: str

use_case: str

example: str

features = [

KustomizeFeature("namePrefix", "namePrefix: prod-", "แยก Resource ตาม Env", "prod-my-app"),

KustomizeFeature("namespace", "namespace: production", "กำหนด Namespace", "Deploy to NS"),

KustomizeFeature("images", "images: [{name, newTag}]", "เปลี่ยน Image Tag", "v1.5.0"),

KustomizeFeature("patches", "patches: [path: patch.yaml]", "แก้ไข Resource", "Replicas Resources"),

KustomizeFeature("configMapGenerator", "configMapGenerator:", "สร้าง ConfigMap", "ENV Variables"),

KustomizeFeature("secretGenerator", "secretGenerator:", "สร้าง Secret", "DB Password"),

KustomizeFeature("commonLabels", "commonLabels:", "ใส่ Label ทุก Resource", "app: my-app"),

]

print("=== Kustomize Features ===")

for f in features:

print(f" [{f.feature}] {f.syntax}")

print(f" Use: {f.use_case} | Example: {f.example}")

Multi-client Setup

=== Freelance Multi-client Kustomize ===

Directory Structure for Multiple Clients

platform/

├── base/

│ ├── kustomization.yaml

│ ├── deployment.yaml

│ ├── service.yaml

│ ├── ingress.yaml

│ └── configmap.yaml

├── clients/

│ ├── client-a/

│ │ ├── kustomization.yaml # namespace: client-a

│ │ ├── domain-patch.yaml # client-a.example.com

│ │ └── config-patch.yaml # Client-specific config

│ ├── client-b/

│ │ ├── kustomization.yaml

│ │ ├── domain-patch.yaml # client-b.example.com

│ │ └── resource-patch.yaml # Different resource needs

│ └── client-c/

│ ├── kustomization.yaml

│ └── domain-patch.yaml

Client Overlay Example

clients/client-a/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1

kind: Kustomization

resources:

  • ../../base

namespace: client-a

namePrefix: ca-

images:

  • name: my-app

newTag: v2.1.0

patches:

  • path: domain-patch.yaml

configMapGenerator:

  • name: app-config

behavior: merge

literals:

  • CLIENT_NAME=ClientA
  • DOMAIN=client-a.example.com
  • PLAN=enterprise

@dataclass

class ClientSetup:

client: str

namespace: str

domain: str

plan: str

replicas: int

monthly_fee: str

clients = [

ClientSetup("Client A (E-commerce)", "client-a", "shop-a.example.com", "Enterprise", 3, "$2,000"),

ClientSetup("Client B (SaaS)", "client-b", "app-b.example.com", "Business", 2, "$1,500"),

ClientSetup("Client C (Startup)", "client-c", "client-c.example.com", "Starter", 1, "$800"),

ClientSetup("Client D (Agency)", "client-d", "client-d.example.com", "Business", 2, "$1,500"),

]

print("\n=== Multi-client Deployments ===")

total_revenue = 0

for c in clients:

fee = int(c.monthly_fee.replace("$", "").replace(",", ""))

total_revenue += fee

print(f" [{c.client}] NS: {c.namespace}")

print(f" Domain: {c.domain} | Plan: {c.plan}")

print(f" Replicas: {c.replicas} | Fee: {c.monthly_fee}/mo")

print(f"\n Total Monthly Revenue: ")

print(f" Infrastructure Cost: ~$500/mo")

print(f" Profit Margin: {((total_revenue - 500) / total_revenue) * 100:.0f}%")

GitOps Workflow

=== GitOps with Kustomize + ArgoCD ===

ArgoCD Application

apiVersion: argoproj.io/v1alpha1

kind: Application

metadata:

name: client-a-production

namespace: argocd

spec:

project: default

source:

repoURL: https://github.com/freelancer/platform

targetRevision: main

path: clients/client-a

destination:

server: https://kubernetes.default.svc

namespace: client-a

syncPolicy:

automated:

prune: true

selfHeal: true

syncOptions:

  • CreateNamespace=true

CI/CD — GitHub Actions

name: Deploy

on:

push:

branches: [main]

jobs:

deploy:

runs-on: ubuntu-latest

steps:

  • uses: actions/checkout@v4
  • name: Validate Kustomize

run: |

for dir in clients/*/; do

echo "Validating $dir..."

kubectl kustomize "$dir" | kubeval --strict

done

  • name: Update image tag

run: |

cd clients/client-a

kustomize edit set image my-app=my-app:}

  • name: Commit and push

run: |

git add .

git commit -m "Update image to }"

git push

freelance_workflow = {

"New Client Onboarding": "Copy template overlay ปรับ Config 30 นาที",

"Deploy Update": "Git push → ArgoCD auto-sync 2 นาที",

"Rollback": "Git revert → ArgoCD auto-sync 1 นาที",

"Scale Up": "Edit replica-patch.yaml → Git push",

"Add Feature": "Update base → All clients get update",

"Client-specific": "Edit client overlay → Only that client",

"Monthly Report": "ArgoCD Dashboard + kubectl top",

}

print("Freelance GitOps Workflow:")

for step, desc in freelance_workflow.items():

print(f" [{step}]: {desc}")

เคล็ดลับ

  • Base: สร้าง Base ที่ดี ใช้ซ้ำกับทุก Client
  • Overlay: แต่ละ Client มี Overlay แยก ไม่ปนกัน
  • GitOps: ใช้ ArgoCD ทุก Deploy ผ่าน Git Review ได้
  • Template: สร้าง Client Template Onboard ไว ภายใน 30 นาที
  • Validate: ตรวจสอบ Kustomize Output ก่อน Apply ทุกครั้ง

Kustomize คืออะไร

Kubernetes Configuration Template-free Overlay Pattern Base kustomization.yaml Resources Patches Generators kubectl apply -k GitOps ArgoCD Flux