Skip to content

Kubernetes

ระบบจัดการ container orchestration ที่ช่วยให้จัดการ container หลายตัวใน cluster ได้อย่างมีประสิทธิภาพ รองรับการ scale, deploy, และ manage applications อัตโนมัติ

สร้าง resource จาก YAML ด้วย kubectl apply โดยแต่ละ snippet สามารถแยกเป็นไฟล์แล้วนำไปใช้ได้ทันที

Pod เหมาะสำหรับการทดลองหรือ workload ที่ไม่ต้องการ rolling update และ self-healing แบบ Deployment

apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
Terminal window
# สร้าง Pod
kubectl apply -f pod.yaml
# ตรวจสอบ Pod และดูรายละเอียด
kubectl get pod nginx-pod
kubectl describe pod nginx-pod
# ลบ Pod
kubectl delete -f pod.yaml

Deployment เหมาะสำหรับ application ที่ต้องการ replicas, rolling update และ self-healing

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
env:
- name: APP_ENV
value: production
- name: API_URL
valueFrom:
configMapKeyRef:
name: app-config
key: api-url
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: database-password
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
ports:
- containerPort: 80

โครงสร้าง spec ของ Deployment มีส่วนสำคัญดังนี้:

  • spec.replicas และ spec.selector — กำหนดจำนวน replicas และบอกว่า Deployment จะดูแล Pod ไหน
  • spec.template — template สำหรับสร้าง Pod ใหม่ โดย label ต้องตรงกับ selector.matchLabels
  • spec.template.spec — กำหนดรายละเอียดของ Pod เช่น containers, volumes และ serviceAccountName
  • spec.template.spec.containers[].env — กำหนด environment variables ให้ container แต่ละตัว
  • spec.template.spec.containers[].resources — กำหนด resource ที่ container ขอใช้และใช้ได้สูงสุด

requests ใช้ให้ Kubernetes เลือก Node ที่มี resource เพียงพอ ส่วน limits ใช้จำกัดการใช้งานสูงสุดของ container หากใช้ memory เกิน limit อาจถูก OOMKilled และถ้าใช้ CPU เกิน limit จะถูก throttle

ค่าใน env มีได้หลายรูปแบบ:

env:
# ค่าแบบเขียนตรง ๆ เหมาะกับค่าที่ไม่ sensitive
- name: APP_ENV
value: production
# อ่านค่าจาก ConfigMap
- name: API_URL
valueFrom:
configMapKeyRef:
name: app-config
key: api-url
# อ่านค่าจาก Secret ห้ามใส่ password ตรง ๆ ใน Deployment YAML
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: database-password

ถ้าต้องการโหลดทุก key จาก ConfigMap หรือ Secret เป็น environment variables ให้ใช้ envFrom แทน env:

spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.27
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secret
Terminal window
# สร้างหรืออัปเดต Deployment
kubectl apply -f deployment.yaml
# รอให้ rollout เสร็จ
kubectl rollout status deployment/nginx
# ตรวจสอบ Pods ที่ Deployment ดูแล
kubectl get deployment,pods -l app=nginx
# ลบ Deployment
kubectl delete -f deployment.yaml

Service ใช้เปิด endpoint ให้ Pod อื่นหรือผู้ใช้งานเข้าถึง โดย selector ต้องตรงกับ label ของ Pod

apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: ClusterIP
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
Terminal window
# สร้าง Service
kubectl apply -f service.yaml
# ตรวจสอบ Service และ endpoints
kubectl get svc nginx
kubectl get endpoints nginx
# ทดสอบจากเครื่อง local
kubectl port-forward svc/nginx 8080:80
# ลบ Service
kubectl delete -f service.yaml

NodePort — เปิดผ่าน port ของ Node (ช่วง 30000-32767) เหมาะกับ cluster ที่ยังไม่มี LoadBalancer

apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
Terminal window
# เข้าถึงผ่าน IP ของ Node ใด Node หนึ่ง
curl http://<node-ip>:30080

LoadBalancer — ให้ cloud provider สร้าง external load balancer ให้อัตโนมัติ เหมาะกับการเปิด traffic จากภายนอก cluster

apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
Terminal window
# รอจนได้ external IP
kubectl get svc nginx-lb -w
# ทดสอบจากภายนอก
curl http://<external-ip>

Headless — ตั้ง clusterIP: None เพื่อไม่สร้าง virtual IP และไม่ทำ load balancing แต่จะ return IP ของ Pod ทุกตัวผ่าน DNS แทน เหมาะกับ StatefulSet ที่ต้องติดต่อ Pod ตรง ๆ เช่น database cluster

apiVersion: v1
kind: Service
metadata:
name: postgres-headless
spec:
clusterIP: None
selector:
app: postgres
ports:
- name: postgres
port: 5432
targetPort: 5432
Terminal window
# DNS จะ resolve เป็น IP ของ Pod ทุกตัว ไม่ใช่ IP เดียว
nslookup postgres-headless
# เข้าถึง Pod เฉพาะตัวของ StatefulSet ผ่าน pattern <pod-name>.<service-name>
nslookup postgres-0.postgres-headless
Avatar whiteCat
Headless Service มักใช้คู่กับ StatefulSet เพราะ Pod แต่ละตัวมี identity ชัดเจน (เช่น postgres-0, postgres-1) ทำให้ client เลือกติดต่อ Pod ใด Pod หนึ่งได้โดยตรง ไม่ผ่าน load balancing

ใช้เก็บ configuration ที่ไม่เป็นความลับ และนำไปใช้เป็น environment variables หรือ file ได้

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
app.properties: |
feature.new-ui=true
http.timeout=30s
Terminal window
# สร้าง ConfigMap
kubectl apply -f configmap.yaml
# ตรวจสอบค่าใน ConfigMap
kubectl get configmap app-config -o yaml
# ลบ ConfigMap
kubectl delete -f configmap.yaml

ใช้เก็บข้อมูล sensitive เช่น password, token หรือ API key โดยใช้ stringData เพื่อให้เขียนค่า plain text ใน manifest ได้ง่าย

apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
stringData:
DATABASE_USER: app
DATABASE_PASSWORD: change-me
API_TOKEN: replace-me
Terminal window
# สร้าง Secret
kubectl apply -f secret.yaml
# ตรวจสอบ metadata โดยไม่แสดงค่า secret
kubectl get secret app-secret
# อ่านค่าและ decode เฉพาะ key ที่ต้องการ
kubectl get secret app-secret -o jsonpath='{.data.DATABASE_PASSWORD}' | base64 -d
# ลบ Secret
kubectl delete -f secret.yaml

Secret ที่เก็บใน Kubernetes เป็น Base64 encoding ไม่ใช่ encryption โดยอัตโนมัติ หลีกเลี่ยงการ commit ค่า secret จริงลง Git

ตัวอย่างด้านล่างเป็น snippets ที่พบบ่อยสำหรับเพิ่ม volume และ volumeMounts ใน spec ของ Pod หรือ Deployment template

emptyDir สำหรับ temporary storage

Section titled “emptyDir สำหรับ temporary storage”

ข้อมูลอยู่ตลอดอายุของ Pod และจะหายเมื่อ Pod ถูกลบหรือย้ายไป Node ใหม่

apiVersion: v1
kind: Pod
metadata:
name: emptydir-demo
spec:
containers:
- name: app
image: nginx:1.27
volumeMounts:
- name: cache
mountPath: /var/cache/app
volumes:
- name: cache
emptyDir: {}

เหมาะกับ cache ชั่วคราวที่ต้องการความเร็ว แต่ใช้ RAM ของ Node และควรกำหนดขนาดจำกัด

volumes:
- name: memory-cache
emptyDir:
medium: Memory
sizeLimit: 256Mi

hostPath สำหรับ mount directory จาก Node

Section titled “hostPath สำหรับ mount directory จาก Node”

ใช้เฉพาะกรณีที่จำเป็นจริง ๆ เพราะ Pod จะผูกกับ filesystem ของ Node และอาจมีปัญหาเมื่อย้าย Node

volumes:
- name: node-data
hostPath:
path: /var/lib/my-app
type: DirectoryOrCreate
volumes:
- name: app-config
configMap:
name: app-config
items:
- key: app.properties
path: app.properties
volumeMounts:
- name: app-config
mountPath: /etc/my-app/app.properties
subPath: app.properties
readOnly: true
volumes:
- name: app-secret
secret:
secretName: app-secret
defaultMode: 0400
volumeMounts:
- name: app-secret
mountPath: /etc/my-app/secrets
readOnly: true

ใช้ PVC เป็น persistent storage

Section titled “ใช้ PVC เป็น persistent storage”

PVC เป็นวิธีมาตรฐานสำหรับขอ storage ที่ยังอยู่แม้ Pod ถูกสร้างใหม่ โดย storageClassName ต้องตรงกับ StorageClass ใน cluster

แบบทั่วไปให้ใช้ PVC ขอ storage จาก StorageClass ที่มีอยู่ใน cluster:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 1Gi

ถ้า cluster ไม่มี dynamic provisioning สามารถสร้าง PV เองแล้วให้ PVC bind ด้วย storageClassName และขนาดที่ตรงกันได้:

apiVersion: v1
kind: PersistentVolume
metadata:
name: app-data-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /mnt/data/app
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: manual
resources:
requests:
storage: 1Gi

hostPath เหมาะกับ local cluster หรือ lab เท่านั้น สำหรับ production ควรใช้ StorageClass และ CSI driver ของ cloud หรือ storage platform

volumeMounts:
- name: app-data
mountPath: /var/lib/my-app
volumes:
- name: app-data
persistentVolumeClaim:
claimName: app-data
Terminal window
# สร้าง PVC
kubectl apply -f pvc.yaml
# ตรวจสอบสถานะ PVC และ PV ที่ถูก bind
kubectl get pvc,pv
# ลบ PVC เมื่อไม่ต้องการใช้แล้ว
kubectl delete -f pvc.yaml

Mount เฉพาะ file ด้วย subPath

Section titled “Mount เฉพาะ file ด้วย subPath”

ใช้เมื่อต้องการ mount key เดียวจาก ConfigMap หรือ Secret โดยไม่ทับทั้ง directory

volumeMounts:
- name: app-config
mountPath: /etc/my-app/app.properties
subPath: app.properties
readOnly: true

File ที่ mount ด้วย subPath จะไม่รับการ update จาก ConfigMap หรือ Secret โดยอัตโนมัติ ต้อง restart Pod หลังแก้ค่า

รวมหลาย source ด้วย projected

Section titled “รวมหลาย source ด้วย projected”

รวม ConfigMap, Secret และ Downward API ไว้ใน directory เดียว

volumes:
- name: runtime-config
projected:
sources:
- configMap:
name: app-config
- secret:
name: app-secret
- downwardAPI:
items:
- path: pod-name
fieldRef:
fieldPath: metadata.name

ตัวอย่างการนำ volume ไปใช้ใน Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 1
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: nginx:1.27
volumeMounts:
- name: runtime-config
mountPath: /etc/my-app
readOnly: true
volumes:
- name: runtime-config
projected:
sources:
- configMap:
name: app-config
- secret:
name: app-secret
Terminal window
# ตรวจสอบ volume mount จากใน container
kubectl exec deploy/app -- ls -la /etc/my-app
# ดูรายละเอียด volume และ mount configuration
kubectl describe pod -l app=app
Avatar whiteCat
ถ้าเป็นข้อมูลชั่วคราวใช้ emptyDir, ถ้าต้องการเก็บข้ามการสร้าง Pod ใหม่ให้ใช้ PVC และถ้าเป็น configuration ให้เลือก ConfigMap หรือ Secret ตามความ sensitive

Pod คือ smallest deployable unit ใน Kubernetes โดยแต่ละ Pod จะ contain หนึ่งหรือหลาย containers ที่ใช้ shared storage และ network

Terminal window
# แสดง pods ทั้งหมดใน namespace ปัจจุบัน
kubectl get pods
# แสดง pods พร้อม detail เพิ่มเติม
kubectl get pods -o wide
# แสดง pods ทั้งหมดในทุก namespace
kubectl get pods --all-namespaces
# ดูข้อมูล detail ของ pod
kubectl describe pod <pod-name>
# ดู logs ของ pod
kubectl logs <pod-name>
# ดู logs แบบ follow
kubectl logs -f <pod-name>
# exec เข้าไปใน container
kubectl exec -it <pod-name> -- /bin/sh
# ลบ pod
kubectl delete pod <pod-name>
Avatar whiteCat
ถ้าต้องการ exec เข้า container ที่มีหลายตัว ให้ระบุ -c <container-name> ด้วย

Deployment คือ abstraction layer ที่อยู่บน Pod ช่วยให้จัดการ scaling, rolling updates, และ rollback ได้ง่ายขึ้น

Terminal window
# แสดง deployments ทั้งหมด
kubectl get deployments
# ดูข้อมูล detail ของ deployment
kubectl describe deployment <deployment-name>
# สร้าง deployment จาก yaml file
kubectl apply -f <deployment.yaml>
# ดู rollout status
kubectl rollout status deployment/<deployment-name>
# rollback deployment กลับไป version ก่อนหน้า
kubectl rollout undo deployment/<deployment-name>
# ดู history ของ rollout
kubectl rollout history deployment/<deployment-name>
Avatar whiteCat
Deployment เป็นตัวที่ทำให้ Pod มี self-healing อัตโนมัติ ถ้า Pod ตายมันจะสร้างใหม่ให้ทันที

สำหรับ PostgreSQL ให้ใช้ pg_isready ตรวจสอบว่า database พร้อมรับ connection หรือยัง โดยวาง probes ไว้ภายใน containers[] ของ Pod หรือ Deployment template

containers:
- name: postgres
image: postgres:17
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgres-secret
key: username
- name: POSTGRES_DB
value: app
livenessProbe:
exec:
command:
- sh
- -c
- pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
readinessProbe:
exec:
command:
- sh
- -c
- pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 3
  • livenessProbe ใช้ตรวจว่า PostgreSQL ยังทำงานอยู่หรือไม่ ถ้าล้มเหลวต่อเนื่อง Kubernetes จะ restart container
  • readinessProbe ใช้ตรวจว่า PostgreSQL พร้อมรับ traffic หรือไม่ ถ้ายังไม่พร้อม Pod จะไม่ถูกส่ง traffic จาก Service
Avatar blackCat
ค่า POSTGRES_USER และ POSTGRES_DB ต้องมีอยู่ใน environment ของ container ก่อน จึงจะใช้ในคำสั่ง pg_isready ได้
Terminal window
# scale deployment ไปที่จำนวน replicas ที่ต้องการ
kubectl scale deployment <deployment-name> --replicas=3
# scale แบบ horizontal pod autoscaler
kubectl autoscale deployment <deployment-name> --min=2 --max=10 --cpu-percent=80
Terminal window
# แสดง replicasets ทั้งหมด
kubectl get replicasets
# ดูข้อมูล detail ของ replicaset
kubectl describe replicaset <replicaset-name>

Service คือ abstraction ที่ defines logical set of pods และ policy สำหรับเข้าถึง pods นั้นๆ

Terminal window
# แสดง services ทั้งหมด
kubectl get services
kubectl get svc
# ดูข้อมูล detail ของ service
kubectl describe service <service-name>
# สร้าง service แบบ LoadBalancer
kubectl expose deployment <deployment-name> --port=80 --type=LoadBalancer
# สร้าง service แบบ ClusterIP (internal)
kubectl expose deployment <deployment-name> --port=80 --type=ClusterIP
# สร้าง service แบบ NodePort
kubectl expose deployment <deployment-name> --port=80 --type=NodePort
Avatar whiteCat
Service types มี 3 แบบ: ClusterIP (internal), NodePort (expose ผ่าน port ของ node), LoadBalancer (external cloud provider)
Terminal window
# forward port จาก local ไปยัง pod
kubectl port-forward pod/<pod-name> 8080:80
# forward port จาก local ไปยัง service
kubectl port-forward svc/<service-name> 8080:80

ConfigMap ใช้เก็บ configuration ที่ไม่เป็น secret เช่น environment variables, command-line arguments, config files

Terminal window
# สร้าง configmap จาก literal
kubectl create configmap <configmap-name> --from-literal=key=value
# สร้าง configmap จาก file
kubectl create configmap <configmap-name> --from-file=<file-path>
# สร้าง configmap จาก env file
kubectl create configmap <configmap-name> --from-env-file=<env-file-path>
# ดู configmap
kubectl get configmaps
kubectl describe configmap <configmap-name>
Avatar whiteCat
ConfigMap เหมาะสำหรับ config ที่ไม่ sensitive ถ้าเป็น secret ต้องใช้ Secret แทน

Secret ใช้เก็บข้อมูลที่ sensitive เช่น passwords, tokens, keys

Terminal window
# สร้าง secret จาก literal
kubectl create secret generic <secret-name> --from-literal=key=value
# สร้าง secret จาก file
kubectl create secret generic <secret-name> --from-file=<file-path>
# สร้าง secret แบบ docker registry
kubectl create secret docker-registry <secret-name> --docker-server=<server> --docker-username=<user> --docker-password=<pass>
# ดู secrets
kubectl get secrets
# ดู secret value (base64 decode)
kubectl get secret <secret-name> -o jsonpath='{.data.key}' | base64 -d
Avatar blackCat
Secret ใน k8s ไม่ได้ encrypted โดย default! ต้อง enable encryption หรือใช้ external secrets manager อย่าง Vault

kubectl edit ใช้แก้ Secret ได้ เหมาะกับการแก้เร่งด่วน แต่ค่าที่เปิดขึ้นมาจะอยู่ใน data และต้องเป็น Base64 ไม่ใช่ plaintext:

Terminal window
# ตรวจสอบ cluster และเปิด Secret ใน editor
kubectl config current-context
kubectl edit secret one-id-secret -n production

ใน editor แก้ค่าของ key ใต้ data: หรือเอาบรรทัดของ key ออกเพื่อลบ key นั้น แล้ว save และปิด editor ควรหลีกเลี่ยงการคัดลอกหรือถ่ายภาพหน้าจอที่มีค่า Secret

ถ้าต้องการใส่ plaintext โดยไม่ encode เอง ให้ใช้ kubectl patch กับไฟล์ชั่วคราวที่มี permission จำกัด:

Terminal window
# สร้างไฟล์โดยจำกัดสิทธิ์ให้อ่าน/เขียนได้เฉพาะเจ้าของ
umask 077
${EDITOR:-vi} secret-patch.yaml
# secret-patch.yaml — ระบุเฉพาะ key ที่ต้องการเปลี่ยน
stringData:
DATABASE_URL: "postgresql://user:password@host:5432/db"
Terminal window
# แก้เฉพาะ key ที่ระบุ โดยไม่กระทบ key อื่น
kubectl patch secret one-id-secret -n production --type merge --patch-file secret-patch.yaml
# ลบไฟล์ชั่วคราวหลังใช้งาน
rm secret-patch.yaml

ลบ key ด้วย kubectl patch ได้เช่นกัน:

Terminal window
# ลบ key API_TOKEN ออกจาก Secret
kubectl patch secret one-id-secret -n production --type merge -p '{"data":{"API_TOKEN":null}}'

ถ้า Deployment ใช้ Secret เป็น environment variable ให้ restart เพื่อให้ Pod ใหม่รับค่า และตรวจสอบ rollout กับ health check หลังแก้:

Terminal window
# Restart Deployment และรอให้ rollout เสร็จ
kubectl rollout restart deployment/one-id-service -n production
kubectl rollout status deployment/one-id-service -n production

Secret ที่ mount เป็น volume ปกติจะทยอยอัปเดต แต่ subPath และ environment variables ไม่อัปเดตใน Pod เดิม ส่วน K9s เหมาะกับการตรวจสอบ Secret/Pod

Avatar blackCat
ถ้า Secret ถูกจัดการโดย Argo CD หรือ GitOps controller การแก้ด้วย kubectl อาจถูก sync กลับเป็นค่าเดิม ให้ตรวจ ownership ก่อน และอย่าแก้ Secret ที่เป็น GitOps-managed โดยไม่อัปเดต source of truth

สำหรับการใช้งานระยะยาว ควรจัดการ Secret ผ่าน External Secrets หรือ Secret Manager แทนการแก้ใน cluster โดยตรง

Namespace ช่วยให้แบ่ง cluster ออกเป็นหลาย virtual clusters

Terminal window
# แสดง namespaces ทั้งหมด
kubectl get namespaces
kubectl get ns
# สร้าง namespace
kubectl create namespace <namespace-name>
# เปลี่ยน namespace ปัจจุบัน
kubectl config set-context --current --namespace=<namespace-name>
# แสดง resources ใน namespace ที่ระบุ
kubectl get pods -n <namespace-name>
Avatar whiteCat
ถ้าไม่ระบุ namespace คำสั่งจะใช้ namespace ปัจจุบัน (default) ตลอด
Terminal window
# แสดง ingresses ทั้งหมด
kubectl get ingress
# ดู ingress detail
kubectl describe ingress <ingress-name>
# apply ingress from yaml
kubectl apply -f <ingress.yaml>
Terminal window
# แสดง nodes ทั้งหมด
kubectl get nodes
# ดูข้อมูล detail ของ node
kubectl describe node <node-name>
# แสดง node resource usage
kubectl top nodes
Terminal window
# แสดง events ทั้งหมด sort by time
kubectl get events --sort-by='.lastTimestamp'
# แสดง events ใน namespace ที่ระบุ
kubectl get events -n <namespace-name>
# แสดง events แบบ watch
kubectl get events --watch
Avatar whiteCat
Events เป็นตัวช่วยสำคัญในการ troubleshoot ปัญหา เพราะมันจะบอกว่าเกิดอะไรใน cluster
Terminal window
# แสดง pods ที่มีปัญหา
kubectl get pods | grep -v Running
# ดู logs ของ pod ที่มีหลาย containers
kubectl logs <pod-name> -c <container-name>
# ดู logs จาก previous container instance (ถ้า container restart แล้ว)
kubectl logs <pod-name> --previous
# describe pod ดูสาเหตุ
kubectl describe pod <pod-name>
# เข้าไปใน container เพื่อ debug
kubectl exec -it <pod-name> -c <container-name> -- /bin/sh
# ตรวจสอบ endpoint
kubectl get endpoints <service-name>
Terminal window
# แสดง resources ทั้งหมดใน cluster
kubectl api-resources
# แสดง resources ที่มีใน namespace
kubectl api-resources --namespaced=true
# แสดง resources ที่ไม่มีใน namespace (cluster-wide)
kubectl api-resources --namespaced=false
# แสดง API version ของ resource
kubectl api-resources -o wide
Terminal window
# แสดง yaml ของ resource (ไม่ apply)
kubectl get pod <pod-name> -o yaml
# สร้าง resource จาก yaml
kubectl apply -f <file.yaml>
# สร้างหลาย resources จาก directory
kubectl apply -f <directory>/
# ลบ resource จาก yaml
kubectl delete -f <file.yaml>
# ดู difference ก่อน apply
kubectl diff -f <file.yaml>
Terminal window
# แสดง contexts ทั้งหมด
kubectl config get-contexts
# เปลี่ยน context
kubectl config use-context <context-name>
# แสดง current context
kubectl config current-context
# แสดง clusters ทั้งหมด
kubectl config get-clusters
# ดู config ทั้งหมด
kubectl config view

แยก kubeconfig ของแต่ละ environment และบังคับให้เข้า shell ของ environment ก่อนใช้ kubectl ช่วยลดโอกาสส่งคำสั่งไปผิด cluster โดยจะแสดง label และสีของ environment ไว้ใน prompt

Terminal window
# สร้าง directory สำหรับเก็บ kubeconfig แยกตาม environment
mkdir -p ~/.kube/envs
# จำกัดสิทธิ์ให้มีเฉพาะ user เจ้าของ directory
chmod 700 ~/.kube/envs
# สร้างหรือนำ kubeconfig ของแต่ละ environment มาเก็บไว้ในไฟล์ที่เกี่ยวข้อง
nano ~/.kube/envs/prod.yaml
# จำกัดสิทธิ์ของ kubeconfig ไม่ให้ user อื่นอ่านได้
chmod 600 ~/.kube/envs/prod.yaml

โครงสร้างไฟล์ที่แนะนำ:

~/.kube/envs/
├── dev.yaml
├── uat.yaml
└── prod.yaml

ทดสอบ kubeconfig โดยระบุไฟล์โดยตรงก่อนนำไปใช้กับ shell function:

Terminal window
# ตรวจสอบว่า kubeconfig ของ production เชื่อมต่อ cluster ได้
kubectl --kubeconfig ~/.kube/envs/prod.yaml get nodes

ถ้าแสดงรายการ nodes ได้ แสดงว่า kubeconfig ใช้งานได้

เพิ่ม function เหล่านี้ใน ~/.zshrc เพื่อเปิด subshell ที่กำหนด kubeconfig และ label ให้ตรงกับ environment:

Terminal window
# เปิด subshell สำหรับ Development
function kube-dev() {
KUBECONFIG="$HOME/.kube/envs/dev.yaml" \
KUBE_ENV="DEV" \
KUBE_LABEL="DEVELOPMENT" \
zsh
}
# เปิด subshell สำหรับ UAT
function kube-uat() {
KUBECONFIG="$HOME/.kube/envs/uat.yaml" \
KUBE_ENV="UAT" \
KUBE_LABEL="UAT" \
zsh
}
# เปิด subshell สำหรับ Production
function kube-prod() {
KUBECONFIG="$HOME/.kube/envs/prod.yaml" \
KUBE_ENV="PROD" \
KUBE_LABEL="PRODUCTION" \
zsh
}

เพิ่ม prompt สำหรับแยก environment:

Terminal window
# แสดงสีและ label ของ environment ใน prompt
if [[ "$KUBE_ENV" == "PROD" ]]; then
PROMPT='%F{red}[PRODUCTION]%f %~ %# '
elif [[ "$KUBE_ENV" == "UAT" ]]; then
PROMPT='%F{yellow}[UAT]%f %~ %# '
elif [[ "$KUBE_ENV" == "DEV" ]]; then
PROMPT='%F{green}[DEVELOPMENT]%f %~ %# '
fi

ตรวจ syntax และโหลด configuration ใหม่:

Terminal window
# ตรวจสอบ syntax ของ zsh configuration โดยไม่ execute
zsh -n ~/.zshrc
# โหลด zsh configuration ใหม่
source ~/.zshrc

เข้าและออกจาก Environment

Section titled “เข้าและออกจาก Environment”

เปิด shell ของ environment ที่ต้องการก่อนใช้คำสั่ง Kubernetes:

Terminal window
# เข้า Development environment
kube-dev
# หรือเข้า UAT / Production environment
kube-uat
kube-prod

เมื่อเข้า kube-prod แล้ว prompt จะแสดง label สีแดง เช่น [PRODUCTION] ~ % คำสั่งต่อไปนี้จะใช้ ~/.kube/envs/prod.yaml:

Terminal window
# ตรวจสอบ nodes ใน production cluster
kubectl get nodes
# ตรวจสอบ pods ทุก namespace
kubectl get pods -A
# แสดง Helm releases ทุก namespace
helm list -A
# เปิด k9s ด้วย kubeconfig ของ environment นี้
k9s
# ตรวจสอบ kubeconfig และ context ที่กำลังใช้งาน
echo $KUBECONFIG
kubectl config current-context

ออกจาก environment shell เพื่อกลับไปยัง shell ปกติ:

Terminal window
# ปิด subshell และคืนสู่ shell เดิม
exit

หลัง exit ค่า KUBECONFIG, KUBE_ENV และ KUBE_LABEL ที่กำหนดให้ subshell จะไม่ติดกลับไปยัง shell ปกติ

Avatar blackCat
อย่าใส่ production kubeconfig หรือ production context ไว้ใน default ~/.kube/config หากไม่จำเป็น เพราะการแยกไฟล์ช่วยลดโอกาสยิงคำสั่งผิด cluster ได้มากขึ้น
Terminal window
# -n : ระบุ namespace
kubectl get pods -n <namespace>
# -o : กำหนด output format (yaml, json, wide)
kubectl get pods -o yaml
kubectl get pods -o json
kubectl get pods -o wide
# -l : filter ด้วย label
kubectl get pods -l app=myapp
# -f : ระบุ filename
kubectl apply -f deployment.yaml
# --dry-run : ทดสอบคำสั่งโดยไม่ apply
kubectl apply -f deployment.yaml --dry-run
# -w : watch mode
kubectl get pods -w
Avatar whiteCat
kubectl มี shorthand หลายตัว เช่น: pods=po, services=svc, deployments=deploy, namespaces=ns
คำสั่งคำอธิบาย
kubectl get podsแสดง pods ทั้งหมด
kubectl get svcแสดง services ทั้งหมด
kubectl get nsแสดง namespaces ทั้งหมด
kubectl get allแสดง resources หลักทั้งหมด
kubectl apply -fapply yaml file
kubectl delete -fdelete จาก yaml file
kubectl describeดู detail ของ resource
kubectl logsดู logs ของ pod
kubectl execexec เข้า container
kubectl port-forwardforward port
kubectl scalescale deployment
kubectl rolloutmanage rollout
kubectl topดู resource usage
kubectl configจัดการ kubeconfig
kubectl api-resourcesแสดง resource types ทั้งหมด