一、定义一个 Pod 的两种常见方式

创建 Pod 最常见的方式有两种:写 YAML 和直接用命令行。

1. 用 YAML 创建,最推荐

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
    ports:
    - containerPort: 80

创建命令:

kubectl create -f nginx.yaml

查看状态:

kubectl get -f nginx.yml
kubectl get -f nginx.yml -o wide

YAML 方式最大的好处,是配置可追踪、可复用、可版本化。

2. 用命令直接创建

kubectl run nginx --image=registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2

然后查看:

kubectl get po nginx
kubectl get po nginx -o wide

这种方式适合临时测试,但长期维护还是更适合 YAML。

二、一个 Pod 里也可以放多个容器

单 Pod 多容器的典型写法如下:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-redis
spec:
  containers:
  - name: nginx
    image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
    ports:
    - containerPort: 80
  - name: redis
    image: registry.cn-hangzhou.aliyuncs.com/abroad_images/redis:7.2.5
    ports:
    - containerPort: 6379

创建之后:

kubectl create -f nginx-redis.yml
kubectl get -f nginx-redis.yml -o wide

如果要进入指定容器,可以显式加 -c

kubectl exec -it nginx-redis -c nginx -- sh

这也是多容器 Pod 最实用的一点:虽然它们共享 Pod 环境,但排查时仍然可以单独进入某个容器。

三、如何修改 Pod 的启动命令和参数

覆盖镜像默认启动命令时,最常见的是 commandargs 的三种写法。

1. 直接把命令写完整

command: ["/bin/sh", "-c", "sleep 10"]

2. commandargs 分开写

command: ["/bin/sh", "-c"]
args: ["sleep 10"]

3. 用多行脚本写复杂启动逻辑

command: ["/bin/sh", "-c"]
args:
  - |
    sleep 10
    echo "Command completed"

修改后如果是直接管理 Pod,通常更稳妥的方式是删掉旧 Pod 再重新创建:

kubectl delete -f nginx.yml
kubectl create -f nginx01.yml

如果容器命令会在 10 秒后退出,而 restartPolicy 还是默认的 Always,就会看到 Pod 不断重启,这也是很多人第一次接触 Pod 时常见的现象。

四、删除 Pod 时为什么有时删不掉

删除 Pod 常见有两类方式。

普通删除:

kubectl delete -f nginx.yml
kubectl delete po nginx

强制删除:

kubectl delete po nginx --grace-period=0 --force

这里要特别注意:强制删除是直接跳过优雅终止时间,不代表底层资源一定已经完全清理完成,所以生产环境不要滥用。

五、给 Pod 分配 CPU 和内存时,最重要的是搞清 requests 和 limits

典型配置:

resources:
  requests:
    cpu: "100m"
    memory: "100Mi"
  limits:
    cpu: "500m"
    memory: "1Gi"

核心区别是:

  • requests:调度依据,表示至少需要这么多资源
  • limits:运行上限,表示最多只能用这么多资源

1. requests 的意义

调度器会根据 requests 判断节点能不能放下这个 Pod。

例如:

  • cpu: 100m 等于 0.1
  • memory: 100Mi 大约是 104.86MB

如果节点剩余可分配资源不满足 requests,Pod 就会一直处于 Pending

2. limits 的意义

limits 更像运行期的边界:

  • CPU 超限通常会被限流,不一定立刻杀容器
  • 内存超限更容易触发 OOMKilled

3. requests 和 limits 的实际表现

有两个非常容易混淆的点:

  • limits 设置得比节点总资源还大,Pod 仍然可能启动,因为 limits 允许超配
  • requests 设置得超过节点可分配资源,Pod 会直接调度失败,进入 Pending

这也是为什么有时你会看到节点明明“还有资源”,但 Pod 依然起不来。真正影响调度的,是 Kubernetes 计算出来的可分配资源和 requests 是否匹配。

六、怎么看资源问题是不是调度失败导致的

看节点资源:

kubectl describe node k8s-node02

重点关注:

  • Capacity
  • Allocatable
  • Allocated resources

如果 Pod 起不来,再看:

kubectl describe po nginx

常见事件会直接告诉你:

  • Insufficient cpu
  • Insufficient memory
  • 有无污点不匹配

七、Pod 实战里最值得先建立的习惯

如果你是刚开始练 Pod,建议优先建立这套操作顺序:

  1. 先写最小 YAML,而不是一上来堆很多字段
  2. kubectl get -o wide 看节点和 IP
  3. kubectl describe 看事件和调度细节
  4. 先区分清楚 requestslimits
  5. 临时实验可以直接用 Pod,长期管理还是交给 Deployment

这样能帮你更快从“会创建 Pod”进入“能理解 Pod 为什么这样运行”。