Chuyển tới nội dung

Ingress trong Kubernetes

Trong bài viết này tôi đưa ra hướng dẫn cách cài đặt Ingress Controller nginx, kong, yard trong k8s

1. Nguyên tắc nhiều Ingress Controller = nhiều Ingress Class

Từ Kubernetes networking.k8s.io/v1, với cơ chế “chuẩn” là dùng IngressClass:

  • Mỗi Ingress Controller (nginx, Kong, YARP, v.v..) đăng ký một (hoặc nhiều) IngressClass với spec.controller tương ứng.
  • Mỗi resource Ingress sẽ khai báo:
spec:
  ingressClassName: kong      # hoặc nginx, yarp, ...
  • Controller nào có IngressClass trùng với ingressClassName mới claim và xử lý Ingress đó

Ví dụ trong cùng 1 cluster:

  • IngressClass tên nginx -> do Ingress Nginx xử lý
  • IngressClass tên kong -> do Kong Ingress Controller xử lý
  • IngressClass tên yarp -> do YARP Ingress/Gateway xử lý

2. Ví dụ YAML minh họa

IngressClass cho Nginx

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"  # tuỳ, nếu muốn làm default
spec:
  controller: k8s.io/ingress-nginx

IngressClass cho Kong

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: kong
spec:
  controller: konghq.com/ingress-controller

Ingress dùng Nginx

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-nginx
spec:
  ingressClassName: nginx
  rules:
    - host: app-nginx.dominio.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-svc
                port:
                  number: 80

Ingress dùng Kong

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-kong
spec:
  ingressClassName: kong
  rules:
    - host: app-kong.dominio.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-svc
                port:
                  number: 80

Lưu ý:

  • Mỗi controller chỉ nên xử lý Ingress class của nó
  • Chỉ nên có 1 Ingress được đánh dấu is-default-class: "true"
  • Với các controller còn lại, bắt buộc set spec.IngressClassName trong Ingress, không nên để trống
  • Mỗi Ingress Controller thường sẽ có 1 Service LoadBalancer / NodePort riêng
  • Bạn có thể
    • Dùng nhiều IP / nhiều LB cho các entrypoint khác nhau (public, Internal, API,…)
    • Hoặc dùng 1 LB Front rồi route tiếp bên trong (tùy thiết kế)

Hướng dẫn cài đặt Ingress Controller

Dưới đây là từng bước cài đặt các Ingress Controller sau:

  • Ingress-nginx
  • Kong Ingress Controller
  • YARP Ingress Controller

1. Chuẩn bị chung

  • Cluster k8s đã chạy
  • Có kubectl, helm trên máy
  • Có quyền cluster-admin hoặc tương đương

2. Deploy ingress-nginx + IngresClass

2.1 Cài ingress-nginx bằng Helm

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

kubectl create namespace ingress-nginx

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --set controller.ingressClassResource.name=nginx \
  --set controller.ingressClassResource.controllerValue="k8s.io/ingress-nginx" \
  --set controller.ingressClassByName=true \
  --set controller.service.type=NodePort \
  --set controller.service.nodePorts.http=30080 \
  --set controller.service.nodePorts.https=30443

Lệnh này để tạo Ingress với Service là NodePort, có Port HTTP=30080 và Port HTTPS=30443

Ta cũng có thể cài theo cách sau:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm pull ingress-nginx/ingress-nginx

Edit file values.yaml trong thư mục ingress-nginx

  • Sửa type: LoadBanlancer thành type: NodePort
  •  http: 30080 
  • https: 30443

Sau đó chạy các lệnh

kubectl create ns ingress-nginx
# helm -n <namespace> install <release name> -f ingress-nginx/ingress-nginx/values.yaml <helm chart>
helm -n ingress-nginx install ingress-nginx -f ingress-nginx/ingress-nginx/values.yaml ingress-nginx

# Kiểm tra
kubectl get all -n ingress-nginx

Muốn xóa và cài lại từ đầu

helm uninstall ingress-nginx -n ingress-nginx
helm list -n ingress-nginx
kubectl get all -n ingress-nginx

Nếu namespace không còn gì thì cài lại

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --set controller.ingressClassResource.name=nginx \
  --set controller.ingressClassResource.controllerValue="k8s.io/ingress-nginx" \
  --set controller.ingressClassByName=true \
  --set controller.service.type=NodePort \
  --set controller.service.nodePorts.http=30080 \
  --set controller.service.nodePorts.https=30443

Nếu muốn giữ release cũ và chỉ chỉnh cấu hình

Trong trường hợp đã có ingress-nginx chạy rồi, chỉ muốn đổi sang NodePort/ port mới, không cần install lại

helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --set controller.ingressClassResource.name=nginx \
  --set controller.ingressClassResource.controllerValue="k8s.io/ingress-nginx" \
  --set controller.ingressClassByName=true \
  --set controller.service.type=NodePort \
  --set controller.service.nodePorts.http=30180 \
  --set controller.service.nodePorts.https=31443

helm upgrade sẽ update release ingress-nginx hiện có với config mới

Nếu muốn dùng tên khác, giữ release cũ và cài thêm một ingress-nginx khác

helm install ingress-nginx-nodeport ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  ...

Chart này tự tạo IngressClass tên nginx với controller: k8s.io/ingress-nginx.

Nếu bạn muốn viết tay IngressClass, vẫn có thể apply thêm

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"   # nếu muốn làm default
spec:
  controller: k8s.io/ingress-nginx

2.2 Service backend & Ingress demo

Giả sử:

  • Namespace app: demo
  • Service backend: demo-service, port 80

Service:

apiVersion: v1
kind: Service
metadata:
  name: demo-service
  namespace: demo
spec:
  selector:
    app: demo-app
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP

Ingress dùng NGINX cho demo.diendo.pro.vn

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-nginx
  namespace: demo
spec:
  ingressClassName: nginx
  rules:
    - host: demo.diendo.pro.vn
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: demo-service
                port:
                  number: 80

3. Deploy Kong Ingress Controller và IngressClass

Kong có chart riêng, có thể deploy ở namespace kong

3.1 Cài Kong bằng Helm

helm repo add kong https://charts.konghq.com
helm repo update

kubectl create namespace kong

helm install kong kong/kong \
  --namespace kong \
  --set ingressController.enabled=true \
  --set ingressController.ingressClass=kong \
  --set proxy.type=LoadBalancer \
  --set proxy.http.enabled=true \
  --set proxy.tls.enabled=false 
  --set ingressController.ingressClassAnnotations."ingressclass\.kubernetes\.io/is-default-class"="false"

Chart sẽ deploy Kong Gateway + Kong Ingress Controller và tạo IngressClass (tùy version chart, nhưng thường dùng k8s.io/ingress-nginx -style / konghq.com/ingress-controller). Bạn có thể tự khai báo IngressClass cho rõ ràng:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: kong
spec:
  controller: konghq.com/ingress-controller

spec.controller phải khớp với controller classs của KIC (thường là konghq.com/ingress-controller).

3.2 Ví dụ Ingress dùng Kong

Giả sử:

  • Namespace: corejs
  • Service: corejs-service, port 80

Service:

apiVersion: v1
kind: Service
metadata:
  name: corejs-service
  namespace: corejs
spec:
  selector:
    app: corejs-app
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP

Ingress dùng cho Kong corejs.diendo.pro.vn

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: corejs-kong
  namespace: demo
  annotations:
    konghq.com/strip-path: "true"
spec:
  ingressClassName: kong
  rules:
    - host: corejs.diendo.pro.vn
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: corejs-service
                port:
                  number: 80

4. Deploy YARP Ingress Controller + IngressClass

YARP không phải chart Helm chính thức, mà thường deploy bằng manifest mẫu từ repo .NET YARP hoặc Microsoft

Ý tưởng:

  • Deploy một Deployment + Service chạy YARP Ingress Controller (image .NET YARP)
  • Deploy kèm Ingress Monitor hoặc sample “combined” (controller + monitoring trong 1 pod)
  • Khai báo IngressClass với spec.controller tương ứng, ví dụ yarp.microsoft.com/ingress-controller

4.1 Tạo namespace và IngressClass cho YARP

kubectl create namespace yarp
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: yarp
spec:
  controller: yarp.microsoft.com/ingress-controller

spec.controller phải đúng với controller ID mà YARP sử dụng trong code (có thể khác)

4.2 Deploy YARP Ingress Controller

Trong repo YARP có sẵn manifest: samples/KubernetesIngress.Sample/Ingress/ingress-controller.yaml

# Sau khi chỉnh lại image registry/tag, controller ID... trong file
kubectl apply -f ingress-controller.yaml -n yarp

Hoặc nếu dùng sample “combined” (Ingress + Monitor trong một pod)

kubectl apply -f combined-ingress-controller.yaml -n yarp

Kiểm tra

kubectl get pods -n yarp
kubectl get svc -n yarp

4.3 Ví dụ deployment + service YARP Ingress (mẫu)

Giả sử bạn build sẵn image YARP ingress controller trong registry.diendo.pro.vn/yarp/ingress:latest

File deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: yarp-ingress-controller
  namespace: yarp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: yarp-ingress-controller
  template:
    metadata:
      labels:
        app: yarp-ingress-controller
    spec:
      containers:
        - name: yarp
          image: registry.diendo.pro.vn/yarp/ingress:latest
          ports:
            - containerPort: 80
          # env, volumeMounts... tuỳ theo cách bạn config YARP (appsettings.json, etc.)

File service.yaml

apiVersion: v1
kind: Service
metadata:
  name: yarp-ingress
  namespace: yarp
spec:
  type: LoadBalancer
  selector:
    app: yarp-ingress-controller
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP

IP của service này dùng để map DNS api.diendo.pro.vn

4.4 Service backend & Ingress api.diendo.pro.vn

Giả sử:

  • Namespace: api
  • Service: api-service, port 80

Service backend

apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: api
spec:
  selector:
    app: api-app
  ports:
    - port: 80
      targetPort: 5000
      protocol: TCP

Ingress dùng YARP cho api.diendo.pro.vn

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-yarp
  namespace: api
spec:
  ingressClassName: yarp
  rules:
    - host: api.diendo.pro.vn
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80

YARP ingress controller sẽ:

  • Nhận traffic từ LB của Service yarp-ingress
  • Dựa và Ingress có ingressClassName: yarp + host api.diendo.pro.vn để route và api-service
Liên hệ