Kubernetes Service là gì ? Tự học Kubernetes từ A-Z – phần 1

Kubernetes là một Platform dùng để tự động hoá việc quản lý, scaling và triển khai ứng dụng dưới dạng container hoá, Kubernetes còn gọi là Container orchestration engine. Trong serial bài viết về kubernetes này, mục tiêu là cho dù bạn là người chưa từng đụng đến kubernestes đi nữa thì cũng có thể hiểu được khái niệm k8s, và có thể tự mình triển khai k8s trên một ứng dụng thực tế.


1068

Kubernetes là gì ?

Kubernetes là một nền tảng nguồn mở, khả chuyển, có thể mở rộng để quản lý các ứng dụng được đóng gói và các service, giúp thuận lợi trong việc cấu hình và tự động hoá việc triển khai ứng dụng. Kubernetes là một hệ sinh thái lớn và phát triển nhanh chóng. Các dịch vụ, sự hỗ trợ và công cụ có sẵn rộng rãi.

Tên gọi Kubernetes có nguồn gốc từ tiếng Hy Lạp, có ý nghĩa là người lái tàu hoặc hoa tiêu. Google mở mã nguồn Kubernetes từ năm 2014. Kubernetes xây dựng dựa trên một thập kỷ rưỡi kinh nghiệm mà Google có được với việc vận hành một khối lượng lớn workload trong thực tế, kết hợp với các ý tưởng và thực tiễn tốt nhất từ cộng đồng.

Kubernetes bao gồm

Có 4 kiểu service chính

kubernetes

Tôi muốn bạn tưởng tượng rằng nếu bạn tạo một dịch vụ NodePort thì nó cũng tạo ra một dịch vụ ClusterIP. Và nếu bạn tạo LoadBalancer, nó sẽ tạo NodePort, sau đó tạo ClusterIP. Nếu bạn làm điều này, dịch vụ k8s sẽ dễ dàng. Chúng ta sẽ tìm hiểu trong bài viết này.

Services và Pods Kubernetes

Services trỏ đến pods(nhóm). Services không trỏ đến bản deployments hoặc bản sao. Services trỏ trực tiếp bằng cách label(dán nhãn). Điều này mang lại sự linh hoạt cao bởi vì nó không phải là vấn đề. Qua đó có các cách khác nhau (thậm chí có thể tùy chỉnh) đã được tạo ra.

Chúng ta sẽ bắt đầu với một ví dụ đơn giản và mở rộng từng bước với các loại dịch vụ khác nhau để xem cách chúng được xây dựng trên nhau.

No Services

Chúng tabắt đầu mà không có bất kỳ service(dịch vụ).

kubernetes

Chúng ta có 2 node, 1 pod. Node có phần external(bên ngoài) (4.4.4.14.4.4.2) và internal(bên trong) (1.1.1.11.1.1.2) địa chỉ IP. Pod pod-python chỉ có 1 phần internal

kubernetes

Bây giờ chúng ta thêm một pod pod-nginx thứ hai trên node-1. Trong Kubernetes, tất cả pod đều có thể trỏ tới bất kì pod trong địa chỉ IP bên trong.

Có nghĩa pod-nginx có thể ping và kết nối với pod-python bằng cách sử dụng IP bên trong 1.1.1.3.

kubernetes

Bây giờ hãy tưởng tượng pod-python đã bị xóa và tạo ra cái mới. Đột nhiên pod-nginx không thể kết nối tới 1.1.1.3 nữa, và đột nhiên thế giới bùng cháy thành ngọn lửa khủng khiếp như để ngăn chặn điều này, chúng ta tạo ra service đầu tiên của mình!

ClusterIP trong Kubernetes

Cùng một kịch bản như trên, nhưng chúng ta đã cấu hình service ClusterIP. Đối với bài viết này, để giả sử một dịch vụ có sẵn trong bộ nhớ trong toàn bộ cụm

Pod-nginx luôn có thể kết nối an toàn với 1.1.10.1 hoặc DNS service-python và được chuyển hướng đến pod-python. Tuyệt vời chưa

Chúng ta mở rộng ví dụ ra như sau, với 3 trường hợp của python và bây giờ chúng ta hiển thị các port thuộc địa chỉ IP bên trong của tất cả các pod và service.

Tất cả các pod bên trong cluster có thể connect các pod trên port 443 thông qua http://1.1.10.1:3000 hoặc http://service-python:3000. ClusterIP service-python phân phối các yêu cầu dựa trên cách tiếp cận ngẫu nhiên hoặc vòng tròn. Đó là những gì ClusterIP thực hiện, nó cung cấp các pod có sẵn bên trong cluster thông qua tên và IP.

service-python trong hình trên có yaml như thế này:

apiVersion: v1
kind: Service
metadata:
  name: service-python
spec:
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 443
  selector:
    run: pod-python
  type: ClusterIP

Chạy thử kubectl get svc :

NodePort

Bây giờ chúng ta muốn cung cấp service ClusterIP ra bên ngoài, vì vậy chúng ta chuyển đổi nó thành một service NodePort. Trong ví dụ này, chúng ta chuyển  service-python chỉ với 2 thay đổi trên Yaml như sau:

apiVersion: v1
kind: Service
metadata:
  name: service-python
spec:
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 443
// chuyển thành nodeport
    nodePort: 30080
  selector:
    run: pod-python
// đây là thay đổi
  type: NodePort
external request over node-2

Điều này có nghĩa là service-python bên trong của chúng ta có thể truy cập được từ mọi địa chỉ IP bên trong và bên ngoài trên cổng 30080.

external request over node-1

Một pod bên trong cụm cũng có thể kết nối với một node IP bên trong trên cổng 30080.

kubernetes

Chạy cmd kubectl get svc sẽ hiển thị tương tự như ClusterIP. Chỉ thay đổi Type và Port

kubernetes

Trong nội bộ service NodePort vẫn hoạt động như service ClusterIP. Nó giúp tưởng tượng rằng một service NodePort tạo ra một s ClusterIP, mặc dù không còn đối tượng ClusterIP nào nữa.

LoadBalancer (Cân bằng tải)

Chúng ta sử dụng service LoadBalancer nếu chúng ta muốn có một IP duy nhất phân phối các yêu cầu (sử dụng một số phương thức như vòng tròn) cho tất cả các node IP bên ngoài. Vì vậy, nó được xây dựng dựa trên service NodePort:

kubernetes

Hãy tưởng tượng rằng service LoadBalancer tạo ra service NodePort rồi tạo r service dịch vụ ClusterIP. Yaml đã thay đổi cho LoadBalancer trái ngược với NodePort trước đây chỉ đơn giản là:

apiVersion: v1
kind: Service
metadata:
  name: service-python
spec:
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 443
    nodePort: 30080
  selector:
    run: pod-python
// thay đổi
  type: LoadBalancer

Tất cả service LoadBalancer là nó tạo ra service NodePort. Ngoài ra, nó sẽ gửi một thông báo tới nhà cung cấp lưu trữ cụm Kubernetes yêu cầu loadbalancer được thiết lập trỏ đến tất cả các node IP bên ngoài và nodePort cụ thể. Nếu nhà cung cấp không hỗ trợ thông báo yêu cầu, thì không có gì xảy ra và LoadBalancer sẽ tương tự như NodePort.

Chạy cmd kubectl get svc sẽ hiển thị thêm EXTERNAL-IP và sự khác biệt của type:

Dịch vụ LoadBalancer vẫn mở cổng 30080 trên các node IP bên trong và bên ngoài như trước đây. Và nó vẫn hoạt động như một dịch vụ ClusterIP.

ExternalName

Cuối cùng, service ExternalName, có thể được coi là tách biệt một chút và không giống như 3 service trên. Nói tóm lại: nó tạo ra một service nội bộ với điểm cuối trỏ đến tên DNS.

Lấy ví dụ ban đầu của chúng ta, bây giờ chúng ta cho pod-nginx đã có trong Kubernetes. Nhưng api python vẫn ở bên ngoài:

Ở đây pod-nginx phải kết nối với http://remote.server.url.com, và hoạt động. Nhưng chúng ta sẽ sớm tích hợp api python đó vào cụm cho đến lúc đó, chúng ta có thể tạo ra InternalName:

Thay đổi yaml như sau :

kind: Service
apiVersion: v1
metadata:
  name: service-python
spec:
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 443
  type: ExternalName
  externalName: remote.server.url.com

Bây giờ pod-nginx có thể chỉ cần kết nối với http: // service-python: 3000, giống như với ClusterIP. Cuối cùng khi chúng ta quyết định di chuyển api python cũng như trong cụm Kubernetes, chúng ta chỉ cần thay đổi service thành một ClusterIP với label (nhãn) chính xác:

Python api still reachable at 

Lợi thế lớn khi sử dụng các service của InternalName là bạn đã có thể tạo cơ sở hạ tầng Kubernetes hoàn chỉnh của mình và cũng đã áp dụng các quy tắc và hạn chế dựa trên các dịch vụ và IP, mặc dù một số dịch vụ vẫn có thể ở bên ngoài.

Kết luận

Qua bài viết, chúng ta đã tìm hiểu về Kubernetes một cách rõ ràng.

Tìm hiểu thêm về DevOps : Docker là gì? Từng bước tạo ứng dụng đầu tiên với Docker


Like it? Share with your friends!

1068