iT邦幫忙

2025 iThome 鐵人賽

DAY 22
1
Build on AWS

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

DAY22 - Ingress Controller:幫服務掛上招牌

  • 分享至 

  • xImage
  •  

在 Kubernetes 裡,服務要對外提供流量,第一個會遇到的問題就是:
「我要怎麼把外部的使用者流量,正確導到後端的 Pod?」🤔

這時候 Ingress 就登場了!
它就像 Kubernetes 世界裡的交通指揮官 ,負責把不同的網址、路徑,導向到對應的服務。
而在 AWS 上,搭配 ALB Ingress Controller,我們就能把這個流量指揮官,直接變成雲端級別的 Application Load Balancer,既能負責路由,又能享受 ALB 提供的安全性與擴展性。

AWS Application Load Balancer (ALB) Ingress Controller 是一個 Kubernetes 控制器,它管理 AWS Application Load Balancers 來為 Kubernetes 服務提供入口流量路由。它將 Kubernetes Ingress 資源轉換為 AWS ALB 配置。

ALB Ingress Controller 工作原理

核心概念

ALB Ingress Controller 監控 Kubernetes 集群中的 Ingress 資源變化,並自動:

  1. 創建 ALB:根據 Ingress 規則創建對應的 Application Load Balancer
  2. 配置目標群組:將 Kubernetes 服務的 Pod 註冊為 ALB 的目標
  3. 設定路由規則:根據 Ingress 規則配置 ALB 的監聽器和路由
  4. 管理生命週期:自動更新和刪除不再需要的 ALB 資源

架構流程

Internet → ALB → Target Groups → Kubernetes Pods
  1. 外部流量進入 AWS ALB
  2. ALB 根據路由規則將流量分發到不同的目標群組
  3. 目標群組包含 Kubernetes 集群中的 Pod IP
  4. 流量直接路由到 Pod,繞過 Kubernetes Service

在 EKS 中的角色

主要功能

  1. 入口流量管理

    • 提供集群外部訪問的統一入口
    • 支援 HTTP/HTTPS 流量路由
    • 整合 AWS Certificate Manager (ACM) 進行 SSL/TLS 終止
  2. 高可用性

    • 跨多個可用區分發流量
    • 自動健康檢查和故障轉移
    • 與 AWS 基礎設施深度整合
  3. 安全性

    • 支援 AWS WAF 整合
    • 安全群組和 NACL 控制
    • 支援私有和公有子網部署
  4. 成本優化

    • 相比 Classic Load Balancer 更具成本效益
    • 支援多個服務共享同一個 ALB
    • 按使用量計費

與傳統 Ingress 的比較

特性 ALB Ingress 傳統 Nginx Ingress
負載均衡器 AWS 託管 ALB 集群內 Pod
高可用性 AWS 原生支援 需要額外配置
SSL 終止 ACM 整合 需要手動管理證書
WAF 整合 原生支援 需要額外配置
成本 ALB 使用費 計算資源成本

EKS Auto Mode vs 傳統模式差異

EKS Auto Mode 中的 ALB Ingress

自動化優勢

  1. 自動安裝和配置

    # Auto Mode 自動提供,無需手動安裝
    # AWS Load Balancer Controller 預設啟用
    
  2. 簡化的 RBAC 管理

    • 自動配置必要的 IAM 角色和權限
    • 無需手動創建 ServiceAccount 和 IAM 角色綁定
  3. 自動更新

    • Controller 版本自動管理和更新
    • 減少維護負擔

Auto Mode 範例配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 80

傳統 EKS 模式中的 ALB Ingress

手動配置需求

  1. 安裝 AWS Load Balancer Controller

    # 1. 創建 IAM 角色
    eksctl create iamserviceaccount \
      --cluster=my-cluster \
      --namespace=kube-system \
      --name=aws-load-balancer-controller \
      --attach-policy-arn=arn:aws:iam::aws:policy/ElasticLoadBalancingFullAccess \
      --override-existing-serviceaccounts \
      --approve
    
    # 2. 安裝 Controller
    helm repo add eks https://aws.github.io/eks-charts
    helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
      -n kube-system \
      --set clusterName=my-cluster \
      --set serviceAccount.create=false \
      --set serviceAccount.name=aws-load-balancer-controller
    
  2. 手動 RBAC 配置

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: aws-load-balancer-controller
      namespace: kube-system
      annotations:
        eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT-ID:role/AmazonEKSLoadBalancerControllerRole
    
  3. 版本管理

    • 需要手動監控和更新 Controller 版本
    • 需要測試兼容性

功能對比表

特性 EKS Auto Mode 傳統 EKS 模式
安裝複雜度 自動 手動多步驟
IAM 配置 自動 手動配置
版本管理 自動更新 手動管理
RBAC 設定 預設配置 手動配置
故障排除 簡化 需要深入了解
自定義程度 標準配置 高度可定制

最佳實踐

1. 安全配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: secure-ingress
  annotations:
    # 使用 HTTPS
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/ssl-redirect: '443'
    
    # 整合 ACM 證書
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:region:account:certificate/cert-id
    
    # WAF 整合
    alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:region:account:webacl/name/id

故障排除

常見問題

  1. ALB 創建失敗

    # 檢查 Controller 日誌
    kubectl logs -n kube-system deployment/aws-load-balancer-controller
    
    # 檢查 IAM 權限
    kubectl describe ingress <ingress-name>
    
  2. 目標註冊問題

    # 檢查目標群組狀態
    aws elbv2 describe-target-health --target-group-arn <target-group-arn>
    
    # 檢查 Pod 網路連接
    kubectl get pods -o wide
    
  3. DNS 解析問題

    # 檢查 ALB DNS 名稱
    kubectl get ingress <ingress-name> -o yaml
    
    # 測試 DNS 解析
    nslookup <alb-dns-name>
    

實際操做看看

我們先產生一份部屬用的yaml檔。

cat <<EOF > 2048-deployment.yaml
apiVersion: v1
kind: Namespace# 定義 Namespace,用來將這個遊戲環境隔離在一個命名空間內,這樣可以保持 Kubernetes 集群的組織性。
apiVersion: v1
kind: Namespace
metadata:
  name: game-2048  # 自定義命名空間名稱

---
# 部署設定:這裡定義了部署 (Deployment) 物件,表示 Kubernetes 中的應用程式部署。
# 它管理容器的生命週期、擴展等。

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: game-2048  # 將部署放置在 game-2048 命名空間中
  name: deployment-2048  # 部署名稱
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-2048  # 選擇器,用來識別應用程式的標籤
  replicas: 5  # 設定部署 5 個副本,確保遊戲服務的可用性
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-2048  # 部署的標籤,與選擇器相匹配
    spec:
      containers:
      - image: public.ecr.aws/l6m2t8p7/docker-2048:latest  # 容器映像檔,這是部署的 2048 遊戲容器
        imagePullPolicy: Always  # 每次啟動容器時都會拉取最新的映像檔
        name: app-2048  # 容器名稱
        ports:
        - containerPort: 80  # 容器開放的端口
        # 注:如果需要設定更多容器選項(如環境變數、資源限制等)可以在此處擴展

---
# 定義 Service,這是 Kubernetes 中的一個服務,負責負載均衡和將流量導向相對應的容器。
# 它允許其他應用程式或用戶訪問 2048 遊戲服務。

apiVersion: v1
kind: Service
metadata:
  namespace: game-2048  # 將 Service 放在 game-2048 命名空間
  name: service-2048  # 服務名稱
spec:
  ports:
    - port: 80  # 外部端口是 80,這是服務接收請求的端口
      targetPort: 80  # 容器內部的端口也是 80,請求會被轉發到容器內的該端口
      protocol: TCP  # 使用 TCP 協議
  type: NodePort  # Service 類型是 NodePort,表示可以通過節點的指定端口來訪問服務
  selector:
    app.kubernetes.io/name: app-2048  # 選擇標籤來匹配對應的 Pod(這裡是應用 2048 的 Pod)

---
# 定義 Ingress,用來控制外部 HTTP 請求如何路由到 Kubernetes 內部的服務。
# 這裡使用了 AWS ALB(Application Load Balancer)來進行流量的管理。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: game-2048  # 將 Ingress 放在 game-2048 命名空間
  name: ingress-2048  # Ingress 的名稱
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing  # 設定 ALB 方案為 "internet-facing",意味著這個 ALB 可以從互聯網訪問
    alb.ingress.kubernetes.io/target-type: ip  # 使用 IP 作為目標類型
spec:
  ingressClassName: alb  # 設定 ingress 類別為 alb,意味著這個 ingress 會由 ALB 處理
  rules:
    - http:
        paths:
        - path: /  # 設定匹配的路徑,這裡是將所有以 `/` 開頭的請求都導向到該服務
          pathType: Prefix  # 路徑類型,表示這是以 `Prefix` 的方式匹配
          backend:
            service:
              name: service-2048  # 將請求路由到名為 service-2048 的服務
              port:
                number: 80  # 服務的端口是 80
        # 如果需要設置更多的路由規則或其他路徑,可以在此處進行擴展

EOF

透過以下指令進行部屬

kubectl apply -f ./2048-deployment.yaml

觀測產生的ALB DNS進行連線測試

kubectl get service -n game-2048

小提醒: 可以看這次的指令多了 -n ,因為我們是建立在 game-2048 這個 namespace,我們需要去指定他要到那裡作查詢。

總結

AWS ALB Ingress Controller 在 EKS 中提供了強大的入口流量管理能力。EKS Auto Mode 大幅簡化了部署和管理流程,而傳統模式則提供了更高的自定義靈活性。選擇哪種模式取決於你的具體需求:

  • 選擇 Auto Mode:如果你需要快速部署、簡化管理,並且標準配置能滿足需求
  • 選擇傳統模式:如果你需要精細控制、自定義配置,或有特殊的合規要求

上一篇
DAY21 - 部署應用:K8s 版 NGINX!
系列文
AWS 雲原生,學起來比泡咖啡還快22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言