K8s · 入門基礎 · 第 08 課 · · 10min read

第一個 Pod 完整 CRUD:建立、查看、修改、刪除一次教完

寫完第一份 Pod YAML,下一步就是 kubectl apply。這篇從零跑出第一個 nginx Pod,學會 get / describe / logs / exec / delete 五個必背指令。

#Kubernetes #Pod #kubectl #CRUD #教學
章節目錄 · 14

學完概念,動手才是真的

前面六篇全都在講概念。現在真的把第一個 Pod 跑起來——這篇做完,你會 kubectl 的五個核心指令:

apply → get → describe → logs → exec → delete

這 5 招會了,新手到中階就過關了

前置準備

裝好 minikube 或 k3d(沒裝看這篇),確認叢集活著:

kubectl get nodes
# NAME       STATUS   ROLES           AGE   VERSION
# minikube   Ready    control-plane   3m    v1.28.x

STATUSReady 就 OK。

Step 1:寫 YAML

開一個檔案 my-nginx.yaml

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx:1.25-alpine
      ports:
        - containerPort: 80

四個區塊都齊:apiVersion / kind / metadata / spec。看不懂的回去看 K8s YAML 完整教學

Step 2:apply — 建立 Pod

kubectl apply -f my-nginx.yaml
# pod/my-nginx created

apply -f 是「用這份 YAML 建立資源」。如果 Pod 已存在會做更新(叫做「reconcile」)。

為什麼不是 kubectl create

  • create = 第一次建立(已存在會錯)
  • apply = 不存在就建立、存在就更新(最常用,記這個就好

Step 3:get — 看狀態

kubectl get pods
# NAME       READY   STATUS    RESTARTS   AGE
# my-nginx   1/1     Running   0          10s

幾秒鐘內 STATUS 會從 ContainerCreating 變成 Running

get 的進階用法

kubectl get pods -o wide                   # 加 IP、Node 等資訊
kubectl get pods -w                        # watch 模式,狀態變化即時看
kubectl get pod my-nginx -o yaml           # 把這個 Pod 的完整 YAML 印出
kubectl get pod my-nginx -o json           # 同上但 JSON 格式
kubectl get all                            # 看 default namespace 全部資源
kubectl get pods -n kube-system            # 看 kube-system namespace

-w 特別好用——你可以開另一個 terminal 跑 -w,主視窗操作 Pod,狀態變化即時看到

Step 4:describe — 詳細資訊(排錯主力)

kubectl describe pod my-nginx

輸出很長,但重點看這幾段:

Name:         my-nginx
Namespace:    default
Labels:       app=web
Status:       Running
IP:           10.244.0.5
Containers:
  nginx:
    Image:        nginx:1.25-alpine
    Image ID:     ...
    Port:         80/TCP
    State:        Running
    Ready:        True
    Restart Count: 0
Events:
  Type    Reason     Age   From    Message
  ----    ------     ----  ----    -------
  Normal  Scheduled  10s   ...     Successfully assigned default/my-nginx to minikube
  Normal  Pulling    10s   kubelet Pulling image "nginx:1.25-alpine"
  Normal  Pulled     8s    kubelet Successfully pulled image
  Normal  Created    8s    kubelet Created container nginx
  Normal  Started    8s    kubelet Started container nginx

最重要的是 Events——按時間順序記錄發生了什麼。Pod 出問題第一個看這裡:

  • ImagePullBackOff → image 名字錯 / 沒權限
  • CrashLoopBackOff → 容器啟動失敗一直重試
  • FailedScheduling → Scheduler 找不到合適的 Node
describe 是 K8s 排錯第一指令——記住這句。

Step 5:logs — 看容器在說什麼

kubectl logs my-nginx

會看到 nginx 的標準輸出:

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
...
2026/04/27 10:30:00 [notice] 1#1: nginx/1.25.x
2026/04/27 10:30:00 [notice] 1#1: start worker processes

進階用法

kubectl logs my-nginx -f                   # follow 模式(即時 tail)
kubectl logs my-nginx --tail=20            # 只看最後 20 行
kubectl logs my-nginx --since=5m           # 5 分鐘內的
kubectl logs my-nginx -p                   # 上一次崩潰前的 log(除錯神器)

-p 超重要:容器崩了重啟,原本的 log 會被覆蓋-p 看的是「上一次運行」的 log,找崩潰原因靠這個

Step 6:exec — 進到容器裡面

docker exec -it 一樣,直接進 Pod 裡的容器

kubectl exec -it my-nginx -- sh

進去後就是容器裡的 shell:

/ # ls
bin   docker-entrypoint.d   etc    ...
/ # ps
PID   USER    TIME  COMMAND
    1 root    0:00 nginx: master process nginx
   29 nginx   0:00 nginx: worker process
/ # exit

注意 -- 之後是要在容器內執行的指令——這是 kubectl 跟 Docker 不太一樣的地方。

不想進去互動,想跑單一指令:

kubectl exec my-nginx -- ls /etc/nginx
kubectl exec my-nginx -- cat /etc/nginx/nginx.conf

Step 7:在瀏覽器看到 nginx 頁面(port-forward)

Pod 起來了,但你怎麼從瀏覽器連到它?最簡單的方法是 port-forward

kubectl port-forward pod/my-nginx 8080:80
# Forwarding from 127.0.0.1:8080 -> 80

開瀏覽器打 http://localhost:8080 → 看到 Welcome to nginx! 頁面 🎉

這個指令會佔據 terminal——關掉 terminal 就斷線。要長期對外用 Service / Ingress(後面文章會教)。

Step 8:delete — 刪掉

# 用名字刪
kubectl delete pod my-nginx

# 或用 YAML 刪
kubectl delete -f my-nginx.yaml

刪掉後 kubectl get pods 就空了。

故意搞壞看看:image 名字打錯

my-nginx.yaml 的 image 改成 nginx:not-exist

kubectl apply -f my-nginx.yaml
kubectl get pods
# NAME       READY   STATUS         RESTARTS   AGE
# my-nginx   0/1     ErrImagePull   0          10s

ErrImagePull → 拉不到 image。等一下會變 ImagePullBackOff(K8s 會用指數退避重試)。

describe 看 Events:

kubectl describe pod my-nginx | grep -A 5 Events
# Events:
#   Type     Reason          ...    Message
#   Warning  Failed          ...    Failed to pull image "nginx:not-exist": ...
#   Warning  ImagePullBackOff ...   Back-off pulling image "nginx:not-exist"

3 步排錯流程

  • get 看 STATUS 異常 → 知道有問題

  • describe 看 Events → 看到具體錯誤訊息

  • 改 YAML → apply 一次(K8s 會自動更新)
  • 五招速查表

    動作指令
    建立 / 更新kubectl apply -f xxx.yaml
    列出kubectl get pods
    詳細資訊 / 排錯kubectl describe pod xxx
    看日誌kubectl logs xxx -f
    進容器kubectl exec -it xxx -- sh
    刪除kubectl delete pod xxx
    這 6 個會了,K8s 基礎實戰就過關

    重點整理

    • 寫 YAML → kubectl apply 是 K8s 最常用的工作流
    • get 看狀態、describe 排錯、logs 看輸出、exec 進容器、delete 刪掉
    • describeEvents 段是排錯第一手線索
    • logs -p 看上次崩潰的 log,找崩潰原因必備
    • port-forward 是「從本機連 Pod 的最簡單方法」(生產環境用 Service / Ingress)
    • 故意搞壞 → describe 看 Events → 改 YAML → re-apply 是排錯標準流程

    下一步

    成功跑了第一個 Pod,下一篇你故意搞壞 Pod 學排錯Pod 生命週期與排錯:CrashLoopBackOff、ImagePullBackOff 怎麼解——把 K8s 最常見的兩種錯誤搞清楚,真實工作 80% 的 Pod 問題都是這兩種