Chuyển đến nội dung chính

Bài 9: Services & Ingress

Service types: ClusterIP, NodePort, LoadBalancer, ExternalName. kubectl expose. Ingress resources, IngressClass, TLS termination và path-based routing.

Service Types và Ingress Routing — ClusterIP, NodePort, LoadBalancer

1. Service Types

TypeAccessDùng khi nào
ClusterIPInternal only (cluster DNS)Service-to-service communication (default)
NodePortNodeIP:30000-32767Dev/test external access
LoadBalancerCloud LB external IPProduction external access (cloud)
ExternalNameCNAME DNS aliasRoute to external DNS name
ClusterIP (default):
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  type: ClusterIP     # Can omit — default
  selector:
    app: myapp
  ports:
  - port: 80          # Service port (what clients connect to)
    targetPort: 8080  # Container port (where app listens)

NodePort:
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080   # Optional: 30000-32767 range (auto-assigned if omitted)

2. kubectl expose

# Expose Deployment as ClusterIP (default)
kubectl expose deployment myapp --port=80 --target-port=8080

# Expose as NodePort
kubectl expose deployment myapp --port=80 --target-port=8080 --type=NodePort

# Expose a Pod
kubectl expose pod mypod --port=80 --name=mypod-svc

# Expose existing service quickly and redirect traffic
kubectl run nginx --image=nginx --port=80 --expose
# This creates both the Pod AND the ClusterIP Service

Exam tip: kubectl expose cần selector match với Pod labels. Nếu Deployment đang dùng app: myapp, Service selector phải là app: myapp. Flag --expose khi dùng với kubectl run tạo cả Pod lẫn Service cùng lúc — rất nhanh trong exam.

3. Ingress

Ingress là L7 HTTP/HTTPS routing — một điểm vào, route đến nhiều Services dựa trên host/path.

                     ┌─────────────────────────────────┐
Internet ──────────►│   Ingress Controller (nginx)     │
                     │                                  │
                     │  /api  ──────────► api-service   │
                     │  /web  ──────────► web-service   │
                     │  blog.example.com → blog-service │
                     └─────────────────────────────────┘
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx       # Which IngressClass to use
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls       # TLS cert stored as Secret
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix        # Prefix or Exact
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
pathTypeHành viVí dụ
ExactMatch chính xác path/api chỉ match /api
PrefixMatch path prefix/api match /api, /api/v1, /api/users
ImplementationSpecificTùy IngressClassDepends on controller

Exam tip: Ingress cần Ingress Controller (như nginx, traefik) mới hoạt động — Ingress resource chỉ là config. IngressClass chỉ định controller nào xử lý. Trong exam, IngressClass thường đã được setup sẵn. Nhớ check kubectl get ingressclass để biết tên.

4. Debug Service Connectivity

# Check service exists và endpoints
kubectl get services
kubectl get endpoints myapp-svc

# Test connectivity từ trong cluster (create temp pod)
kubectl run test --image=busybox --rm -it -- wget -qO- http://myapp-svc
kubectl run test --image=curlimages/curl --rm -it -- curl http://myapp-svc:80

# Check if selector matches pods
kubectl get pods -l app=myapp  # Should match service selector
kubectl describe service myapp-svc  # Shows Endpoints section

# If Endpoints is empty: selector mismatch!
# Check: kubectl get pods --show-labels

5. Cheat Sheet

TaskCommand
Expose Deploymentkubectl expose deploy/app --port=80 --type=NodePort
Create Pod + Servicekubectl run nginx --image=nginx --port=80 --expose
Check service endpointskubectl get endpoints svc-name
Test service từ trong clusterkubectl run tmp --image=busybox --rm -it -- wget -O- http://svc
Ingress với TLStls: secretName + hosts trong rules

6. Practice Questions

Q1: A Deployment named "webapp" with selector app=webapp runs on port 8080. You need to create a Service that makes it accessible within the cluster on port 80. Which command creates this correctly?

  • A) kubectl expose deployment webapp --port=8080
  • B) kubectl expose deployment webapp --port=80 --target-port=8080 ✓
  • C) kubectl create service clusterip webapp --port=8080:80
  • D) kubectl expose deployment webapp --type=ClusterIP --port=80

Explanation: --port=80 is the Service port (what clients use), --target-port=8080 is the container port (where the app listens). Without --target-port, Kubernetes assumes target-port equals port. Option D would work but uses same port 80 for both.

Q2: An Ingress resource exists but traffic doesn't reach the backend Services. kubectl get endpoints shows the correct Pod IPs. What is the most likely cause?

  • A) The Service type should be LoadBalancer instead of ClusterIP
  • B) No Ingress Controller is installed or the ingressClassName is wrong ✓
  • C) The Ingress needs TLS configured
  • D) The pathType should be Exact instead of Prefix

Explanation: Ingress resources are just configuration objects. Without an Ingress Controller, nothing processes the rules. If the ingressClassName doesn't match an IngressClass connected to a running controller, the Ingress is effectively ignored. Always verify kubectl get ingressclass and that the controller Pod is running.

Q3: Which Service type provides external access using a port in the range 30000-32767 on every cluster node?

  • A) ClusterIP
  • B) ExternalName
  • C) NodePort ✓
  • D) LoadBalancer

Explanation: NodePort opens a port in the 30000-32767 range on every Node in the cluster. External traffic can reach the Service via NodeIP:NodePort. This is typically used for development and testing. LoadBalancer provides a cloud load balancer with a stable external IP, which is preferred for production.