K8s Pod 管理实战:虚拟机环境下的具体命令与步骤

前言

本文面向 Kubernetes 初学者,以两台 CentOS 7 虚拟机(Master 与 Node1)为基础环境,围绕 Pod 的创建、管理、生命周期与常见 kubectl 命令,提供一套可直接照做的完整实验文档。全文按「命令式对象管理」「kubectl 命令实操」「Pod 的生命周期」「按当前虚拟机地址执行的完整实验步骤」四章组织,每一条命令都给出具体执行节点、完整命令与预期输出,方便读者在真实环境中逐步复现。

阅读本文前,建议先掌握以下基础概念:

  • Pod:Kubernetes 中最小的调度与运行单元,一个 Pod 内可包含一个或多个容器,共享网络命名空间与存储卷。
  • 命名空间(Namespace) :用于在同一集群内对资源进行逻辑隔离,默认命名空间为 default
  • 控制器(Controller):如 Deployment、ReplicaSet,负责维护 Pod 的期望副本数并处理滚动更新与故障恢复。
  • 探针(Probe):包括存活探针(livenessProbe)与就绪探针(readinessProbe),用于判断容器是否存活、是否具备对外提供服务的能力。

一、命令式对象管理

1. 命名空间管理

以下命令在 Master 节点(k8s-master,172.25.254.100)上执行。

查看命名空间

bash 复制代码
[root@k8s-master ~]# kubectl get namespaces
NAME              STATUS   AGE
default           Active   4h20m
kube-flannel      Active   3h31m
kube-node-lease   Active   4h20m
kube-public       Active   4h20m
kube-system       Active   4h20m

创建命名空间

bash 复制代码
[root@k8s-master ~]# kubectl create namespace timinglee
namespace/timinglee created
[root@k8s-master ~]# kubectl get namespaces
NAME              STATUS   AGE
default           Active   4h22m
kube-flannel      Active   3h32m
kube-node-lease   Active   4h22m
kube-public       Active   4h22m
kube-system       Active   4h22m
timinglee         Active   5s

删除命名空间

bash 复制代码
[root@k8s-master ~]# kubectl delete namespaces timinglee
namespace "timinglee" deleted

2. Pod 管理

查看 Pod 运行情况

bash 复制代码
[root@k8s-master ~]# kubectl get pods -o wide
No resources found in default namespace.

创建 Pod

bash 复制代码
[root@k8s-master ~]# kubectl run lee --image nginx:latest
pod/lee created
[root@k8s-master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
lee    1/1     Running   0          25s   10.244.1.10   k8s-node1   <none>           <none>

当 Pod 创建出现问题(镜像拉取失败)

bash 复制代码
[root@k8s-master ~]# kubectl run error --image lee:v1
[root@k8s-master ~]# kubectl get pods -o wide
NAME    READY   STATUS             RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
error   0/1     ImagePullBackOff   0          38s   10.244.2.3    k8s-node2   <none>           <none>
lee     1/1     Running            0          91s   10.244.1.10   k8s-node1   <none>           <none>

查看 Pod 详细信息

bash 复制代码
[root@k8s-master ~]# kubectl describe pods error
Name:             error
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8s-node2/172.25.254.20
Start Time:       Thu, 20 Aug 2026 15:08:30 +0800
Labels:           run=error
Annotations:      <none>
Status:           Pending
IP:               10.244.2.3
IPs:
  IP:  10.244.2.3
Containers:
  error:
    Container ID:
    Image:          lee:v1
    Image ID:
    Port:           <none>
    Host Port:      <none>
    State:          Waiting
      Reason:       ImagePullBackOff
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-kfcjl (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True
  Initialized                 True
  Ready                       False
  ContainersReady             False
  PodScheduled                True
Volumes:
  kube-api-access-kfcjl:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    Optional:                false
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  87s                default-scheduler  Successfully assigned default/error to k8s-node2
  Warning  Failed     28s (x2 over 65s)  kubelet            spec.containers{error}: Failed to pull image "lee:v1": Error response from daemon: failed to resolve reference "docker.io/library/lee:v1": docker.io/library/lee:v1: not found
  Warning  Failed     28s (x2 over 65s)  kubelet            spec.containers{error}: Error: ErrImagePull
  Normal   BackOff    16s (x2 over 64s)  kubelet            spec.containers{error}: Back-off pulling image "lee:v1"
  Warning  Failed     16s (x2 over 64s)  kubelet            spec.containers{error}: Error: ImagePullBackOff
  Normal   Pulling    2s (x3 over 86s)   kubelet            spec.containers{error}: Pulling image "lee:v1"

删除 Pod

bash 复制代码
[root@k8s-master ~]# kubectl delete pods error
[root@k8s-master ~]# kubectl delete pods --all
pod "error" deleted from default namespace
pod "lee" deleted from default namespace

二、kubectl 命令实操

本章通过实际操作演示 kubectl 的常用命令。实验前请先完成第四章的环境准备,并确保 myapp:v1myapp:v2 镜像已上传到私有仓库 reg.timinglee.org/library。以下命令默认在 Master 节点(k8s-master)上执行。

1. 上传实验镜像到仓库 library 中

bash 复制代码
[root@k8s-master ~]# docker load -i myapp.tar.gz
[root@k8s-master ~]# docker tag timinglee/myapp:v1 reg.timinglee.org/library/myapp:v1
[root@k8s-master ~]# docker push reg.timinglee.org/library/myapp:v1
[root@k8s-master ~]# docker tag timinglee/myapp:v2 reg.timinglee.org/library/myapp:v2
[root@k8s-master ~]# docker push reg.timinglee.org/library/myapp:v2

2. 生成实验所需 yml 文件

bash 复制代码
[root@k8s-master ~]# vim replica.yml
yaml 复制代码
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  labels:
    app: replica    # 设定控制器标签
  name: replica
spec:
  replicas: 2       # 启动 pod 数量
  selector:
    matchLabels:
      app: replica  # 控制器标签选择器
  template:
    metadata:
      labels:
        app: replica  # 开启 pod 的属性模板
    spec:
      containers:
      - image: myapp:v1
        name: myapp

3. kubectl 命令使用方法

create
bash 复制代码
[root@k8s-master ~]# kubectl create deployment webcluster --replicas 2 --image myapp:v1
deployment.apps/webcluster created
[root@k8s-master ~]# kubectl get deployments.apps
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
webcluster   2/2     2            2           15s
[root@k8s-master ~]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
webcluster-77c87d9946-28thm   1/1     Running   0          24s
webcluster-77c87d9946-vwrsq   1/1     Running   0          24s
[root@k8s-master ~]# kubectl delete deployments.apps webcluster
deployment.apps "webcluster" deleted from default namespace
[root@k8s-master ~]# kubectl get pods
No resources found in default namespace.
edit
bash 复制代码
[root@k8s-master ~]# kubectl create deployment webcluster --image myapp:v1
[root@k8s-master ~]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
webcluster-77c87d9946-2cgr7   1/1     Running   0          36s
[root@k8s-master ~]# kubectl edit deployments.apps webcluster
replicas: 2
[root@k8s-master ~]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
webcluster-77c87d9946-2cgr7   1/1     Running   0          36s
webcluster-77c87d9946-2wqn7   1/1     Running   0          103s
patch
bash 复制代码
# 创建 deployment
[root@k8s-master ~]# kubectl create deployment webcluster --image myapp:v1 --replicas 2
deployment.apps/webcluster created
[root@k8s-master ~]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
webcluster-77c87d9946-5vsrl   1/1     Running   0          5s
webcluster-77c87d9946-r7q8c   1/1     Running   0          5s
# 使用 patch 动态修改副本数为 1
[root@k8s-master ~]# kubectl patch deployments.apps webcluster -p '{"spec":{"replicas":1}}'
deployment.apps/webcluster patched
[root@k8s-master ~]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
webcluster-77c87d9946-r7q8c   1/1     Running   0          21s
expose
bash 复制代码
# 扩容到 4 个副本用于演示负载均衡
[root@k8s-master ~]# kubectl scale deployment webcluster --replicas 4
deployment.apps/webcluster scaled
[root@k8s-master ~]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
webcluster-77c87d9946-8wb5c   1/1     Running   0          10s
webcluster-77c87d9946-kp265   1/1     Running   0          10s
webcluster-77c87d9946-m49sc   1/1     Running   0          10s
webcluster-77c87d9946-r7q8c   1/1     Running   0          42s
# 暴露 Service
[root@k8s-master ~]# kubectl expose deployment webcluster --port 80 --target-port 80
service/webcluster exposed
[root@k8s-master ~]# kubectl get service
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   3d1h
webcluster   ClusterIP   10.111.5.166   <none>        80/TCP    0s
# 查看 Service 详情
[root@k8s-master ~]# kubectl describe svc webcluster
Name:                     webcluster
Namespace:                default
Labels:                   app=webcluster
Annotations:              <none>
Selector:                 app=webcluster
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.111.5.166
IPs:                      10.111.5.166
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
Endpoints:                10.244.1.6:80,10.244.2.13:80,10.244.2.14:80 + 1 more...
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>
# 测试负载均衡(多次访问会轮询到不同的 Pod)
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-kp265
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-r7q8c
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-8wb5c
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-8wb5c
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-m49sc
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-r7q8c
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-r7q8c
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-8wb5c
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-r7q8c
[root@k8s-master ~]# curl 10.111.5.166/hostname.html
webcluster-77c87d9946-kp265
logs
bash 复制代码
[root@k8s-master ~]# kubectl logs pods/webcluster-77c87d9946-gh9v7
10.244.0.0 - - [20/Aug/2026:08:43:52 +0000] "GET /hostname.html HTTP/1.1" 200 28 "-" "curl/7.76.1" "-"
10.244.0.0 - - [20/Aug/2026:08:43:52 +0000] "GET /hostname.html HTTP/1.1" 200 28 "-" "curl/7.76.1" "-"
attach
bash 复制代码
[root@k8s-master ~]# docker load -i busybox-latest.tar.gz
Loaded image: busybox:latest
[root@k8s-master ~]# docker tag busybox:latest reg.timinglee.org/library/busybox:latest
[root@k8s-master ~]# kubectl run -it testpod --image busybox:latest
All commands and output from this session will be recorded in container logs, including credentials and sensitive information passed through the command prompt.
If you don't see a command prompt, try pressing enter.
/ #
/ #
/ #  <ctrl+pq>
[root@k8s-master ~]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
testpod                       1/1     Running   0          55s
[root@k8s-master ~]# kubectl attach pods/testpod -it
All commands and output from this session will be recorded in container logs, including credentials and sensitive information passed through the command prompt.
If you don't see a command prompt, try pressing enter.
/ #
/ #
/ #
[root@k8s-master ~]# kubectl attach pods/testpod -it
All commands and output from this session will be recorded in container logs, including credentials and sensitive information passed through the command prompt.
If you don't see a command prompt, try pressing enter.
/ #
exec
bash 复制代码
[root@k8s-master ~]# kubectl run testpod --image nginx:latest
pod/testpod created
[root@k8s-master ~]# kubectl get pods
NAME      READY   STATUS    RESTARTS   AGE
testpod   1/1     Running   0          4s
[root@k8s-master ~]# kubectl exec -it pods/testpod -c testpod -- /bin/bash
root@testpod:/#
cp
bash 复制代码
[root@k8s-master ~]# kubectl cp testpod:/usr/share/nginx/html/index.html /mnt/test
tar: Removing leading `/' from member names
[root@k8s-master ~]# kubectl cp testpod:/usr/share/nginx/html /mnt/
tar: Removing leading `/' from member names
[root@k8s-master ~]# ls /mnt/
50x.html  docker.service  file1  hgfs  index.html  test
[root@k8s-master ~]# echo timinglee > /mnt/index.html
[root@k8s-master ~]# kubectl cp /mnt/index.html testpod:/usr/share/nginx/html/index.html
[root@k8s-master ~]# kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE    IP            NODE        NOMINATED NODE   READINESS GATES
testpod   1/1     Running   0          6m3s   10.244.1.12   k8s-node1   <none>           <none>
[root@k8s-master ~]# curl 10.244.1.12
timinglee
rollout
bash 复制代码
[root@k8s-master pod]# kubectl create deployment webcluster --image myapp:v1 --replicas 2 --dry-run=client -o yaml > webcluster.yml
[root@k8s-master pod]# vim webcluster.yml
yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp
bash 复制代码
[root@k8s-master pod]# kubectl apply -f webcluster.yml
deployment.apps/webcluster created
[root@k8s-master pod]# kubectl get deployments.apps
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
webcluster   2/2     2            2           7s
[root@k8s-master pod]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
webcluster-77c87d9946-5qbxt   1/1     Running   0          16s
webcluster-77c87d9946-95b2g   1/1     Running   0          16s
[root@k8s-master pod]# kubectl rollout status deployment webcluster
deployment "webcluster" successfully rolled out
deployment.apps/webcluster resumed
[root@k8s-master pod]# kubectl rollout restart deployment webcluster
deployment.apps/webcluster restarted
[root@k8s-master pod]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
webcluster-7bfd865747-jmhwl   1/1     Running   0          6s
webcluster-7bfd865747-qv2xt   1/1     Running   0          8s
[root@k8s-master pod]# kubectl rollout restart deployment webcluster
deployment.apps/webcluster restarted
[root@k8s-master pod]# kubectl get pods
NAME                          READY   STATUS              RESTARTS   AGE
webcluster-7bfd865747-jmhwl   1/1     Running             0          19s
webcluster-7bfd865747-qv2xt   0/1     Completed           0          21s
webcluster-9787d97f6-z7xv5    1/1     Running             0          1s
webcluster-9787d97f6-zl6q2    0/1     ContainerCreating   0          0s
scale
bash 复制代码
[root@k8s-master pod]# kubectl scale deployment webcluster --replicas 4
deployment.apps/webcluster scaled
[root@k8s-master pod]# kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
webcluster-9787d97f6-bh796   1/1     Running   0          2s
webcluster-9787d97f6-bh8jd   1/1     Running   0          2s
webcluster-9787d97f6-z7xv5   1/1     Running   0          89s
webcluster-9787d97f6-zl6q2   1/1     Running   0          88s
[root@k8s-master pod]# kubectl scale deployment webcluster --replicas 1
deployment.apps/webcluster scaled
[root@k8s-master pod]# kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
webcluster-9787d97f6-zl6q2   1/1     Running   0          93s
label
bash 复制代码
[root@k8s-master pod]# kubectl get pods --show-labels
NAME                         READY   STATUS    RESTARTS   AGE     LABELS
webcluster-9787d97f6-zl6q2   1/1     Running   0          6m57s   app=webcluster,p

三、Pod 的生命周期

Pod 从创建到销毁会经历多个阶段,本章通过 init 容器、存活探针与就绪探针三个实验,演示如何控制 Pod 的启动顺序、健康检查与流量接入。实验均在 Master 节点(k8s-master)的 pod 目录下进行。

1. init 容器

bash 复制代码
[root@k8s-master pod]# kubectl run webserver --image myapp:v1 --dry-run=client -o yaml > init-example.yml
[root@k8s-master pod]# vim init-example.yml
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  initContainers:
  - name: busybox
    image: busybox:latest
    command:
    - /bin/sh
    - -c
    - "until test -e /testfile;do echo wating for myservice; sleep 2;done"
  containers:
  - image: myapp:v1
    name: webserver
  restartPolicy: Always
bash 复制代码
[root@k8s-master pod]# watch -n 1 kubectl get pods -o wide
[root@k8s-master pod]# kubectl apply -f init-example.yml
pod/webserver created
[root@k8s-master pod]# kubectl exec -it pods/webserver -c busybox -- /bin/sh
/ #
/ # touch /testfile

2. 存活探针 liveness

没有存活探针时

bash 复制代码
[root@k8s-master pod]# kubectl run testpod --image myapp:v1 --dry-run=client -o yaml > livness-example.yaml
[root@k8s-master pod]# vim livness-example.yaml
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: myapp:v1
    name: webserver
    command: ["/bin/sh", "-c"]
    args:
    - |
      nginx -g "daemon off;"
      sleep 10000
  restartPolicy: Always
bash 复制代码
[root@k8s-master pod]# kubectl apply -f livness-example.yaml
# 监控程序
[root@k8s-master pod]# watch -n 1 kubectl get pods -o wide
# 测试操作:停止 nginx
[root@k8s-master pod]# kubectl exec -it pods/webserver -c webserver -- /bin/sh
# nginx -s stop
# 查看 pod 的状态仍然是 Running,但是访问此 pod 时访问失败
[root@k8s-node2 ~]# curl 10.244.5.47
curl: (7) Failed to connect to 10.244.5.47 port 80: 拒绝连接

配置存活探针后

bash 复制代码
[root@k8s-master pod]# kubectl delete -f livness-example.yaml --force
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: myapp:v1
    name: testpod
    command: ["/bin/sh", "-c"]
    args:
    - |
      nginx -g "daemon off;"
      sleep 10000
    livenessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 3
      periodSeconds: 1
      timeoutSeconds: 1
  restartPolicy: Always
bash 复制代码
[root@k8s-master pod]# kubectl get pods -o wide -w
[root@k8s-master pod]# kubectl exec -it pods/webserver -c webserver -- /bin/sh
/ # nginx -s stop
2026/08/23 03:59:45 [notice] 15#15: signal process started
/ # exit
[root@k8s-master pod]# curl 10.244.5.66
curl: (7) Failed to connect to 10.244.5.66 port 80: 拒绝连接
[root@k8s-master pod]# curl 10.244.5.66
curl: (7) Failed to connect to 10.244.5.66 port 80: 拒绝连接
[root@k8s-master pod]# curl 10.244.5.66
curl: (7) Failed to connect to 10.244.5.66 port 80: 拒绝连接
[root@k8s-master pod]# curl 10.244.5.66
curl: (7) Failed to connect to 10.244.5.66 port 80: 拒绝连接
[root@k8s-master pod]# curl 10.244.5.66
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

3. 就绪探针 readiness

没有就绪探针的情况

bash 复制代码
[root@k8s-master pod]# vim readness-example.yml
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: myapp:v1
    name: webserver
  restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: webserver
bash 复制代码
[root@k8s-master pod]# kubectl apply -f readness-example.yml
pod/webserver unchanged
service/webserver created
[root@k8s-master pod]# kubectl describe svc webserver
Name:                     webserver
Namespace:                default
Labels:                   run=webserver
Annotations:              <none>
Selector:                 run=webserver
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.102.162.217
IPs:                      10.102.162.217
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
Endpoints:                10.244.5.67:80
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>
# 删除默认发布文件
[root@k8s-master ~]# kubectl exec -it pods/webserver -c webserver -- /bin/sh
/ # cd /usr/share/nginx/
/usr/share/nginx # ls
html
/usr/share/nginx # cd html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # rm -fr index.html
/usr/share/nginx/html # ls
50x.html
/usr/share/nginx/html #
# 验证是否在访问 service 时 endpoints 中被下架
[root@k8s-master pod]# kubectl describe svc webserver
Name:                     webserver
Namespace:                default
Labels:                   run=webserver
Annotations:              <none>
Selector:                 run=webserver
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.102.162.217
IPs:                      10.102.162.217
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
Endpoints:                10.244.5.67:80   # 还在
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>
# 业务问题
[root@k8s-master pod]# curl 10.102.162.217
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>

有就绪探针的情况

bash 复制代码
[root@k8s-master pod]# vim readness-example.yml
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: myapp:v1
    name: webserver
    readinessProbe:
      httpGet:
        path: /index.html
        port: 80
      initialDelaySeconds: 3
      periodSeconds: 2
      timeoutSeconds: 1
  restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: webserver
bash 复制代码
[root@k8s-master pod]# kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
webserver   1/1     Running   0          7s    10.244.5.69   k8s-node2   <none>           <none>
[root@k8s-master pod]# kubectl describe svc webserver
Name:                     webserver
Namespace:                default
Labels:                   run=webserver
Annotations:              <none>
Selector:                 run=webserver
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.110.248.237
IPs:                      10.110.248.237
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
Endpoints:                10.244.5.69:80
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>
# 复现问题
/usr/share/nginx/html # command terminated with exit code 137
[root@k8s-master ~]#
/ # rm -fr /usr/share/nginx/html/index.html
/ # echo timinglee > /usr/share/nginx/html/index.html
/ #

四、按当前虚拟机地址执行的完整实验步骤

本章按当前实验环境(Master:172.25.254.100,Node1:172.25.254.10)给出从零开始搭建 Kubernetes 集群并完成 Pod 管理实验的完整步骤。请严格按照 4.1 至 4.6 的顺序执行,每完成一小节即可通过验证命令确认结果。

本节按当前环境修正:

  • Kubernetes Master:172.25.254.100,主机名 k8s-master
  • Kubernetes Node:172.25.254.10,主机名 k8s-node1
  • Pod 网络:假设使用 Flannel,CIDR 为 10.244.0.0/16
  • 以下命令中的 [master] 表示在 Master 执行,[node1] 表示在 Node1 执行

4.1 两台虚拟机配置主机名和 hosts

master 执行

bash 复制代码
hostnamectl set-hostname k8s-master

node1 执行

bash 复制代码
hostnamectl set-hostname k8s-node1

masternode1 都执行

bash 复制代码
cat >> /etc/hosts <<EOF
172.25.254.100 k8s-master
172.25.254.10  k8s-node1
EOF

验证主机名和 hosts 配置

bash 复制代码
[root@k8s-master ~]# hostname
k8s-master
[root@k8s-master ~]# ping -c 2 k8s-node1
PING k8s-node1 (172.25.254.10) 56(84) bytes of data.
64 bytes from k8s-node1 (172.25.254.10): icmp_seq=1 ttl=64 time=0.3 ms
64 bytes from k8s-node1 (172.25.254.10): icmp_seq=2 ttl=64 time=0.3 ms

4.2 初始化集群(Master 节点执行)

master 执行 kubeadm init

bash 复制代码
[root@k8s-master ~]# kubeadm init \
  --apiserver-advertise-address=172.25.254.100 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.28.2 \
  --pod-network-cidr=10.244.0.0/16

配置 kubectl 访问集群

bash 复制代码
[root@k8s-master ~]# mkdir -p $HOME/.kube
[root@k8s-master ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master ~]# chown $(id -u):$(id -g) $HOME/.kube/config
[root@k8s-master ~]# kubectl get nodes
NAME         STATUS     ROLES           AGE   VERSION
k8s-master   NotReady   control-plane   2m    v1.28.2

4.3 安装 Flannel 网络插件(Master 节点执行)

bash 复制代码
[root@k8s-master ~]# kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
[root@k8s-master ~]# kubectl get pods -n kube-flannel -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP              NODE
kube-flannel-ds-abc12   1/1     Running   0          30s   172.25.254.100  k8s-master

4.4 加入 Node 节点(node1 执行)

node1 执行 kubeadm join

bash 复制代码
[root@k8s-node1 ~]# kubeadm join 172.25.254.100:6443 \
  --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

master 验证节点状态

bash 复制代码
[root@k8s-master ~]# kubectl get nodes -o wide
NAME         STATUS   ROLES           AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE
k8s-master   Ready    control-plane   5m    v1.28.2   172.25.254.100   <none>        CentOS Linux 7
k8s-node1    Ready    <none>          1m    v1.28.2   172.25.254.10    <none>        CentOS Linux 7

4.5 上传实验镜像到私有仓库

bash 复制代码
[root@k8s-master ~]# docker load -i myapp.tar.gz
[root@k8s-master ~]# docker tag timinglee/myapp:v1 reg.timinglee.org/library/myapp:v1
[root@k8s-master ~]# docker push reg.timinglee.org/library/myapp:v1
[root@k8s-master ~]# docker tag timinglee/myapp:v2 reg.timinglee.org/library/myapp:v2
[root@k8s-master ~]# docker push reg.timinglee.org/library/myapp:v2

**说明:**若私有仓库未配置 HTTPS 证书,需先在每台节点上配置 Docker 的 insecure-registries 信任,否则后续创建 Pod 拉取镜像时会报 ErrImagePull 错误。

4.6 按章节顺序执行 Pod 管理实验

**说明:**执行实验前,请确认 myapp:v1 和 myapp:v2 镜像已成功上传到私有仓库,且各节点已配置好镜像仓库信任;否则后续章节中的 kubectl run、create deployment 等命令会因镜像拉取失败而无法正常演示。

完成上述环境准备后,即可按本文「一、命令式对象管理」「二、kubectl 命令实操」「三、Pod 的生命周期」三章中的命令和步骤,在 Master 节点(k8s-master)上依次执行全部实验,验证命名空间、Pod 创建删除、kubectl 常用命令以及 init 容器、存活探针、就绪探针等生命周期特性。

建议按以下顺序依次完成实验:

  1. 在「一、命令式对象管理」中,先练习命名空间的查看、创建与删除,再通过 kubectl run 创建 Pod,并观察镜像拉取失败时的排错流程。
  2. 在「二、kubectl 命令实操」中,依次练习 create、edit、patch、expose、logs、attach、exec、cp、rollout、scale、label 等命令,重点理解 Deployment 的滚动更新与副本扩缩容。
  3. 在「三、Pod 的生命周期」中,分别验证 init 容器、存活探针与就绪探针的行为差异,理解探针对 Pod 状态和 Service 后端摘除的影响。

全部实验完成后,建议清理实验资源,避免占用集群资源:

bash 复制代码
[root@k8s-master pod]# kubectl delete deployment webcluster
[root@k8s-master pod]# kubectl delete svc webserver
[root@k8s-master pod]# kubectl delete pods --all
相关推荐
梦梦代码精1 小时前
深度体验BuildingAI:一款集成商业闭环的开源智能体平台
人工智能·docker·开源·代码规范
数据狐(Datafox)1 小时前
1688.item_search工程实战:1688商品列表API分页采集与B2B货源数据分析落地
java·前端·数据分析
省长1 小时前
不想写代码,但想要集成一个登录页面?Sa-Token-Quick-Login 帮你实现!
java·后端·开源
得物技术1 小时前
企业级 MultiAgent 的记忆系统:短期上下文与四层记忆架构实现|得物技术
java·人工智能·后端
撩得Android一次心动1 小时前
Kotlin 语言【知识点整理3】
java·开发语言·笔记·学习·kotlin
朝发如雪1 小时前
快速掌握Linux(4)(进程)
java·linux·服务器
JackSparrow4141 小时前
Kafka(七)集成Apache Avro+Apicurio Schema Registry以保障生产者与消费者的消息兼容性
java·中间件·rpc·kafka·apache·avro·schema-registry
林森lsjs1 小时前
零基础吃透二叉树:定义、遍历与高频算法 —数据结构柒
java·开发语言·数据结构·算法·二叉树
MacroZheng1 小时前
又一个神级画图Skill开源,再见draw.io!
java·人工智能·后端