Kubernetes Services vs. Ingress มันต่างกันยังไงนะ?

Nopnithi Khaokaew (Game)
5 min readMar 2, 2024

--

บทความนี้เป็นเวอร์ชั่นเก่าแล้ว เวอร์ชั่นที่ถูกปรับปรุงใหม่จะถูกย้ายไปที่ Kubernetes Services และ Kubernetes Ingress ต่างกันยังไง? ครับ

และหลังจากนี้ผมจะเขียนบทความที่ nopnithi.com เป็นหลักครับ

อัพเดทล่าสุด: 4 Mar 2024

มือใหม่บางคนที่พึ่งเริ่มศึกษา Kubernetes อาจจะสับสนระหว่าง Service กับ Ingress ว่ามันต่างกันยังไง ใช้ใน use cases แบบไหนบ้าง ลองอ่านบทความนี้ดูครับ

ก่อนจะเริ่ม…รบกวนกด Like/Follow/Subscribe ให้ผมด้วยนะครับ 🙏

Introduction

บทความนี้เหมาะสำหรับผู้ใช้ Kubernetes มือใหม่และกำลังสับสนว่า Kubernetes Services กับ Kubernetes Ingress มันต่างกันยังไง โดยผมจะค่อย ๆ อธิบายรวมถึงยกตัวอย่าง application ขึ้นมาลอง deploy ในใจดู ทั้งแบบที่ “ไม่ใช้ Ingress” และ “ใช้ Ingress” เพื่อให้ทุกคนเห็นภาพความแตกต่างและประโยชน์ของ ingress

Table of Contents

  1. Introduction
  2. Kubernetes Services คืออะไร?
  3. ชนิดของ Kubernetes Services (Recap สั้น ๆ)
  4. [V.1] ลอง Deploy App (ในใจ) โดยใช้แค่ Services
  5. Kubernetes Ingress คืออะไร?
  6. [V.2] ลอง Deploy App (ในใจ) โดยใช้ Ingress มาช่วย
  7. Conclusion

Kubernetes Services คืออะไร?

A Kubernetes Service

Kubernetes Services คือ endpoint หรือ interface ของ pod (หรือกลุ่มของ pods) ที่ทำงานเดียวกันอยู่ พูดง่าย ๆ มันคือประตูนั่นแหละ แต่เป็นประตูขาเข้าเท่านั้น

การสร้าง service จึงเป็นการสร้างประตูให้ traffic จากข้างนอกสามารถเข้ามาพูดคุยกับ pod เจ้าของประตูได้ง่ายขึ้น

ลองคิดถึงเบอร์โทรศัพท์ 191 ว่าเป็น service ก็ได้ครับ ซึ่งเป็นเบอร์ที่เราทุกคนรู้ว่ามันใช้โทรหาตำรวจ (pod)

เราไม่จำเป็นต้องรู้ชื่อ (DNS name) ของตำรวจ ไม่ต้องรู้ว่าเบอร์โทรศัพท์ส่วนตัว (IP) ของเค้าคืออะไร เราไม่สนว่าจะมีตำรวจกี่นายที่กำลังทำงานอยู่หรือใครบ้างที่ลา (จำนวนของ pods)

ในมุมประชาชน (user) ถ้าเราต้องการจะคุยกับตำรวจก็แค่โทรไปที่ 191 เท่านั้น

ชนิดของ Kubernetes Services (Recap สั้น ๆ)

1. ClusterIP

เมื่อเราสร้าง ClusterIP service, Kubernetes จะสร้าง virtual IP ให้กับ service นั้นโดยดึง IP มาจาก pool ที่ reserve เอาไว้ ทำให้ pods หรือ services อื่น ๆ ภายใน cluster สามารถ access service นี้ได้ผ่าน IP นั้น

ClusterIP เหมาะสำหรับ expose service ที่คุยกันแค่ภายใน เช่น database, cache หรือพวก message queue (ไม่มีใครจากข้างนอกไปคุยกับมัน)

ยกเว้นกรณีที่เรามี Kubernetes Ingress ซึ่งเดี๋ยวผมจะอธิบายต่อไป

2. NodePort

เมื่อเราสร้าง NodePort service ขึ้นมา, Kubernetes จะ reserve port หนึ่งขึ้นมาบน node ใน cluster ทุกตัว (โดยทั่วไปจะใช้ port 30000–32767) และ traffic ที่ถูกส่งมาด้วย node IP + port จะถูก forward เข้ามายัง service นั้น ซึ่งจะเป็น IP ของ node ใดก็ได้

เช่น

  • [Node1] IP X.X.X.X Port 30000 จะ forward ไปที่ shopping cart
  • [Node2] IP Y.Y.Y.Y Port 30000 ก็จะ forward ไปที่ shopping cart เช่นกัน
  • [Node1] IP X.X.X.X Port 30001 จะถูก forward ไปที่ product catalog

NodePort service เหมาะสำหรับใช้ในการ expose service ตัวเดียวออกไปเพื่อ test หรือ debug ระหว่างการพัฒนา app

3. LoadBalancer

เมื่อเราสร้าง LoadBalancer service, Kubernetes จะสร้าง load balancer จริง ๆ ขึ้นมานอก cluster (ถ้าใช้ cloud มันก็สร้างขึ้นมาบน cloud platform) ทำให้ user จากข้างนอกสามารถ access เข้ามายัง service ของเราผ่าน load balancer IP

LoadBalancer service เหมาะสำหรับใช้ในการ expose service ใน production ที่ต้องการให้ access มาจากข้างนอก Kubernetes หรือจาก public internet ได้ เช่น simple web app ที่ไม่ได้ซับซ้อน

ที่จริง Kubernetes ยังมี service อีกชนิดที่อาจจะไม่ค่อยได้พูดถึงกันโดยทั่วไปอย่าง ExternalName ซึ่งผมขอไม่ลงรายละเอียดนะครับ เอาเป็นว่ามันใช้ map service เข้ากับ DNS name (redirection) และไม่ได้ทำ load balancing แต่อย่างใด

[V.1] ลอง Deploy App (ในใจ) โดยใช้แค่ Services

สมมุติผมมี e-commerce app ซึ่งประกอบด้วย 4 ส่วน ได้แก่

  1. Frontend
  2. Product Catalog
  3. Shopping Cart
  4. PostgresSQL Database

ถ้าผมจะ deploy app นี้ด้วย Kubernetes services ก็อาจจะเลือก service ดังนี้

  • Frontend service ใช้ LoadBalancer เพราะ user จากข้างนอกจะเรียกเข้ามา
  • Catalog service ใช้ LoadBalancer เพราะ user จากข้างนอกจะเรียกเข้ามา
  • Cart service ใช้ LoadBalancer เพราะ user จากข้างนอกจะเรียกเข้ามา
  • Database service ใช้ ClusterIP เพราะเรียกจาก service ข้างในด้วยกันเอง

อันนี้แค่ยกตัวอย่างนะครับ เพราะในความเป็นจริง product catalog service หรือ shopping cart service อาจจะไม่ได้ถูก expose ตรงไปหา public user ก็ได้ (อยู่หลัง frontend อีกที) ขึ้นอยู่กับ design ของแต่ละ app ครับ

และผมจะต้องสร้าง record จาก DNS ข้างนอกแบบนี้

  • nopnithi.tech ชี้ไปหา load balancer IP ของ frontend service
  • products.nopnithi.tech ชี้ไปหา load balancer IP ของ catalog service
  • cart.nopnithi.tech ชี้ไปหา load balancer IP ของ cart service
Architecture V.1: Nopnithi Shop without Kubernetes Ingress

ซึ่งมันก็ใช้ได้นะ แต่ปัญหาคือ…

  1. เปลือง: ต้องเสียค่า load balancer ถึง 3 ตัว
  2. ยุ่งยาก: ต้องจัดการ DNS record ถึง 3 records
  3. มีข้อจำกัด: ไม่สามารถทำ URL path routing ได้ ต้องใช้ subdomain แทน เช่น
    - ใช้ nopnithi.tech/products ไม่ได้ → ต้องใช้ products.nopnithi.tech
    - ใช้ nopnithi.tech/cart ไม่ได้ → ต้องใช้ cart.nopnithi.tech
  4. (อาจจะ)วุ่นวาย: ถ้า load balancer IP เปลี่ยนขึ้นมาก็ต้องแก้ DNS record ใหม่ (ยกเว้นบน cloud ที่เรามักชี้ DNS ไปที่ load balancer DNS name)

ที่จริงเรื่อง URL path routing เราสามารถ deploy proxy ขึ้นมาทำได้เหมือนกัน ลดความยุ่งยากเรื่อง DNS record ด้วย แต่มันก็ต้องมาคอยดูแล proxy และยังคงเปลืองค่า load balancer อยู่ดีครับ

และเดี๋ยวลองมาดูว่า Kubernetes Ingress จะเข้ามาช่วยอะไรเราได้บ้าง

Kubernetes Ingress คืออะไร?

A Kubernetes Ingress

Kubernetes Ingress คือ traffic controller ตัวหนึ่งใน Kubernetes cluster ซึ่งมาแทรกอยู่ด้านหน้า services อื่น ๆ ทำหน้าที่รับ traffic จาก load balancer แล้วส่ง traffic ให้ service ต่าง ๆ ตาม routing rules

การจะใช้ Ingress ต้องมี 2 ส่วน (ผมไม่ได้ลงรายละเอียดนะครับ)

  1. Ingress Controller ซึ่งเราก็ต้อง deploy controller (เช่น NGINX, Traefik, HAProxy, etc.) ขึ้นมาก่อน โดยมาทำงานเสมือนเป็น proxy ให้เรา
  2. Ingress Resource คือการ configure ให้ controller ทำงานตามที่เราต้องการ โดยตัวนี้เป็น Kubernetes resource เหมือนกับพวก pods หรือ deployments

[V.2] ลอง Deploy App (ในใจ) โดยใช้ Ingress มาช่วย

ย้ำอีกครั้ง อันนี้แค่ยกตัวอย่างนะครับ เพราะในความเป็นจริง product catalog service หรือ shopping cart service อาจจะไม่ได้ถูก expose ตรงไปหา public user ก็ได้ (อยู่หลัง frontend อีกที) ขึ้นอยู่กับ design ของแต่ละ app ครับ

ผมจะเปลี่ยน services ทั้ง 3 ตัว (frontend, catalog, cart) จาก LoadBalancer เป็น ClusterIP ให้หมด เพราะจะใช้ load balancer ของ ingress ตัวเดียวในการ expose ออกไปข้างนอก cluster

และ DNS ก็จะเหลือแค่ 1 record ชี้ไปหา load balancer IP ของ ingress

Architecture V2: Nopnithi Shop with Kubernetes Ingress

และนี่สิ่งที่ได้หลังจากนำ ingress เข้ามาช่วย

  1. จากที่ต้องใช้ load balancer 3 ตัว ก็เหลือ 1 ตัว
  2. จัดการ DNS record เดียว โดยชี้มาที่ ingress
  3. สามารถทำ routing จาก URL path ได้ เช่น
    - nopnithi.tech → frontend service
    - nopnithi.tech/products → catalog service
    - nopnithi.tech/cart → cart service
  4. Configuration เกี่ยวกับ URL routing หรือ TLS สามารถทำที่ ingress ได้หมด และเก็บเป็น code (Kubernetes manifest) อยู่กับ manifest อื่น ๆ ได้ที่เดียว

ตัวอย่าง Ingress Manifest (ไม่รวม Ingress Controller)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nopnithi-shop-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: nopnithi.tech
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- path: /products
pathType: Prefix
backend:
service:
name: catalog-service
port:
number: 80
- path: /cart
pathType: Prefix
backend:
service:
name: cart-service
port:
number: 80

Conclusion

Services และ Ingress หากมองผ่าน ๆ จะรู้สึกคล้ายกัน แต่ความเป็นจริงนั้นต่างกัน และมันไม่ได้มาแทนที่กัน แต่มาช่วยเสริมกันและกัน

เราอาจจะใช้แค่ Kubernetes Services ถ้า…

  • Service ของเราคุยกันแค่ภายใน
  • ต้องการ access เข้า service เพื่อ test หรือ debug ในขั้นตอนการพัฒนา
  • เป็นแค่ service ที่เราต้องการ expose ให้ข้างนอกสามารถเข้าไปได้ตรง ๆ เช่น database หรือแม้แต่ simple web app

แต่เมื่อใดก็ตามที่เราต้องการ…

  • จัดการหลาย ๆ services จากที่เดียว
  • ทำ URL path-based routing
  • ทำ SSL/TLS termination ง่าย ๆ

อันนี้ Kubernetes Ingress จะเข้ามาช่วยได้ และใช่ครับ…ส่วนมากเราก็มักจะได้ใช้ Ingress อยู่แล้วแหละ 😂

#Kubernetes, #DevOps, #Cloud, #Ingress, #Microservices

บทความนี้เป็นเวอร์ชั่นเก่าแล้ว เวอร์ชั่นที่ถูกปรับปรุงใหม่จะถูกย้ายไปที่ Kubernetes Services และ Kubernetes Ingress ต่างกันยังไง? ครับ

และหลังจากนี้ผมจะเขียนบทความที่ nopnithi.com เป็นหลักครับ

--

--

Nopnithi Khaokaew (Game)
Nopnithi Khaokaew (Game)

Written by Nopnithi Khaokaew (Game)

Cloud Solutions Architect & Hobbyist Developer | 8x AWS/Azure Certified, CKA, CKAD, CKS, 2x HashiCorp Certified (Terraform, Vault), etc.

Responses (1)