อะไรคือความแตกต่างระหว่างประเภทบริการ ClusterIP, NodePort และ LoadBalancer ใน Kubernetes


230

1 - ฉันกำลังอ่านเอกสารและฉันสับสนเล็กน้อยกับถ้อยคำ มันบอกว่า:

ClusterIP : exposes บริการบน IP ภายในคลัสเตอร์ การเลือกค่านี้ทำให้บริการสามารถเข้าถึงได้จากภายในคลัสเตอร์เท่านั้น นี่คือ ServiceType เริ่มต้น

NodePort : exposes บริการบนแต่ละ IP ของโหนดที่พอร์ตแบบคงที่ (NodePort) บริการ ClusterIP ซึ่งบริการเส้นทาง NodePort จะถูกสร้างขึ้นโดยอัตโนมัติ คุณจะสามารถที่จะติดต่อบริการ NodePort <NodeIP>:<NodePort>จากนอกคลัสเตอร์โดยการร้องขอ

LoadBalancer : เปิดเผยบริการภายนอกโดยใช้ load balancer ของผู้ให้บริการ บริการ NodePort และ ClusterIP ซึ่งจะสร้างเส้นทางตัวโหลดบาลานซ์ภายนอกจะถูกสร้างขึ้นโดยอัตโนมัติ

ประเภทบริการ NodePort ยังคงใช้ClusterIPแต่ที่พอร์ตอื่นซึ่งเปิดให้กับไคลเอ็นต์ภายนอกหรือไม่ ดังนั้นในกรณีนี้เป็น<NodeIP>:<NodePort>เช่นเดียวกับ<ClusterIP>:<NodePort>?

หรือเป็นNodeIPIP จริงที่พบเมื่อคุณเรียกใช้kubectl get nodesและไม่ใช่ IP เสมือนที่ใช้สำหรับประเภทบริการ ClusterIP

2 - นอกจากนี้ในแผนภาพจากลิงค์ด้านล่าง:

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

มีเหตุผลพิเศษใด ๆ ที่ว่าทำไมจึงClientอยู่ข้างในNode? ฉันคิดว่ามันจะต้องอยู่ใน a Clusterในกรณีของประเภทบริการ ClusterIP

หากไดอะแกรมเดียวกันนั้นถูกวาดขึ้นสำหรับ NodePort มันจะถูกต้องหรือไม่ที่จะดึงลูกค้าออกไปข้างนอกอย่างสมบูรณ์ทั้งNodeและและClusterหรือฉันกำลังพลาดจุดที่สมบูรณ์

คำตอบ:


217

ClusterIP เปิดเผยสิ่งต่อไปนี้:

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

คุณสามารถเข้าถึงบริการนี้ได้เฉพาะในกลุ่มเท่านั้น สามารถเข้าถึงได้จากspec.clusterIpพอร์ตของมัน หากมีการspec.ports[*].targetPortตั้งค่ามันจะกำหนดเส้นทางจากพอร์ตไปยัง targetPort CLUSTER-IP ที่คุณได้รับเมื่อมีการโทรkubectl get servicesคือ IP ที่กำหนดให้กับบริการนี้ภายในคลัสเตอร์ภายใน

NodePort จะเปิดเผยสิ่งต่อไปนี้:

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

หากคุณเข้าถึงบริการนี้บน nodePort จาก IP ภายนอกของโหนดมันจะกำหนดเส้นทางคำขอไปยังspec.clusterIp:spec.ports[*].portซึ่งจะเปลี่ยนเส้นทางไปยังspec.ports[*].targetPortหากคุณตั้งค่าไว้ บริการนี้สามารถเข้าถึงได้ในลักษณะเดียวกับ ClusterIP

NodeIPs ของคุณเป็นที่อยู่ IP ภายนอกของโหนด <ClusterIP>:spec.ports[*].nodePortคุณไม่สามารถเข้าถึงบริการของคุณจาก

LoadBalancer แสดงสิ่งต่อไปนี้:

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

คุณสามารถเข้าถึงบริการนี้จากที่อยู่ IP ของ load balancer ซึ่งกำหนดเส้นทางการร้องขอของคุณไปยัง nodePort ซึ่งจะกำหนดเส้นทางการร้องขอไปยังพอร์ต clusterIP คุณสามารถเข้าถึงบริการนี้ได้เช่นเดียวกับบริการ NodePort หรือ ClusterIP เช่นกัน


3
คุณสามารถแสดงความคิดเห็นเกี่ยวกับการexternalIPsเปลี่ยนแปลงสมการที่นี่ได้อย่างไร โดยเฉพาะมันเป็นไปได้ที่จะกำหนดexternalIPsอาร์เรย์ให้กับClusterIP-type Service และจากนั้นบริการจะสามารถเข้าถึงได้บน IP ภายนอกเช่นกัน? เมื่อใดที่คุณจะเลือกสิ่งนี้ผ่าน NodePort
Bosh

คำถามไม่ได้กล่าวถึง ExternalIPs - ฉันคิดว่าคุณน่าจะได้รับบริการที่ดีที่สุดด้วยการโพสต์คำถามนี้เป็นคำถามใหม่
kellanburket

39
จริงๆแล้วโพสต์นี้มีประโยชน์มากกว่าที่จะอธิบายความแตกต่างเหล่านี้มากกว่าเอกสารทางการของ Kubernetes
adrpino

@kellanburket spec.clusterIpวิธีการทำงานนี้: สามารถ ClusterIP ได้อย่างชัดเจนใน service.yaml และในทำนองเดียวกันspec.loadBalancerIp
samshers

คุณทำวันของฉันด้วยคำตอบของคุณขอบคุณมาก! (เป็นหมายเหตุด้านในปี 2020 เอกสารเครือข่ายยังคงคลุมเครือเล็กน้อย)
user430191

103

เพื่อชี้แจงให้ทุกคนที่กำลังมองหาสิ่งที่แตกต่างระหว่าง 3 ในระดับที่เรียบง่าย คุณสามารถเปิดเผยบริการของคุณด้วย ClusterIp ที่น้อยที่สุด (ภายในคลัสเตอร์ k8s) หรือการเปิดรับที่ใหญ่ขึ้นด้วย NodePort (ภายในคลัสเตอร์ภายนอกกับคลัสเตอร์ k8s) หรือ LoadBalancer (โลกภายนอกหรือสิ่งที่คุณกำหนดไว้ใน LB ของคุณ)

การเปิดรับ ClusterIp <การรับแสง NodePort <การรับแสง LoadBalancer

  • ClusterIp
    เปิดเผยบริการผ่านคลัสเตอร์ k8ด้วยip/name:port
  • NodePort
    เปิดเผยบริการผ่านเครือข่ายภายในของ VMยังเป็นภายนอกกับ k8sip/name:port
  • LoadBalancer
    เปิดเผยบริการผ่านโลกภายนอกหรืออะไรก็ตามที่คุณกำหนดไว้ใน LB

53

ClusterIP: บริการสามารถเข้าถึงได้โดย
พ็อด/ บริการใน Clusterถ้าฉันสร้างบริการที่เรียกว่า myservice ในเนมสเปซเริ่มต้นประเภท: ClusterIP ดังนั้นที่อยู่ DNS แบบคงที่ที่คาดการณ์ได้สำหรับบริการจะถูกสร้างขึ้น:

myservice.default.svc.cluster.local (หรือเพียงแค่ myservice.default หรือโดยฝักในเนมสเปซเริ่มต้นเพียง "myservice" จะทำงาน)

และชื่อ DNS นั้นสามารถแก้ไขได้โดยพ็อดและบริการภายในคลัสเตอร์เท่านั้น

NodePort: บริการสามารถเข้าถึงได้โดยไคลเอนต์บน LAN / ไคลเอนต์เดียวกันที่สามารถ ping โฮสต์โหนด K8s (และพ็อด / บริการในคลัสเตอร์) (หมายเหตุเพื่อความปลอดภัยโหนดโฮสต์ k8s ของคุณควรอยู่บนซับเน็ตส่วนตัวดังนั้นไคลเอ็นต์บนอินเทอร์เน็ตจะชนะ ไม่สามารถเข้าถึงบริการนี้)
หากฉันให้บริการที่เรียกว่า mynodeportservice ใน mynamespace namespace ประเภท: NodePort บน 3 โหนดโหนดคลัสเตอร์ จากนั้นให้บริการประเภท: ClusterIP จะถูกสร้างขึ้นและลูกค้าสามารถเข้าถึงได้ภายในคลัสเตอร์ที่ที่อยู่ DNS แบบคงที่ที่คาดเดาได้ดังต่อไปนี้:

mynodeportservice.mynamespace.svc.cluster.local (หรือเพียง mynodeportservice.mynamespace)

สำหรับแต่ละพอร์ตที่ mynodeportservice ฟังบนโหนดในช่วง 30000 - 32767 จะถูกเลือกแบบสุ่ม เพื่อให้ไคลเอ็นต์ภายนอกที่อยู่นอกคลัสเตอร์สามารถเข้าถึงบริการ ClusterIP ที่มีอยู่ภายในคลัสเตอร์ ให้บอกว่าโหนดโฮสต์ 3 K8 ของเรามี IP 10.10.10.1, 10.10.10.2, 10.10.10.3, บริการ Kubernetes กำลังฟังบนพอร์ต 80 และ Nodeport เลือกโดยสุ่มคือ 31852

ลูกค้าที่อยู่นอกคลัสเตอร์สามารถเยี่ยมชมได้ 10.10.10.1:31852, 10.10.10.2:31852, หรือ 10.10.10.3:31852 (เนื่องจาก NodePort ถูกฟังโดยโหนด Kubernetes ทุกโฮสต์) Kubeproxy จะส่งต่อคำร้องขอไปยังพอร์ต 80 ของ mynodeportservice

LoadBalancer: บริการสามารถเข้าถึงได้โดยทุกคนที่เชื่อมต่อกับอินเทอร์เน็ต * (สถาปัตยกรรมทั่วไปคือ L4 LB สามารถเข้าถึงได้โดยสาธารณะบนอินเทอร์เน็ตโดยวางไว้ใน DMZ หรือให้ทั้งโหนดส่วนตัวและสาธารณะ IP และโฮสต์โหนด k8s อยู่บนเครือข่ายส่วนตัวย่อย)
( หมายเหตุ: นี่เป็นบริการประเภทเดียวที่ใช้งานไม่ได้กับการใช้งานของ Kubernetes 100% เช่นเดียวกับ Kubernetes โลหะเปลือยทำงานได้เมื่อ Kubernetes มีการรวมผู้ให้บริการคลาวด์)

หากคุณสร้างบริการ mylbservice จะมี L4 LB VM เกิดขึ้น (บริการ IP ของคลัสเตอร์และบริการ NodePort จะถูกวางโดยปริยายเช่นกัน) เวลานี้ NodePort ของเราคือ 30222 แนวคิดคือ L4 LB จะมี IP สาธารณะที่ 1.2.3.4 และจะโหลดยอดคงเหลือและส่งต่อการรับส่งข้อมูลไปยังโหนดโฮสต์ 3 K8 ที่มีที่อยู่ IP ส่วนตัว (10.10.10.1:30222, 10.10.10.2:30222, 10.10.10.3:30222) จากนั้น Kube Proxy จะส่งต่อไปยังบริการประเภท ClusterIP ที่มีอยู่ภายในคลัสเตอร์


คุณยังถามว่า: ประเภทบริการ NodePort ยังคงใช้ ClusterIP อยู่หรือไม่ ใช่ *
หรือว่า NodeIP เป็น IP จริง ๆ ที่พบเมื่อคุณรัน kubectl เพื่อรับโหนด? ใช่ยัง

ช่วยให้วาดเส้นประระหว่างพื้นฐาน:
ภาชนะอยู่ในฝัก พ็อดอยู่ภายในเรพลิคาชุด เรพลิคาอยู่ภายในการปรับใช้
ในทำนองเดียวกัน:
บริการ ClusterIP เป็นส่วนหนึ่งของบริการ NodePort บริการ NodePort เป็นส่วนหนึ่งของบริการโหลดบาลานซ์


ในแผนภาพนั้นคุณแสดงให้เห็นว่าลูกค้าจะเป็นฝักภายในคลัสเตอร์


ตามคำถามการติดตามของคุณฉันอยู่ภายใต้การแสดงผลที่คุณต้องการทราบว่าปริมาณข้อมูลเข้ามาในคลัสเตอร์อย่างไร ฉันใช้เสรีภาพในการสร้างคำถามและคำตอบเกี่ยวกับเรื่องนี้หากคุณสนใจ stackoverflow.com/questions/52241501/…
neokyle

1
เฮ้คำอธิบายที่ดีจริงๆฉันสงสัยเกี่ยวกับ LoadBalancer LoadBalancer จะส่งต่อทราฟฟิกใด ๆ ไปยัง NodeIP: NodePort (โหนดนั้นซึ่งเป็นโหนดถัดไปใน round robin) และการเรียกดำเนินการกับโหนดนั้นอย่างไร พอร์ตโหนดรู้ได้อย่างไรว่านี่คือการเรียกใช้บริการและควรแจกจ่ายผ่าน kube-proxy ไปยัง IP เสมือนของบริการ kube-proxy จะสร้างพอร์ตแบบง่าย ๆ
ItFreak

kube-proxy มีบทบาทหลัก 3 ประการ: 1. ให้บริการอยู่ / ทำงานโดยการทำให้ iptables บนโหนดตรงกับสถานะของบริการที่ต้องการใน etcd 2. เป็นผู้รับผิดชอบในการแมปพอร์ตโหนดเพื่อให้บริการแก่พ็อด (ความเข้าใจของฉันคือการทำเช่นนี้ผ่าน iptables) + การปรับแต่งพอร์ต 3. ตรวจสอบให้แน่ใจว่าแต่ละพ็อดมีไอพีที่ไม่ซ้ำกัน โหนดสามารถป้อนใน 1 โหนดคำจำกัดความการบริการที่มีอยู่ใน iptables ของทุกโหนด / บริการที่มีอยู่ในทุกโหนดฝักมักจะอยู่บนเครือข่ายโอเวอร์เลย์เสมือนและโหนดสองเท่าเป็นเราเตอร์ดังนั้นแม้ว่าการจราจรมาใน 1 โหนด รับเส้นทางไปยัง pod ที่มีอยู่บนโหนดอื่น
neokyle

รู้ว่ามันทำงานอย่างไรในระดับที่ลึกกว่านี้ไม่มีจุดหมายเพราะคูเบเนเทสนั้นทำมาจากชิ้นส่วนแยกส่วนและเช่นเดียวกับที่ลินุกซ์มีรสชาติ / distros ที่ทั้งหมดทำงานแตกต่างกันเล็กน้อยกับธีมที่ครอบคลุมบางส่วน ตัวอย่าง cilium cni กำลังมองหาที่จะแทนที่ kube-proxy ทั้งหมดซึ่งหมายความว่าการทำงานเบื้องหลังคือเป้าหมายที่เคลื่อนไหวดังนั้นจึงไม่คุ้มค่าที่จะเข้าใจหากคุณไม่ได้มีส่วนร่วมในโครงการ / พยายามแก้ไขข้อบกพร่อง
neokyle

มีวิธีติดต่อคุณหรือไม่? ฉันกำลังเขียนวิทยานิพนธ์ระดับปริญญาตรีเกี่ยวกับความปลอดภัยใน k8s และชอบที่จะเรียนรู้เกี่ยวกับฟังก์ชั่นฝึกงานของพร็อกซีเช่นเขาจะกระจาย IP ที่อยู่ไปยังโหนดและ
พ็อด

45

สมมติว่าคุณสร้าง Ubuntu VM บนเครื่องของคุณ ที่อยู่ IP มันเป็น192.168.1.104

คุณเข้าสู่ VM และติดตั้ง Kubernetes จากนั้นคุณสร้างพ็อดที่รูปภาพ nginx ทำงานอยู่

1- หากคุณต้องการเข้าถึงพ็อด nginx นี้ภายใน VM ของคุณคุณจะสร้างClusterIP ที่เชื่อมโยงกับพ็อดนั้นตัวอย่างเช่น

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

จากนั้นบนเบราว์เซอร์ของคุณคุณสามารถพิมพ์ที่อยู่ ip ของ nginxclusterip ด้วยพอร์ต 80 เช่น:

http://10.152.183.2:80

2- ถ้าคุณต้องการที่จะเข้าถึงฝัก Nginx นี้จากเครื่องโฮสต์ของคุณคุณจะต้องเปิดเผยการใช้งานของคุณด้วยNodePort ตัวอย่างเช่น:

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

ตอนนี้จากเครื่องโฮสต์ของคุณคุณสามารถเข้าถึง nginx เช่น:

http://192.168.1.104:31865/

ในแผงควบคุมของฉันมันจะปรากฏเป็น:

ป้อนคำอธิบายรูปภาพที่นี่

ด้านล่างเป็นแผนภาพแสดงความสัมพันธ์ขั้นพื้นฐาน

ป้อนคำอธิบายรูปภาพที่นี่


31865 มาจากไหน สร้างขึ้น?
HoaPhan

1
@HoaPhan คุณสามารถระบุพอร์ตของคุณอย่างชัดเจนในช่วง 30000-32767 หรือให้มันสุ่มโดย Kubernetes ในช่วงนี้
Mohammad Torkashvand

20

แม้ว่าคำถามนี้จะมีคำตอบอยู่แล้วก็ตามฉันจะให้อีกคำถามหนึ่งอาจจะมีรูปภาพเพิ่มเติมเพื่อให้เข้าใจได้ดีขึ้น

1. ClusterIPเป็นบริการเริ่มต้นใน Kubernetes และบริการนี้ให้บริการภายในคลัสเตอร์ ด้วยการใช้สิ่งนี้แอปพลิเคชันอื่น ๆ จากคลัสเตอร์สามารถเข้าถึงบริการผ่านพร็อกซี Kubernetes

ฉันควรพูดถึงว่าบริการประเภทนี้ไม่ควรใช้เพื่อเปิดเผยบริการการผลิต อย่างไรก็ตามมันสามารถใช้สำหรับ

  • การรวมการดีบักระหว่างบริการ
  • การเข้าถึงบริการภายในที่เปิดเผยข้อมูลที่ไม่เกี่ยวข้องกับธุรกิจ (แดชบอร์ดการตรวจสอบ)

วิธีที่คำขอเป็นดังต่อไปนี้: ปริมาณข้อมูล -> พร็อกซี K8s -> บริการ K8s (ClusterIP) -> พ็อดและแสดงในรูปต่อไปนี้

ป้อนคำอธิบายรูปภาพที่นี่

2. NodePortเป็นวิธีดั้งเดิมที่สุดในการยอมรับทราฟฟิกภายนอกและส่งต่อไปยังบริการ kubernetes ตามชื่อหมายถึงชนิดของบริการ NodePort จะเปิดพอร์ตเฉพาะบนเครื่องเสมือนทั้งหมดซึ่งในความเป็นจริงแล้วโหนด Kubernetes เพื่อให้ทราฟฟิกที่ส่งไปยังพอร์ตเฉพาะนั้นถูกส่งต่อไปยังบริการนั้น

ประเภทบริการ NodePort มีข้อเสีย:

  • จำเป็นต้องมีเพียงหนึ่งบริการต่อพอร์ต
  • หาก ip ของเครื่องเสมือนจะเปลี่ยนแปลงต้องทำการเปลี่ยนแปลงบางอย่างในคลัสเตอร์
  • เฉพาะพอร์ตระหว่าง 3000-32767 เท่านั้นที่สามารถใช้ได้

วิธีที่คำขอนั้นเป็นดังต่อไปนี้: ปริมาณการใช้งาน -> พอร์ตที่เปิดเผยบนเครื่องเสมือน -> บริการ K8s (NodePort) -> พ็อดและจะแสดงในรูปภาพต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่

3. LoadBalancerเป็นวิธีมาตรฐานในการแสดงบริการกับอินเทอร์เน็ต หากความต้องการของคุณคือการเปิดเผยบริการโดยตรงและปริมาณการใช้งานทั้งหมดบนพอร์ตเฉพาะที่จะถูก forwared กับบริการนี่คือวิธีที่จะทำ นอกจากนี้ประเภทบริการ LoadBalancer ไม่เกี่ยวข้องกับการกรองหรือการกำหนดเส้นทาง นอกจากนี้คุณสามารถส่งปริมาณการรับส่งข้อมูล TCP, UDP, HTTP gRPC

ข้อเสีย: แต่ละบริการที่เปิดเผยผ่าน LoadBalancer จะมีที่อยู่ IP ของตัวเองและทุกบริการจะถูกเปิดเผยผ่านทาง LoadBalancer เดียวซึ่งอาจมีราคาแพง

คำขอมีเส้นทางดังต่อไปนี้: ปริมาณการใช้ -> LoadBalancer -> บริการ K8s -> ฝักและจะแสดงในภาพต่อไปนี้

ป้อนคำอธิบายรูปภาพที่นี่


7
  1. clusterIP: IP สามารถเข้าถึงได้ภายในคลัสเตอร์ (ข้ามโหนดภายใน d คลัสเตอร์)
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.

pod3 สามารถพูดคุยกับ pod1 ผ่านเครือข่าย clusterIP ของพวกเขา

  1. nodeport: เพื่อให้สามารถเข้าถึง pods จากภายนอกคลัสเตอร์ผ่าน nodeIP: nodeport มันจะสร้าง / เก็บ clusterIP ด้านบนเป็นเครือข่าย clusterIP
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX

คุณอาจเข้าถึงบริการบน pod1 ผ่านทาง nodeIPA: nodeportX หรือ nodeIPB: nodeportX วิธีใดวิธีหนึ่งจะทำงานได้เนื่องจาก kube-proxy (ซึ่งติดตั้งในแต่ละโหนด) จะได้รับคำขอของคุณและแจกจ่าย [เปลี่ยนเส้นทาง (คำศัพท์ iptables)] ข้ามโหนดโดยใช้เครือข่าย clusterIP

  1. เครื่องถ่วงล้อ

โดยทั่วไปเพียงแค่วาง LB ไว้ด้านหน้าเพื่อให้ทราฟฟิกขาเข้าถูกแจกจ่ายไปยัง nodeIPA: nodeportX และ nodeIPB: nodeportX จากนั้นดำเนินการต่อด้วยหมายเลขผังกระบวนการที่ 2 ด้านบน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.