Sự khác biệt giữa các loại dịch vụ ClusterIP, NodePort và LoadBalancer trong Kubernetes là gì?


230

1 - Tôi đang đọc tài liệu và tôi hơi bối rối với từ ngữ. Nó nói rằng:

ClusterIP : Tiếp xúc dịch vụ trên IP cụm nội bộ. Chọn giá trị này làm cho dịch vụ chỉ có thể truy cập từ trong cụm. Đây là ServiceType mặc định

NodePort : Hiển thị dịch vụ trên mỗi IP của Node tại một cổng tĩnh (NodePort). Một dịch vụ ClusterIP, mà dịch vụ NodePort sẽ định tuyến, sẽ tự động được tạo. Bạn sẽ có thể liên hệ với dịch vụ NodePort, từ bên ngoài cụm, bằng cách yêu cầu <NodeIP>:<NodePort>.

LoadBalancer : Tiếp xúc dịch vụ bên ngoài bằng cách sử dụng bộ cân bằng tải của nhà cung cấp đám mây. Các dịch vụ NodePort và ClusterIP, mà bộ cân bằng tải bên ngoài sẽ định tuyến, sẽ tự động được tạo.

Loại dịch vụ NodePort vẫn sử dụng ClusterIPnhưng chỉ ở một cổng khác, mở cho các máy khách bên ngoài? Vậy trong trường hợp này có <NodeIP>:<NodePort>giống như <ClusterIP>:<NodePort>?

Hoặc là NodeIPIP thực sự được tìm thấy khi bạn chạy kubectl get nodesvà không phải IP ảo được sử dụng cho loại dịch vụ ClusterIP?

2 - Cũng trong sơ đồ từ liên kết dưới đây:

http://kubernetes.io/images/docs/service-iptables-overview.svg

Có bất kỳ lý do cụ thể tại sao Clientlà bên trong Node? Tôi giả định rằng nó sẽ cần phải nằm trong một Clustertrường hợp của loại dịch vụ ClusterIP.

Nếu cùng một sơ đồ được vẽ cho NodePort, nó có hợp lệ để vẽ máy khách hoàn toàn bên ngoài cả NodeClustertôi hoàn toàn thiếu điểm không?

Câu trả lời:


217

Một ClusterIP hiển thị như sau:

  • spec.clusterIp:spec.ports[*].port

Bạn chỉ có thể truy cập dịch vụ này trong khi bên trong cụm. Nó có thể truy cập từ spec.clusterIpcổng của nó . Nếu a spec.ports[*].targetPortđược đặt, nó sẽ định tuyến từ cổng đến cổng đích. CLUSTER-IP bạn nhận được khi gọi kubectl get serviceslà IP được gán cho dịch vụ này trong cụm bên trong.

Một NodePort hiển thị như sau:

  • <NodeIP>:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port

Nếu bạn truy cập dịch vụ này trên một nodePort từ IP bên ngoài của nút, nó sẽ định tuyến yêu cầu đến spec.clusterIp:spec.ports[*].port, nó sẽ lần lượt định tuyến nó tới spec.ports[*].targetPort, nếu được đặt. Dịch vụ này cũng có thể được truy cập theo cách tương tự như ClusterIP.

Các NodeIP của bạn là địa chỉ IP bên ngoài của các nút. Bạn không thể truy cập dịch vụ của bạn từ <ClusterIP>:spec.ports[*].nodePort.

Một LoadBalancer hiển thị như sau:

  • spec.loadBalancerIp:spec.ports[*].port
  • <NodeIP>:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port

Bạn có thể truy cập dịch vụ này từ địa chỉ IP của bộ cân bằng tải, định tuyến yêu cầu của bạn đến một nodePort, từ đó định tuyến yêu cầu đến cổng clusterIP. Bạn cũng có thể truy cập dịch vụ này như dịch vụ NodePort hoặc ClusterIP.


3
Bạn có thể nhận xét về cách externalIPsthay đổi phương trình ở đây? Cụ thể, có thể chỉ định một externalIPsmảng cho ClusterIPDịch vụ kiểu, và sau đó dịch vụ cũng có thể truy cập được trên IP bên ngoài? Khi nào bạn sẽ chọn cái này qua NodePort?
Bosh

Câu hỏi không đề cập đến cácIP bên ngoài - Tôi nghĩ rằng bạn có thể sẽ được phục vụ tốt nhất bằng cách đăng câu hỏi này dưới dạng câu hỏi mới.
kellanburket

39
Bài đăng này thực sự hữu ích hơn khi làm rõ những khác biệt này so với tài liệu chính thức của Kubernetes.
adrpino

@kellanburket, cách này hoạt động : spec.clusterIp. ClusterIP có thể được đề cập rõ ràng trong service.yaml. Và tương tựspec.loadBalancerIp
samshers

bạn đã làm cho ngày của tôi với câu trả lời của bạn, cảm ơn bạn rất nhiều! (như một lưu ý phụ, năm 2020 tài liệu mạng vẫn còn hơi mơ hồ)
user430191

103

Để làm rõ cho bất cứ ai đang tìm kiếm sự khác biệt giữa 3 ở mức độ đơn giản hơn. Bạn có thể hiển thị dịch vụ của mình với ClusterIp tối thiểu (trong cụm k8s) hoặc phơi sáng lớn hơn với NodePort (trong cụm bên ngoài cụm k8s) hoặc LoadBalancer (thế giới bên ngoài hoặc bất cứ điều gì bạn đã xác định trong LB của mình).

Phơi nhiễm ClusterIp <Phơi nhiễm NodePort <Phơi nhiễm LoadBalancer

  • ClusterIp
    Expose dịch vụ thông qua cụm k8s vớiip/name:port
  • NodePort
    Dịch vụ phơi bày thông qua VM mạng nội bộ cũng nằm ngoài k8sip/name:port
  • LoadBalancer Tiếp xúc
    dịch vụ thông qua Thế giới bên ngoài hoặc bất cứ điều gì bạn đã xác định trong LB.

53

ClusterIP: Có thể truy cập các dịch vụ theo nhóm / dịch vụ trong Cụm
Nếu tôi tạo một dịch vụ có tên myservice trong không gian tên mặc định của loại: ClusterIP thì địa chỉ DNS tĩnh dự đoán sau cho dịch vụ sẽ được tạo:

myservice.default.svc.cluster.local (hoặc chỉ myservice.default hoặc theo nhóm trong không gian tên mặc định chỉ "myservice" sẽ hoạt động)

Và tên DNS đó chỉ có thể được giải quyết bằng các nhóm và dịch vụ bên trong cụm.

NodePort: Các dịch vụ có thể truy cập được bởi các máy khách trên cùng mạng LAN / máy khách có thể ping các Nút máy chủ của K8 (và các cụm / dịch vụ trong cụm) (Lưu ý để bảo mật các nút máy chủ k8 của bạn phải ở trên một mạng con riêng tư, do đó, các máy khách trên internet đã thắng 'không thể truy cập dịch vụ này)
Nếu tôi thực hiện một dịch vụ có tên mynodeportservice trong không gian tên mynamespace của loại: NodePort trên Cụm 3 Node Kubernetes. Sau đó, một Dịch vụ loại: ClusterIP sẽ được tạo và khách hàng có thể truy cập được trong cụm tại địa chỉ DNS tĩnh dự đoán sau:

mynodeportservice.mOUNDespace.svc.cluster.local (hoặc chỉ mynodeportservice.mOUNDespace)

Đối với mỗi cổng mà mynodeportservice lắng nghe trên một nút dịch chuyển trong phạm vi 30000 - 32767 sẽ được chọn ngẫu nhiên. Vì vậy, các máy khách bên ngoài nằm ngoài cụm có thể đánh vào dịch vụ ClusterIP tồn tại bên trong cụm. Hãy nói rằng các nút máy chủ 3 K8 của chúng tôi có IP 10.10.10.1, 10.10.10.2, 10.10.10.3, dịch vụ Kubernetes đang lắng nghe trên cổng 80 và Nodeport được chọn ngẫu nhiên là 31852.

Một khách hàng tồn tại bên ngoài cụm có thể truy cập 10.10.10.1:31852, 10.10.10.2:31852 hoặc 10.10.10.3:31852 (vì NodePort được lắng nghe bởi mọi Nút máy chủ Kubernetes) Kubeproxy sẽ chuyển tiếp yêu cầu tới cổng 80 của mynodeportservice.

LoadBalancer: Mọi người có thể truy cập dịch vụ đều có thể truy cập dịch vụ * (Kiến trúc phổ biến là L4 LB có thể truy cập công khai trên internet bằng cách đặt nó trong DMZ hoặc cung cấp cho cả các nút máy chủ IP và k8s riêng trên mạng con riêng tư)
( Lưu ý: Đây là loại dịch vụ duy nhất không hoạt động trong 100% triển khai Kubernetes, như Kubernetes kim loại trần, nó hoạt động khi Kubernetes có tích hợp nhà cung cấp đám mây.)

Nếu bạn tạo mylbservice, thì L4 LB VM sẽ được sinh ra (dịch vụ IP cụm và Dịch vụ NodePort cũng sẽ được sinh ra hoàn toàn). Lần này NodePort của chúng tôi là 30222. ý tưởng là L4 LB sẽ có IP công khai là 1.2.3.4 và nó sẽ tải cân bằng và chuyển tiếp lưu lượng đến 3 nút máy chủ K8 có địa chỉ IP riêng. (10.10.10.1:30222, 10.10.10.2:30222, 10.10.10.3:30222) và sau đó Kube Proxy sẽ chuyển tiếp nó đến dịch vụ của ClusterIP loại tồn tại bên trong cụm.


Bạn cũng hỏi: Loại dịch vụ NodePort có còn sử dụng ClusterIP không? Có *
Hoặc NodeIP thực sự là IP được tìm thấy khi bạn chạy kubectl lấy các nút? Ngoài ra Có *

Cho phép vẽ song song giữa các Nguyên tắc cơ bản:
Một thùng chứa bên trong một nhóm. một pod nằm trong một bản sao. một bản sao nằm trong một triển khai.
Cũng tương tự:
Dịch vụ ClusterIP là một phần của Dịch vụ NodePort. Dịch vụ NodePort là một phần của Dịch vụ cân bằng tải.


Trong sơ đồ mà bạn đã chỉ ra, Máy khách sẽ là một nhóm bên trong cụm.


Dựa trên các câu hỏi tiếp theo của bạn, tôi có ấn tượng rằng bạn muốn biết làm thế nào lưu lượng truy cập vào cụm. Tôi đã tự do đưa ra một câu hỏi và trả lời về điều đó nếu bạn quan tâm. stackoverflow.com/questions/52241501/ từ
neokyle

1
Hey, giải thích thực sự tốt, tôi đang tự hỏi về LoadBalancer. LoadBalancer sẽ chuyển tiếp bất kỳ lưu lượng truy cập nào đến NodeIP: NodePort (nút đó là nút tiếp theo trong vòng tròn) và cuộc gọi tiến hành như thế nào trên nút đó? Làm thế nào để cổng nút biết rằng đây là một cuộc gọi dịch vụ và nó sẽ phân phối nó thông qua proxy kube đến IP ảo của dịch vụ? Liệu kube-proxy sẽ tạo ra một cổng đơn giản chuyển tiếp?
ItFreak

kube-proxy đóng 3 vai trò chính: 1. làm cho các dịch vụ tồn tại / hoạt động bằng cách làm cho các iptables trên nút khớp với trạng thái dịch vụ mong muốn trong vvd. 2. chịu trách nhiệm ánh xạ cổng nút thành dịch vụ cho nhóm (sự hiểu biết của tôi là nó thực hiện điều này thông qua iptables) + bản tóm tắt cổng 3. đảm bảo mỗi nhóm có một ip duy nhất. Nút dịch chuyển có thể nhập vào 1 nút, các định nghĩa dịch vụ tồn tại trong iptables của mỗi nút / dịch vụ tồn tại trên mỗi nút, các nhóm thường nằm trên mạng lớp phủ ảo hóa và các nút tăng gấp đôi như bộ định tuyến, do đó, mặc dù lưu lượng truy cập vào 1 nút được định tuyến đến pod hiện có trên một nút khác.
neokyle

Biết làm thế nào nó hoạt động ở một mức độ sâu hơn mức này là vô nghĩa, bởi vì kubernetes nó được tạo thành từ các phần mô-đun, và giống như cách linux có hương vị / bản phân phối mà tất cả đều hoạt động hơi khác nhau với một số chủ đề bao quát, mỗi bản phân phối k8s hơi khác nhau. Ví dụ cilium cni đang tìm cách thay thế hoàn toàn kube-proxy, điều đó có nghĩa là cách nó hoạt động đằng sau hậu trường là một mục tiêu di động, do đó không đáng để hiểu trừ khi bạn thực sự đóng góp cho dự án / cố gắng sửa lỗi.
neokyle

Có cách nào để liên lạc với bạn? Tôi đang viết luận án cử nhân về bảo mật trong k8s và rất thích tìm hiểu về các chức năng thực tập của proxy, ví dụ như cách anh ta phân phối địa chỉ IP cho các nút và nhóm và cách các dịch vụ nhận IP ảo của họ
ItFreak 16/07/19

45

Giả sử bạn đã tạo một máy ảo Ubuntu trên máy cục bộ của mình. Địa chỉ IP của nó là 192.168.1.104 .

Bạn đăng nhập vào VM và cài đặt Kubernetes. Sau đó, bạn đã tạo một pod nơi hình ảnh nginx chạy trên nó.

1- Nếu bạn muốn truy cập nhóm nginx này bên trong máy ảo của mình, bạn sẽ tạo một ClusterIP được liên kết với nhóm đó chẳng hạn:

$ kubectl expose deployment nginxapp --name=nginxclusterip --port=80 --target-port=8080

Sau đó, trên trình duyệt của bạn, bạn có thể nhập địa chỉ IP của nginxclusterip với cổng 80, như:

http://10.152.183.2:80

2- Nếu bạn muốn truy cập pod nginx này từ máy chủ của mình, bạn sẽ cần phải triển khai triển khai của mình với NodePort . Ví dụ:

$ kubectl expose deployment nginxapp --name=nginxnodeport --port=80 --target-port=8080 --type=NodePort

Bây giờ từ máy chủ của bạn, bạn có thể truy cập vào nginx như:

http://192.168.1.104:31865/

Trong bảng điều khiển của tôi, chúng xuất hiện dưới dạng:

nhập mô tả hình ảnh ở đây

Dưới đây là một sơ đồ cho thấy mối quan hệ cơ bản.

nhập mô tả hình ảnh ở đây


31865 đến từ đâu? tạo ra?
HoaPhan

1
@HoaPhan Bạn có thể chỉ định rõ ràng cổng của mình trong phạm vi 30000-32767 hoặc để nó được chọn ngẫu nhiên bởi Kubernetes trong phạm vi này
Mohammad Torkashvand

20

Ngay cả khi câu hỏi này đã có câu trả lời, tôi sẽ cung cấp một câu hỏi khác, có thể với một số hình ảnh khác để hiểu rõ hơn.

1. ClusterIP là loại dịch vụ mặc định trong Kubernetes và loại này cung cấp cho bạn một dịch vụ bên trong cụm. Bằng cách sử dụng điều này, các ứng dụng khác từ cụm có thể truy cập dịch vụ thông qua proxy Kubernetes.

Tôi nên đề cập rằng loại dịch vụ này không nên được sử dụng để phơi bày dịch vụ sản xuất. Tuy nhiên, nó có thể được sử dụng cho

  • gỡ lỗi tích hợp giữa các dịch vụ;
  • truy cập các dịch vụ nội bộ đang phơi bày dữ liệu phi kinh doanh (bảng điều khiển giám sát).

Cách mà yêu cầu thực hiện theo cách sau: lưu lượng truy cập -> proxy K8s -> dịch vụ K8s (ClusterIP) -> nhóm và nó được hiển thị trong hình dưới đây.

nhập mô tả hình ảnh ở đây

2. NodePort là cách nguyên thủy nhất để chấp nhận lưu lượng truy cập bên ngoài và chuyển tiếp nó đến các dịch vụ kubernetes. Đúng như tên gọi, loại dịch vụ NodePort mở một cổng cụ thể trên tất cả các Máy ảo, trên thực tế là các nút Kubernetes, để cho phép lưu lượng truy cập được gửi đến cổng cụ thể đó được chuyển tiếp đến dịch vụ.

Loại dịch vụ NodePort có một số nhược điểm:

  • chỉ cần có một dịch vụ trên mỗi cổng;
  • nếu ip của máy ảo sẽ bị thay đổi, một số thay đổi phải được thực hiện trong cụm;
  • chỉ cổng giữa 3000-32767 có thể được sử dụng.

Cách yêu cầu thực hiện theo cách sau: lưu lượng truy cập -> cổng được hiển thị trên máy ảo -> dịch vụ K8s (NodePort) -> nhóm và nó được hiển thị trong hình sau:

nhập mô tả hình ảnh ở đây

3. LoadBalancer là cách tiêu chuẩn để đưa dịch vụ lên internet. Nếu mong muốn của bạn là trực tiếp tiếp xúc với một dịch vụ và tất cả lưu lượng truy cập trên một cổng cụ thể sẽ được chuyển sang dịch vụ, thì đây là cách để thực hiện. Ngoài ra, loại dịch vụ LoadBalancer không liên quan đến bất kỳ bộ lọc hoặc định tuyến. Ngoài ra, bạn gửi lưu lượng TCP, UDP, HTTP gRPC tới nó.

Nhược điểm: mỗi dịch vụ được hiển thị qua LoadBalancer sẽ có địa chỉ IP riêng và mọi dịch vụ sẽ được hiển thị thông qua một LoadBalancer duy nhất có thể trở nên đắt đỏ.

Yêu cầu có đường dẫn sau: lưu lượng truy cập -> LoadBalancer -> Dịch vụ K8s -> nhóm và nó được hiển thị trong hình dưới đây.

nhập mô tả hình ảnh ở đây


7
  1. clusterIP: IP có thể truy cập bên trong cụm (trên các nút trong cụm d).
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.

pod3 có thể nói chuyện với pod1 thông qua mạng clusterIP của họ.

  1. gật đầu: để làm cho các nhóm có thể truy cập từ bên ngoài cụm thông qua nútIP: gật đầu, nó sẽ tạo / giữ clusterIP ở trên như mạng clusterIP của nó.
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX

bạn có thể truy cập dịch vụ trên pod1 thông qua nodeIPA: gật đầuX HOẶC nodeIPB: gật đầuX. Cả hai cách đều hoạt động vì kube-proxy (được cài đặt trong mỗi nút) sẽ nhận được yêu cầu của bạn và phân phối [chuyển hướng nó (thuật ngữ iptables)] trên các nút bằng mạng clusterIP.

  1. Cân bằng tải

về cơ bản chỉ cần đặt LB ở phía trước, để lưu lượng truy cập vào được phân phối đến nútIPA: gật đầu và nútIPB: gật đầu sau đó tiếp tục với dòng quy trình số 2 ở trên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.