K8s · 網路與服務 · 第 21 課 · · 12min read

從零串起完整鏈路:Pod → Deployment → Service → Ingress 一條龍

前面學了一堆零件,這篇把它們組起來:寫一份 Deployment、暴露成 Service、用 Ingress 路由,從外網一路打進 Pod。這就是 K8s 部署的標準流程。

#Kubernetes #完整鏈路 #Pod #Deployment #Service #Ingress
章節目錄 · 13

為什麼要把它們串起來?

前 20 篇我們把 K8s 的零件一個一個拆開講:

但工作上你不會「只建一個 Pod」,而是一次部署一整條鏈路。 這篇把它們組起來,做一次端到端部署。

完成後從瀏覽器打 http://demo.local/,流量會一路穿過:

你的瀏覽器
    ↓
Ingress(對外網域、路徑路由)
    ↓
Service(叢集內 DNS、固定 IP)
    ↓
Pod(你的容器,可能 3 個副本)

完整流程:6 個檔案

我們要部署一個 nginx 服務,從零到 Ingress:

Step 1:建 Namespace            → 隔離環境
Step 2:寫 Deployment            → 定義「3 個 nginx 副本」
Step 3:寫 ClusterIP Service     → 叢集內固定入口
Step 4:寫 Ingress              → 對外路由 demo.local
Step 5:本機 hosts 設定          → 把 demo.local 指到 Node IP
Step 6:瀏覽器驗證 + 排錯

Step 1:建 Namespace

$ kubectl create namespace demo

為什麼第一步是這個? 真實工作上不會把資源直接丟到 default。一個專案 = 一個 namespace,避免互相干擾。

Step 2:Deployment

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: demo                # ← 注意每個資源都要寫
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80
$ kubectl apply -f deployment.yaml
$ kubectl get pods -n demo
NAME                            READY   STATUS
nginx-deploy-7d8c9f-abc12       1/1     Running
nginx-deploy-7d8c9f-def34       1/1     Running
nginx-deploy-7d8c9f-ghi56       1/1     Running

3 個 Pod 跑起來。但現在還連不到 — Pod IP 隨時會變,沒有穩定入口。

Step 3:ClusterIP Service

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  namespace: demo
spec:
  type: ClusterIP                # 預設值,可省略
  selector:
    app: nginx                   # ← 對應 Pod labels
  ports:
    - port: 80
      targetPort: 80
$ kubectl apply -f service.yaml
$ kubectl get svc -n demo
NAME        TYPE        CLUSTER-IP      PORT(S)
nginx-svc   ClusterIP   10.43.0.150     80/TCP

# 從叢集內驗證
$ kubectl run test --image=busybox:1.36 --rm -it --restart=Never -n demo \
-- wget -qO- http://nginx-svc
<h1>Welcome to nginx!</h1>

叢集內的 Pod 已經能用 nginx-svc:80 連到。但外面的瀏覽器還是連不上

Step 4:Ingress

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: demo
spec:
  ingressClassName: traefik       # k3d 預設用 traefik
  rules:
    - host: demo.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-svc   # ← 對應 Service 名稱
                port:
                  number: 80
$ kubectl apply -f ingress.yaml
$ kubectl get ingress -n demo
NAME            CLASS     HOSTS         ADDRESS          PORTS
nginx-ingress   traefik   demo.local    192.168.97.2     80

ADDRESS 顯示 Ingress Controller 的對外 IP。如果是 ,表示 Ingress Controller 還沒裝(k3d / minikube 預設都有)。

Step 5:本機 hosts 設定

Ingress 用 demo.local 路由,但這個網域 DNS 不認識。最簡單做法:把它寫進 /etc/hosts

# macOS / Linux
$ sudo vim /etc/hosts

# 加一行
192.168.97.2 demo.local

192.168.97.2 就是上一步 ADDRESS 顯示的 IP。

Step 6:瀏覽器驗證

$ curl http://demo.local/
<h1>Welcome to nginx!</h1>

或直接打開瀏覽器輸入 http://demo.local/

完整鏈路通了

瀏覽器 demo.local
    ↓ DNS(hosts)→ 192.168.97.2:80
Ingress Controller (Traefik)
    ↓ host=demo.local, path=/
nginx-svc:80 (ClusterIP)
    ↓ selector app=nginx
nginx-deploy 的 3 個 Pod 之一

排錯:每一層都能單獨驗證

這條鏈路最棒的是每一段都能拆開測。任何一段斷了,從下往上一層一層看:

症狀檢查
瀏覽器轉圈圈curl http://demo.local/ 看 status code
curl: Could not resolve hosthosts 沒設好,ping demo.local 看 IP
curl 通但 404Ingress host 寫錯,kubectl describe ingress
Ingress 通但 503Service 沒 endpoint,kubectl get endpoints -n demo
Service 沒 endpointPod labels 跟 selector 對不上,kubectl get pods --show-labels
Pod 不是 Runningkubectl describe pod + kubectl logs
口訣:從外往內,每層用 kubectl get / describe 看一眼。

真實工作的差別

正式環境跟這個 demo 主要差三件事:

  • Ingress 走 HTTPS — 加 TLS Secret + cert-manager 自動續憑證(下一篇

  • 多服務分流/api → backend-svc/admin → admin-svc(一個 Ingress 管多個 Service)

  • DNS 不靠 hosts — 公司網域 api.company.com 指到 LoadBalancer 的公網 IP
  • 但底層原理完全一樣。學會這條鏈路,後面只是疊功能上去。

    對照 Docker Compose

    Docker ComposeKubernetes
    docker-compose.yml 一份4 份 YAML(Namespace + Deploy + Svc + Ingress)
    ports: 8080:80NodePort 或 Ingress
    networksNamespace + DNS
    docker-compose upkubectl apply -f .
    K8s 確實比 Compose 囉嗦,但換來的是對外路由、副本管理、自我修復、滾動更新全內建。一個 docker-compose.yml 在 prod 撐不住,K8s 這套可以。

    重點整理

    • 完整鏈路:Namespace → Deployment → Service → Ingress
    • ClusterIP 對內、Ingress 對外,Service 和 Ingress 是兩件事
    • 排錯順序從外往內,每層拆開驗證
    • /etc/hosts 是本機開發的方便做法,prod 走真 DNS
    • 3 + 1 個 YAML 檔,apply 完就有完整服務

    下一步

    你已經把整條 K8s 部署鏈路串起來了。但 Ingress 篇只講了 path-based 路由 — 真實工作會用多個 host(api.example.com / admin.example.com)並走 HTTPS。

    下一篇:Ingress Host-based 路由 + TLS