一、模板与帮助手册:kubectl 的隐藏技能

🔍 1. 内置帮助系统

# 查看命令帮助
kubectl get --help
kubectl create pod --help

# 查看资源字段说明(关键!)
kubectl explain pod
kubectl explain pod.spec.containers
kubectl explain deployment.spec.template.spec.volumes

作用:无需翻阅文档,直接在终端查看 API 字段定义、类型、是否必填。

🧩 2. 使用 Go Template 自定义输出

# 只显示 Pod 名称和 IP
kubectl get pods -o go-template='{{range .items}}{{.metadata.name}} {{.status.podIP}}{{"\n"}}{{end}}'

# 显示容器镜像
kubectl get pods -o go-template='{{range .items}}{{.metadata.name}}: {{range .spec.containers}}{{.image}} {{end}}{{"\n"}}{{end}}'

📋 3. 生成基础 YAML 模板

# 生成 Pod 模板(dry-run)
kubectl create pod nginx --image=nginx --dry-run=client -o yaml > nginx-pod.yaml

# 生成带多个容器的模板(需手动编辑)
kubectl run multi-container --image=busybox --dry-run=client -o yaml --command -- sleep 3600

💡 提示--dry-run=client 在 k8s v1.25+ 替代了旧版 --dry-run


二、多容器 Pod:设计模式与实战场景

Pod 支持在一个逻辑单元中运行多个容器,共享网络与存储。

🌐 共享机制

  • 同一 IP 地址:容器间通过 localhost 通信
  • 共享 Volume:通过 emptyDir 或 PVC 实现文件交换
  • 共享 PID 命名空间(可选)shareProcessNamespace: true

🧠 三大经典模式

1. Sidecar 模式(辅助容器)

主容器 + 日志收集 / 监控 / 配置同步

apiVersion: v1
kind: Pod
metadata:
  name: app-with-sidecar
spec:
  containers:
  - name: main-app
    image: nginx
    volumeMounts:
    - name: logs
      mountPath: /var/log/nginx

  - name: fluentd-sidecar
    image: fluent/fluentd:v1.16-1
    volumeMounts:
    - name: logs
      mountPath: /var/log/nginx
    env:
    - name: FLUENTD_CONF
      value: "fluent.conf"

  volumes:
  - name: logs
    emptyDir: {}
2. Adapter 模式(标准化输出)

主容器生成原始数据,Adapter 容器转换为统一格式

3. Ambassador 模式(代理网络)

主容器通过 localhost 访问 Ambassador 容器,后者代理外部服务(如数据库连接池)


三、多容器 Pod 管理技巧

📊 查看特定容器日志

# 查看 sidecar 日志
kubectl logs app-with-sidecar -c fluentd-sidecar

# 实时跟踪
kubectl logs -f app-with-sidecar -c main-app

🚪 进入指定容器

kubectl exec -it app-with-sidecar -c main-app -- /bin/sh

⏱ 控制启动顺序:Init Containers

在主容器启动前执行一次性任务(如数据库迁移、等待依赖服务)

apiVersion: v1
kind: Pod
metadata:
  name: app-with-init
spec:
  initContainers:
  - name: wait-for-db
    image: busybox:1.36
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for db; sleep 2; done']

  containers:
  - name: app
    image: myapp:1.0

特点

  • Init 容器按顺序执行,全部成功后主容器才启动;
  • 失败会自动重试(受 restartPolicy 影响)。

四、嵌入式脚本:动态配置与初始化

在容器启动时执行脚本,实现环境适配。

方法 1:通过 command 覆盖入口

containers:
- name: app
  image: alpine
  command: ["/bin/sh", "-c"]
  args:
    - |
      echo "Starting at $(date)" >> /var/log/start.log;
      if [ "$ENV" = "prod" ]; then
        echo "Production mode enabled";
      fi;
      sleep 3600
  env:
  - name: ENV
    value: "prod"

方法 2:挂载 ConfigMap 作为启动脚本

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: startup-script
data:
  start.sh: |
    #!/bin/sh
    echo "Custom init script running..."
    /app/main

# pod.yaml
containers:
- name: app
  image: myapp
  volumeMounts:
  - name: script-volume
    mountPath: /startup
  command: ["/startup/start.sh"]

volumes:
- name: script-volume
  configMap:
    name: startup-script
    defaultMode: 0755

优势:脚本版本化、可复用、与镜像解耦。


五、Pod 调度策略:精准控制运行位置

1. NodeSelector(简单匹配)

spec:
  nodeSelector:
    disktype: ssd
    zone: east

前提:节点已打标签 kubectl label node node1 disktype=ssd

2. Node Affinity(高级匹配)

支持 requiredDuringScheduling(硬性要求)和 preferredDuringScheduling(软性偏好)

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/os
            operator: In
            values: ["linux"]
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: rack
            operator: In
            values: ["rack-1"]

3. Taints 与 Tolerations(排斥机制)

  • Taint:节点“拒绝”某些 Pod
  • Toleration:Pod “容忍”特定 Taint
# 给 GPU 节点加污点
kubectl taint nodes gpu-node dedicated=gpu:NoSchedule
# Pod 容忍该污点
spec:
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

典型用途

  • Master 节点默认有 node-role.kubernetes.io/control-plane:NoSchedule
  • 专用硬件节点(GPU/FPGA)仅供特定任务使用

六、Pod 标签管理:组织、选择与运维基石

🏷 什么是标签(Labels)?

  • Key/Value 对(如 app=web, env=prod, version=v2
  • 用于标识和分类资源
  • 非唯一、可重复、可动态修改

🔧 标签操作命令

# 创建时指定
kubectl run nginx --image=nginx --labels="app=web,team=frontend"

# 动态添加/修改
kubectl label pod nginx app=web version=v1.2 --overwrite

# 删除标签
kubectl label pod nginx version-

# 按标签筛选
kubectl get pods -l app=web
kubectl get pods -l 'env in (prod,stage)'

🎯 选择器(Selectors)应用场景

场景 选择器示例
Service 后端 selector: {app: web}
Deployment 管理 matchLabels: {app: api}
kubectl 批量操作 kubectl delete pods -l owner=legacy

📁 推荐标签规范(CNCF 建议)

metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: mysql-prod
    app.kubernetes.io/version: "8.0"
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress
    app.kubernetes.io/managed-by: helm

好处:工具链(Helm、Operator)可识别,实现标准化管理。

更多推荐