ในโลกของระบบ Cloud‑Native ปัจจุบัน การบริหารจัดการเส้นทางของ API ไม่ได้หยุดอยู่แค่การรับ‑ส่ง Traffic ผ่าน Ingress Controller อีกต่อไป แต่ต้องสามารถควบคุม ตรวจสอบ และปรับแต่งพฤติกรรมของการไหลของข้อมูลได้แบบ Real‑time และ มีความยืดหยุ่นสูง เพื่อรองรับสถาปัตยกรรมแบบ Microservices ที่ซับซ้อนขึ้นเรื่อย ๆ
บทความนี้จะพาไปเรียนรู้การติดตั้งและใช้งาน Apache APISIX ซึ่งเป็น API Gateway ระดับองค์กรที่รองรับการทำงานแบบ Dynamic 100% โดยสามารถเพิ่ม Route, Auth, Rate Limit หรือ Plugin ต่าง ๆ ได้ทันทีโดยไม่ต้อง Reload ระบบ เหมาะอย่างยิ่งสำหรับสภาพแวดล้อม Kubernetes ที่ต้องการประสิทธิภาพ ความเร็ว และความเสถียรในการจัดการ Traffic
APISIX จะเข้ามาทำหน้าที่เป็น “สมองกลางด้านการจราจรของ API” คั่นกลางระหว่าง Ingress‑Nginx และบริการภายใน Cluster ช่วยให้เราสามารถ:
และเมื่อผสานเข้ากับ ArgoCD (GitOps) จะช่วยให้การ Deploy แอปใหม่ ๆ เป็นเรื่องง่ายขึ้น เพราะเราไม่จำเป็นต้องสร้าง Ingress ให้ทุก Service อีกต่อไป เพียงแค่ Deploy Application แล้วกำหนด Route ผ่าน APISIX เท่านั้น (ใน deployment.yaml ของแต่ละแอป เราจะประกาศแค่ Deployment + Service เท่านั้น ไม่จำเป็นต้องมี Ingress อีกต่อไป)
หลังจากเรามีโครงสร้างพื้นฐานหลักของ Cluster ครบแล้ว ได้แก่
ขั้นตอนต่อไป คือ การติดตั้ง Apache APISIX ซึ่งจะทำหน้าที่เป็น API Gateway ชั้นกลาง เพื่อบริหารจัดการ Traffic อย่างมีประสิทธิภาพกว่า Ingress ปกติ เช่น
helm repo add apisix https://charts.apiseven.com
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
apisix:
enabled: true
gateway:
type: ClusterIP # ให้ Nginx Ingress เป็นตัวรับ Traffic แล้วส่งต่อมาที่นี่ภายใน Cluster
http:
containerPort: 9080
# เปิดใช้งาน Dashboard เพื่อให้จัดการ API ผ่านหน้าเว็บได้ง่าย
dashboard:
enabled: true
service:
type: ClusterIP
# ติดตั้ง etcd (ฐานข้อมูลของ APISIX) แบบเบา ๆ สำหรับ Cluster ขนาดเล็ก
etcd:
replicaCount: 1 # สำหรับ k3s 2 เครื่อง 1-3 replica พอครับ
persistence:
enabled: true
size: 8Gi
helm install apisix apisix/apisix \
--namespace apisix \
--create-namespace \
--values apisix-values.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: apisix-dashboard-ingress
namespace: apisix
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- apisix-admin.panmodel.com
secretName: apisix-dashboard-tls
rules:
- host: apisix-admin.panmodel.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: apisix-dashboard
port:
number: 80
รันคำสั่ง
kubectl apply -f apisix-ingress.yaml
รันคำสั่งนี้เพื่อดูว่ามีตัวไหนขึ้นสถานะ Pending หรือ CrashLoopBackOff หรือไม่ หรือ Dashboard Pod หายไป
kubectl get pods -n apisix
หากพบว่า Dashboard ไม่ถูกสร้าง เกิดจาก Chart apisix เวอร์ชันปัจจุบัน ได้แยก Dashboard ออกมาเป็นอีกชุดหนึ่งเพื่อให้ระบบ Core ทำงานได้เบาขึ้นครับ ดังนั้น การสั่ง set dashboard.enabled=true ในตัวหลักจึงไม่ส่งผลให้เกิด Pod ใหม่
ให้เรามาใช้แผน "ติดตั้ง Dashboard แยก" เพื่อดึงหน้าจอจัดการกลับมา โดยรันคำสั่งนี้เพื่อติดตั้ง Dashboard โดยเชื่อมเข้ากับ etcd ที่รันอยู่แล้ว
helm upgrade --install apisix-dashboard apisix/apisix-dashboard \
--namespace apisix \
--set config.conf.apisix.admin_key="<Your Key>" \
--set config.conf.etcd.endpoints={apisix-etcd:2379}
เมื่อรันเสร็จแล้ว ให้เช็คชื่อ Service ของ Dashboard ให้มั่นใจก่อนแก้ Ingress
kubectl get svc -n apisix
ปรับแก้ไฟล์ apisix-ingress.yaml (ถ้าชื่อ service.name ไม่ตรงกับชื่อในคำสั่ง kubectl get svc -n apisix)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: apisix-dashboard-ingress
namespace: apisix
annotations:
# ใช้ Cert-Manager และ SSL Redirect เหมือนเดิม
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- apisix-admin.panmodel.com
secretName: apisix-dashboard-tls
rules:
- host: apisix-admin.panmodel.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: apisix-dashboard # ชื่อนี้ต้องตรงกับที่เห็นใน kubectl get svc
port:
number: 80 # พอร์ต 80 ตามที่เห็นใน Log
User: admin
Password: admin
Dashboard ของ APISIX มักจะมี User/Password เริ่มต้นเป็น admin / admin (อย่าลืมเข้าไปเปลี่ยนนะครับ)
kubectl get configmap -n apisix
แก้ค่าใน ConfigMap apisix-dashboard
kubectl edit configmap apisix-dashboard -n apisix
แล้วแก้ส่วน authentication.users จากนั้น Restart Deployment
kubectl rollout restart deployment apisix-dashboard -n apisix
แล้วทดลอง Login ด้วยรหัสผ่านใหม่
การทดสอบสร้าง "Route" เพื่อทดสอบพลังของ API Gateway
เพื่อทดลองการสร้าง Route ใน APISIX
Name ตั้งชื่อว่า fastapi-route
Path ใส่เป็น /* (หมายความว่ารับทุก Path ที่ส่งมา)
Matching Rules ในช่อง Host ให้ใส่ Domain ที่ต้องการใช้ เช่น test.panmodel.com (อย่าลืมไปชี้ DNS หรือแก้ hosts ไฟล์มาที่ IP ของ Server ด้วยนะครับ)
Nodes กด + เพื่อเพิ่ม Node
Host ให้ใส่ ชื่อ Service ใน Kubernetes ของแอป FastAPI ครับ (ชื่อ service ดูจาก Rancher หรือ kubectl get svc)
FQDN (ชื่อเต็ม) Rancher มักจะบอกชื่อเต็มไว้ด้วย เช่น fastapi-service
Port ใส่พอร์ตของ Service นั้น (ตามที่ตั้งไว้ใน Kubernetes Service)
Weight ใส่ 100
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-app
namespace: apisix # แนะนำให้ระบุ namespace ให้ตรงกับที่ตั้งไว้ใน ArgoCD
spec:
replicas: 2
selector:
matchLabels:
app: fastapi-app
template:
metadata:
labels:
app: fastapi-app
spec:
automountServiceAccountToken: false
imagePullSecrets:
- name: nexus-auth
containers:
- name: fastapi
image: registry.panmodel.com/my-app:49 # เลข Tag นี้ Jenkins จะเป็นคนสั่ง sed แก้ให้เองเมื่อ Build เสร็จ
ports:
- containerPort: 8000 # FastAPI ปกติรันที่พอร์ต 8000
resources:
requests:
memory: "64Mi"
cpu: "50m"
ephemeral-storage: "50Mi"
limits:
memory: "128Mi"
cpu: "100m"
ephemeral-storage: "100Mi"
readinessProbe: # เพิ่ม Liveness & Readiness Probe เพื่อให้ Kubernetes เช็คว่าแอปค้างหรือไม่
httpGet:
path: /healthz
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: fastapi-service
namespace: apisix # ย้ายมาที่นี่เพื่อให้คุยกับ apisix-gateway ได้ แทน default
spec:
selector:
app: fastapi-app
ports:
- port: 80 # พอร์ตที่ Service รับ traffic
targetPort: 8000 # ส่งต่อไปที่พอร์ต 8000 ของ Container
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fastapi-ingress
namespace: apisix # ระบุให้ตรงกันเพื่อป้องกันอาการ Missing
annotations:
kubernetes.io/ingress.class: "nginx" # 🛡ใช้ Nginx และ Cert-Manager ตามที่ติดตั้งไว้
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- test.panmodel.com
secretName: fastapi-tls-cert # Let's Encrypt จะมาสร้างกุญแจ SSL ไว้ที่ชื่อนี้
rules:
- host: test.panmodel.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: apisix-gateway # เปลี่ยนตรงนี้ให้ชี้ไปที่ Gateway ของ APISIX แทนของเดิม fastapi-service
port:
number: 80
kubectl get secret nexus-auth --namespace=default -o yaml | sed 's/namespace: default/namespace: apisix/' | kubectl apply -f -
"Too many requests, please slow down!"