返回首頁Kubernetes

Kubernetes 入門教學:從零開始的 K8s 實戰指南【2025 更新】

17 min 分鐘閱讀
#Kubernetes#K8s#教學#入門#Minikube#kubectl#實戰

Kubernetes 入門教學:從零開始的 K8s 實戰指南【2025 更新】

Kubernetes 入門教學:從零開始的 K8s 實戰指南【2025 更新】

看了一堆 Kubernetes 的概念,是時候動手做了。

這篇教學會帶你從零開始,一步一步完成:安裝環境、部署第一個應用程式、學會基本指令。

不需要雲端帳號,在你的電腦上就能完成。

Kubernetes 的基本概念,請先參考 Kubernetes 完整指南


環境準備

在開始之前,你需要準備本地的 Kubernetes 環境。

安裝 kubectl

kubectl 是 Kubernetes 的命令列工具,用來跟叢集溝通。

macOS:

# 使用 Homebrew
brew install kubectl

# 驗證安裝
kubectl version --client

Windows:

# 使用 Chocolatey
choco install kubernetes-cli

# 或使用 winget
winget install -e --id Kubernetes.kubectl

# 驗證安裝
kubectl version --client

Linux(Ubuntu/Debian):

# 下載最新版本
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

# 安裝
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# 驗證安裝
kubectl version --client

本地叢集選擇

有幾種工具可以在本地跑 Kubernetes:

工具特點適合
Minikube最知名,功能完整初學者首選
Kind用 Docker 跑 K8sCI/CD、輕量使用
k3dK3s 的 Docker 版資源有限的環境
Docker Desktop內建 K8sMac/Windows 用戶

本教學使用 Minikube,因為它最適合學習。

Minikube 安裝與啟動

安裝 Minikube:

# macOS
brew install minikube

# Windows
choco install minikube

# Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

啟動叢集:

# 啟動 Minikube(預設使用 Docker driver)
minikube start

# 如果要指定資源
minikube start --cpus=4 --memory=8192

驗證叢集狀態:

# 查看叢集狀態
minikube status

# 查看節點
kubectl get nodes

輸出應該像這樣:

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.28.3

常用 Minikube 指令:

指令說明
minikube start啟動叢集
minikube stop停止叢集
minikube delete刪除叢集
minikube dashboard開啟 Web UI
minikube service <name>在瀏覽器開啟服務

插圖:終端機視窗顯示 minikube start 指令執行過程

場景描述: 終端機視窗顯示 minikube start 指令執行過程,畫面中可見下載進度條、啟動訊息,最後顯示 Done! kubectl is now configured 的成功訊息,終端機使用深色主題。需要顯示的中文字:無

視覺重點:

  • 主要內容清晰呈現

必須出現的元素:

  • 依據描述中的關鍵元素

需要顯示的中文字:

顏色調性: 專業、清晰

避免元素: 抽象圖形、齒輪、發光特效

Slug: minikube-terminal-startup


第一個應用程式部署

環境準備好了,來部署第一個應用程式。

建立 Deployment

我們用 nginx 作為範例,這是最簡單的方式:

方法一:用指令建立

kubectl create deployment nginx --image=nginx:1.25

這個指令做了什麼?

  • 建立一個叫 nginx 的 Deployment
  • 使用 nginx:1.25 映像檔
  • 預設建立 1 個 Pod

方法二:用 YAML 建立(推薦)

建立檔案 nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80

套用設定:

kubectl apply -f nginx-deployment.yaml

查看 Pod 狀態

# 查看 Pod
kubectl get pods

# 查看更多資訊
kubectl get pods -o wide

# 持續監看狀態變化
kubectl get pods -w

輸出:

NAME                     READY   STATUS    RESTARTS   AGE
nginx-7854ff8877-x2vnz   1/1     Running   0          30s

狀態說明:

狀態說明
Pending等待調度或下載映像檔
ContainerCreating正在建立容器
Running正常執行中
Error發生錯誤
CrashLoopBackOff反覆崩潰重啟

如果狀態不是 Running,用這個指令查看原因:

kubectl describe pod <pod-name>

建立 Service

Pod 跑起來了,但還沒辦法存取它。需要建立 Service。

用指令建立:

kubectl expose deployment nginx --port=80 --type=NodePort

或用 YAML:

建立檔案 nginx-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080

套用:

kubectl apply -f nginx-service.yaml

查看 Service:

kubectl get services

輸出:

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        10m
nginx        NodePort    10.96.123.45    <none>        80:30080/TCP   10s

存取應用程式

在 Minikube 中存取:

# 方法一:用 minikube service
minikube service nginx

# 方法二:取得 URL
minikube service nginx --url

這會自動開啟瀏覽器,顯示 nginx 的歡迎頁面。

恭喜!你成功部署了第一個 Kubernetes 應用程式。


💡 K8s 學習遇到困難?

從概念到實作,我們提供完整的培訓和諮詢服務。

👉 預約免費諮詢


kubectl 常用指令

kubectl 是你每天都會用的工具。這裡整理最常用的指令。

資源查看

基本查看:

# 查看 Pod
kubectl get pods

# 查看 Deployment
kubectl get deployments

# 查看 Service
kubectl get services

# 查看所有資源
kubectl get all

# 查看特定 namespace
kubectl get pods -n kube-system

詳細資訊:

# 查看 Pod 詳細資訊
kubectl describe pod <pod-name>

# 查看 Deployment 詳細資訊
kubectl describe deployment <deployment-name>

# 以 YAML 格式輸出
kubectl get pod <pod-name> -o yaml

# 以 JSON 格式輸出
kubectl get pod <pod-name> -o json

自訂輸出欄位:

# 只顯示名稱和狀態
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase

# 依標籤篩選
kubectl get pods -l app=nginx

資源建立與管理

建立資源:

# 從 YAML 建立
kubectl apply -f deployment.yaml

# 從目錄建立所有 YAML
kubectl apply -f ./manifests/

# 從 URL 建立
kubectl apply -f https://example.com/deployment.yaml

修改資源:

# 編輯資源(會開啟編輯器)
kubectl edit deployment nginx

# 擴展副本數
kubectl scale deployment nginx --replicas=3

# 更新映像檔
kubectl set image deployment/nginx nginx=nginx:1.26

刪除資源:

# 刪除單個資源
kubectl delete pod <pod-name>

# 刪除 Deployment(會連帶刪除 Pod)
kubectl delete deployment nginx

# 從 YAML 刪除
kubectl delete -f deployment.yaml

# 刪除特定 namespace 的所有 Pod
kubectl delete pods --all -n <namespace>

除錯指令

這些指令在出問題時非常有用:

查看日誌:

# 查看 Pod 日誌
kubectl logs <pod-name>

# 持續追蹤日誌
kubectl logs -f <pod-name>

# 查看前一個容器的日誌(如果重啟過)
kubectl logs <pod-name> --previous

# 多容器 Pod 指定容器
kubectl logs <pod-name> -c <container-name>

進入容器:

# 進入容器執行 shell
kubectl exec -it <pod-name> -- /bin/bash

# 如果沒有 bash,用 sh
kubectl exec -it <pod-name> -- /bin/sh

# 執行單一指令
kubectl exec <pod-name> -- ls /app

Port Forward:

# 把 Pod 的 port 轉發到本地
kubectl port-forward <pod-name> 8080:80

# 把 Service 的 port 轉發到本地
kubectl port-forward service/nginx 8080:80

事件查看:

# 查看所有事件
kubectl get events

# 依時間排序
kubectl get events --sort-by='.lastTimestamp'

進階技巧

設定別名(提高效率):

# 在 .bashrc 或 .zshrc 加入
alias k='kubectl'
alias kgp='kubectl get pods'
alias kgs='kubectl get services'
alias kgd='kubectl get deployments'
alias kd='kubectl describe'
alias kl='kubectl logs'

kubectl 自動補全:

# Bash
source <(kubectl completion bash)

# Zsh
source <(kubectl completion zsh)

Context 管理(多叢集):

# 查看所有 context
kubectl config get-contexts

# 切換 context
kubectl config use-context <context-name>

# 查看目前 context
kubectl config current-context

插圖:分割畫面的終端機視窗

場景描述: 分割畫面的終端機視窗,左側顯示 kubectl get pods 的輸出列表,右側顯示 kubectl describe pod 的詳細資訊,兩邊都使用語法高亮顯示不同的狀態和欄位。需要顯示的中文字:無

視覺重點:

  • 主要內容清晰呈現

必須出現的元素:

  • 依據描述中的關鍵元素

需要顯示的中文字:

顏色調性: 專業、清晰

避免元素: 抽象圖形、齒輪、發光特效

Slug: kubectl-cheatsheet-terminal


YAML 檔案撰寫

用 YAML 管理 Kubernetes 資源是最佳實踐。

基本結構

每個 Kubernetes YAML 都有四個必要欄位:

apiVersion: v1          # API 版本
kind: Pod               # 資源類型
metadata:               # 元資料
  name: my-pod
spec:                   # 規格(資源的詳細設定)
  containers:
  - name: my-container
    image: nginx

常見 apiVersion:

資源類型apiVersion
Pod, Service, ConfigMapv1
Deployment, ReplicaSetapps/v1
Ingressnetworking.k8s.io/v1
Job, CronJobbatch/v1

常見 kind:

Kind用途
Pod最小部署單位
Deployment管理 Pod 的生命週期
Service網路存取
ConfigMap設定資訊
Secret敏感資訊
IngressHTTP 路由

Deployment YAML 詳解

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app                    # Deployment 名稱
  labels:
    app: my-app                   # Deployment 的標籤
spec:
  replicas: 3                     # Pod 副本數
  selector:
    matchLabels:
      app: my-app                 # 選擇器,要跟 template 的 labels 一致
  template:                       # Pod 模板
    metadata:
      labels:
        app: my-app               # Pod 的標籤
    spec:
      containers:
      - name: app                 # 容器名稱
        image: my-app:1.0         # 映像檔
        ports:
        - containerPort: 8080     # 容器 Port
        resources:                # 資源限制
          requests:
            memory: "128Mi"
            cpu: "250m"
          limits:
            memory: "256Mi"
            cpu: "500m"
        env:                      # 環境變數
        - name: NODE_ENV
          value: "production"
        livenessProbe:            # 存活檢查
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10

Service YAML 詳解

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  type: ClusterIP                 # 類型:ClusterIP, NodePort, LoadBalancer
  selector:
    app: my-app                   # 選擇有這個 label 的 Pod
  ports:
  - name: http
    port: 80                      # Service 的 Port
    targetPort: 8080              # Pod 的 Port
    protocol: TCP

常見錯誤

1. selector 和 labels 不一致

# 錯誤:selector 和 template labels 不一致
spec:
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-application  # 應該是 my-app

2. 縮排錯誤

# 錯誤:YAML 縮排不正確
spec:
containers:    # 應該要縮排
- name: app

3. 忘記必要欄位

# 錯誤:Deployment 缺少 selector
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  # 缺少 selector
  template:
    ...

驗證 YAML:

# 乾跑,不實際建立
kubectl apply -f deployment.yaml --dry-run=client

# 驗證語法
kubectl apply -f deployment.yaml --validate=true

更多物件的詳細說明,請參考 Kubernetes 核心物件教學


🏗️ 需要 Kubernetes 架構設計?

從開發到生產環境的最佳實踐,讓專家幫你規劃。

👉 預約架構諮詢


實戰練習:部署完整應用

來做一個更完整的練習:部署一個有前後端的應用。

應用架構

我們要部署:

使用者 → Frontend (React) → Backend (Node.js) → Database (PostgreSQL)

為了簡化,我們用現成的映像檔。

步驟教學

Step 1:建立 Namespace

kubectl create namespace demo

Step 2:部署 PostgreSQL

建立 postgres.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
  namespace: demo
data:
  POSTGRES_DB: myapp
  POSTGRES_USER: admin
---
apiVersion: v1
kind: Secret
metadata:
  name: postgres-secret
  namespace: demo
type: Opaque
data:
  POSTGRES_PASSWORD: cGFzc3dvcmQxMjM=  # password123 的 base64
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15-alpine
        ports:
        - containerPort: 5432
        envFrom:
        - configMapRef:
            name: postgres-config
        - secretRef:
            name: postgres-secret
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: demo
spec:
  selector:
    app: postgres
  ports:
  - port: 5432
    targetPort: 5432

套用:

kubectl apply -f postgres.yaml

Step 3:部署 Backend

建立 backend.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  namespace: demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: hashicorp/http-echo
        args:
        - "-text=Hello from Backend!"
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: backend
  namespace: demo
spec:
  selector:
    app: backend
  ports:
  - port: 80
    targetPort: 5678

套用:

kubectl apply -f backend.yaml

Step 4:部署 Frontend

建立 frontend.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  namespace: demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
  namespace: demo
spec:
  type: NodePort
  selector:
    app: frontend
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30000

套用:

kubectl apply -f frontend.yaml

驗證結果

檢查所有資源:

kubectl get all -n demo

輸出:

NAME                            READY   STATUS    RESTARTS   AGE
pod/backend-xxx                 1/1     Running   0          1m
pod/backend-yyy                 1/1     Running   0          1m
pod/frontend-xxx                1/1     Running   0          30s
pod/frontend-yyy                1/1     Running   0          30s
pod/postgres-xxx                1/1     Running   0          2m

NAME               TYPE        CLUSTER-IP       PORT(S)        AGE
service/backend    ClusterIP   10.96.xxx.xxx    80/TCP         1m
service/frontend   NodePort    10.96.xxx.xxx    80:30000/TCP   30s
service/postgres   ClusterIP   10.96.xxx.xxx    5432/TCP       2m

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/backend    2/2     2            2           1m
deployment.apps/frontend   2/2     2            2           30s
deployment.apps/postgres   1/1     1            1           2m

存取 Frontend:

minikube service frontend -n demo

測試擴展:

# 擴展 backend 到 5 個
kubectl scale deployment backend -n demo --replicas=5

# 查看結果
kubectl get pods -n demo -l app=backend

清理:

kubectl delete namespace demo

FAQ:常見問題

Q1: Pod 一直 Pending 怎麼辦?

可能原因:

原因解法
資源不足增加 Node 資源或減少 requests
映像檔拉不到檢查映像檔名稱和網路
PVC 未綁定檢查 StorageClass 和 PV

除錯:

kubectl describe pod <pod-name>
# 看 Events 區塊

Q2: Pod 一直 CrashLoopBackOff 怎麼辦?

可能原因:

  • 應用程式啟動失敗
  • 設定錯誤
  • 依賴服務未就緒

除錯:

# 看日誌
kubectl logs <pod-name>

# 看前一次的日誌
kubectl logs <pod-name> --previous

Q3: Service 連不到 Pod 怎麼辦?

檢查清單:

  1. Pod 有在 Running 嗎?
  2. Service 的 selector 對嗎?
  3. Port 設定對嗎?

驗證:

# 檢查 Endpoints
kubectl get endpoints <service-name>

# 如果 Endpoints 是空的,表示 selector 沒對上

Q4: 怎麼在本地測試不同的 K8s 版本?

# Minikube 可以指定版本
minikube start --kubernetes-version=v1.27.0

# 刪除舊叢集重建
minikube delete
minikube start --kubernetes-version=v1.28.0

Q5: 學完這些之後下一步是什麼?

目標建議
深入學習學習 Ingress、PV/PVC、RBAC
工具學習 Helm、Kustomize
雲端嘗試 EKS/GKE/AKS
認證準備 CKA/CKAD

下一步

完成這個教學後,你可以:

目標行動
選擇雲端服務閱讀 Kubernetes 雲端服務比較
學習更多工具閱讀 Kubernetes 工具生態系指南
深入了解物件閱讀 Kubernetes 核心物件教學
準備認證閱讀 Kubernetes 認證指南

🚀 準備把 Kubernetes 用到生產環境?

從本地開發到生產部署,CloudInsight 協助你的團隊順利過渡。

👉 立即預約諮詢


延伸閱讀


參考資料

需要專業的雲端建議?

無論您正在評估雲平台、優化現有架構,或尋找節費方案,我們都能提供協助

預約免費諮詢

相關文章