自訂 ALB 路由

透過 Traefik 中介軟體資源、Ingress 註解以及 ibm-ingress-deploy-config ConfigMap,自訂您的應用程式負載平衡器 (ALB) 處理路由、標頭、超時、驗證及流量的方式。

將伺服器埠號新增至主機標頭

預設情況下,Traefik 處理 Host 標頭的方式與大多數現代應用程式相容。 不建議修改 Host 標頭以加入埠號。 在進行任何變更之前,請先檢視 Traefik 預設如何處理標頭,並了解何時適合進行覆寫。

Host 標頭的預設處理方式

Host Traefik 預設會透過 passHostHeader: true。 它會自動新增以下獨立的轉發標頭,而非將埠號嵌入 Host 標頭中:

  • X-Forwarded-Host
  • X-Forwarded-Port
針對舊版應用程式覆寫 Host 標頭

如果您的應用程式需要使用 Host 標頭中嵌入的埠號,請使用 Traefik 標頭中介軟體來覆寫該埠號。

# Example (Kubernetes Middleware)
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: test-header
spec:
  headers:
    customRequestHeaders:
      Host: "legacy-app.example:8080"

使用 Traefik Ingress 註解,將中介軟體套用至您的 Ingress 資源。 請確認已啟用 CRD 處理功能(預設為啟用)。 若要設定 CRD 處理,請參閱 ibm-ingress-deploy-config ConfigMap processTraefikCRDs 欄位

使用私有 ALB 路由傳入的請求

預設情況下,公開的 ALB 會處理 Ingress 資源。 若要將傳入的請求改由私有 ALB 進行路由,請在 Ingress 資源 的「spec.ingressClassName」欄位中指定「private-iks-traefik」類別。

spec.ingressClassName: "private-iks-traefik"

使用 App ID

使用 IBM Cloud App ID 來為您的應用程式強制實施身份驗證。 如需更多資訊,請參閱《 在應用程式中新增「App ID」驗證 》。

設定客戶端請求正文的最大大小

預設情況下,Traefik 不會對客戶端請求正文的大小施加限制。 若要設定上限,請建立一個緩衝中介軟體,並將其套用至您的 Ingress 資源。

Traefik 會以 HTTP 413 回應,拒絕任何超過設定限制的請求。

  1. 建立一個 Traefik 緩衝中介軟體資源。 將 maxRequestBodyBytes 設定為客戶端可傳送的最大位元組數。 以下範例將限制設定為 2 MB(2097152 位元組)。

    # Example (Kubernetes Middleware)
    apiVersion: traefik.io/v1alpha1
    kind: Middleware
    metadata:
      name: limit
    spec:
      buffering:
        maxRequestBodyBytes: 2097152
    
  2. 使用 Traefik Ingress 註解,將中介軟體套用至您的 Ingress 資源。

啟用客戶端回應資料緩衝

預設情況下,Traefik 會直接傳輸回應,不會進行緩衝。 透過 緩衝中介軟體,Traefik 可以在將回應傳送給客戶端之前,將其儲存於記憶體中或寫入磁碟。 請僅在您的應用程式確實需要時才使用此中介軟體,因為在大多數情況下,不建議進行回應緩衝。

若要啟用回應緩衝,請執行以下步驟:

  1. 建立一個 Traefik 緩衝中介軟體資源。 將 maxResponseBodyBytes 設定為回應的最大大小(以位元組為單位),並將 memResponseBodyBytes 設定為閾值;當回應大小超過此閾值時,系統會將回應寫入磁碟,而非保留在記憶體中。 以下範例會緩衝總計最多 5 MB 的資料,其中前 1 MB 會保存在記憶體中。

    # Example (Kubernetes Middleware)
    apiVersion: traefik.io/v1alpha1
    kind: Middleware
    metadata:
      name: response-buffer
    spec:
      buffering:
        maxResponseBodyBytes: 5242880    # 5 MB max response size
        memResponseBodyBytes: 1048576    # 1 MB in memory, then disk
    
  2. 使用 Traefik Ingress 註解,將中介軟體套用至您的 Ingress 資源。

調整超時設定

Traefik 提供了兩組超時控制機制:客戶端與 ALB 之間的超時設定,以及 ALB 與您的後端應用程式之間的超時設定。 請根據瓶頸所在的位置,分別進行設定。

若要設定客戶端至 ALB 的超時值,請配置對應的「ibm-ingress-deploy-config」ConfigMap 欄位

若要設定 ALB 與您的後端應用程式之間的連線及讀取超時,請使用 ServersTransport 來設定 Traefik 與您的 HTTP 伺服器之間的傳輸設定。

# Example (Kubernetes ServersTransport)
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
  name: mytransport
spec:
  forwardingTimeouts:
    dialTimeout: 30s
    responseHeaderTimeout: 10s
    idleConnTimeout: 90s

對於 VPC 叢集,您還必須修改公開 ALB 所對應的負載平衡器服務上的閒置連線超時設定。 請將 CLUSTER_ID 替換為您的叢集 ID,您可透過執行 ibmcloud ks cluster get --cluster CLUSTER_NAME_OR_ID`` 來取得該 ID。 以下範例將超時設定為 910 秒:

kubectl annotate svc -n kube-system public-cr<clusterid> service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-idle-connection-timeout="910"

Traefik 支援將超時設定為 0 ,此設定可停用超時機制。

VPC 負載平衡器上的 ibm-load-balancer-cloud-provider-vpc-idle-connection-timeout 註解不支援零值。 您可以將超時值設定在 50 秒至 7200 秒(2 小時)之間。 若您需要超過 2 小時的處理時間,請提交 支援案件 並提供業務上的理由。

如果您的叢集是透過 IBM Cloud Internet Services (CIS) 或 Cloudflare 對外公開,且已啟用 Web 應用程式防火牆 (WAF) 或全球負載平衡,請將這些超時設定值設為超過 900 秒。 如需更多資訊,請參閱 Cloudflare 文件

建立 ServersTransport 資源後,請使用 Traefik Service 註解將其套用至您的 Service 資源。

自訂錯誤處理動作

若要指定 ALB 針對特定的 HTTP 錯誤可執行的自訂動作,請設定 Traefik 錯誤中介軟體。 建立中介軟體後,請使用 Traefik Ingress 註解將其套用至您的 Ingress 資源。

變更預設的 HTTP 和 HTTPS 埠號

預設情況下,ALB 會於 80 號埠監聽 HTTP,並於 443 號埠監聽 HTTPS。 如果您的叢集需要使用非標準埠號,您可以透過在 ibm-ingress-deploy-config ConfigMap 中,使用「httpPort」和「httpsPort」欄位,針對每個 ALB 變更這些值。

自訂請求標頭

使用 Traefik 標頭中介軟體,在將客戶端請求轉發至後端應用程式之前,對其標頭欄位進行新增、覆寫或移除。 這對於注入應用程式所需的上下文(例如腳本名稱、租戶識別碼或其他元資料)非常有用。

# Example (Kubernetes Middleware)
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: test-header
spec:
  headers:
    customRequestHeaders:
      X-Script-Name: "test"

建立中介軟體後,請使用 Traefik Ingress 註解將其套用至您的 Ingress 資源。

自訂回應標頭

使用 Traefik 標頭中介軟體,在將回應傳送給客戶端之前,對其新增、覆寫或移除標頭欄位。 這對於執行安全性政策、新增 CORS 標頭,或在標頭傳送至客戶端之前移除內部標頭,都相當有用。

# Example (Kubernetes Middleware)
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: test-header
spec:
  headers:
    customResponseHeaders:
      X-Custom-Response-Header: "value"

建立中介軟體後,請使用 Traefik Ingress 註解將其套用至您的 Ingress 資源。

將不安全的請求重新導向

httpsRedirect 若要強制實施僅限 HTTPS 的存取權限,並將所有傳入的 HTTP 請求永久重定向至 HTTPS 端點,請在 ibm-ingress-deploy-config ConfigMap 中設定 xml-ph-0003@deepl.internal 欄位。

啟用與停用 HTTP 嚴格傳輸安全性

HTTP「嚴格傳輸安全性」( HSTS )會指示瀏覽器僅透過 HTTPS 存取網域,藉此防止協定降級攻擊。 此功能在 Traefik 中需手動啟用。 請透過「Headers 中介軟體」,並設定 stsSecondsstsIncludeSubdomainsstsPreload 這三個欄位來啟用此功能。

# Example (Kubernetes Middleware) - produces: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: security-headers
spec:
  headers:
    stsSeconds: 31536000            # max-age=1 year
    stsIncludeSubdomains: true
    stsPreload: true

請使用以下 Traefik Ingress 註解, 將中介軟體套用至您的 Ingress 資源。

修改 ALB 匹配請求 URI 的方式

預設情況下,Traefik 會使用 PathPrefix 匹配器 來路由請求。 如果您的應用程式需要精確路徑匹配或基於正規表達式的路由,請使用以下 Traefik Ingress 註解來覆寫匹配器。

traefik.ingress.kubernetes.io/router.pathmatcher: PathRegexp

配置交互鑑別

互信 TLS ( mTLS ) 要求伺服器與客戶端均須出示有效的憑證,其驗證強度高於標準的 TLS。 若要在您的 ALB 上要求進行客戶端憑證驗證,請建立一個引用您的 CA 憑證機密值的 TLSOption 資源。

# Example (Kubernetes TLSOption)
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
  name: mtls
  namespace: default
spec:
  minVersion: VersionTLS12
  clientAuth:
    secretNames:
      - my-ca-secret
    clientAuthType: RequireAndVerifyClientCert

建立 TLSOption 資源後,請使用 Traefik Ingress 註解將其套用至您的 Ingress 資源。

設定上游請求的重試行為

當後端伺服器無法回應時,Traefik 會自動將該請求重新傳送至另一台上游伺服器。 使用 Traefik 重試中介軟體來設定重試行為。 建立中介軟體後,請使用 Traefik Ingress 註解將其套用至您的 Ingress 資源。

速率限制

速率限制透過限制 ALB 在特定時間區間內處理的請求數量,來保護您的後端應用程式免受流量驟增及濫用行為的影響。 使用 Traefik 的 RateLimit 中介軟體 來設定速率限制。 建立中介軟體後,請使用 Traefik Ingress 註解將其套用至您的 Ingress 資源。

重新編寫路徑

路徑重寫可讓您公開一個與後端應用程式監聽的路徑不同的公共 URL 路徑。 例如,您可以將發送至 /app 的請求轉發至一個在 / 上監聽的後端應用程式。 請根據您需要的是固定替換還是基於模式的替換,選用以下其中一個 Traefik 資源:

# Example Replace the path with /foo
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: test-replacepath
spec:
  replacePath:
    path: "/foo"
# Example Replace path with regex
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: test-replacepathregex
spec:
  replacePathRegex:
    regex: "^/foo/(.*)"
    replacement: "/bar/$1"

請使用以下 Traefik Ingress 註解, 將中介軟體套用至您的 Ingress 資源。

使用黏性 Cookie 進行流量路由

「黏性會話」可確保在整個會話期間,客戶端的請求始終被路由至同一台後端伺服器。 這對於將會話資料儲存於伺服器本地的具狀態應用程式而言非常實用。 透過在您的 Ingress 資源上設定 Traefik Service 的 sticky cookie 註解,來啟用黏性會話。

加密您的應用程式與 ALB 之間的流量

預設情況下,Traefik 會透過標準的 HTTP 將流量轉發至您的後端應用程式。 如果您的應用程式需要加密的上游連線,請使用 ServersTransport 資源來設定 ALB 與您的應用程式之間的 TLS,其中包含 CA 憑證及預期的伺服器名稱。

# Example (Kubernetes ServersTransport)
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
  name: backend-transport
spec:
  rootCAs:
    - secret: my-ca-cert
  serverName: <myapp.example.com> # must match your certificate

請使用以下 Traefik Service 註解, ServersTransport 套用至您的 Service 資源。

自訂 ALB 部署

ibm-ingress-deploy-config ( ConfigMap )負責控制 ALB 層級的設定,例如複本數量、埠號、日誌等級、超時值以及 Ingress 提供者。 請使用此 ConfigMap,將配置變更套用至叢集中的一个或多個 ALB,而無需修改個別的 Ingress 資源。

  1. 取得每個 ALB 所對外公開的服務名稱。 請記下這些服務名稱,因為您將在後續步驟中使用它們。

    • 標準叢集:
        kubectl get svc -n kube-system | grep alb
        ```
    * VPC 叢集:在輸出結果中,請尋找格式類似 `public-crc204dl7w0qf6n6sp7tug` 的服務名稱。
    
    ```sh {: pre}
        kubectl get svc -n kube-system | grep LoadBalancer
        ```
    
  2. ibm-ingress-deploy-config 建立一個 YAML 檔案 ConfigMap。 針對每個 ALB ID,您可以指定以下一項或多項可選設定。 您只需包含想要設定的選項即可。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ibm-ingress-deploy-config
      namespace: kube-system
    data:
      <alb1-id>: '{"replicas":<number_of_replicas>, "ingressClass":"<class>", "httpsPort":"<port>", "httpPort":"<port>", "logLevel": "<TRACE|DEBUG|INFO|WARN|ERROR|FATAL|PANIC>", "ingressProvider": "<ingress|ingress-nginx>", "processTraefikCRDs": <true|false>, "traefikIngressNginxAllowExternalNameServices": <true|false>, "traefikCRDAllowCrossNamespace": <true|false>, "traefikCRDAllowExternalNameServices": <true|false>, "httpReadTimeout": <seconds>, "httpWriteTimeout": <seconds>, "httpIdleTimeout": <seconds>, "httpsReadTimeout": <seconds>, "httpsWriteTimeout": <seconds>, "httpsIdleTimeout": <seconds>, "httpsRedirect": <true|false>, "customEntryPoints": {"<name>": {"port": <port>, "protocol": "<TCP|UDP>", "readTimeout": <seconds|0>, "writeTimeout": <seconds|0>, "idleTimeout": <seconds|0>, "udpTimeout": <seconds>}}, "tolerations": [{"key":"<key>","operator":"<Equal|Exists>","value":"<value>","effect":"<NoSchedule|PreferNoSchedule|NoExecute>"}]}'
      <alb2-id>: '{"replicas":<number_of_replicas>, "ingressClass":"<class>", "httpsPort":"<port>", "httpPort":"<port>", "logLevel": "<TRACE|DEBUG|INFO|WARN|ERROR|FATAL|PANIC>", "ingressProvider": "<ingress|ingress-nginx>", "processTraefikCRDs": <true|false>, "traefikIngressNginxAllowExternalNameServices": <true|false>, "traefikCRDAllowCrossNamespace": <true|false>, "traefikCRDAllowExternalNameServices": <true|false>, "httpReadTimeout": <seconds>, "httpWriteTimeout": <seconds>, "httpIdleTimeout": <seconds>, "httpsReadTimeout": <seconds>, "httpsWriteTimeout": <seconds>, "httpsIdleTimeout": <seconds>, "httpsRedirect": <true|false>, "customEntryPoints": {"<name>": {"port": <port>, "protocol": "<TCP|UDP>", "readTimeout": <seconds|0>, "writeTimeout": <seconds|0>, "idleTimeout": <seconds|0>, "udpTimeout": <seconds>}}, "tolerations": [{"key":"<key>","operator":"<Equal|Exists>","value":"<value>","effect":"<NoSchedule|PreferNoSchedule|NoExecute>"}]}'
    
    replicas
    預設情況下,每個 ALB 都有兩個副本。 透過增加 ALB Pod 的數量,來擴展您的 ALB 處理能力。 如需更多資訊,請參閱「增加 ALB Pod 複本的數量」。
    ingressClass
    若您在 Ingress 資源中指定了除 public-iks-traefik private-iks-traefik 以外的類別,請在此處輸入該類別名稱。
    httpPort, httpsPort
    透過新增您要開啟的 HTTP 或 HTTPS 埠,為 Ingress ALB 公開非預設埠。
    預設值:80/443。
    logLevel
    指定記錄等級。 請從以下連結中選擇:TRACEDEBUGINFOWARNERRORFATALPANIC
    預設值: INFO
    ingressProvider
    請指定此 ALB 應使用哪個 Traefik Ingress 提供者。 有效值:
    ingress: 使用 Traefik 自帶的 ingress 控制器。 它會處理 Ingress 資源上專屬於 Traefik 的註解。
    ingress-nginx: 使用一個暫時的 Traefik 中用於 Ingress 的相容性層 —NGINX。 它會處理為 Ingress( NGINX )所建立的註解,並在可能的情況下模擬 Ingress( NGINX )的行為。 請使用此值,以協助從 Ingress- NGINX 遷移至 Traefik。
    預設值: ingress
    processTraefikCRDs
    當設定為 true 時,Traefik 除了處理 Ingress 資源外,還會處理其自身的 CRD 資源。 支援的 CRD 包括 IngressRouteMiddleware 以及 TLSOption。 如需完整清單,請參閱 Traefik 關於 CRD 的文件
    預設值: true
    traefikIngressNginxAllowExternalNameServices
    啟用對由「ingress-nginx」提供者處理的 Ingress 物件所提供的 ExternalName 服務支援。 此選項僅在將 ingressProvider 設定為 ingress-nginx`` 時才適用。
    預設值: true
    traefikCRDAllowCrossNamespace
    允許 IngressRoute 資源(Traefik CRD)引用其他命名空間中的資源。
    預設值: false
    traefikCRDAllowExternalNameServices
    允許 IngressRoute 資源(Traefik CRD)引用 ExternalName 服務。
    預設值: false
    httpReadTimeout, httpsReadTimeout
    設定 ALB 與客戶端之間的 HTTP / HTTPS 讀取超時時間。 該值必須為整數秒數,若將其設定為零,則會停用超時功能。
    如需更多資訊,請參閱 Traefik 文件
    httpWriteTimeout, httpsWriteTimeout
    設定 ALB 與客戶端之間的 HTTP / HTTPS 寫入超時時間。 該值必須為整數秒數,若將其設定為零,則會停用超時功能。
    如需更多資訊,請參閱 Traefik 文件
    httpIdleTimeout, httpsIdleTimeout
    設定 ALB 與客戶端之間的 HTTP / HTTPS 閒置超時(保持連線)時間。 該值必須為整數秒數,若將其設定為零,則會停用超時功能。
    如需更多資訊,請參閱 Traefik 文件
    若您使用 IBM Cloud Internet Services (CIS) 或 Cloudflare 並搭配 Web 應用程式防火牆 (WAF) 或全球負載平衡功能,請將此值設定為超過 900 秒。 如需更多資訊,請參閱「調整超時設定」。
    httpsRedirect
    啟用將所有傳入的 HTTP 請求永久重定向至 HTTPS 端點的功能。
    預設值: false
    customEntryPoints
    指定 Traefik 的其他自訂入口點。 入口點的名稱將作為該物件的鍵。 以下入口點名稱已預留,不得使用:webwebsecuretraefikhchttp 以及 https
    若入口點配置無效,則所有自訂入口點均不會被處理!
    customEntryPoints.<name>.port
    要使用的入口點的埠號。 這是必要欄位。 請確保它不會與其他埠發生衝突。
    此處定義的埠號與協定必須在負載平衡器上手動啟用,操作說明請參閱下文。
    customEntryPoints.<name>.protocol
    應使用的入口點協定。 這是必要欄位。 有效值為 TCPUDP
    customEntryPoints.<name>.readTimeout
    設定 ALB 與客戶端之間入口點的讀取超時設定。 該值必須為整數秒數,若設定為零,則會停用超時功能。
    如需更多資訊,請參閱 Traefik 文件
    customEntryPoints.<name>.writeTimeout
    設定 ALB 與客戶端之間入口點的寫入超時值。 該值必須為整數秒數,若設定為零,則會停用超時功能。
    如需更多資訊,請參閱 Traefik 文件
    customEntryPoints.<name>.idleTimeout
    設定 ALB 與客戶端之間入口點的閒置超時(保持連線)時間。 該值必須為整數秒數,若設定為零,則會停用超時功能。
    如需更多資訊,請參閱 Traefik 文件
    customEntryPoints.<name>.udpTimeout
    設定 UDP 監聽器的入口點閒置超時。 此欄位僅適用於使用 UDP 協定的端點。 該值必須為秒的整數,且大於零。
    如需更多資訊,請參閱 Traefik 文件
    tolerations
    為 ALB Pod 指定額外的自訂容差設定。 如需更多資訊,請參閱《 污染與容忍 》。
  3. 在您的叢集中建立「ibm-ingress-deploy-config」ConfigMap。

    kubectl create -f ibm-ingress-deploy-config.yaml
    
  4. 請更新您的 ALB 以套用這些變更。 變更可能需要長達五分鐘才會生效。 如果該指令執行後未顯示任何輸出,則表示更新已成功提交。

    ibmcloud ks ingress alb update -c CLUSTER_NAME_OR_ID
    
  5. 若您指定了非標準的 HTTP、HTTPS 埠號,或建立了額外的入口點,則必須在每個 ALB 服務上開啟這些埠號。

    1. 針對您在步驟 1 中找到的每個 ALB 服務,請編輯對應的 YAML 檔案。
        kubectl edit svc -n kube-system <alb_svc_name>
        ```
    2. 在「`spec.ports`」區段中,新增您要開啟的埠號。 依預設,會開啟埠 80 及 443。 若您希望保持 80 和 443 埠開放,請勿將它們從此檔案中移除。 任何未指定的埠都會關閉。 請勿指定 ` `nodePort``。 新增埠並套用變更後,系統會自動指派一個 `nodePort`。
    
    ```sh {: codeblock}
        ...
        ports:
        - name: port-80
          port: 80
          protocol: TCP
          targetPort: 80
        - name: port-443
          port: 443
          protocol: TCP
          targetPort: 443
        - name: <new_port>
          port: <port>
          protocol: TCP
          targetPort: <port>
        ...
        ```
    3. 儲存並關閉檔案。 您的變更會自動套用。
    
    

自訂 Ingress 類別

Ingress 類別會將類別名稱與某種 Ingress 控制器類型關聯起來,從而允許多個控制器在同一個叢集中共存。 請使用 IngressClass 資源來為您的 ALB 定義自訂類別。

Traefik 僅會處理那些將 .spec.controller 設定為 traefik.io/ingress-controller`` 的 Ingress 類別。

在應用程式中新增 App ID 驗證功能

透過將 IBM Cloud App ID 與您的 Ingress ALB 整合,以保護您的應用程式免受未經授權的存取。 當配置了身份驗證時,ALB 會透過 OAuth2-Proxy 轉發請求,該服務會在將流量傳送至您的應用程式之前,先透過 App ID 驗證憑證。

  1. 選擇現有實例,或建立新的 App ID 實例。

    一個 App ID 實例在您的叢集中只能用於一個命名空間。 若要為多個命名空間中的 Ingress 資源設定 App ID,請重複本節中的步驟,為每個命名空間中的 Ingress 資源指定一個唯一的 App ID 實例。

    • 若要使用現有的實例,請確保服務實例名稱僅包含小寫的英數字元,且長度不超過 25 個字元。 若要變更名稱,請在服務實例詳細資訊頁面的「更多選項」選單中,選擇「重新命名服務」。
    • 若要佈建新的 App ID 實例,請執行下列動作:
      1. 請將「服務名稱」替換為您為該服務執行個體所設定的專屬名稱。 服務實例名稱必須僅包含小寫的英數字元,且長度不得超過 25 個字元。
      2. 選擇叢集部署所在的相同地區。
      3. 按一下建立
  2. 新增應用程式的重新導向 URL。 重新導向 URL 是應用程式的回呼端點。 為防止網路釣魚攻擊,IBM Cloud App ID 會將請求 URL 與重定向 URL 的白名單進行比對驗證。

    1. 在 App ID 管理主控台,導覽至管理鑑別
    2. 身分提供者標籤中,確保已選取身分提供者。 若未選取任何身分識別提供者,系統將不會對您進行身分驗證,但會發放一個存取憑證,供您以匿名方式存取該應用程式。
    3. 在「驗證設定」分頁中,請以 https://<hostname>/oauth2-<App_ID_service_instance_name>/callback 這種格式為您的應用程式新增重定向網址。 服務實例名稱中的所有字母都必須為小寫。

    若您使用 IBM Cloud App ID 的登出功能,請將 /sign_out 附加至您的網域後面,格式為 https://<hostname>/oauth2-<App_ID_service_instance_name>/sign_out,並將此連結 URL 加入重定向網址清單中。 若要使用自訂登出頁面,請在 OAuth2-Proxy 中的 ConfigMap 設定 whitelist_domains。 請透過 rd 查詢參數呼叫 https://<hostname>/oauth2-<App_ID_service_instance_name>/sign_out 端點,或設定 X-Auth-Request-Redirect 標頭,並指定您的自訂登出頁面 URL。 如需更多資訊,請參閱「登出」。

  3. 將 App ID 服務實例連結至叢集。 此指令會為服務實例建立一個服務金鑰;您也可以加入 --key 選項,以使用現有的服務金鑰憑證。 將服務實例綁定至與您的 Ingress 資源位於同一命名空間中。 服務實例名稱中的所有字母都必須為小寫。

    ibmcloud ks cluster service bind --cluster CLUSTER_NAME_OR_ID --namespace NAMESPACE --service APP_ID_SERVICE_INSTANCE_NAME [--key SERVICE_INSTANCE_KEY]
    

    當服務成功綁定至您的叢集時,系統會建立一個叢集機密,其中包含該服務實例的憑證。 下列範例顯示輸出:

    ibmcloud ks cluster service bind --cluster mycluster --namespace mynamespace --service appid1
    Binding service instance to namespace...
    OK
    Namespace:    mynamespace
    Secret name:  binding-<service_instance_name>
    
  4. 在您的叢集中啟用 ALB「OAuth」代理程式附加元件。 此附加元件會建立並管理以下 Kubernetes 資源:一個用於您的 App ID 服務實例的 OAuth2-Proxy 部署、一個包含 OAuth2-Proxy 配置的機密,以及一個將傳入請求路由至 OAuth2-Proxy 部署的 Ingress 資源。 每個資源的名稱均以 oauth2- 開頭。

    1. 啟用「alb-oauth-proxy」附加元件。
        ibmcloud ks cluster addon enable alb-oauth-proxy --cluster CLUSTER_NAME_OR_ID
        ```
    2. 請確認 ALB「OAuth Proxy」附加元件的狀態為「`Addon Ready`」。 如果狀態顯示為「`Enabling`」,請等待幾分鐘後重新執行該指令。
    ```sh {: pre}
        ibmcloud ks cluster addon ls --cluster CLUSTER_NAME_OR_ID
        ```
    
  5. 在 Ingress 應用程式資源中,若您想新增 App ID 驗證功能,請確保資源名稱不超過 25 個字元。 接著設定 ForwardAuth 中介軟體:

    1. 建立一個 Traefik ForwardAuth 中介軟體資源。 address 指定了您的 App ID 實例所屬的 OAuth2-Proxy 的 URL,該實例擔任 OIDC 依賴方 (RP) 的角色。 服務實例名稱中的所有字母都必須為小寫。
        apiVersion: traefik.io/v1alpha1
        kind: Middleware
        metadata:
          name: oauth-verify
          namespace: default
        spec:
          forwardAuth:
            address: "https://oauth2-<App_ID_service_instance_name>.<namespace_of_Ingress_resource>.svc.cluster.local/oauth2-<App_ID_service_instance_name>/auth"
            tls:
              insecureSkipVerify: true
        ```
        預設情況下,Traefik 會驗證 TLS  IP 主體替代名稱 (SAN)。 IBM- 提供的憑證預計會通過此驗證,因此請使用 `insecureSkipVerify: true` 選項。 此設定可確保 Traefik 執行個體或 ALB 能與 `oauth2-proxy` 的部署執行個體進行通訊。
        {: note}
    
    2. 選擇要在「`Authorization`」標頭中傳送至您應用程式的憑證。 有關 ID 和存取憑證的更多資訊,請參閱 [App ID 的文件](/docs/appid?topic=appid-tokens)。
        * 若要僅傳送 `ID Token`,請在您的 ForwardAuth 中介軟體中加入 `authResponseHeaders` 選項:
    
            ```yaml {: codeblock}
            apiVersion: traefik.io/v1alpha1
            kind: Middleware
            metadata:
              name: oauth-verify
              namespace: default
            spec:
              forwardAuth:
                address: "https://oauth2-<App_ID_service_instance_name>.<namespace_of_Ingress_resource>.svc.cluster.local/oauth2-<App_ID_service_instance_name>/auth"
                authResponseHeaders:
                  - Authorization
                tls:
                  insecureSkipVerify: true
            ```
        * 若要僅傳送 `Access Token`,請在您的 ForwardAuth 中介軟體中加入 `authResponseHeaders` 選項:
    
            ```yaml {: codeblock}
            apiVersion: traefik.io/v1alpha1
            kind: Middleware
            metadata:
              name: oauth-verify
              namespace: default
            spec:
              forwardAuth:
                address: "https://oauth2-<App_ID_service_instance_name>.<namespace_of_Ingress_resource>.svc.cluster.local/oauth2-<App_ID_service_instance_name>/auth"
                authResponseHeaders:
                  - X-Auth-Request-Access-Token
                tls:
                  insecureSkipVerify: true
            ```
        * 若要同時傳送 `Access Token`  `ID Token`,請在您的 ForwardAuth 中間件中加入 `authResponseHeaders` 選項:
    
            ```yaml {: codeblock}
            apiVersion: traefik.io/v1alpha1
            kind: Middleware
            metadata:
              name: oauth-verify
              namespace: default
            spec:
              forwardAuth:
                address: "https://oauth2-<App_ID_service_instance_name>.<namespace_of_Ingress_resource>.svc.cluster.local/oauth2-<App_ID_service_instance_name>/auth"
                authResponseHeaders:
                  - X-Auth-Request-Access-Token
                  - Authorization
                tls:
                  insecureSkipVerify: true
            ```
    3. 可選:若您的應用程式除了支援 [API 策略](/docs/appid?topic=appid-key-concepts#term-api-strategy) 之外,還支援 [網路應用程式策略](/docs/appid?topic=appid-key-concepts#term-web-strategy) (或以 取代 ),請將 `authSigninURL` 加入您的 ForwardAuth 中間件中。 服務實例名稱中的所有字母都必須為小寫。
    
    ```yaml {: codeblock}
        apiVersion: traefik.io/v1alpha1
        kind: Middleware
        metadata:
          name: oauth-verify
          namespace: default
        spec:
          forwardAuth:
            address: "https://oauth2-<App_ID_service_instance_name>.<namespace_of_Ingress_resource>.svc.cluster.local/oauth2-<App_ID_service_instance_name>/auth"
            authResponseHeaders:
              - X-Auth-Request-Access-Token
              - Authorization
            authSigninURL: /oauth2-<App_ID_service_instance_name>/sign_in?rd={url}
            tls:
              insecureSkipVerify: true
        ```
        * 若您設定為 `authSigninURL`,且客戶端驗證失敗時,系統會將客戶端重定向至 OAuth2-Proxy,該頁面隨後會將客戶端重定向至 App ID 登入頁面。
        * 若未指定 ` `authSigninURL``,客戶端必須使用有效的 Bearer 憑證進行驗證。 若驗證失敗,系統將以 `401 Unauthorized` 錯誤拒絕該請求。
    
    
  6. 可選:若您的設定有此需求,請建立一個 Traefik ServersTransport 資源,以跳過轉發至您應用程式 Service 資源之請求的 TLS 驗證。

    # Example (Kubernetes ServersTransport)
    apiVersion: traefik.io/v1alpha1
    kind: ServersTransport
    metadata:
      name: skip-tls-verify
    spec:
      insecureSkipVerify: true
    

    請透過 Traefik Service 註解 ,將 ServersTransport 套用至您的 Service 資源。

  7. 編輯您的 Ingress 資源,透過套用您所建立的 ForwardAuth 中介軟體,來強制執行 App ID 驗證。 請使用以下 Traefik Ingress 註解

    traefik.ingress.kubernetes.io/router.middlewares: "default-oauth-verify@kubernetescrd"
    

    在重新套用具有適當註解的 Ingress 資源後,ALB OAuth Proxy 附加元件會部署一個 oauth2-proxy 部署,為該部署建立一個服務,並建立一個獨立的 Ingress 資源,用以配置 oauth2-proxy 部署的路由設定。 請勿刪除這些附加資源。

  8. 請確認您的應用程式已強制執行 App ID 驗證。

    • 如果您的應用程式支援 網頁應用程式策略:請在網頁瀏覽器中存取應用程式的 URL。 若正確套用 App ID,系統將將您重定向至 App ID 的驗證登入頁面。
    • 如果您的應用程式支援 API 策略:請在發送至該應用程式的請求中,於「Authorization」標頭中指定您的 Bearer 存取憑證。 如需取得存取憑證,請參閱 App ID 的文件。 若正確套用 App ID,該請求即會成功通過驗證,並被路由至您的應用程式。 若您在「Authorization」標頭中未包含存取憑證便向您的應用程式發送請求,或者該存取憑證未被 App ID 接受,該請求將會被拒絕。
  9. 可選:若您在叢集中使用網路政策或其他防火牆解決方案來限制外發流量,請確保您的叢集能夠存取公開的 App ID 服務。 如需取得此服務的 IP 位址範圍,請透過 客戶支援 提交請求。

  10. 可選:您可以透過建立 Kubernetes ConfigMap 來自訂 OAuth2-Proxy 的預設行為。

    1. 建立一個名為 ConfigMap 的 YAML 檔案,並在其中為您想要變更的 OAuth2-Proxy 設定指定數值。
        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: oauth2-<App_ID_service_instance_name>
          namespace: <ingress_resource_namespace>
        data:
          auth_logging: <true|false>
          # Log all authentication attempts.
          auth_logging_format:
          # Format for authentication logs. For more info, see https://oauth2-proxy.github.io/oauth2-proxy/configuration/overview#logging-configuration
          cookie_csrf_expire: "15m"
          # Expiration time for CSRF cookie. Default is "15m".
          cookie_csrf_per_request: <true|false>
          # Enable multiple CSRF cookies per request, making it possible to have parallel requests. Default is "false".
          cookie_domains:
          # A list of optional domains to force cookies to. The longest domain that matches the request’s host is used. If there is no match for the request’s host, the shortest domain is used. Example: sub.domain.com,example.com
          cookie_expire: "168h0m0s"
          # Expiration time for cookies. Default: "168h0m0s".
          cookie_samesite: ""
          # SameSite attribute for cookies. Supported values: "lax", "strict", "none", or "".
          email_domains: ""
          # Authenticate IDs that use the specified email domain. To authenticate IDs that use any email domain, use "*". Default: "". Example: example.com,example2.com
          pass_access_token: <true|false>
          # Pass the OAuth access token to the back-end app via the X-Forwarded-Access-Token header.
          request_logging: <true|false>
          # Log all requests to the back-end app.
          request_logging_format:
          # Format for request logs. For more info, see https://oauth2-proxy.github.io/oauth2-proxy/configuration/overview#request-log-format
          scope:
          # Scope of the OAuth authentication. For more info, see https://oauth.net/2/scope/
          set_authorization_header: <true|false>
          # Set the Authorization Bearer response header when the app responds to the Ingress ALB, such as when using the Traefik ForwardAuth Middleware.
          set_xauthrequest: <true|false>
          # Set X-Auth-Request-User, X-Auth-Request-Email, and X-Auth-Request-Preferred-Username response headers when the app responds to the Ingress ALB, such as when using the Traefik ForwardAuth Middleware.
          standard_logging: <true|false>
          # Log standard runtime information.
          standard_logging_format:
          # Format for standard logs. For more info, see https://oauth2-proxy.github.io/oauth2-proxy/configuration/overview#standard-log-format
          tls_secret_name:
          # The name of a secret that contains the server-side TLS certificate and key to enable TLS between the OAuth2-Proxy and the Ingress ALB. By default, the TLS secret defined in your Ingress resources is used.
          whitelist_domains:
          # Allowed domains for redirection after authentication. Default: "". Example: example.com,*.example2.com For more info, see: https://oauth2-proxy.github.io/oauth2-proxy/configuration/overview#command-line-options
          oidc_extra_audiences:
          # Additional audiences which are allowed to pass verification.
          cookie_refresh:
          # Refresh the cookie after this duration. Example: "15m". To use this feature, you must enable "Refresh token" for the AppID instance. For more info, see: /docs/appid?topic=appid-managing-idp&interface=ui#idp-token-lifetime
        ```
    2. 將「ConfigMap」資源套用至您的附加元件。 您的變更會自動套用。
    ```sh {: pre}
        kubectl apply -f oauth2-<App_ID_service_instance_name>.yaml
        ```
    

有關各版本 ALB OAuth Proxy 附加元件的變更清單,請參閱 IBM Cloud ALB OAuth Proxy 附加元件變更記錄

升級 ALB OAuth 代理程式附加元件

若要將 ALB OAuth Proxy 附加元件升級至較新版本,請先停用當前安裝,然後使用您想要的版本重新啟用它。 在升級過程中,您現有的 oauth2-proxy 實例不會受到中斷。

由於受監控的 oauth2-proxy 實例即使在停用附加元件時仍會保留在叢集上,因此升級過程不會中斷服務。

  1. 停用該附加元件。
    ibmcloud ks cluster addon disable alb-oauth-proxy --cluster CLUSTER_NAME_OR_ID
    
  2. 請列出可用的附加元件版本,並註明您要使用的版本。 輸出結果會顯示可用的版本,以及哪個版本是預設版本。
    ibmcloud ks cluster addon versions --addon alb-oauth-proxy
    
  3. 啟用此附加元件,並設定「--version」選項。 若未指定版本,則會啟用預設版本。
    ibmcloud ks cluster addon enable alb-oauth-proxy --cluster CLUSTER_NAME_OR_ID [--version VERSION]
    

保留來源 IP 位址

預設情況下,Ingress ALB 不會保留客戶端請求的原始來源 IP 位址。 這可能會導致基於 IP 的存取控制、登錄記錄及安全政策無法正常運作。 請選擇適用於您叢集類型的方法,以啟用來源 IP 保留功能。

在 VPC 叢集中啟用 PROXY 協定

PROXY 協定會將原始的客戶端 IP 位址透過負載平衡器層傳遞至 ALB。

啟用 PROXY 協定會重新建立您的負載平衡器,這可能會導致服務短暫中斷。 在重新建立過程中,每個子網中必須為每個負載平衡器預留兩個未使用的 IP 位址。

  1. 啟用 PROXY 協定。 有關命令參數的更多資訊,請參閱 CLI 參考 手冊。

    ibmcloud ks ingress lb proxy-protocol enable --cluster CLUSTER_NAME_OR_ID --cidr SUBNET_CIDR
    
  2. 請確認您叢集中提供 ALB 的負載平衡器已啟用 PROXY 協定。 在輸出結果中,請確認「Proxy Protocol」欄位顯示為「Enabled」。

    ibmcloud ks ingress lb get --cluster CLUSTER_NAME_OR_ID
    
  3. 若要稍後停用 PROXY 協定,請執行以下指令:

    ibmcloud ks ingress lb proxy-protocol disable --cluster CLUSTER_NAME_OR_ID
    

在經典叢集中變更 externalTrafficPolicy

在經典叢集環境中,請將公開 ALB 的負載平衡器服務上的 externalTrafficPolicy 設定為 Local 。 這可防止負載平衡器在轉發流量時,將客戶端來源 IP 替換為工作節點的 IP。

依預設,不會保留用戶端要求的來源 IP 位址。 當客戶端請求傳送到您的叢集時,該請求會被路由至負責提供 ALB 的負載平衡器服務所對應的 Pod。 如果沒有應用程式 Pod 存在於與負載平衡器服務 Pod 相同的工作者節點上,則負載平衡器會將要求轉遞至不同工作者節點上的應用程式 Pod。 執行應用程式 Pod 的工作節點會將封包的來源 IP 位址變更為其公開 IP 位址。

若要保留客戶端請求的原始來源 IP 位址,您可以啟用「來源 IP 位址保留」功能。 保護客戶端 IP 位址在某些情況下相當有用,例如當應用程式伺服器必須執行安全與存取控制政策時。

當啟用來源 IP 保留功能時,負載平衡器會將流量轉向同一工作節點上的 ALB Pod,而非轉向位於不同工作節點上的 ALB Pod。 在此轉換期間,您的應用程式可能會出現服務中斷的情況。 若您執行 停用 ALB,您對公開 ALB 的負載平衡服務所做的任何來源 IP 變更都將失效。 當您重新啟用 ALB 時,必須重新啟用來源 IP。

在經典叢集環境中,將 ALB 複本數增加至超過兩個 雖會增加複本數量,但當 externalTrafficPolicy 設定為 Local 時,超過兩個的複本將不會被使用。 在主動-被動架構下,叢集中僅有兩個負載平衡器 Pod,且由於此流量政策,它們僅將傳入流量轉發至同一節點上的 ALB Pod。

若要啟用來源 IP 保留,請編輯用於公開 Ingress ALB 的負載平衡器服務:

  1. 啟用叢集裡單一 ALB 或所有 ALB 的來源 IP 保留。

    • 若要設定單一 ALB 的來源 IP 保留,請執行下列動作:
      1. 取得您要啟用來源 IP 的 ALB ID。 ALB 服務的格式類似 public-cr18e61e63c6e94b658596ca93d087eed9-alb1(若為公用 ALB)或 private-cr18e61e63c6e94b658596ca93d087eed9-alb1(若為專用 ALB)。

        kubectl get svc -n kube-system | grep alb
        
      2. 開啟用於公開 ALB 的負載平衡器服務的 YAML。

        kubectl edit svc <ALB_ID> -n kube-system
        
      3. spec 下,將 externalTrafficPolicy 的值從 Cluster 變更為 Local

      4. 儲存並關閉配置檔。 輸出與下列內容類似:

        service "public-cr18e61e63c6e94b658596ca93d087eed9-alb1" edited
        
    • 若要設定叢集裡所有公用 ALB 的來源 IP 保留,請執行下列指令:
        kubectl get svc -n kube-system | grep alb | awk '{print $1}' | grep "^public" | while read alb; do kubectl patch svc $alb -n kube-system -p '{"spec":{"externalTrafficPolicy":"Local"}}'; done
        ```
        輸出範例:
    
        ```sh {: screen}
        "public-cr18e61e63c6e94b658596ca93d087eed9-alb1", "public-cr17e61e63c6e94b658596ca92d087eed9-alb2" patched
        ```
    * 若要設定叢集裡所有專用 ALB 的來源 IP 保留,請執行下列指令:
    ```sh {: pre}
        kubectl get svc -n kube-system | grep alb | awk '{print $1}' | grep "^private" | while read alb; do kubectl patch svc $alb -n kube-system -p '{"spec":{"externalTrafficPolicy":"Local"}}'; done
        ```
        輸出範例:
    
        ```sh {: screen}
        "private-cr18e61e63c6e94b658596ca93d087eed9-alb1", "private-cr17e61e63c6e94b658596ca92d087eed9-alb2" patched
        ```
    
  2. 請確認來源 IP 位址是否已保留在您的 ALB Pod 日誌中。

    1. 取得您所修改的 ALB 對應的 Pod 名稱。 請尋找以您所修改的 ALB ID 開頭的 Pod 名稱,例如 public-cr<hash>-alb1-<suffix>
        kubectl get pods -n kube-system | grep alb
        ```
    2. 開啟該 ALB Pod 的日誌。 請確認「`client`」欄位的 IP 位址是原始客戶端請求的 IP 位址,而非負載平衡服務的 IP 位址。
    ```sh {: pre}
        kubectl logs <ALB_pod_ID> traefik -n kube-system
        ```
    
  3. 請確認客戶端 IP 位址是否出現在發送至後端應用程式的請求中,位於 x-forwarded-for 標頭內。 您可以透過檢查應用程式日誌,或檢視應用程式中的傳入請求標頭來驗證這一點。

  4. 可選:若您不再希望保留來源 IP,請還原您對該服務所做的變更。

    • 若要回復公用 ALB 的來源 IP 保留,請執行下列指令:
        kubectl get svc -n kube-system | grep alb | awk '{print $1}' | grep "^public" | while read alb; do kubectl patch svc $alb -n kube-system -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'; done
        ```
    * 若要回復專用 ALB 的來源 IP 保留,請執行下列指令:
    ```sh {: pre}
        kubectl get svc -n kube-system | grep alb | awk '{print $1}' | grep "^private" | while read alb; do kubectl patch svc $alb -n kube-system -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'; done
        ```
    

設定 TLS 通訊協定與加密套件

使用 TLSOption 資源來強制執行最低的 TLS 版本、限制加密套件,並為傳輸至您的 ALB 的流量配置其他 TLS 連線參數。 建立 TLSOption 資源後,請使用 Traefik Ingress 註解將其套用至您的 Ingress 資源。

將自訂憑證傳送至舊式用戶端

不支援伺服器名稱指示 (SNI) 的舊版裝置無法協商應使用哪張 TLS 憑證,因此它們會收到 ALB 的預設 Let's Encrypt 憑證,而非您的自訂憑證。 為確保這些裝置能收到您的自訂憑證,請更新 ALB 的預設伺服器設定,使其指向您的自訂 TLS 祕密。

預設情況下所產生的 Let's Encrypt 憑證,並非供生產環境使用。 針對生產環境的工作負載,請自行提供自訂憑證。

當您建立經典叢集時,IBM 會為預設的 Ingress 機密提供一張 Let's Encrypt 憑證。 如果您建立自訂密鑰並在 Ingress 資源中將其指定為 TLS 的終端憑證,ALB 便會向客戶端傳送您的自訂憑證,而非 Let's Encrypt 憑證。 然而,如果客戶端不支援 SNI,ALB 會預設使用 Let's Encrypt 憑證,因為預設的密鑰已列於 ALB 的預設伺服器設定中。 若要將您的自訂憑證傳送至非 SNI 裝置,請完成以下步驟。

  1. 編輯 alb-default-server Ingress 資源。

    kubectl edit ingress alb-default-server -n kube-system
    
  2. spec.tls 區段中,將 hosts.secretName 設定的值變更為包含您自訂憑證之自訂密碼的名稱。

    spec:
      rules:
      ...
      tls:
      - hosts:
        - invalid.mycluster-<hash>-0000.us-south.containers.appdomain.cloud
        secretName: <custom_secret_name>
    
  3. 儲存資源檔。

  4. 驗證資源現在指向您的自訂密碼名稱。 變更會自動套用至 ALB。 請在輸出結果中確認,spec.tls[].secretName 是否與您的自訂密鑰名稱相符。

    kubectl get ingress alb-default-server -n kube-system -o yaml
    

調整 ALB 效能

工作節點會自動配置經過最佳化的核心調校,以適應大多數工作負載。 如果您的叢集有特定的高吞吐量或低延遲需求,您可以 調整工作節點上的 Linux 核心參數 sysctl,以進一步優化 ALB 的效能。 請僅在有明確的效能優化需求時才變更這些設定,因為不正確的數值可能會導致節點運作不穩定。

下一步