熱門分類
載入中…
目錄0%

🚀 Kubernetes 完整入門指南:從零部署 K3s 到 Pod / Service / Ingress 全流程實戰

    🚀 Kubernetes 完整入門指南:從零部署 K3s 到 Pod / Service / Ingress 全流程實戰

    Kubernetes(K8s)是目前容器編排的業界標準,但官方版安裝門檻高、資源需求大。
    K3s 是由 Rancher 開發的輕量化 Kubernetes,安裝只需一行指令,記憶體需求僅 512 MB,
    非常適合 Home Lab、Proxmox VM、學習環境 使用,生產等級功能一樣完整。
    本篇從安裝到 Ingress 全流程實戰,帶你建立第一套可用的 K3s 叢集。


    📋 目錄

    1. K3s 與 K8s 的差異
    2. 環境規劃與安裝
    3. kubectl 基礎操作
    4. Namespace 與資源隔離
    5. 部署第一個 App(Deployment + Pod)
    6. Service 對外暴露服務
    7. Ingress 統一入口管理
    8. ConfigMap 與 Secret
    9. PV / PVC 持久化儲存
    10. 常見問題排查

    ⚖️ 一、K3s 與 K8s 的差異

    項目K8s(官方)K3s(輕量版)
    安裝難度複雜,需 kubeadm / 多步驟一行 curl 指令
    最低記憶體2 GB+512 MB
    內建元件需自行選配Traefik Ingress、CoreDNS、Flannel、Metrics Server 內建
    資料庫etcdSQLite(單節點)/ etcd(HA)
    適用場景大型企業叢集Home Lab、邊緣運算、學習、小型生產
    kubectl 相容性完整完整(100% API 相容)
    💡 K3s 完整支援所有 Kubernetes API,在 K3s 學到的知識可以直接用在正式 K8s 環境。

    🖥️ 二、環境規劃與安裝

    建議規格

    節點類型角色最低規格建議規格
    Server(Master)控制平面1 CPU / 512 MB2 CPU / 2 GB
    Agent(Worker)執行工作負載1 CPU / 512 MB2 CPU / 2 GB

    本篇以 單節點(all-in-one) 示範,OS 為 Ubuntu 22.04 / Debian 12。

    1️⃣ 安裝 K3s Server

    # 一鍵安裝(官方腳本)
    curl -sfL https://get.k3s.io | sh -
    
    # 安裝完成後確認狀態
    sudo systemctl status k3s
    
    # 確認節點加入
    sudo kubectl get nodes

    安裝完成後 kubectl 已自動設定,/etc/rancher/k3s/k3s.yaml 為 kubeconfig 檔案。

    2️⃣ 設定 kubectl 給一般使用者使用

    mkdir -p $HOME/.kube
    sudo cp /etc/rancher/k3s/k3s.yaml $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    echo 'export KUBECONFIG=$HOME/.kube/config' >> ~/.bashrc
    source ~/.bashrc
    
    # 驗證
    kubectl get nodes

    3️⃣ 加入 Worker 節點(多節點時)

    # 在 Server 上取得 Token
    sudo cat /var/lib/rancher/k3s/server/node-token
    
    # 在 Agent 節點執行
    curl -sfL https://get.k3s.io | K3S_URL=https://<SERVER_IP>:6443 \
      K3S_TOKEN=<NODE_TOKEN> sh -

    🔧 三、kubectl 基礎操作

    常用指令速查

    # 查看節點
    kubectl get nodes -o wide
    
    # 查看所有 Namespace 的 Pod
    kubectl get pods -A
    
    # 查看特定 Namespace
    kubectl get pods -n kube-system
    
    # 查看資源詳細資訊
    kubectl describe pod <pod-name>
    
    # 查看 Pod 日誌
    kubectl logs <pod-name>
    kubectl logs -f <pod-name>   # 持續輸出
    
    # 進入 Pod 內部
    kubectl exec -it <pod-name> -- /bin/bash
    
    # 刪除資源
    kubectl delete pod <pod-name>
    kubectl delete -f manifest.yaml

    快速別名設定(建議加入 ~/.bashrc)

    alias k='kubectl'
    alias kga='kubectl get all -A'
    alias kgp='kubectl get pods'
    alias kdp='kubectl describe pod'

    📁 四、Namespace 與資源隔離

    Namespace 是 K8s 中的邏輯隔離單位,不同專案 / 環境建議用不同 Namespace 管理。

    # 查看所有 Namespace
    kubectl get namespaces
    
    # 建立 Namespace
    kubectl create namespace myapp
    
    # 在指定 Namespace 操作
    kubectl get pods -n myapp
    
    # 設定預設 Namespace(避免每次加 -n)
    kubectl config set-context --current --namespace=myapp

    K3s 預設 Namespace:

    • default:預設操作空間
    • kube-system:系統元件(CoreDNS、Traefik 等)
    • kube-public:公開可讀資源

    🐳 五、部署第一個 App(Deployment + Pod)

    概念說明

    • Pod:K8s 最小部署單位,包含一個或多個 Container
    • Deployment:管理 Pod 的副本數量、滾動更新、自動重啟
    • ReplicaSet:由 Deployment 自動管理,確保 Pod 數量

    方式一:指令直接部署(快速測試)

    # 部署 nginx
    kubectl create deployment nginx --image=nginx:latest --replicas=2
    
    # 查看狀態
    kubectl get deployment nginx
    kubectl get pods -l app=nginx

    方式二:YAML 宣告式部署(建議)

    # deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
      namespace: myapp
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.25
            ports:
            - containerPort: 80
            resources:
              requests:
                memory: "64Mi"
                cpu: "100m"
              limits:
                memory: "128Mi"
                cpu: "250m"
    # 套用
    kubectl apply -f deployment.yaml
    
    # 查看 Rollout 狀態
    kubectl rollout status deployment/nginx -n myapp
    
    # 更新映像檔(滾動更新)
    kubectl set image deployment/nginx nginx=nginx:1.26 -n myapp
    
    # 回滾
    kubectl rollout undo deployment/nginx -n myapp

    🌐 六、Service 對外暴露服務

    Pod 的 IP 是動態的,Service 提供穩定的存取入口,自動做 Load Balancing。

    Service 類型比較

    類型說明適用場景
    ClusterIP叢集內部 IP,預設類型服務間通訊
    NodePort開放 Node 的固定 Port(30000-32767)開發測試、直接存取
    LoadBalancer雲端環境自動配置外部 LB雲端(AWS/GCP/Azure)

    建立 NodePort Service

    # service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-svc
      namespace: myapp
    spec:
      type: NodePort
      selector:
        app: nginx
      ports:
      - protocol: TCP
        port: 80          # Service Port
        targetPort: 80    # Container Port
        nodePort: 30080   # 對外 Port(可省略讓系統自動分配)
    kubectl apply -f service.yaml
    
    # 查看
    kubectl get svc -n myapp
    
    # 測試(從 Host 存取)
    curl http://<NODE_IP>:30080

    🔀 七、Ingress 統一入口管理

    K3s 內建 Traefik Ingress Controller,可用域名路由到不同 Service,不需要每個服務開不同 Port。

    Ingress 架構

    Internet
        ↓
    Traefik(80/443)
        ├── /app-a  →  Service A → Pods
        └── /app-b  →  Service B → Pods

    建立 Ingress 規則

    # ingress.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx-ingress
      namespace: myapp
      annotations:
        traefik.ingress.kubernetes.io/router.entrypoints: web
    spec:
      rules:
      - host: nginx.local          # 本機測試可加到 /etc/hosts
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-svc
                port:
                  number: 80
    kubectl apply -f ingress.yaml
    
    # 查看 Ingress
    kubectl get ingress -n myapp
    
    # 本機測試(加到 /etc/hosts)
    echo "<NODE_IP> nginx.local" | sudo tee -a /etc/hosts
    curl http://nginx.local

    多路由 Ingress 範例

    spec:
      rules:
      - host: mysite.example.com
        http:
          paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-svc
                port:
                  number: 8080
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-svc
                port:
                  number: 3000

    🔐 八、ConfigMap 與 Secret

    ConfigMap — 存放非機密設定

    # configmap.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: app-config
      namespace: myapp
    data:
      APP_ENV: production
      LOG_LEVEL: info
      DB_HOST: mariadb-svc
    # 在 Deployment 中使用 ConfigMap
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        envFrom:
        - configMapRef:
            name: app-config

    Secret — 存放機密資料(Base64 編碼)

    # 產生 base64
    echo -n 'mypassword' | base64
    # 輸出:bXlwYXNzd29yZA==
    
    # secret.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: db-secret
      namespace: myapp
    type: Opaque
    data:
      DB_PASSWORD: bXlwYXNzd29yZA==
      DB_USER: YWRtaW4=
    # 在 Pod 中使用 Secret
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_PASSWORD

    💾 九、PV / PVC 持久化儲存

    Pod 重啟後資料會消失,需要 PersistentVolume(PV)PersistentVolumeClaim(PVC) 保存資料。

    K3s 內建 Local Path Provisioner,可自動建立 PV(資料存在 Node 本機磁碟)。

    建立 PVC

    # pvc.yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: nginx-data
      namespace: myapp
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: local-path    # K3s 預設 StorageClass
      resources:
        requests:
          storage: 1Gi
    # 在 Deployment 掛載 PVC
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        volumeMounts:
        - name: data
          mountPath: /usr/share/nginx/html
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: nginx-data
    # 查看 PVC 狀態(Bound = 已掛載)
    kubectl get pvc -n myapp

    ❓ 十、常見問題排查

    問題 1:Pod 一直 CrashLoopBackOff

    排查步驟:

    # 查看詳細錯誤
    kubectl describe pod <pod-name> -n myapp
    
    # 查看最近 50 行 Log
    kubectl logs <pod-name> --previous --tail=50 -n myapp

    常見原因:映像不存在、環境變數缺少、資源不足(OOMKilled)

    問題 2:Pod 狀態 Pending

    kubectl describe pod <pod-name> -n myapp
    # 看 Events 欄位

    常見原因:Node 資源不足(CPU/Memory)、PVC 未 Bound、Node 有 Taint

    問題 3:Service 無法存取

    # 確認 Endpoints 是否有 Pod IP
    kubectl get endpoints <service-name> -n myapp
    
    # 確認 Pod Label 是否與 Service Selector 一致
    kubectl get pods --show-labels -n myapp

    問題 4:Ingress 404 / 無法路由

    # 查看 Traefik 日誌
    kubectl logs -n kube-system -l app.kubernetes.io/name=traefik
    
    # 確認 Ingress 是否正確建立
    kubectl describe ingress <ingress-name> -n myapp

    問題 5:查看叢集整體資源使用

    # 需要 Metrics Server(K3s 已內建)
    kubectl top nodes
    kubectl top pods -A

    📌 總結

    K3s 讓 Kubernetes 的入門門檻大幅降低,只需一台 Linux VM 就能體驗完整的 K8s 功能。
    本篇涵蓋了從安裝到 Deployment → Service → Ingress → ConfigMap → PVC 的完整流程,
    這套架構可以直接延伸到多節點叢集或正式 K8s 環境,學習成本一次搞定。

    元件功能
    Deployment管理 Pod 副本、滾動更新
    Service穩定入口、負載平衡
    Ingress域名路由、統一對外入口
    ConfigMap注入環境設定
    Secret安全存放機密
    PVC資料持久化

    💬 你的 Home Lab 有在跑 Kubernetes 嗎?或者你覺得 K3s 和 Proxmox 搭配起來如何?歡迎留言交流!

    📚 延伸閱讀

    🔗 分享這篇 LINE Facebook X

    沒有留言:

    字級