Technology

Crossplane Composition Interview Preparation — เตรียมสัมภาษณ์ Kubernetes Infrastructure

crossplane composition interview preparation
Crossplane Composition Interview Preparation | SiamCafe Blog
2025-09-28· อ. บอม — SiamCafe.net· 1,383 คำ

Crossplane คืออะไร

Crossplane เป็น open source Kubernetes add-on ที่เปลี่ยน Kubernetes cluster ให้เป็น universal control plane สำหรับจัดการ cloud infrastructure ทุกชนิด ใช้ Kubernetes API และ custom resources ในการสร้างและจัดการ cloud resources เช่น databases, storage buckets, VPCs, Kubernetes clusters บน AWS, GCP, Azure และ providers อื่นๆ

หลักการสำคัญของ Crossplane ได้แก่ Infrastructure as Data ประกาศ infrastructure เป็น Kubernetes YAML manifests, Compositions สร้าง abstractions ที่รวม resources หลายตัวเข้าด้วยกัน, Self-Healing Kubernetes reconciliation loop ดูแลให้ infrastructure ตรงกับ desired state, GitOps Ready ใช้กับ ArgoCD หรือ Flux ได้ทันที และ Multi-Cloud จัดการ resources จากหลาย cloud providers ด้วย API เดียว

Crossplane เหมาะสำหรับ platform teams ที่ต้องการสร้าง Internal Developer Platform (IDP) ให้ developers สร้าง infrastructure ได้เองผ่าน self-service API โดยไม่ต้องเรียนรู้ cloud-specific tools

ติดตั้ง Crossplane บน Kubernetes

ขั้นตอนติดตั้ง Crossplane

# === ติดตั้ง Crossplane ===

# 1. Prerequisites
# ===================================
# Kubernetes cluster (1.24+)
# kubectl configured
# Helm 3.x installed

kubectl version --client
helm version

# 2. Install Crossplane with Helm
# ===================================
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update

helm install crossplane crossplane-stable/crossplane \
 --namespace crossplane-system \
 --create-namespace \
 --set args='{"--enable-composition-revisions"}' \
 --wait

# Verify
kubectl get pods -n crossplane-system
# crossplane-xxx 1/1 Running
# crossplane-rbac-manager-xxx 1/1 Running

# 3. Install Crossplane CLI
# ===================================
curl -sL "https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh" | sh
sudo mv crossplane /usr/local/bin/

crossplane --version

# 4. Install AWS Provider
# ===================================
cat <<'EOF' | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
 name: provider-aws
spec:
 package: xpkg.upbound.io/upbound/provider-aws-s3:v1.1.0
EOF

# Wait for provider to be healthy
kubectl get providers
kubectl wait provider provider-aws --for=condition=Healthy --timeout=300s

# 5. Configure AWS Credentials
# ===================================
# Create credentials secret
cat > aws-credentials.txt << 'CRED'
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
CRED

kubectl create secret generic aws-secret \
 -n crossplane-system \
 --from-file=creds=./aws-credentials.txt

# Create ProviderConfig
cat <<'EOF' | kubectl apply -f -
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
 name: default
spec:
 credentials:
 source: Secret
 secretRef:
 namespace: crossplane-system
 name: aws-secret
 key: creds
EOF

# 6. Verify Setup
# ===================================
kubectl get providers
kubectl get providerconfigs
kubectl api-resources | grep aws

echo "Crossplane installed and configured"

Compositions และ Composite Resources

สร้าง Compositions สำหรับ infrastructure abstractions

# === Crossplane Compositions ===

# 1. CompositeResourceDefinition (XRD)
# กำหนด API สำหรับ developers
cat <<'EOF' | kubectl apply -f -
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:
 parameters:
 type: object
 properties:
 engine:
 type: string
 enum: ["postgres", "mysql"]
 default: "postgres"
 size:
 type: string
 enum: ["small", "medium", "large"]
 default: "small"
 region:
 type: string
 default: "ap-southeast-1"
 storageGB:
 type: integer
 default: 20
 required:
 - engine
 - size
EOF

# 2. Composition
# กำหนดว่า XDatabase สร้าง resources อะไรบ้าง
cat <<'EOF' | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
 name: database-aws
 labels:
 provider: aws
spec:
 compositeTypeRef:
 apiVersion: platform.example.com/v1alpha1
 kind: XDatabase
 resources:
 - name: rds-instance
 base:
 apiVersion: rds.aws.upbound.io/v1beta1
 kind: Instance
 spec:
 forProvider:
 engine: postgres
 engineVersion: "15"
 instanceClass: db.t3.micro
 allocatedStorage: 20
 publiclyAccessible: false
 skipFinalSnapshot: true
 masterUsername: admin
 masterPasswordSecretRef:
 namespace: crossplane-system
 name: db-password
 key: password
 patches:
 - type: FromCompositeFieldPath
 fromFieldPath: spec.parameters.engine
 toFieldPath: spec.forProvider.engine
 - type: FromCompositeFieldPath
 fromFieldPath: spec.parameters.region
 toFieldPath: spec.forProvider.region
 - type: FromCompositeFieldPath
 fromFieldPath: spec.parameters.storageGB
 toFieldPath: spec.forProvider.allocatedStorage
 - type: FromCompositeFieldPath
 fromFieldPath: spec.parameters.size
 toFieldPath: spec.forProvider.instanceClass
 transforms:
 - type: map
 map:
 small: db.t3.micro
 medium: db.t3.medium
 large: db.r6g.large
 - name: security-group
 base:
 apiVersion: ec2.aws.upbound.io/v1beta1
 kind: SecurityGroup
 spec:
 forProvider:
 description: "Database security group"
 ingress:
 - fromPort: 5432
 toPort: 5432
 protocol: tcp
 cidrBlocks:
 - "10.0.0.0/8"
 patches:
 - type: FromCompositeFieldPath
 fromFieldPath: spec.parameters.region
 toFieldPath: spec.forProvider.region
EOF

# 3. Claim (Developer API)
# Developer สร้าง database ด้วย simple YAML
cat <<'EOF' | kubectl apply -f -
apiVersion: platform.example.com/v1alpha1
kind: Database
metadata:
 name: my-app-db
 namespace: default
spec:
 parameters:
 engine: postgres
 size: small
 region: ap-southeast-1
 storageGB: 50
EOF

# 4. Check Status
kubectl get databases
kubectl get xdatabases
kubectl get managed

สร้าง Cloud Infrastructure ด้วย Crossplane

ตัวอย่างการสร้าง infrastructure จริง

#!/usr/bin/env python3
# crossplane_manager.py — Crossplane Infrastructure Manager
import json
import logging
import subprocess
from typing import Dict, List, Optional
from dataclasses import dataclass

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("crossplane")

class CrossplaneManager:
 def __init__(self):
 self.resources = []
 
 def apply_manifest(self, manifest: Dict):
 """Apply a Kubernetes manifest"""
 manifest_json = json.dumps(manifest)
 # result = subprocess.run(
 # ["kubectl", "apply", "-f", "-"],
 # input=manifest_json, capture_output=True, text=True
 # )
 self.resources.append(manifest)
 kind = manifest.get("kind", "Unknown")
 name = manifest.get("metadata", {}).get("name", "unnamed")
 logger.info(f"Applied: {kind}/{name}")
 return {"status": "applied", "kind": kind, "name": name}
 
 def create_database_claim(self, name, namespace="default",
 engine="postgres", size="small",
 region="ap-southeast-1", storage_gb=20):
 claim = {
 "apiVersion": "platform.example.com/v1alpha1",
 "kind": "Database",
 "metadata": {"name": name, "namespace": namespace},
 "spec": {
 "parameters": {
 "engine": engine,
 "size": size,
 "region": region,
 "storageGB": storage_gb,
 }
 }
 }
 return self.apply_manifest(claim)
 
 def create_bucket_claim(self, name, namespace="default",
 region="ap-southeast-1", versioning=True):
 claim = {
 "apiVersion": "platform.example.com/v1alpha1",
 "kind": "Bucket",
 "metadata": {"name": name, "namespace": namespace},
 "spec": {
 "parameters": {
 "region": region,
 "versioning": versioning,
 }
 }
 }
 return self.apply_manifest(claim)
 
 def create_app_infrastructure(self, app_name, environment="staging"):
 """Create complete infrastructure for an application"""
 results = []
 
 # Database
 db_size = "small" if environment == "staging" else "medium"
 results.append(self.create_database_claim(
 f"{app_name}-db-{environment}",
 engine="postgres", size=db_size, storage_gb=50
 ))
 
 # Cache (Redis)
 results.append(self.apply_manifest({
 "apiVersion": "platform.example.com/v1alpha1",
 "kind": "Cache",
 "metadata": {"name": f"{app_name}-cache-{environment}"},
 "spec": {
 "parameters": {
 "engine": "redis",
 "size": "small" if environment == "staging" else "medium",
 }
 }
 }))
 
 # Storage Bucket
 results.append(self.create_bucket_claim(
 f"{app_name}-assets-{environment}",
 versioning=(environment == "production")
 ))
 
 return {
 "app": app_name,
 "environment": environment,
 "resources_created": len(results),
 "details": results,
 }
 
 def get_resource_status(self):
 # result = subprocess.run(
 # ["kubectl", "get", "managed", "-o", "json"],
 # capture_output=True, text=True
 # )
 return {
 "total_resources": len(self.resources),
 "resources": [
 {
 "kind": r["kind"],
 "name": r["metadata"]["name"],
 "status": "Ready",
 }
 for r in self.resources
 ]
 }

mgr = CrossplaneManager()
result = mgr.create_app_infrastructure("my-app", "production")
print(json.dumps(result, indent=2))
print(json.dumps(mgr.get_resource_status(), indent=2))

Interview Questions และคำตอบ

คำถามสัมภาษณ์เกี่ยวกับ Crossplane

# === Crossplane Interview Questions ===

# Q1: Crossplane ต่างจาก Terraform อย่างไร?
# ===================================
# Crossplane:
# - Kubernetes-native (uses CRDs and controllers)
# - Continuous reconciliation (self-healing)
# - Uses kubectl / Kubernetes API
# - Compositions = reusable abstractions
# - Built-in RBAC via Kubernetes
# - GitOps-ready (ArgoCD/Flux)
# - Real-time drift detection and correction
#
# Terraform:
# - Standalone tool with HCL language
# - Plan/Apply workflow (not continuous)
# - Uses terraform CLI
# - Modules = reusable components
# - Separate state management
# - Requires wrapper for GitOps
# - Drift detection only on terraform plan

# Q2: Composition คืออะไรและทำไมต้องใช้?
# ===================================
# Composition คือ template ที่กำหนดว่าเมื่อ user สร้าง
# Composite Resource (XR) จะต้องสร้าง managed resources อะไรบ้าง
#
# ใช้เพราะ:
# 1. Abstraction: ซ่อน complexity จาก developers
# 2. Standardization: enforce standards (security, naming, tags)
# 3. Self-service: developers สร้าง infra เองได้
# 4. Multi-cloud: เปลี่ยน provider โดยไม่ต้องเปลี่ยน Claim

# Q3: XRD, Composition, XR, Claim ต่างกันอย่างไร?
# ===================================
# XRD (CompositeResourceDefinition):
# - กำหนด API schema (เหมือน CRD)
# - กำหนดว่า user ส่ง parameters อะไรได้บ้าง
#
# Composition:
# - กำหนดว่า XR สร้าง resources อะไร
# - มี patches สำหรับ map parameters ไป resources
# - สามารถมีหลาย Compositions ต่อ 1 XRD (multi-cloud)
#
# XR (Composite Resource):
# - Instance ของ XRD ที่สร้างจริง
# - Cluster-scoped
# - Owner ของ managed resources
#
# Claim:
# - Namespace-scoped wrapper ของ XR
# - สำหรับ developers (ไม่ต้องเห็น cluster-level details)

# Q4: Crossplane reconciliation loop ทำงานอย่างไร?
# ===================================
# 1. User creates Claim/XR
# 2. Composition controller creates managed resources
# 3. Provider controller calls cloud API to create resources
# 4. Controller continuously checks actual state vs desired state
# 5. If drift detected, controller corrects it automatically
# 6. Status propagated back to XR and Claim
#
# Interval: default 1 minute (configurable)
# This is why Crossplane provides "self-healing" infrastructure

# Q5: วิธี handle secrets ใน Crossplane?
# ===================================
# 1. ConnectionDetails: Crossplane propagates secrets from
# managed resources to Kubernetes secrets automatically
# 2. External Secrets Operator: integrate with Vault, AWS SM
# 3. ProviderConfig credentials: stored as K8s secrets
# 4. IRSA/Workload Identity: cloud-native auth (no static keys)

# Q6: Crossplane กับ ArgoCD ใช้ร่วมกันอย่างไร?
# ===================================
# ArgoCD manages Crossplane manifests in Git:
# - XRDs and Compositions in platform-team repo
# - Claims in application-team repos
# - ArgoCD syncs Claims to cluster
# - Crossplane creates cloud resources
# - GitOps workflow for infrastructure changes

echo "Interview preparation complete"

Best Practices และ Production Tips

แนวปฏิบัติสำหรับ production

# === Crossplane Production Best Practices ===

# 1. Composition Design Patterns
# ===================================
# a) Keep Compositions simple (< 10 resources)
# b) Use sensible defaults in XRD schema
# c) Version your XRDs (v1alpha1 -> v1beta1 -> v1)
# d) Use labels and annotations for tracking
# e) Test Compositions in staging before production

# 2. Security Best Practices
# ===================================
# a) Use IRSA/Workload Identity instead of static credentials
# b) Least privilege for provider service accounts
# c) Namespace-scoped Claims (not cluster-scoped XRs) for developers
# d) Use Kubernetes RBAC to control who can create Claims
# e) Encrypt sensitive ConnectionDetails

# Example RBAC for developers
cat <<'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
 name: database-consumer
rules:
 - apiGroups: ["platform.example.com"]
 resources: ["databases"]
 verbs: ["get", "list", "create", "update", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
 name: dev-team-databases
subjects:
 - kind: Group
 name: dev-team
roleRef:
 kind: ClusterRole
 name: database-consumer
 apiGroup: rbac.authorization.k8s.io
EOF

# 3. Monitoring and Alerting
# ===================================
# Prometheus metrics:
# crossplane_managed_resource_exists{kind="Instance"}
# crossplane_managed_resource_ready{kind="Instance"}
# crossplane_composite_resource_ready{kind="XDatabase"}
#
# Alert rules:
# - Resource not ready for > 10 minutes
# - Provider unhealthy
# - Composition error rate > 0

# 4. Disaster Recovery
# ===================================
# a) Backup Crossplane CRDs and custom resources
# b) Store Compositions and XRDs in Git (GitOps)
# c) Claims stored in application repos
# d) Cloud resources exist independently of Crossplane
# e) deletionPolicy: Orphan prevents resource deletion

# 5. Performance Tuning
# ===================================
# a) Increase provider replicas for many resources
# b) Set appropriate pollInterval (default 1m)
# c) Use providerConfigRef to distribute load
# d) Monitor controller memory usage

# Tune provider resources
cat <<'EOF'
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
 name: provider-aws
spec:
 package: xpkg.upbound.io/upbound/provider-aws-s3:v1.1.0
 controllerConfigRef:
 name: aws-config
---
apiVersion: pkg.crossplane.io/v1alpha1
kind: ControllerConfig
metadata:
 name: aws-config
spec:
 resources:
 limits:
 memory: 512Mi
 cpu: 500m
 requests:
 memory: 256Mi
 cpu: 100m
 args:
 - --poll=30s
 - --max-reconcile-rate=10
EOF

echo "Best practices documented"

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

Q: Crossplane เหมาะกับองค์กรแบบไหน?

A: เหมาะกับองค์กรที่ใช้ Kubernetes เป็นหลักอยู่แล้ว, ต้องการสร้าง Internal Developer Platform (IDP) ให้ developers self-service infrastructure, ใช้ multi-cloud หรือ hybrid cloud, ต้องการ GitOps workflow สำหรับ infrastructure และ ต้องการ continuous reconciliation (self-healing) ไม่เหมาะกับองค์กรที่ไม่ใช้ Kubernetes หรือ team เล็กที่ Terraform เพียงพอ

Q: Crossplane กับ Pulumi ต่างกันอย่างไร?

A: Crossplane เป็น Kubernetes-native ใช้ YAML declarative approach ทำงานเป็น controller ใน cluster มี continuous reconciliation เหมาะสำหรับ platform teams ที่สร้าง abstractions Pulumi ใช้ general-purpose programming languages (Python, Go, TypeScript) มี flexibility สูงกว่า ไม่ต้องใช้ Kubernetes เหมาะสำหรับ teams ที่ต้องการ programmatic control ใช้ Crossplane ถ้า Kubernetes-centric ใช้ Pulumi ถ้าต้องการ code-first approach

Q: Composition patches ทำงานอย่างไร?

A: Patches ใช้ map ค่าจาก Composite Resource (XR) ไปยัง managed resources มีหลายประเภท FromCompositeFieldPath copy ค่าจาก XR ไป resource, ToCompositeFieldPath copy ค่าจาก resource กลับไป XR, CombineFromComposite รวมหลายค่าเข้าด้วยกัน (เช่น naming), transforms แปลงค่า (map, math, string) เช่น map size small/medium/large ไปเป็น instance class patches ทำให้ Compositions flexible และ reusable

Q: จะ migrate จาก Terraform ไป Crossplane อย่างไร?

A: ทำ gradual migration ไม่ต้องเปลี่ยนทั้งหมดในครั้งเดียว เริ่มจาก import existing resources ด้วย crossplane managed resource annotations, สร้าง Compositions สำหรับ new resources, ใช้ Terraform สำหรับ existing resources และ Crossplane สำหรับ new ones, ค่อยๆ migrate resources เมื่อ team พร้อม ใช้ Upbound marketplace สำหรับ pre-built providers และ configurations เพื่อเร่ง migration

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

Kustomize Overlay Interview Preparationอ่านบทความ → Ansible Vault Interview Preparationอ่านบทความ → Crossplane Composition Service Level Objective SLOอ่านบทความ → Crossplane Composition Cache Strategy Redisอ่านบทความ → Crossplane Composition Low Code No Codeอ่านบทความ →

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