0

Tìm hiểu Ingress trong Kubernetes: từ lý thuyết đến thực hành với NGINX Ingress

1. Tổng quan

Khi mới bắt đầu với Kubernetes, một trong những câu hỏi khiến nhiều người bối rối nhất là: “Làm sao để người dùng bên ngoài truy cập được vào ứng dụng chạy trong Kubernetes?” Ở bài trước, mình đã nói về service, 1 lớp giúp chúng ta có thể giao tiếp với pod chứa ứng dụng của mình. image.png

Có thể thấy service có nhiệm vụ:

  • Gom nhiều Pod lại thành một endpoint logic
  • Cung cấp IP ổn định (ClusterIP)
  • Load balancing giữa các Pod

Tuy nhiên, Service chưa đủ tốt cho truy cập từ bên ngoài, vì:

  • ClusterIP → chỉ dùng trong nội bộ cluster
  • NodePort → phải mở port cao (30000–32767), khó quản lý

Ví dụ: bạn có service backend với nodePort: 30080 và người dùng sẽ truy cập bằng http://<node-ip>:30080, khi đó, một phiền phức đó là người dùng phải nhớ đến port 30080, port mà thay đổi thì link cũ sẽ die và phải nhớ port mới, và rõ ràng nó không thân thiện với người dùng. NodePort sẽ chỉ phù hợp để test nhanh, ko phải dùng cho hệ thống thật trên production.

  • LoadBalancer → mỗi service cần 1 IP public (tốn chi phí)

Ví dụ: service với type: LoadBalancer, bạn sẽ có http://34.xxx.xxx.xxx, có vẻ ổn hơn so với NodePort, nhưng vấn đề xảy ra khi scale hệ thống, mỗi service sẽ có IP riêng, rất tốn chi phí nếu hệ thống chạy trên cloud, không routing được theo path (/api, /admin,...) .

Vấn đề khi ứng dụng bắt đầu lớn dần

Hãy tưởng tượng chúng ta có 1 hệ thống gồm: frontend, api-service, auth-service, admin-service Nếu muốn người dùng truy cập từng url như sau: myweb.com vào frontend, api.myapp.com để vào api-service, admin.myapp.com để vào admin-service

Khi không có ingress, thì mỗi service sẽ cần 1 LoadBalancer, mỗi service cần 1 IP public, tự cấu hình DNS cho từng IP, không quản lý được routing tập trung, khó bật https đồng loạt. Hệ thống trở nên cồng kềnh, khó scale, khó maintain, node IP mà thay đổi thì sửa rất mệt.

http://<node-ip>:30001   → frontend
http://<node-ip>:30002   → api
http://<node-ip>:30003   → admin

Và lúc này, ingress xuất hiện như 1 vị cứu tinh. Nó sẽ có tác dụng như một cổng chính duy nhất, cho toàn bộ hệ thống

image.png

Ingress giúp bạn:

  • Có thể dùng 1 IP duy nhất cho toàn bộ hệ thống
  • Route request dựa trên domain hoặc path
  • Quản lý SSL/TLS tập trung
  • Dễ scale, dễ maintain
https://myapp.com        → frontend
https://api.myapp.com    → api
https://admin.myapp.com  → admin

2. Ingress Controller hoạt động như thế nào?

Ở phần trước, chúng ta đã biết:

  • Ingress là “luật điều hướng”
  • Nhưng Ingress tự nó KHÔNG hoạt động

👉 Để Ingress thực sự hoạt động, ta cần một thành phần rất quan trọng: Ingress Controller

2.1 Ingress Controller là gì?

Để dễ hiểu thì:

Ingress Controller là phần thực sự đứng ra nhận request từ bên ngoài và chuyển nó đến đúng Service bên trong Kubernetes.

Nếu ví Ingress như bảng chỉ đường, thì Ingress Controller chính là người lái xe đọc bảng đó và đưa khách đi đúng nơi.

2.2 Vì sao Ingress Controller lại quan trọng?

Về cơ bản thì, Kubernetes không tự xử lý HTTP routing.

Khi bạn tạo một file Ingress.yaml, Kubernetes chỉ lưu cấu hình, chứ không tự động:

  • Lắng nghe port 80 / 443, lắng nghe request từ bên ngoài

  • Sinh cert, terminate TLS

  • Route request theo domain hoặc path

👉 Các việc trên là do do Ingress Controller đảm nhiệm.

2.3 Các loại Ingress Controller phổ biến

  • NGINX Ingress: Phổ biến nhất, dễ dùng, cộng đồng lớn
  • Traefik: Tự động, cấu hình gọn
  • HAProxy: Hiệu năng cao
  • Kong: Mạnh về API Gateway

Trong bài này mình sẽ demo với NGINX Ingress vì nó dễ học, phổ biến, nhiều tài liệu, và rất phù hợp với người mới tiếp cận.

2.4 Minh hoạ luồng hoạt động khi có Ingress Controller

image.png

Một request sẽ đi qua Ingress Controller -> Ingress Rules -> Service -> Pod

Ingress Controller sẽ đọc các rule được định nghĩa trong object ingress rồi sẽ quyết định:

  • Request này sẽ đến service nào?

Ví dụ: image.png Khi user gọi https://api.myapp.com/users thì ingress controller sẽ hiểu Request này sẽ đi tới user-service

  • Có cần rewrite path không?

Ví dụ: image.png Khi user gọi https://myapp.com/api/users thì backend thực tế sẽ nhận /users mà ko cần phải xử lý prefix /api

  • Có dùng https không? Trong cấu hình ingress sẽ chỉ rõ phần này

Từ đây có thể nói Ingress Controller sẽ là cửa ngõ của hệ thống vì mọi request từ bên ngoài sẽ đều phải đi của cổng này. Và có thể thấy rằng, ko có ingress controller thì ingress sẽ là vô nghĩa. Và có ingress sẽ giúp hệ thống gọn - đẹp - dễ scale - dễ maintain hơn bao giờ hết.

3. Demo

Sau khi biết được tác dụng to lớn của Ingress và Ingress Controller, chúng ta sẽ tự tay dựng một bản demo hoàn chỉnh

Phần demo này sẽ đơn giản là demo việc điều hướng tuyệt vời nhờ ingress mà ko cần setup quá phức tạp

Công cụ quen thuộc khi làm việc k8s ở local của mình lại là minikube + kubectl. Ngoài ra sẽ dùng 2 image để demo được sự điều hướng của ingress controller: nginx:alpine (đại diện cho frontend) và hashicorp/http-echo (đại diện cho api).

3.1 Khởi động minikube và ingress

minikube start
minikube addons enable ingress

3.2 Tạo service frontend

deployment-frontend.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80

service-frontend.yaml

apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  selector:
    app: frontend
  ports:
    - port: 80
      targetPort: 80

3.3 Tạo service api

deployment-api.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: hashicorp/http-echo
          args:
            - "-text=Hello from API service"
          ports:
            - containerPort: 5678

service-api.yaml

apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  selector:
    app: api
  ports:
    - port: 80
      targetPort: 5678

3.4 Tạo ingress

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-ingress
spec:
  rules:
    - host: demo.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80

3.5 Apply yaml & kiểm tra

kubectl apply -f .
kubectl get ingress

3.6 Gán domail local

Lấy IP của minikue: minikube ip

Thêm vào /etc/hosts: 192.168.123.123 demo.local

3.7 Kiểm tra kết quả

image.png

image.png

3.8 Tổng quan luồng

Screencast from 31-12-2025 10-17-15.gif

Nếu không có ingress, trường hợp này bạn sẽ phải gắn nodePort cho từng service sau đó sẽ truy cập như sau: ví dụ: http://192.168.49.2:30001 http://192.168.49.2:30002 và nó không thân thiện với người dùng chút nào

4. Một số lỗi thường gặp

  • 404 Not Found do sai path
  • Quên enable ingress controller
  • Service port mismatch
  • Thiếu host mapping
  • Không dùng rewrite-target

5. Nên dùng ingress khi nào?

Tác dụng của ingress thì có thể thấy vô cùng tuyệt vời, nhưng liệu có nên lúc nào cũng áp dụng nó không? Dĩ nhiên là không rồi, cùng mình điểm qua một số trường hợp nhé

Nên dùng ingress khii:

  • Có nhiều service cần expose ra ngoài
  • Muốn dùng chung 1 domain cho nhiều route
  • Cần SSL/TLS tập trung
  • Muốn kiến trúc sạch, chuẩn production
  • Dùng Kubernetes lâu dài

Và không nên dùng khi:

  • Ứng dụng cực kỳ đơn giản (1 service duy nhất)
  • Chỉ chạy local/test tạm thời
  • Không cần domain, chỉ test nhanh (chỉ cần NodePort hoặc kubectl port-forward là đủ)

6. Tổng kết

Ingress không phải là thứ bạn cần ngay từ đầu, nhưng nó sẽ là mảnh ghép không thế thiếu khi hệ thống scale lên. Tóm lại

  • Ingress giúp gom traffic về một cửa duy nhất
  • Giúp hệ thống gọn gàng, dễ scale, dễ maintain
  • Là nền tảng cho các kiến trúc production hiện đại.

Tài liệu tham khảo

https://kubernetes.io/docs/concepts/services-networking/ingress/

https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/

https://www.kerno.io/blog/kubernetes-services

https://www.solo.io/topics/api-gateway/kubernetes-ingress


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí