# Kubernetes Gateway API  測試

您說得對，為了確保這份文件是「自包含 (Self-contained)」且可立即執行的，必須包含後端應用的部署宣告。

身為架構師，在測試金絲雀發佈時，我們會使用具備 **不同環境變數** 的 Pod 來區分版本。以下是完整的 `apps.yaml` 內容與更新後的部署流程。

<div aria-busy="false" aria-live="polite" id="bkmrk-"><div aria-busy="false" aria-live="polite">---

</div></div>## 1. 應用程式定義層：`apps.yaml`

此檔案定義了兩個版本的 Deployment 與對應的 Service。我們使用 `nginxdemos/hello` 映像檔，因為它會直接在網頁內容中顯示 **Server Name**，方便我們觀察流量去向。

<div aria-busy="false" aria-live="polite" id="bkmrk-yaml-%23-----version-1"><div aria-busy="false" aria-live="polite"><div data-hveid="0" data-ved="0CAAQhtANahgKEwjssI2WoeCTAxUAAAAAHQAAAAAQ3wk"><div><span class="ng-tns-c1695782856-863">YAML</span><div><button aria-label="複製代碼" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c1695782856-863 mat-unthemed ng-star-inserted"></button></div></div><div><div>```
<span class="hljs-comment"># --- Version 1 (90% 流量) ---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app-v1</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">2</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
      <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
        <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">nginx</span>
        <span class="hljs-attr">image:</span> <span class="hljs-string">nginxdemos/hello:plain-text</span>
        <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">80</span>
<span class="hljs-meta">---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app-v1</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
    <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
  <span class="hljs-attr">ports:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>
    <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
    <span class="hljs-attr">targetPort:</span> <span class="hljs-number">80</span>
<span class="hljs-meta">---</span>
<span class="hljs-comment"># --- Version 2 (10% 權重測試) ---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app-v2</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">2</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
      <span class="hljs-attr">version:</span> <span class="hljs-string">v2</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
        <span class="hljs-attr">version:</span> <span class="hljs-string">v2</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">nginx</span>
        <span class="hljs-attr">image:</span> <span class="hljs-string">nginxdemos/hello:plain-text</span>
        <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">80</span>
<span class="hljs-meta">---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app-v2</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
    <span class="hljs-attr">version:</span> <span class="hljs-string">v2</span>
  <span class="hljs-attr">ports:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>
    <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
    <span class="hljs-attr">targetPort:</span> <span class="hljs-number">80</span>

```

</div></div></div>---

</div></div>## 2. 完整部署與測試標準 SOP (全流程)

### 第一階段：基礎資源與控制器

<div aria-busy="false" aria-live="polite" id="bkmrk-bash-%23-1.-%E5%AE%89%E8%A3%9D-gateway"><div aria-busy="false" aria-live="polite"><div data-hveid="0" data-ved="0CAAQhtANahgKEwjssI2WoeCTAxUAAAAAHQAAAAAQ4Ak"><div><span class="ng-tns-c1695782856-864">Bash</span><div><button aria-label="複製代碼" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c1695782856-864 mat-unthemed ng-star-inserted"></button></div></div><div><div>```
<span class="hljs-comment"># 1. 安裝 Gateway API 與 Traefik CRDs</span>
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml

<span class="hljs-comment"># 2. 部署 Traefik (對齊 8000 埠)</span>
helm upgrade --install traefik traefik/traefik \
  --namespace traefik --create-namespace \
  --<span class="hljs-built_in">set</span> ports.web.nodePort=30080 \
  --<span class="hljs-built_in">set</span> ports.web.port=8000 \
  --<span class="hljs-built_in">set</span> service.type=NodePort \
  --<span class="hljs-built_in">set</span> providers.kubernetesGateway.enabled=<span class="hljs-literal">true</span> \
  --<span class="hljs-built_in">set</span> additionalArguments=<span class="hljs-string">"{--providers.kubernetesgateway,--entrypoints.web.address=:8000}"</span> \
  --skip-crds

```

</div></div></div></div></div>### 第二階段：應用程式與路由套用

<div aria-busy="false" aria-live="polite" id="bkmrk-bash-%23-3.-%E9%83%A8%E7%BD%B2%E5%BE%8C%E7%AB%AF-pods-"><div aria-busy="false" aria-live="polite"><div data-hveid="0" data-ved="0CAAQhtANahgKEwjssI2WoeCTAxUAAAAAHQAAAAAQ4Qk"><div><span class="ng-tns-c1695782856-865">Bash</span><div><button aria-label="複製代碼" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c1695782856-865 mat-unthemed ng-star-inserted"></button></div></div><div><div>```
<span class="hljs-comment"># 3. 部署後端 Pods 與 Services</span>
kubectl apply -f apps.yaml

<span class="hljs-comment"># 4. 部署 Gateway API 路由 (確保 Port 設為 8000)</span>
kubectl apply -f gateway-api.yml

```

</div></div></div>---

</div></div>## 3. 最終驗證與自動化分析

身為系統建設負責人，我們會使用以下腳本進行最後的數據收集，驗證權重分配是否精確。

### A. 檢查 Endpoints 狀態

確保每個版本都有對接到 Pod IP：

<div aria-busy="false" aria-live="polite" id="bkmrk-bash-kubectl-get-end"><div aria-busy="false" aria-live="polite"><div data-hveid="0" data-ved="0CAAQhtANahgKEwjssI2WoeCTAxUAAAAAHQAAAAAQ4gk"><div><span class="ng-tns-c1695782856-866">Bash</span><div><button aria-label="複製代碼" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c1695782856-866 mat-unthemed ng-star-inserted"></button></div></div><div><div>```
kubectl get endpoints my-app-v1 my-app-v2

```

</div></div></div></div></div>### B. 執行金絲雀流量分析

<div aria-busy="false" aria-live="polite" id="bkmrk-bash-%23-%E5%9F%B7%E8%A1%8C-20-%E6%AC%A1%E6%B8%AC%E8%A9%A6%E4%B8%A6%E8%A8%88%E7%AE%97%E7%B5%90"><div aria-busy="false" aria-live="polite"><div data-hveid="0" data-ved="0CAAQhtANahgKEwjssI2WoeCTAxUAAAAAHQAAAAAQ4wk"><div><span class="ng-tns-c1695782856-867">Bash</span><div><button aria-label="複製代碼" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c1695782856-867 mat-unthemed ng-star-inserted"></button></div></div><div><div>```
<span class="hljs-comment"># 執行 20 次測試並計算結果</span>
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> {1..20}; <span class="hljs-keyword">do</span> 
  curl -s -H <span class="hljs-string">"Host: localhost"</span> http://localhost | grep <span class="hljs-string">"Server name"</span>
<span class="hljs-keyword">done</span>

```

</div></div></div>---

</div></div>## 4. 維運經驗總結 (Lead's Summary)

這套全內容方案解決了您在實驗中遇到的所有核心技術挑戰：

<div aria-busy="false" aria-live="polite" id="bkmrk-%E5%9F%A0%E8%99%9F%E5%B0%8D%E9%BD%8A%EF%BC%9A%E8%A7%A3%E6%B1%BA%E4%BA%86-empty-reply"><div aria-busy="false" aria-live="polite">1. **埠號對齊**：解決了 `Empty reply` 與 `PortUnavailable` 問題。
2. **所有權衝突**：透過重置 Gateway 與正確使用 Helm 參數規避了 `SSA Conflict`。
3. **命名空間授權**：透過 `from: All` 解決了跨 Namespace 404 的問題。
4. **內容識別**：修正了 `grep` 關鍵字，確保能從 Nginx 輸出中精確捕捉版本差異。

</div></div>這份完整的清單已準備好，您可以直接將其納入專案的基礎設施維護手冊中。