iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
Build on AWS

AWS 雲原生,學起來比泡咖啡還快系列 第 20

DAY20 - Pod / Deployment / Service / Ingress:角色大集合

  • 分享至 

  • xImage
  •  

Pod / Deployment / Service / Ingress:角色大集合

前言

在 Kubernetes 的世界裡,Pod、Deployment、Service 和 Ingress 是四個最核心的元件。它們各自扮演不同的角色,但又緊密協作,共同構建出一個完整的應用程式架構。本文將深入介紹這些元件的功能、關係,以及實際應用場景。


Pod:最小執行單位

什麼是 Pod?

Pod 是 Kubernetes 中最小的可部署和管理單位。它就像是一個「容器的家」,可以包含一個或多個緊密相關的容器。

Pod 的特性

  • 共享網路:Pod 內的容器共享同一個 IP 地址和端口空間
  • 共享存儲:可以掛載共享的 Volume
  • 生命週期一致:Pod 內的容器會一起啟動和停止
  • 短暫性:Pod 是臨時的,可能隨時被重新創建

Pod 的角色

🏠 Pod = 容器的家
├── 📦 主要應用容器 (如 Web 服務)
├── 📦 輔助容器 (如日誌收集器)
└── 💾 共享存儲空間

基本 Pod 範例

apiVersion: v1
kind: Pod
metadata:
  name: my-app-pod
  labels:
    app: my-app
    version: v1
spec:
  containers:
  - name: web-server
    image: nginx:1.21
    ports:
    - containerPort: 80
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 200m
        memory: 256Mi
  - name: log-collector
    image: fluentd:latest
    volumeMounts:
    - name: log-volume
      mountPath: /var/log
  volumes:
  - name: log-volume
    emptyDir: {}

Pod 的限制

  • 不適合直接使用:Pod 重啟後 IP 會改變
  • 無自動恢復:Pod 故障後不會自動重新創建
  • 無擴展能力:無法自動增減 Pod 數量

Deployment:應用程式管理者

什麼是 Deployment?

Deployment 是 Pod 的管理者,負責確保應用程式按照期望的狀態運行。它就像是一個「智能管家」,會持續監控和維護你的應用程式。

Deployment 的職責

  • 副本管理:確保指定數量的 Pod 副本正在運行
  • 滾動更新:安全地更新應用程式版本
  • 回滾功能:出問題時快速回到上一個版本
  • 自動恢復:Pod 故障時自動重新創建

Deployment 的角色

👨‍💼 Deployment = 應用程式管理者
├── 📊 監控 Pod 健康狀態
├── 🔄 管理滾動更新
├── ⬆️ 處理擴展需求
└── 🛡️ 確保高可用性

基本 Deployment 範例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app-deployment
  labels:
    app: web-app
spec:
  replicas: 3  # 期望的 Pod 副本數
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-server
        image: nginx:1.21
        ports:
        - containerPort: 80
        readinessProbe:  # 就緒檢查
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:   # 存活檢查
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 20
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1

Deployment 的更新策略

# 滾動更新策略
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 25%  # 最多 25% 的 Pod 可以不可用
    maxSurge: 25%        # 最多可以超出期望副本數的 25%

常用 Deployment 操作

# 創建 Deployment
kubectl apply -f deployment.yaml

# 查看 Deployment 狀態
kubectl get deployments
kubectl describe deployment web-app-deployment

# 擴展副本數
kubectl scale deployment web-app-deployment --replicas=5

# 更新映像版本
kubectl set image deployment/web-app-deployment web-server=nginx:1.22

# 查看更新狀態
kubectl rollout status deployment/web-app-deployment

# 回滾到上一個版本
kubectl rollout undo deployment/web-app-deployment

# 查看更新歷史
kubectl rollout history deployment/web-app-deployment

Service:網路流量指揮官

什麼是 Service?

Service 是 Kubernetes 的網路抽象層,為一組 Pod 提供穩定的網路端點。它就像是一個「智能路由器」,將流量分發到健康的 Pod 上。

Service 解決的問題

  • 動態 IP 問題:Pod 重啟後 IP 會改變
  • 負載均衡:將流量分散到多個 Pod
  • 服務發現:提供穩定的 DNS 名稱
  • 健康檢查:只將流量發送到健康的 Pod

Service 的角色

🚦 Service = 網路流量指揮官
├── 🎯 提供穩定的 IP 和 DNS
├── ⚖️ 負載均衡流量分發
├── 🔍 自動發現後端 Pod
└── 💚 健康檢查過濾

Service 類型

1. ClusterIP (預設)

apiVersion: v1
kind: Service
metadata:
  name: web-app-service
spec:
  type: ClusterIP  # 集群內部存取
  selector:
    app: web-app
  ports:
  - protocol: TCP
    port: 80        # Service 端口
    targetPort: 80  # Pod 端口

2. NodePort

apiVersion: v1
kind: Service
metadata:
  name: web-app-nodeport
spec:
  type: NodePort
  selector:
    app: web-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080  # 節點端口 (30000-32767)

3. LoadBalancer

apiVersion: v1
kind: Service
metadata:
  name: web-app-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: web-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

4. ExternalName

apiVersion: v1
kind: Service
metadata:
  name: external-database
spec:
  type: ExternalName
  externalName: database.example.com

Service 發現機制

# DNS 解析
# 同一命名空間:service-name
# 跨命名空間:service-name.namespace-name.svc.cluster.local

# 環境變數
WEB_APP_SERVICE_HOST=10.96.0.100
WEB_APP_SERVICE_PORT=80

Ingress:外部流量入口

什麼是 Ingress?

Ingress 是 Kubernetes 的 HTTP/HTTPS 路由規則集合,管理外部流量如何進入集群內的服務。它就像是一個「智能門衛」,根據 URL 路徑和主機名將流量導向正確的服務。

Ingress 的角色

🚪 Ingress = 外部流量入口門衛
├── 🌐 HTTP/HTTPS 路由管理
├── 🔒 SSL/TLS 終止
├── 📍 基於路徑的路由
└── 🏷️ 基於主機名的路由

Ingress vs Service LoadBalancer

特性 Ingress LoadBalancer Service
成本 一個 Load Balancer 服務多個應用 每個服務一個 Load Balancer
協議 HTTP/HTTPS TCP/UDP
路由 支援路徑和主機名路由 僅支援端口路由
SSL 內建 SSL 終止 需要額外配置

基本 Ingress 範例

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app-service
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080

進階 Ingress 功能

1. SSL/TLS 配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: secure-ingress
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls-secret
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app-service
            port:
              number: 80

2. 多主機路由

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
spec:
  rules:
  - host: app1.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
  - host: app2.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app2-service
            port:
              number: 80

3. 路徑重寫

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rewrite-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /app(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: app-service
            port:
              number: 80

AWS Load Balancer Controller 範例

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aws-alb-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:region:account:certificate/cert-id
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app-service
            port:
              number: 80

元件關係圖解

整體架構關係

 Internet
    ↓
 Ingress (智能門衛)
    ↓ (HTTP/HTTPS 路由)
 Service (流量指揮官)
    ↓ (負載均衡)
 Deployment (管理者)
    ↓ (管理)
 Pod (容器的家)
    ↓
 Container (應用程式)

詳細流量路徑

1. 用戶請求 → https://myapp.example.com/api/users
2. DNS 解析 → Load Balancer IP
3. Ingress 接收請求 → 檢查 host 和 path
4. Ingress 路由 → 選擇對應的 Service
5. Service 負載均衡 → 選擇健康的 Pod
6. Pod 處理請求 → 返回響應
7. 響應原路返回 → 用戶收到結果

標籤選擇器關係

# Deployment 選擇 Pod
spec:
  selector:
    matchLabels:
      app: web-app      # 選擇標籤為 app: web-app 的 Pod

# Service 選擇 Pod
spec:
  selector:
    app: web-app        # 選擇標籤為 app: web-app 的 Pod

# Pod 標籤
metadata:
  labels:
    app: web-app        # 被 Deployment 和 Service 選中


上一篇
DAY19 - 第一個Cluster
系列文
AWS 雲原生,學起來比泡咖啡還快20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言