Crossplane Composition SaaS Architecture — สร้าง
Crossplane SaaS Architecture
Crossplane Composition SaaS Cloud Native Control Plane Kubernetes XRD Provider Self-Service Platform Multi-Cloud GitOps Reconciliation Tenant Infrastructure
| Tool | Approach | Drift Detection | Self-Service | เหมาะกับ |
|---|---|---|---|---|
| Crossplane | K8s Reconcile | อัตโนมัติ | ดีมาก | Platform Engineering |
| Terraform | CLI Plan/Apply | ไม่มี (ต้อง Manual) | ไม่มี | IaC ทั่วไป |
| Pulumi | Code (Python/TS) | ไม่มี | ไม่มี | Developer IaC |
| AWS CDK | Code (TS/Python) | ไม่มี | ไม่มี | AWS Only |
XRD และ Composition
=== Crossplane XRD & Composition ===
CompositeResourceDefinition (XRD)
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xdatabases.platform.example.com
spec:
group: platform.example.com
names:
kind: XDatabase
plural: xdatabases
claimNames:
kind: Database
plural: databases
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
engine:
type: string
enum: [postgres, mysql]
size:
type: string
enum: [small, medium, large]
region:
type: string
default: ap-southeast-1
Composition — What gets created
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: database-aws
spec:
compositeTypeRef:
apiVersion: platform.example.com/v1alpha1
kind: XDatabase
resources:
- name: vpc
base:
apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
spec:
forProvider:
cidrBlock: 10.0.0.0/16
enableDnsSupport: true
- name: subnet-a
base:
apiVersion: ec2.aws.upbound.io/v1beta1
kind: Subnet
spec:
forProvider:
cidrBlock: 10.0.1.0/24
- name: rds
base:
apiVersion: rds.aws.upbound.io/v1beta1
kind: Instance
spec:
forProvider:
engine: postgres
instanceClass: db.t3.medium
allocatedStorage: 20
from dataclasses import dataclass
from typing import List
@dataclass
class CompositionResource:
name: str
kind: str
provider: str
status: str
resources_per_tenant = [
CompositionResource("VPC", "ec2.VPC", "AWS", "Ready"),
CompositionResource("Subnet x2", "ec2.Subnet", "AWS", "Ready"),
CompositionResource("Security Group", "ec2.SecurityGroup", "AWS", "Ready"),
CompositionResource("RDS PostgreSQL", "rds.Instance", "AWS", "Ready"),
CompositionResource("ElastiCache Redis", "elasticache.Cluster", "AWS", "Ready"),
CompositionResource("S3 Bucket", "s3.Bucket", "AWS", "Ready"),
]
print("=== Resources per Tenant (Composition) ===")
for r in resources_per_tenant:
print(f" [{r.status}] {r.name} ({r.kind}) — {r.provider}")
Self-Service Platform
=== Developer Self-Service ===
Developer creates a simple Claim
apiVersion: platform.example.com/v1alpha1
kind: Database
metadata:
name: tenant-acme-db
namespace: tenant-acme
spec:
engine: postgres
size: medium
region: ap-southeast-1
kubectl apply -f database-claim.yaml
kubectl get databases -n tenant-acme
kubectl describe database tenant-acme-db -n tenant-acme
SaaS Tenant Onboarding Script
#!/bin/bash
TENANT=$1
kubectl create namespace tenant-$TENANT
cat <<EOF | kubectl apply -f -
apiVersion: platform.example.com/v1alpha1
kind: Database
metadata:
name: -db
namespace: tenant-
spec:
engine: postgres
size: small
region: ap-southeast-1
---
apiVersion: platform.example.com/v1alpha1
kind: Cache
metadata:
name: -cache
namespace: tenant-
spec:
engine: redis
size: small
EOF
@dataclass
class Tenant:
name: str
plan: str
db_size: str
cache: bool
region: str
status: str
mrr: float
tenants = [
Tenant("acme-corp", "Enterprise", "large", True, "ap-southeast-1", "Active", 29990),
Tenant("startup-xyz", "Pro", "medium", True, "ap-southeast-1", "Active", 9990),
Tenant("shop-abc", "Basic", "small", False, "ap-southeast-1", "Active", 2990),
Tenant("agency-def", "Pro", "medium", True, "us-east-1", "Active", 9990),
Tenant("trial-ghi", "Trial", "small", False, "ap-southeast-1", "Trial", 0),
]
print("\n=== SaaS Tenants ===")
total_mrr = 0
for t in tenants:
total_mrr += t.mrr
cache_str = "Redis" if t.cache else "—"
print(f" [{t.status}] {t.name} ({t.plan})")
print(f" DB: {t.db_size} | Cache: {cache_str} | Region: {t.region} | MRR: {t.mrr:,.0f}")
print(f"\n Total MRR: {total_mrr:,.0f} บาท")
Multi-Cloud และ GitOps
=== Multi-Cloud & GitOps ===
ArgoCD + Crossplane GitOps
Git Repo Structure:
infrastructure/
├── base/
│ ├── xrd-database.yaml
│ ├── composition-aws.yaml
│ └── composition-gcp.yaml
├── tenants/
│ ├── acme-corp/
│ │ ├── database.yaml
│ │ └── cache.yaml
│ └── startup-xyz/
│ ├── database.yaml
│ └── cache.yaml
└── providers/
├── provider-aws.yaml
└── provider-gcp.yaml
ArgoCD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: crossplane-tenants
spec:
source:
repoURL: https://github.com/org/infrastructure
path: tenants
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated:
prune: true
selfHeal: true
platform_metrics = {
"Total Tenants": "45 active + 12 trial",
"Cloud Resources": "270 managed resources",
"Drift Detected (30d)": "3 (auto-corrected)",
"Avg Provisioning Time": "4.5 minutes",
"Failed Provisions (30d)": "1 (quota limit)",
"Multi-region": "3 regions (AP, US, EU)",
"Monthly Cloud Cost": "$8,500",
"Total MRR": "52,960 บาท",
}
print("Platform Engineering Dashboard:")
for k, v in platform_metrics.items():
print(f" {k}: {v}")
Composition Selection by Region
compositions = {
"ap-southeast-1": "composition-aws-ap",
"us-east-1": "composition-aws-us",
"eu-west-1": "composition-aws-eu",
"asia-east1": "composition-gcp-asia",
}
print(f"\n\nComposition by Region:")
for region, comp in compositions.items():
print(f" [{region}]: {comp}")
เคล็ดลับ
- XRD: ออกแบบ XRD ง่ายๆ สำหรับ Developer ซ่อน Cloud Complexity
- Composition: ฝัง Security Best Practices ใน Composition
- GitOps: ใช้ ArgoCD + Crossplane สำหรับ Full GitOps
- Quota: ตั้ง Resource Quota ต่อ Tenant ป้องกัน Overuse
- Monitor: Monitor Crossplane Resources และ Drift Detection
การนำไปใช้งานจริงในองค์กร
สำหรับองค์กรขนาดกลางถึงใหญ่ แนะนำให้ใช้หลัก Three-Tier Architecture คือ Core Layer ที่เป็นแกนกลางของระบบ Distribution Layer ที่ทำหน้าที่กระจาย Traffic และ Access Layer ที่เชื่อมต่อกับผู้ใช้โดยตรง การแบ่ง Layer ชัดเจนช่วยให้การ Troubleshoot ง่ายขึ้นและสามารถ Scale ระบบได้ตามความต้องการ
เรื่อง Network Security ก็สำคัญไม่แพ้กัน ควรติดตั้ง Next-Generation Firewall ที่สามารถ Deep Packet Inspection ได้ ใช้ Network Segmentation แยก VLAN สำหรับแต่ละแผนก ติดตั้ง IDS/IPS เพื่อตรวจจับการโจมตี และทำ Regular Security Audit อย่างน้อยปีละ 2 ครั้ง
เปรียบเทียบข้อดีและข้อเสีย
จากตารางเปรียบเทียบจะเห็นว่าข้อดีมีมากกว่าข้อเสียอย่างชัดเจน โดยเฉพาะในแง่ของประสิทธิภาพและความสามารถในการ Scale สำหรับข้อเสียส่วนใหญ่สามารถแก้ไขได้ด้วยการเรียนรู้อย่างเป็นระบบและวางแผนทรัพยากรให้เหมาะสม
Crossplane คืออะไร
Cloud Native Control Plane Kubernetes API YAML AWS GCP Azure GitOps Reconciliation Self-Service Developer สร้าง Infrastructure เอง
Composition คืออะไร
รวมหลาย Resources เป็น Abstract Resource เดียว VPC Subnet RDS เป็น Database Claim Developer ของ่าย Platform กำหนด Best Practices
Crossplane กับ Terraform ต่างกันอย่างไร
Crossplane K8s Reconciliation Drift Auto Self-healing GitOps Self-Service Terraform CLI Plan Apply Manual ไม่มี Drift ใช้ร่วมกันได้
SaaS Architecture ใช้ Crossplane อย่างไร
Tenant แยก Infrastructure Composition สร้าง DB Cache Queue ต่อ Tenant Onboarding Claim เดียว Offboarding ลบ Claim Scaling ปรับ Spec
สรุป
Crossplane Composition SaaS XRD Claim Self-Service Platform Kubernetes Multi-Cloud GitOps ArgoCD Tenant Onboarding Offboarding Scaling Drift Detection Reconciliation