Chúng ta sẽ cùng tìm hiểu về 3 loại service trong kubernetes, sự khác biệt và trường hợp sử dụng chúng.
ClusterIP
Service ClusterIP là 1 kiểu mặc định Kubernetes service. Nó cung cấp cho bạn một service bên trong cụm của bạn mà các ứng dụng khác bên trong cụm của bạn có thể truy cập nhưng không có quyền truy cập từ bên ngoài.
File YAML cấu hình cho service ClusterIP trông giống như sau:
apiVersion: v1 kind: Service metadata: name: my-internal-service spec: selector: app: my-app type: ClusterIP ports: - name: http port: 80 targetPort: 80 protocol: TCP
Nếu bạn không thể truy cập service ClusterIP từ internet, tại sao chúng ta lại nói về nó? Hóa ra bạn có thể truy cập nó bằng proxy Kubernetes!
Khởi động Kubernetes Proxy:
kubectl proxy --port=8080
Bây giờ, bạn có thể điều hướng qua API Kubernetes để truy cập dịch vụ này bằng cách sử dụng đường dẫn như này:
http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/
Vì vậy, để truy cập service chúng ta đã xác định ở trên, bạn có thể sử dụng địa chỉ sau:
http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/
Khi nào bạn sẽ sử dụng cái này?
Có một số trường hợp bạn sẽ sử dụng proxy Kubernetes để truy cập các service của mình.
- Debug service của bạn hoặc kết nối với chúng trực tiếp từ máy tính xách tay của bạn vì một số lý do.
- Cho phép traffic truy cập nội bộ ví dụ như connect từ pod này qua pod khác, service này qua service khác …
- Sử dụng đến các chức năng của nó như loadbalancer giữa các pod trong cùng 1 service, service discovery …
Vì phương pháp này yêu cầu bạn chạy kubectl với tư cách là user đã được xác thực, bạn KHÔNG nên sử dụng phương pháp này để cho client truy cập service của mình từ ngoài internet, nhưng đây là một phương pháp phù hợp với việc giao tiếp giữa các app bên trong cụm kubernetes.
NodePort
Kiểu NodePort là cách nguyên thủy nhất để có được traffic truy cập bên ngoài trực tiếp đến service của bạn. NodePort, như tên của nó, mở một port cụ thể trên tất cả các Node (máy ảo) và bất kỳ traffic nào được gửi đến port này đều được chuyển tiếp đến dịch vụ.
File YAML cấu hình cho service kiểu NodePort trông giống như sau:
apiVersion: v1 kind: Service metadata: name: my-nodeport-service spec: selector: app: my-app type: NodePort ports: - name: http port: 80 targetPort: 80 nodePort: 30036 protocol: TCP
Về cơ bản, service kiểu NodePort khác biệt so với service kiểu “ClusterIP” thông thường ở chỗ, nó sẽ mở một port ngẫu nhiên trên các node, các port này nếu không được định nghĩa thì sẽ tạo ngẫu nhiên trong range 30000
– 32767
.
Khi nào bạn sẽ sử dụng cái này?
Có nhiều nhược điểm của phương pháp này:
- Bạn chỉ có thể có một service cho mỗi cổng
- Bạn chỉ có thể sử dụng các cổng 30000–32767
- Nếu địa chỉ IP Node / VM của bạn thay đổi, bạn cần phải giải quyết
Vì những lý do này, tôi không khuyên bạn nên sử dụng phương pháp này trong môi trường production để trực tiếp truy cập service của bạn. Nếu bạn đang chạy một service không phải lúc nào cũng có sẵn hoặc bạn rất nhạy cảm về chi phí, phương pháp này sẽ phù hợp với bạn. Một ví dụ điển hình về một ứng dụng như vậy là một ứng dụng demo hoặc một cái gì đó tạm thời.
Cân bằng tải (LoadBalancer)
Dịch vụ LoadBalancer là cách tiêu chuẩn để hiển thị dịch vụ trên internet. Trên GKE, điều này sẽ tạo ra một Bộ cân bằng tải mạng sẽ cung cấp cho bạn một địa chỉ IP duy nhất sẽ chuyển tiếp tất cả lưu lượng truy cập đến dịch vụ của bạn.
Khi nào bạn sẽ sử dụng cái này?
Nếu bạn muốn service của bạn có thể truy cập từ internet, đây là phương pháp mặc định. Tất cả traffic trên port bạn chỉ định sẽ được chuyển tiếp đến service trong kuberentes. Không có filtering, không có routing, v.v. Điều này có nghĩa là bạn có thể gửi hầu hết mọi loại lưu lượng đến nó, như HTTP, TCP, UDP, Websockets, gRPC, hoặc bất cứ thứ gì.
Nhược điểm lớn nhất là mỗi service mà bạn sử dụng LoadBalancer sẽ nhận được địa chỉ IP riêng và bạn phải trả tiền cho một LoadBalancer cho mỗi serrvice được expose, điều này có thể rất đắt!
Ingress
Không giống như tất cả các ví dụ trên, Ingress thực sự KHÔNG phải là một loại service. Thay vào đó, nó nằm trước nhiều service và hoạt động như một “bộ định tuyến thông minh” hoặc entrypoint trong cụm của bạn.
Bạn có thể làm nhiều việc khác nhau với Ingress và có nhiều loại Ingress controller có các khả năng khác nhau.
Ingress controller GKE mặc định sẽ tạo ra một Bộ cân bằng tải HTTP (S) cho bạn. Điều này sẽ cho phép bạn thực hiện cả định tuyến dựa trên đường dẫn và tên miền phụ tới các dịch vụ phụ trợ. Ví dụ: bạn có thể gửi mọi thứ trên foo.yourdomain.com đến service foo và mọi thứ theo đường dẫn yourdomain.com/bar/ tới service bar.
File YAML cấu hình cho đối tượng Ingress trên GKE với Bộ cân bằng tải HTTP L7 có thể trông giống như sau:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: my-ingress spec: backend: serviceName: other servicePort: 8080 rules: - host: foo.mydomain.com http: paths: - backend: serviceName: foo servicePort: 8080 - host: mydomain.com http: paths: - path: /bar/* backend: serviceName: bar servicePort: 8080
Khi nào bạn sẽ sử dụng cái này?
Ingress có lẽ là cách hiệu quả nhất để expose các service của bạn, nhưng cũng có thể là cách phức tạp nhất. Có nhiều loại Ingress controller, từ Google Cloud Load Balancer , Nginx , Contour , Istio , v.v. Ngoài ra còn có các plugin dành cho Ingress controller, như trình quản lý chứng chỉ , có thể tự động cung cấp chứng chỉ SSL cho các service của bạn.
Ingress là hữu ích nhất nếu bạn muốn hiển thị nhiều service dưới cùng một địa chỉ IP và các dịch vụ này đều sử dụng cùng một giao thức L7 (thường là HTTP). Bạn chỉ trả tiền cho một bộ cân bằng tải nếu bạn đang sử dụng tích hợp native GCP và bởi vì Ingress “smart” nên bạn có thể nhận được rất nhiều tính năng ngay từ đầu (như SSL, Auth, Định tuyến, v.v.)