- vừa được xem lúc

[K8S basic] Kubernetes Ingress

0 0 26

Người đăng: Trịnh Quốc Việt

Theo Viblo Asia

Giới thiệu

Xin chào các bạn, chúng ta lại tiếp tục với series k8s basic. Các nội dung đã có trong series:

Trong bài hôm nay chúng ta sẽ tìm hiểu thêm một cách public ứng dụng của chúng ta bằng Ingress kết hợp với một external LoadBalancer với ví dụ cụ thể.

Tại sao cần dùng Kubernetes Ingress

Trong bài trước về Kubernetes Service chúng ta đã biết 4 loại service type và cách sử dụng chúng. Trong đó để expose ứng dụng ra bên ngoài thì chỉ có NodePort và LoadBalancer (trên onprem thì 2 loại này coi như 1).

Sử dụng NodePort có một số hạn chế:

  • Service được expose hoàn toàn ra bên ngoài
  • Phải sử dụng qua port NodePort (thay vì sử dụng port http/https cho các ứng dụng web thì phải thêm cái đuôi NodePort vào sau domainname --> Nhìn nó kém chuyên nghiệp thật sự 😄)
  • Số lượng Port sử dụng cho NodePort hạn chế (mặc định range NodePort từ 30000-32767)

Và Kubernetes Ingress sẽ giúp giải quyết vấn đề nêu trên:

  • Các service ứng dụng sẽ được expose dưới dạng ClusterIP và sau đó được expose ra bên ngoài qua Ingress --> Service thực sự trong suốt với người dùng. Người dùng chỉ thực sự kết nối tới Ingress Controller
  • Có thể dùng thêm external LoadBalancer bên ngoài để trỏ tới IngressController --> Có thể sử dụng port http/https để kết nối tới domain tương ứng của service thay vì phải chỉ định thêm NodePort, nhìn nó chuyên nghiệp hơn hẳn
  • Không bị hạn chế bởi số lượng Port mà NodePort có thể cung cấp.

Kubernetes Ingress là gì

Ingress mở và phân luồng các kết nối HTTP và HTTPS từ bên ngoài k8s cluster vào các services bên trong cluster. Việc phân luồng dữ liệu này được quản lý bởi các "rule" được định nghĩa ở các tài nguyên Ingress trên k8s. Việc thực thi phân luồng dữ liệu được thực hiện bởi Ingress Controller, là một opensource cài đặt trên K8S. Nhiệm vụ của Ingress Controller là nạp các thông tin của các Ingress Resource để thực hiện phân luồng.

Cơ chế hoạt động của Ingress

Cơ chế hoạt động của Ingress gồm 2 thành phần chính:

  • Ingress Controller: Là thành phần điều khiển chính làm nhiệm vụ điều hướng các request tới các service bên trong k8s. Thường thì Ingress Controller được cài đặt trên K8S và được expose ra ngoài dưới dạng NodePort.
  • Ingress Rule: Là một tài nguyên trên K8S. Nó chứa nội dung khai báo rule để điều hướng từ một request tới một service cụ thể trên trong K8S.

NOTE: Có nhiều Ingress Controller từ các nhà phát triển khác bạn có thể lựa chọn để cài đặt. Ngoài ra trên k8s cũng hỗ trợ cài đặt nhiều Ingress Controller tùy nhu cầu sử dụng. Trong giới hạn bài viết này mình sẽ chỉ dùng 1 Ingress Controller.

Cấu trúc của Ingress Resource

Ingress là một tài nguyên ở mức Namespace trên K8S. Và giống như các tài nguyên khác như Pod, Deployment hay Service, ta có thể định nghĩa nó bằng cách sử dụng file manifest dạng yaml.

Ví dụ nội dung một file định nghĩa Ingress như sau:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: name: minimal-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /
spec: ingressClassName: nginx-example rules: - http: paths: - path: /testpath pathType: Prefix backend: service: name: test port: number: 80

Ý nghĩa của khai báo trên là mọi request tới mà có Path chứa Prefix là /testpath thì sẽ được forward tới servcie test ở port 80.

Ingress Rules

Mỗi HTTP rule sẽ bao gồm các thông tin sau:

  • Thông tin host (không bắt buộc). Nếu có khai báo host cụ thể, rule sẽ chỉ apply cho host đó. Nếu host không được khai báo, thì rule được áp dụng cho mọi http đến.
  • Danh sách paths (ví dụ /testpath như bên trên), mỗi path sẽ có thông tin pathType và một backend (service) tương ứng với port của nó.
  • Một backend là một bộ gồm service và port. HTTP (HTTPS) request mà thỏa mãn điều kiện về host và path sẽ được chuyển tới backend đã khai báo

Path types

Mỗi cấu hình path trong ingress đều yêu cầu phải có path type tương ứng. Có 3 loại path type đang được k8s support gồm:

  • ImplementationSpecific
  • Exact
  • Prefix

Về các cấu hình và sử dụng rule của Ingress thì các bạn có thể tham khảo thêm ở đây.

Ví dụ về một kiến trúc triển khai sử dụng Ingress và LoadBalancer

Thông thường để expose các service của dịch vụ HTTP/HTTPS qua Ingress, người ta sử dụng thêm một External Loadblancer bên ngoài. LB này sẽ làm nhiệm vụ forward request HTTP/HTTPS từ client tới NodePort của Ingress Controller.

Lúc này Ingress Controller sẽ phân tích domain của request và các Ingress Rule mà nó đang quản lý để forward request tới service tương ứng trên k8s.

Đây là một ví dụ về kiến trúc triển khai ứng dụng web http/https sử dụng Ingress và Load Balancer:

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

Mình đã có hướng dẫn chi tiết cách cài đặt Ingress Controller và Load Balancer ở đây, mọi người có thể tham khảo chi tiết. Mình đã cài đặt Ingress Controller ready ở namespace ingress để sử dụng như sau:

[sysadmin@vtq-cicd example]$ kubectl -n ingress get service ingress-nginx-ingress-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-ingress-controller NodePort 10.233.63.81 <none> 80:30080/TCP,443:30443/TCP 41d

Chi tiết cấu hình NodePort:

ports: - name: http nodePort: 30080 port: 80 protocol: TCP targetPort: http - name: https nodePort: 30443 port: 443 protocol: TCP targetPort: https

Và để Ingress Class mặc định là nginx:

[sysadmin@vtq-cicd nginx-ingress]$ k get ingressclasses.networking.k8s.io
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 41d

Load Balancer mình sử dụng là Haproxy và nó sẽ làm nhiệm vụ forward request từ port http/https về NodePort của Ingress Controller Service. Mình đã cài đặt haproxy lên node viettq-master1 ở IP 192.168.10.11

Các bạn có thể tham khảo cấu hình routing trên haproxy như bên dưới:

frontend frontend_ssl_443 bind :80 bind *:443 ssl crt /etc/haproxy/ssl/viettq_app.pem mode http option httpclose option forwardfor reqadd X-Forwarded-Proto:\ https #http-request set-header X-Forwarded-Proto:\ https cookie SRVNAME insert indirect nocache default_backend backend_ingress
backend backend_ingress mode http stats enable stats auth username:password balance roundrobin server viettq-worker1 192.168.10.14:30080 cookie p1 weight 1 check inter 2000 server viettq-worker2 192.168.10.15:30080 cookie p1 weight 1 check inter 2000 server viettq-worker3 192.168.10.16:30080 cookie p1 weight 1 check inter 2000

Trong đó 192.168.10.14-16 là IP của các Worker Node, 30080 là NodePort http của Ingress Controller. NOTE: Ở đây mình dùng Self-Sign Cert và cấu hình SSL Termination ở phía Haproxy, do đó kết nối từ Haproxy về Ingres Controller sẽ dùng http. Còn từ Client --> Haproxy sẽ dùng https.

Các bạn có thể tham khảo cách tạo Self-Sign Cert dùng OpenSSL và cấu hình tích xanh cho nó trên client theo hướng dẫn ở đây.

Hướng dẫn expose ứng dụng sử dụng Ingress

Ta sẽ tạo 1 pod ứng dụng và expose nó dưới dạng ClusterIP

Các bạn tạo file manifest apple.yaml với thông tin như sau để tạo Pod apple và expose ra service apple-service dạng ClusterIP:

kind: Pod
apiVersion: v1
metadata: name: apple-app labels: app: apple
spec: containers: - name: apple-app image: hashicorp/http-echo args: - "-text=THIS_IS_APPLE"
--- kind: Service
apiVersion: v1
metadata: name: apple-service
spec: selector: app: apple ports: - port: 5678 # Default port for image

Sau đó apply vào cùng namespace ingress:

[sysadmin@vtq-cicd example]$ k -n ingress apply -f apple.yaml
pod/apple-app created
service/apple-service created

Tạo ingress rule để kết nối ứng dụng

Các bạn tạo file apple.ingress.yaml có nội dung như sau:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: annotations: name: apple.prod.viettq.com
spec: #ingressClassName: nginx rules: - host: apple.prod.viettq.com http: paths: - backend: service: name: apple-service port: number: 5678 path: / pathType: Prefix

Ingress bên trên khai báo một rule là các request tới domain apple.prod.viettq.com/ sẽ được forward tới service apple-service ở Port 5678.

Ta apply file manifest trên để tạo Ingress trên hệ thống:

[sysadmin@vtq-cicd example]$ k -n ingress apply -f apple.ingress.yaml
ingress.networking.k8s.io/apple.prod.viettq.com created

Kiểm tra truy cập vào ứng dụng

Ta sẽ lần lượt truy cập tới ứng dụng như sau:

Truy cập qua IP của Pod

Cách truy cập này chỉ thực hiện được từ bên trong k8s, do Pod được cấp IP nội bộ:

[sysadmin@viettq-master1 ~]$ k -n ingress get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
apple-app 1/1 Running 0 76m 10.233.67.33 viettq-worker3 <none> <none>
ingress-nginx-ingress-controller-546fb6d5f-cn9dr 1/1 Running 1 41d 10.233.68.7 viettq-worker2 <none> <none>
[sysadmin@viettq-master1 ~]$ curl 10.233.67.33:5678
THIS_IS_APPLE

Truy cập qua ClusterIP của Service

Cách truy cập này chỉ thực hiện được từ bên trong k8s, do service dạng ClusterIP cũng chỉ được cấp IP nội bộ của K8S:

[sysadmin@viettq-master1 ~]$ k -n ingress get svc -owide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
apple-service ClusterIP 10.233.11.90 <none> 5678/TCP 41d app=apple
ingress-nginx-ingress-controller NodePort 10.233.63.81 <none> 80:30080/TCP,443:30443/TCP 41d app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress,app.kubernetes.io/name=nginx-ingress-controller
[sysadmin@viettq-master1 ~]$ curl 10.233.11.90:5678
THIS_IS_APPLE

Truy cập qua Ingress Controller bằng domainame

2 cách truy cập qua Pod-IP và Service ClusterIP là mặc định trên K8S hỗ trợ. Tuy nhiên thực tế ta sẽ chủ yếu sử dụng qua Ingress. Ta có thể thực hiện kết nối tới Ingress Controller qua NodePort của service ingress-nginx-ingress-controller, đây là service của Ingress Controller mà mình đã cài đặt (tùy cách đặt tên mà trên hệ thống của các bạn có thể sẽ có tên khác).

Cách kết nối này cho phép chúng ta thực hiện từ bên ngoài K8S, sử dụng Node-IP và NodePort của Ingress Controller Service:

[sysadmin@vtq-cicd example]$ curl -H "host: apple.prod.viettq.com" 192.168.10.11:30080
THIS_IS_APPLE

Ở đây:

  • 192.168.10.11: Là IP của K8S Node (master1). Có thể sử dụng IP của Node bất kỳ trong cluster
  • 30080: Là http NodePort của service ta đã cài đặt cho Ingress Controller

Truy cập qua Load Balancer bằng domainname

Như bên trên mình đã cấu hình LB để thực hiện forward request từ LB tới backend là Ingress Controller. Do đó ta có thể kết nối tới ứng dụng thông qua IP của LB ở port http/https như sau.

Với lab của mình, IP của LB là 192.168.10.11 và port là 80/443.

Dùng console:

[sysadmin@vtq-cicd example]$ curl -H "host: apple.prod.viettq.com" 192.168.10.11:80
THIS_IS_APPLE

Dùng web browser:

Như vậy là các bạn đã có thể truy cập vào ứng dụng của mình thông qua cấu hình Ingress rồi.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Deploying A Containerized Web Application On Kubernetes

1. Overview. Kubernetes is an open source project (available on kubernetes.io) which can run on many different environments, from laptops to high-availability multi-node clusters; from public clouds to on-premise deployments; from virtual machines to bare metal.

0 0 26

- vừa được xem lúc

Kubernetes - Học cách sử dụng Kubernetes Namespace cơ bản

Namespace trong Kubernetes là gì. Tại sao nên sử dụng namespace.

0 0 96

- vừa được xem lúc

[Kubernetes] Kubectl và các command cơ bản

Mở đầu. Kubectl là công cụ quản trị Kubernetes thông qua giao diện dòng lệnh, cho phép bạn thực thi các câu lệnh trong Kubernetes cluster.

0 0 39

- vừa được xem lúc

Triển khai EFK Stack trên Kubernetes

EFK stack on K8S. Giới thiệu. Một hệ thống có thể chạy nhiều dịch vụ hoặc ứng dụng khác nhau, vì vậy việc. theo dõi hệ thống là vô cùng cần thiết.

0 0 54

- vừa được xem lúc

Thực hành Kubernetes (K8S) bằng cách sử dụng lệnh Command

Bài hướng dẫn hôm nay sẽ hướng dẫn sử dụng K8S bằng cách sử dụng câu lệnh thay vì UI trên web. Có 2 lựa chọn để thực hiện:. . Sử dụng Cloud Shell.

0 0 42

- vừa được xem lúc

Kubernetes best practices - Liveness và Readiness Health checks

Mở đầu. Kubernetes cung cấp cho bạn một framework để chạy các hệ phân tán một cách mạnh mẽ.

0 0 35