บทนำ: YAML คืออะไร และทำไมจึงสำคัญสำหรับ Kubernetes
YAML (YAML Ain’t Markup Language) เป็นรูปแบบข้อมูลที่อ่านง่ายและเขียนง่าย ซึ่งใช้กันอย่างแพร่หลายในการกำหนดค่า (Configuration) สำหรับ Kubernetes ทุกครั้งที่คุณต้องการเรียกใช้งาน Pod, Deployment, Service หรือ Resource อื่น ๆ บน Kubernetes คุณจะต้องเขียน YAML manifest เพื่ออธิบายว่าคุณต้องการให้ระบบทำอะไร
เมื่อคุณใช้งาน Cloud VPS ของ ผู้ให้บริการโฮสติ้ง เพื่อรันคลัสเตอร์ Kubernetes ของตัวเอง การเข้าใจ YAML จะช่วยให้คุณสามารถจัดการและปรับแต่งการทำงานของระบบได้อย่างมีประสิทธิภาพ
YAML Syntax พื้นฐาน
1. Indentation (การเยื้อง)
YAML ใช้การเยื้อง (Indentation) เพื่อแสดงโครงสร้างลำดับชั้น (Hierarchy) ของข้อมูล สิ่งสำคัญคือต้องใช้ Space ไม่ใช่ Tab:
parent:
child: value
another_child: another_value
nested:
deep_value: example
2. Key-Value Pairs (คู่คีย์-ค่า)
ข้อมูลในรูปแบบคู่คีย์และค่า โดยคั่นด้วยเครื่องหมายโคลอน:
name: my-app
version: "1.0.0"
port: 8080
active: true
3. Lists (รายการ)
ใช้เครื่องหมายยัติภังค์ (-) เพื่อสร้างรายการ:
replicas: 3
containers:
- name: app
image: myapp:latest
- name: logger
image: logger:latest
env:
- DEBUG=true
- LOG_LEVEL=INFO
4. Multiline Strings (ข้อความหลายบรรทัด)
สำหรับข้อความยาว ใช้ | (preserve newlines) หรือ > (fold lines):
description: |
This is a multiline string
that spans multiple lines
and preserves line breaks
script: >
This is a folded string
that will be converted to
a single line of text
Kubernetes Manifest Structure
ทุก Kubernetes manifest ประกอบด้วยส่วนสำคัญ 4 ส่วน:
1. apiVersion
ระบุเวอร์ชันของ API ที่ใช้ เช่น v1 หรือ apps/v1 ตัวอย่างเช่น:
v1– Pod, Service, ConfigMapapps/v1– Deployment, StatefulSet, DaemonSetbatch/v1– Job, CronJob
2. kind
ระบุประเภทของ Resource เช่น Pod, Deployment, Service, StatefulSet เป็นต้น
3. metadata
ข้อมูลที่ใช้ระบุตัวตน เช่น name, namespace, labels, annotations:
metadata:
name: my-resource
namespace: production
labels:
app: myapp
version: v1
annotations:
description: "My application resource"
team: backend
4. spec
ข้อมูลรายละเอียดของการตั้งค่า ซึ่งแตกต่างกันไปตามประเภท Resource
ตัวอย่าง 1: เขียน Pod YAML
Pod คือ Unit ที่เล็กที่สุดใน Kubernetes ตัวอย่างนี้สร้าง Pod ที่รัน Nginx container:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: default
labels:
app: nginx
tier: web
spec:
containers:
- name: nginx
image: nginx:1.21
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: http
- containerPort: 443
name: https
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
restartPolicy: Always
ในตัวอย่างนี้:
- apiVersion: v1 – ใช้ API version ของ Pod
- kind: Pod – ประเภท Resource คือ Pod
- metadata.name: nginx-pod – ชื่อของ Pod
- spec.containers – อาร์เรย์ของ Container ที่จะรันใน Pod นี้
- containerPort: 80 – Port ที่ Container ฟังการเชื่อมต่อ
- resources.requests – ทรัพยากรที่ Pod ต้องการเสมอ
- resources.limits – ทรัพยากรสูงสุดที่ Pod สามารถใช้ได้
ตัวอย่าง 2: เขียน Deployment YAML ที่สมบูรณ์
Deployment ใช้สำหรับจัดการ Replicas ของ Pod และอัปเดตแอปพลิเคชันอย่างปลอดภัย:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
namespace: default
labels:
app: webapp
version: v2
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
tier: backend
spec:
containers:
- name: webapp
image: mywebapp:1.0.5
imagePullPolicy: Always
ports:
- containerPort: 3000
name: http
env:
- name: DATABASE_URL
value: "postgresql://db:5432/mydb"
- name: ENVIRONMENT
value: "production"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "1000m"
volumeMounts:
- name: config
mountPath: /etc/config
readOnly: true
volumes:
- name: config
configMap:
name: app-config
ในตัวอย่างนี้:
- replicas: 3 – จะสร้าง 3 Pod พร้อมๆ กัน
- strategy: RollingUpdate – อัปเดต Pod ทีละตัวเพื่อไม่ให้ service down
- livenessProbe – ตรวจสอบว่า Container ยังทำงานอยู่หรือไม่
- readinessProbe – ตรวจสอบว่า Container พร้อมรับ traffic หรือไม่
- volumeMounts – เชื่อมต่อ Volume เข้ากับ Container
ตัวอย่าง 3: เขียน Service YAML
Service ใช้สำหรับเปิด Pod ไปยังเครือข่ายภายนอก หรือเชื่อมต่อ Pod กันภายในคลัสเตอร์:
apiVersion: v1
kind: Service
metadata:
name: webapp-service
namespace: default
labels:
app: webapp
spec:
type: LoadBalancer
selector:
app: webapp
ports:
- protocol: TCP
port: 80
targetPort: 3000
nodePort: 30080
name: http
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
ในตัวอย่างนี้:
- type: LoadBalancer – เปิด Pod ไปยังอินเทอร์เน็ตสาธารณะ
- selector: app: webapp – เลือก Pod ที่มี Label app=webapp
- port: 80 – Port ของ Service ที่ Client จะใช้
- targetPort: 3000 – Port ที่แอปพลิเคชันฟัง
- nodePort: 30080 – Port บน Node ที่ traffic เข้ามา
ตัวอย่าง 4: เขียน ConfigMap และ Secret YAML
ConfigMap ใช้เก็บข้อมูลการตั้งค่าแบบไม่มี Secret:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
LOG_LEVEL: "INFO"
API_TIMEOUT: "30"
CACHE_TTL: "3600"
app.properties: |
server.port=8080
server.ssl.enabled=true
server.ssl.protocol=TLSv1.2
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
namespace: default
type: Opaque
data:
db-password: cGFzc3dvcmQxMjM= # base64 encoded
api-key: c2VjcmV0LWFwaS1rZXk= # base64 encoded
YAML Anchors & Aliases – ลดการซ้ำซ้อน
ใช้ & เพื่อสร้าง anchor และ * เพื่อใช้ซ้ำ:
defaults: &defaults
namespace: default
labels:
environment: production
team: backend
---
apiVersion: v1
kind: Pod
metadata:
<<: *defaults
name: pod-1
---
apiVersion: v1
kind: Pod
metadata:
<<: *defaults
name: pod-2
วิธีนี้ช่วยลดการซ้ำซ้อนของโค้ด YAML
Multi-Document YAML Files
คุณสามารถเก็บ Resource หลายตัวในไฟล์เดียวได้โดยใช้ --- (three dashes) เป็นตัวแบ่ง:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
config.yaml: |
key: value
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 1
template:
spec:
containers:
- name: app
image: myapp:latest
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
ports:
- port: 80
targetPort: 3000
ใช้คำสั่ง:
kubectl apply -f multi-resource.yaml
kubectl apply vs kubectl create
มี 2 วิธีในการใช้งาน YAML manifest:
- kubectl apply -f file.yaml - สร้าง Resource ใหม่ หรืออัปเดต Resource ที่มีอยู่แล้ว (Recommended)
- kubectl create -f file.yaml - สร้าง Resource ใหม่เท่านั้น ถ้า Resource มีอยู่แล้ว จะเกิดข้อผิดพลาด
โดยทั่วไป ควรใช้ kubectl apply เพราะมันปลอดภัยกว่า
kubectl Dry-Run และ Diff
ก่อนปรับใช้ YAML ควรทำการทดลอง (dry-run) เพื่อดูว่าจะเกิดอะไรขึ้น:
# ตรวจสอบว่า YAML ถูกต้องและจะสร้างอะไร โดยไม่สร้างจริง
kubectl apply -f deployment.yaml --dry-run=client
# ดูความแตกต่างระหว่างไฟล์ปัจจุบันและไฟล์ใหม่
kubectl apply -f deployment.yaml --dry-run=client --output=yaml
# ดู diff ของสิ่งที่จะเปลี่ยน
kubectl diff -f deployment.yaml
YAML Linting Tools
ใช้เครื่องมือเหล่านี้เพื่อตรวจสอบ YAML syntax และ best practices:
# ใช้ kubeval สำหรับ Kubernetes schema validation
kubeval deployment.yaml
# ใช้ kube-linter สำหรับ Best practices
kube-linter lint deployment.yaml
# ใช้ yamllint สำหรับ YAML formatting
yamllint -d relaxed deployment.yaml
# ติดตั้ง kubeval (macOS)
brew install kubeval
Common YAML Mistakes
1. ใช้ Tab แทน Space
ผิด:
parent:
\tchildren: value # ใช้ Tab
ถูก:
parent:
children: value # ใช้ 2 Spaces
2. ลืมใส่ Quotes ในค่าที่มี Special Characters
name: my-app:v1.0 # อาจเกิดข้อผิดพลาด
name: "my-app:v1.0" # ถูก
3. Indentation ไม่สอดคล้องกัน
containers:
- name: app
image: myapp:latest # Indentation ผิด
Best Practices การเขียน YAML
- ใช้ 2 Spaces สำหรับ Indentation - มี Convention ที่ยอมรับในชุมชน
- เพิ่ม Comments - ใช้ # เพื่อเพิ่มหมายเหตุอธิบาย
- ใช้ Namespaces - แยก Resources ต่าง ๆ ออกจากกันโดยใช้ Namespace
- ใส่ Labels และ Selectors - ช่วยให้ง่ายต่อการจัดการและค้นหา Resources
- ตั้งค่า Resource Limits - กำหนด CPU และ Memory requests/limits เสมอ
- ใส่ Health Checks - เพิ่ม liveness และ readiness probes
- Version Control - เก็บ YAML files ใน Git repository
- ใช้ Templates - พิจารณาใช้ Helm หรือ Kustomize สำหรับ YAML ที่ซับซ้อน
Tools ช่วยเหลือสำหรับ YAML
Online YAML Validators
- YAMLLint.com - ตรวจสอบ YAML syntax ออนไลน์
- JSON Schema Validator - ตรวจสอบ schema
IDE Extensions
- VS Code: YAML extension, Kubernetes extension
- JetBrains IDEs: Built-in YAML support
การใช้งาน YAML บน Cloud VPS ของ ผู้ให้บริการโฮสติ้ง
หากคุณสร้าง Kubernetes cluster บน Cloud VPS ของ ผู้ให้บริการโฮสติ้ง การใช้ YAML manifest ที่เขียนดีจะช่วยให้การ Deploy แอปพลิเคชันของคุณง่ายขึ้น ปลอดภัยขึ้น และง่ายต่อการบำรุงรักษา ด้วยความเป็นมืออาชีพและความเสถียรของ Cloud VPS ของ DE คุณสามารถจัดการทรัพยากร Kubernetes ได้อย่างเต็มที่
สรุป
การเขียน YAML สำหรับ Kubernetes อาจดูซับซ้อนตอนแรก แต่เมื่อคุณเข้าใจโครงสร้างพื้นฐาน syntax rules และ best practices คุณจะสามารถสร้างการกำหนดค่าที่ซับซ้อนและมีประสิทธิภาพได้ ต้องจำไว้ว่า:
- ใช้ Spaces ไม่ใช่ Tab สำหรับ Indentation
- ทดลอง (Dry-Run) ก่อนปรับใช้งาน
- ใช้ Linting Tools เพื่อตรวจสอบความถูกต้อง
- เขียนหมายเหตุ เพื่อให้ผู้อื่นเข้าใจได้
- ทดลองกับตัวอย่าง เช่นจากบทความนี้เพื่อเรียนรู้
เริ่มด้วยตัวอย่างง่าย ๆ ทดสอบใช้งาน และค่อย ๆ เพิ่มความซับซ้อนให้กับการตั้งค่าของคุณ สำหรับการใช้งาน Kubernetes ระดับมืออาชีพ ศึกษาเพิ่มเติมเกี่ยวกับ Helm Charts และ Kustomize ซึ่งจะช่วยให้คุณจัดการ YAML ได้ดีขึ้น
