概述

kubectl 是 Kubernetes 管理员最常用的工具,但大多数人只用了它 20% 的功能。每天敲几十遍 kubectl get pods -n production,却不知道一行别名就能省掉一半字符;遇到问题只知道 kubectl describekubectl logs,却不知道 krew 插件能一键排查网络、资源、证书问题。本文逐步梳理 kubectl 的生产力提升工具链,从别名到插件到交互式工具,让你的 K8s 日常操作效率翻倍。

参考来源:kubectl 官方文档krew 官网

一、kubectl 别名配置

1.1 基础别名

# ~/.bashrc 或 ~/.zshrc

# 基础缩写
alias k='kubectl'
alias kg='kubectl get'
alias kd='kubectl describe'
alias kdel='kubectl delete'
alias ke='kubectl exec'
alias kl='kubectl logs'
alias kf='kubectl apply -f'
alias kdf='kubectl delete -f'
alias kr='kubectl run'

# 常用资源缩写
alias kgp='kubectl get pods'
alias kgs='kubectl get svc'
alias kgn='kubectl get nodes'
alias kgd='kubectl get deployments'
alias kgsec='kubectl get secrets'
alias kgcm='kubectl get configmaps'
alias kging='kubectl get ingress'
alias kgns='kubectl get namespaces'
alias kgpv='kubectl get pv'
alias kgpvc='kubectl get pvc'
alias kdsa='kubectl describe sa'

# 宽输出 + 自定义列
alias kgpw='kubectl get pods -o wide'
alias kgsw='kubectl get svc -o wide'
alias kgnw='kubectl get nodes -o wide'

# watch 模式
alias kgpw='watch -n 2 kubectl get pods -o wide'
alias kgnw='watch -n 5 kubectl get nodes -o wide'

# 所有命名空间
alias kgpa='kubectl get pods --all-namespaces'
alias kgsa='kubectl get svc --all-namespaces'

# YAML 输出
alias kgpy='kubectl get pods -o yaml'
alias kgsy='kubectl get svc -o yaml'

1.2 高级别名与函数

# === 上下文和命名空间快速切换 ===
alias kctx='kubectl config current-context'
alias kuctx='kubectl config use-context'
alias kc='kubectl config'

# === 日志相关 ===
# 跟随日志
alias klf='kubectl logs -f'
# 上一个容器的日志(崩溃后排查)
alias klp='kubectl logs --previous'
# 多容器 Pod 日志
klall() {
    kubectl logs "$1" --all-containers=true --tail=100
}

# === 临时调试 Pod ===
kdebug() {
    kubectl run debug-"$RANDOM" -it --rm --image=nicolaka/netshoot -- bash
}

# 在指定节点上启动调试 Pod
kdebug-node() {
    local node="$1"
    kubectl run debug-"$RANDOM" -it --rm --image=nicolaka/netshoot \
        --overrides='{"spec":{"nodeName":"'"$node"'","hostNetwork":true,"dnsPolicy":"ClusterFirstWithHostNet"}}' \
        -- bash
}

# === 快速进入 Pod ===
kexec() {
    local pod="$1"
    shift
    kubectl exec -it "$pod" -- "${@:-bash}"
}

# 进入 Pod 的指定容器
kexec-c() {
    local pod="$1"
    local container="$2"
    shift 2
    kubectl exec -it "$pod" -c "$container" -- "${@:-sh}"
}

# === 端口转发 ===
alias kpf='kubectl port-forward'

# 快速转发到 Deployment
kpfd() {
    local deployment="$1"
    local local_port="$2"
    local remote_port="${3:-$2}"
    kubectl port-forward "deployment/${deployment}" "${local_port}:${remote_port}"
}

# === 获取 Pod 资源使用 ===
alias ktop='kubectl top'
alias ktopp='kubectl top pods'
alias ktopn='kubectl top nodes'
alias ktoph='kubectl top pods --sort-by=cpu'

# === Rollout 管理 ===
alias kro='kubectl rollout'
alias kros='kubectl rollout status'
alias kror='kubectl rollout restart'
alias krou='kubectl rollout undo'

# === 标签和注解 ===
alias kgl='kubectl get pods --show-labels'
alias kgla='kubectl get pods -L app,version,env'

# === 事件查看 ===
alias kev='kubectl get events --sort-by=.lastTimestamp'
alias kevw='kubectl get events --watch --sort-by=.lastTimestamp'

# === 应用和回滚 ===
alias kaf='kubectl apply -f'
alias kuff='kubectl diff -f'

# === 配置管理 ===
alias kgsec='kubectl get secrets'
alias kgsecy='kubectl get secret -o yaml'

# 解码 Secret
kdecode() {
    kubectl get secret "$1" -o jsonpath="{.data.$2}" | base64 -d
}

# === 清理资源 ===
# 删除所有 Evicted Pod
kclean-evicted() {
    kubectl get pods --all-namespaces -o json | \
        jq -r '.items[] | select(.status.phase=="Failed" and .status.reason=="Evicted") | "\(.metadata.namespace) \(.metadata.name)"' | \
        xargs -r -n2 kubectl delete pod -n
}

# 删除所有 Completed Pod
kclean-completed() {
    kubectl get pods --all-namespaces -o json | \
        jq -r '.items[] | select(.status.phase=="Succeeded") | "\(.metadata.namespace) \(.metadata.name)"' | \
        xargs -r -n2 kubectl delete pod -n
}

# 强制删除卡在 Terminating 的 Pod
kforce-delete() {
    kubectl delete pod "$1" --grace-period=0 --force
}

# === 快速复制文件 ===
kcp-from() {
    local pod="$1"
    local remote_path="$2"
    local local_path="${3:-.}"
    kubectl cp "$pod:$remote_path" "$local_path"
}

kcp-to() {
    local local_path="$1"
    local pod="$2"
    local remote_path="$3"
    kubectl cp "$local_path" "$pod:$remote_path"
}

1.3 生效与验证

# 重新加载 shell 配置
source ~/.bashrc  # 或 source ~/.zshrc

# 验证别名
alias | grep '^k'

# 测试
k get pods
kgp
kgpw
ktopp

二、kubectx / kubens

2.1 安装

# macOS
brew install kubectx

# Linux
git clone https://github.com/ahmetb/kubectx.git
sudo cp kubectx/kubectx /usr/local/bin/
sudo cp kubectx/kubens /usr/local/bin/

# 或通过 krew 安装
kubectl krew install ctx
kubectl krew install ns

2.2 使用

# === kubectx: 切换上下文 ===

# 列出所有上下文
kubectx

# 切换到指定上下文
kubectx production-cluster

# 切回上一个上下文
kubectx -

# 交互式选择(需要 fzf)
kubectx <TAB>

# 删除上下文
kubectx -d old-cluster

# === kubens: 切换命名空间 ===

# 列出所有命名空间
kubens

# 切换到指定命名空间
kubens production

# 切回上一个命名空间
kubens -

# 交互式选择
kubens <TAB>

2.3 配合别名

# ~/.bashrc
alias kx='kubectx'
alias kn='kubens'

# 快速切换上下文和命名空间
kprod() {
    kubectx production-cluster
    kubens production
}

kstage() {
    kubectx staging-cluster
    kubens staging
}

kdev() {
    kubectx dev-cluster
    kubens default
}

# 显示当前上下文和命名空间(用于提示符)
k8s_prompt() {
    local ctx ns
    ctx=$(kubectl config current-context 2>/dev/null || echo "none")
    ns=$(kubectl config view --minify -o jsonpath='{..namespace}' 2>/dev/null || echo "default")
    echo "[${ctx}:${ns}]"
}

# 集成到 PS1
# PS1='$(k8s_prompt)\w\$ '

三、k9s 交互工具

3.1 安装

# macOS
brew install k9s

# Linux
curl -sS https://webinstall.dev/k9s | bash

# 或下载二进制
curl -L https://github.com/derailed/k9s/releases/latest/download/k9s_Linux_amd64.tar.gz | \
    tar xz -C /usr/local/bin k9s

3.2 常用快捷键

快捷键功能
?显示帮助
:进入命令模式
/过滤搜索
Esc返回上级
q退出
Enter查看详情
l查看日志
s进入 Pod Shell
e编辑资源
ddescribe
Ctrl+d删除资源
Shift+:切换命名空间
Ctrl+a显示所有命名空间

3.3 常用命令模式

# 启动 k9s
k9s

# 指定命名空间
k9s -n production

# 指定上下文
k9s --context production-cluster

# 直接进入特定资源视图
k9s -c pods       # Pod 视图
k9s -c svc        # Service 视图
k9s -c deploy     # Deployment 视图
k9s -c nodes      # Node 视图
k9s -c jobs       # Job 视图
k9s -c secrets    # Secret 视图

3.4 k9s 配置

# ~/.config/k9s/config.yml
k9s:
  refreshRate: 2
  maxLogs: 1000
  logger:
    tail: 500
    buffer: 5000
    sinceSeconds: 300
    fullScreen: false
    textWrap: false
    showTime: false
  currentContext: production-cluster
  currentCluster: production-cluster
  clusters:
    production-cluster:
      namespace:
        active: production
        favorites:
          - production
          - kube-system
          - monitoring
      view:
        active: pods
  thresholds:
    cpu:
      critical: 90
      warn: 70
    memory:
      critical: 90
      warn: 70

3.5 自定义别名

# ~/.config/k9s/aliases.yml
aliases:
  pp: v1/pods
  svc: v1/services
  dep: apps/v1/deployments
  sts: apps/v1/statefulsets
  ds: apps/v1/daemonsets
  ing: networking.k8s.io/v1/ingresses
  cm: v1/configmaps
  sec: v1/secrets
  pv: v1/persistentvolumes
  pvc: v1/persistentvolumeclaims
  sa: v1/serviceaccounts
  crd: apiextensions.k8s.io/v1/customresourcedefinitions
  hr: helm.toolkit.fluxcd.io/v2beta1/helmreleases

3.6 自定义插件

# ~/.config/k9s/plugins.yml
plugins:
  # 在 Pod 中执行 curl
  curl:
    shortCut: Ctrl+C
    description: Curl pod
    scopes:
      - pods
    command: kubectl
    background: false
    args:
      - exec
      - -it
      - $NAME
      - -n
      - $NAMESPACE
      - --
      - curl
      - -s
      - http://localhost:8080/health

  # 端口转发
  fwd:
    shortCut: Ctrl+F
    description: Port forward
    scopes:
      - pods
    command: kubectl
    background: true
    args:
      - port-forward
      - $NAME
      - -n
      - $NAMESPACE
      - 8080:80

  # 在节点上启动调试容器
  debug-node:
    shortCut: Ctrl+D
    description: Debug on node
    scopes:
      - nodes
    command: kubectl
    background: false
    args:
      - debug
      - node/$NAME
      - -it
      - --image=nicolaka/netshoot

四、kubectl 插件(krew)

4.1 安装 krew

# 安装 krew
(
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm64\|aarch64\)/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)

# 添加到 PATH
export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

# 验证
kubectl krew version

4.2 必装插件推荐

# 查看可用插件
kubectl krew search

# === 必装插件 ===

# ctx / ns: 快速切换上下文和命名空间
kubectl krew install ctx
kubectl krew install ns

# whoami: 显示当前身份和权限
kubectl krew install whoami

# who-can: 查看谁有权限执行某操作
kubectl krew install who-can

# access-matrix: 权限矩阵
kubectl krew install access-matrix

# === 排障插件 ===

# diagnose: 诊断集群和资源问题
kubectl krew install diagnose

# debug-pod: 一键调试 Pod
kubectl krew install debug-pod

# sniff: Pod 网络抓包
kubectl krew install sniff

# df-pv: 查看 PV 磁盘使用
kubectl krew install df-pv

# === 资源管理插件 ===

# neat: 清理 YAML 中的默认字段(用于导出干净配置)
kubectl krew install neat

# sort-manifests: 按依赖排序 manifest
kubectl krew install sort-manifests

# modify-secret: 编辑 Secret 时自动编解码
kubectl krew install modify-secret

# === 安全插件 ===

# rbac-lookup: 查找 RBAC 权限
kubectl krew install rbac-lookup

# rbac-view: RBAC 可视化
kubectl krew install rbac-view

# === 效率插件 ===

# get-all: 获取所有资源
kubectl krew install get-all

# tree: 查看资源的树状层级关系
kubectl krew install tree

# tail: 多 Pod 日志聚合
kubectl krew install tail

# stats: 资源统计
kubectl krew install stats

# === 部署插件 ===

# rollout: 增强的 rollout 管理
kubectl krew install rollout

# view-utilization: 资源利用率
kubectl krew install view-utilization

4.3 插件使用示例

# === ctx / ns ===
kubectl ctx production-cluster
kubectl ns monitoring

# === whoami ===
kubectl whoami
kubectl who-can create pods --namespace default

# === neat: 导出干净的 YAML ===
kubectl get deployment myapp -o yaml | kubectl neat > myapp-clean.yaml

# === tree: 查看资源层级 ===
kubectl tree deployment myapp
# myapp (Deployment)
# ├── myapp-xxx (ReplicaSet)
# │   ├── myapp-xxx-yyy (Pod)
# │   └── myapp-xxx-zzz (Pod)

# === tail: 聚合日志 ===
kubectl tail
kubectl tail -n production
kubectl tail -l app=myapp
kubectl tail --since 5m

# === df-pv: PV 磁盘使用 ===
kubectl df-pv

# === sniff: 网络抓包 ===
kubectl sniff myapp-pod -n production -o capture.pcap

# === get-all: 获取所有资源 ===
kubectl get-all -n production

# === view-utilization: 资源利用率 ===
kubectl view-utilization

# === modify-secret: 编辑 Secret ===
kubectl modify-secret myapp-tls -n production

# === rbac-lookup: 查找权限 ===
kubectl rbac-lookup deploy
kubectl rbac-lookup --kind serviceaccount

五、自定义插件开发

5.1 kubectl 插件机制

kubectl 插件就是放在 PATH 中的可执行文件,命名格式为 kubectl-<name>。kubectl 会自动识别并作为子命令调用:

# 创建插件目录
mkdir -p ~/.krew/bin

# 插件就是名为 kubectl-<name> 的可执行脚本
cat > ~/.krew/bin/kubectl-hello << 'EOF'
#!/usr/bin/env bash
echo "Hello from kubectl plugin!"
echo "Current context: $(kubectl config current-context)"
EOF

chmod +x ~/.krew/bin/kubectl-hello

# 使用
kubectl hello
# Hello from kubectl plugin!
# Current context: production-cluster

5.2 实用插件:Pod 资源对比

#!/usr/bin/env bash
# kubectl-resource-compare
# 对比 Pod 的 resource requests/limits 与实际使用

set -euo pipefail

NAMESPACE="${NAMESPACE:-default}"

# 获取所有 Pod 的资源请求和限制
echo "Pod Resource Comparison (namespace: ${NAMESPACE})"
echo "============================================="
printf "%-30s %-10s %-15s %-15s %-15s %-15s\n" \
    "POD" "CONTAINER" "CPU REQ" "CPU LIM" "MEM REQ" "MEM LIM"
echo "---------------------------------------------"

kubectl get pods -n "$NAMESPACE" -o json | \
jq -r '
  .items[] |
  .metadata.name as $pod |
  .spec.containers[] |
  "\($pod) \(.name) \(.resources.requests.cpu // "-") \(.resources.limits.cpu // "-") \(.resources.requests.memory // "-") \(.resources.limits.memory // "-")"
' | while read -r pod container cpu_req cpu_lim mem_req mem_lim; do
    printf "%-30s %-10s %-15s %-15s %-15s %-15s\n" \
        "$pod" "$container" "$cpu_req" "$cpu_lim" "$mem_req" "$mem_lim"
done

# 如果安装了 metrics-server,显示实际使用
if kubectl top pods -n "$NAMESPACE" &>/dev/null; then
    echo ""
    echo "Actual Usage:"
    echo "============================================="
    kubectl top pods -n "$NAMESPACE"
fi

5.3 实用插件:一键排障

#!/usr/bin/env bash
# kubectl-troubleshoot
# 一键收集 Pod 排障信息

set -euo pipefail

POD_NAME="$1"
NAMESPACE="${2:-default}"

if [[ -z "$POD_NAME" ]]; then
    echo "用法: kubectl troubleshoot <pod-name> [namespace]"
    exit 1
fi

echo "============================================"
echo "Pod 排障报告: ${POD_NAME} (ns: ${NAMESPACE})"
echo "时间: $(date)"
echo "============================================"

# 1. Pod 状态
echo -e "\n--- Pod 状态 ---"
kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o wide

# 2. Events
echo -e "\n--- Events ---"
kubectl get events -n "$NAMESPACE" \
    --field-selector involvedObject.name="$POD_NAME" \
    --sort-by='.lastTimestamp'

# 3. 容器状态
echo -e "\n--- 容器状态 ---"
kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o json | \
jq -r '.status.containerStatuses[] | "容器: \(.name)\n  镜像: \(.image)\n  Ready: \(.ready)\n  RestartCount: \(.restartCount)\n  State: \(.state | keys[0])\n  LastState: \(.lastState | keys[0] // "none")\n"'

# 4. 资源使用
echo -e "\n--- 资源使用 ---"
kubectl top pod "$POD_NAME" -n "$NAMESPACE" --containers 2>/dev/null || \
    echo "(metrics-server 不可用)"

# 5. 最近日志
echo -e "\n--- 日志 (最后 50 行) ---"
kubectl logs "$POD_NAME" -n "$NAMESPACE" --tail=50 2>/dev/null || \
    echo "(无法获取日志)"

# 6. 上次崩溃日志
echo -e "\n--- 上次崩溃日志 ---"
kubectl logs "$POD_NAME" -n "$NAMESPACE" --previous --tail=30 2>/dev/null || \
    echo "(无上次崩溃记录)"

# 7. 网络信息
echo -e "\n--- 网络信息 ---"
kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o json | \
jq -r '.status | "IP: \(.podIP)\nHostIP: \(.hostIP)\n"'

# 8. 所在节点信息
NODE=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.nodeName}')
echo -e "\n--- 所在节点: ${NODE} ---"
kubectl describe node "$NODE" | grep -A5 "Allocated resources"

echo -e "\n============================================"
echo "排障信息收集完成"

5.4 实用插件:集群资源总览

#!/usr/bin/env bash
# kubectl-cluster-summary
# 集群资源总览

set -euo pipefail

echo "============================================"
echo "Kubernetes 集群总览"
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "============================================"

# 集群信息
echo -e "\n=== 集群信息 ==="
kubectl cluster-info 2>/dev/null | head -5
echo "Context: $(kubectl config current-context)"

# 节点概览
echo -e "\n=== 节点 (${NODE_COUNT}) ==="
kubectl get nodes -o wide

# 节点资源使用
echo -e "\n=== 节点资源使用 ==="
kubectl top nodes 2>/dev/null || echo "(metrics-server 不可用)"

# 命名空间统计
echo -e "\n=== 命名空间资源统计 ==="
printf "%-20s %-8s %-8s %-8s %-8s %-8s\n" \
    "NAMESPACE" "PODS" "SVC" "DEPLOY" "STS" "ING"
printf "%-20s %-8s %-8s %-8s %-8s %-8s\n" \
    "---------" "----" "---" "------" "---" "---"

for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
    pods=$(kubectl get pods -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null | wc -w)
    svc=$(kubectl get svc -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null | wc -w)
    deploy=$(kubectl get deploy -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null | wc -w)
    sts=$(kubectl get sts -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null | wc -w)
    ing=$(kubectl get ing -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null | wc -w)
    printf "%-20s %-8s %-8s %-8s %-8s %-8s\n" "$ns" "$pods" "$svc" "$deploy" "$sts" "$ing"
done

# 异常 Pod
echo -e "\n=== 异常 Pod ==="
kubectl get pods --all-namespaces \
    --field-selector=status.phase!=Running,status.phase!=Succeeded 2>/dev/null || \
    echo "(无异常 Pod)"

# 最近事件
echo -e "\n=== 最近 Warning 事件 ==="
kubectl get events --all-namespaces \
    --field-selector type=Warning \
    --sort-by='.lastTimestamp' 2>/dev/null | tail -20

echo -e "\n============================================"

5.5 发布插件到 krew

如果你开发了通用插件,可以提交到 krew 索引供社区使用:

# 1. Fork krew-index 仓库
git clone https://github.com/kubernetes-sigs/krew-index.git
cd krew-index

# 2. 创建插件 manifest
# plugins/<plugin-name>.yaml
cat > plugins/my-plugin.yaml << 'EOF'
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
  name: my-plugin
spec:
  version: "v1.0.0"
  homepage: https://github.com/yourname/kubectl-my-plugin
  shortDescription: "One-line description"
  description: |
    Detailed description of what the plugin does.
  platforms:
    - selector:
        matchLabels:
          os: linux
          arch: amd64
      uri: https://github.com/yourname/kubectl-my-plugin/releases/download/v1.0.0/my-plugin-linux-amd64.tar.gz
      sha256: "sha256hash..."
      bin: my-plugin
    - selector:
        matchLabels:
          os: darwin
          arch: amd64
      uri: https://github.com/yourname/kubectl-my-plugin/releases/download/v1.0.0/my-plugin-darwin-amd64.tar.gz
      sha256: "sha256hash..."
      bin: my-plugin
EOF

# 3. 提交 PR
git add plugins/my-plugin.yaml
git commit -m "Add my-plugin v1.0.0"

六、常用操作速查

6.1 Pod 排障速查

# 查看 Pod 状态
kubectl get pod <pod> -o wide
kubectl describe pod <pod>

# 查看容器状态和重启次数
kubectl get pod <pod> -o jsonpath='{.status.containerStatuses[*]}' | jq .

# 查看日志
kubectl logs <pod>
kubectl logs <pod> -c <container>      # 指定容器
kubectl logs <pod> --previous           # 上次崩溃的日志
kubectl logs <pod> --since=1h           # 最近 1 小时
kubectl logs -f <pod>                   # 跟随日志

# 进入 Pod
kubectl exec -it <pod> -- bash
kubectl exec -it <pod> -c <container> -- sh

# 查看 Pod 资源使用
kubectl top pod <pod> --containers

# 查看 Pod 的 YAML(含默认注入的字段)
kubectl get pod <pod> -o yaml

# 查看 Pod 的事件
kubectl get events --field-selector involvedObject.name=<pod>

# 端口转发
kubectl port-forward <pod> 8080:80

# 临时调试 Pod
kubectl run debug -it --rm --image=nicolaka/netshoot -- bash

6.2 节点排障速查

# 节点状态
kubectl get nodes -o wide
kubectl describe node <node>

# 节点资源使用
kubectl top node <node>

# 节点上的 Pod
kubectl get pods --all-namespaces --field-selector spec.nodeName=<node>

# 节点资源分配
kubectl describe node <node> | grep -A 10 "Allocated resources"

# 标记节点为不可调度
kubectl cordon <node>

# 驱逐节点上的 Pod
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data

# 恢复节点调度
kubectl uncordon <node>

6.3 网络排障速查

# 查看 Service 和 Endpoints
kubectl get svc <svc> -o wide
kubectl get endpoints <svc>

# 查看 Endpoints 详情
kubectl describe endpoints <svc>

# 查看 Ingress
kubectl get ingress
kubectl describe ingress <ingress>

# 查看 NetworkPolicy
kubectl get networkpolicy

# 在 Pod 中测试网络
kubectl exec -it <pod> -- curl -v http://<service-name>:<port>

# 查看 DNS
kubectl exec -it <pod> -- nslookup <service-name>
kubectl exec -it <pod> -- cat /etc/resolv.conf

# CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns

6.4 资源管理速查

# 导出资源为 YAML(干净版)
kubectl get deploy <name> -o yaml | kubectl neat > deploy.yaml

# 应用变更(先看 diff)
kubectl diff -f deploy.yaml
kubectl apply -f deploy.yaml

# 重启 Deployment
kubectl rollout restart deployment/<name>

# 查看发布状态
kubectl rollout status deployment/<name>

# 回滚
kubectl rollout undo deployment/<name>
kubectl rollout undo deployment/<name> --to-revision=3

# 查看发布历史
kubectl rollout history deployment/<name>

# 扩缩容
kubectl scale deployment/<name> --replicas=5
kubectl autoscale deployment/<name> --min=2 --max=10 --cpu-percent=80

# 修改镜像
kubectl set image deployment/<name> <container>=<new-image>:<tag>

# 添加标签
kubectl label pod <pod> env=production
kubectl label pod <pod> env-   # 删除标签

七、排障技巧

7.1 Pod 一直 Pending

# 1. 查看 Pod 事件
kubectl describe pod <pod> | grep -A 10 Events

# 常见原因和排查:
# - Unschedulable: 资源不足
kubectl get nodes -o custom-columns="NAME:.metadata.name,CPU:.status.allocatable.cpu,MEM:.status.allocatable.memory"

# - nodeSelector/Affinity 不匹配
kubectl get nodes --show-labels

# - PVC Pending
kubectl get pvc
kubectl describe pvc <pvc>

# - 污点未容忍
kubectl get nodes -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | \
    xargs -I{} kubectl describe node {} | grep -A5 Taints

7.2 Pod 一直 CrashLoopBackOff

# 1. 查看上次崩溃日志
kubectl logs <pod> --previous

# 2. 查看容器退出码
kubectl get pod <pod> -o jsonpath='{.status.containerStatuses[0].lastState}' | jq .

# 常见退出码:
# 0: 正常退出
# 1: 应用错误
# 125: 镜像不存在
# 126: 权限不足
# 127: 命令未找到
# 137: OOM Killed 或 SIGKILL
# 139: Segfault
# 143: SIGTERM

# 3. 检查是否 OOM
kubectl describe pod <pod> | grep -i "OOMKilled\|terminated"

# 4. 检查资源限制
kubectl get pod <pod> -o jsonpath='{.spec.containers[*].resources}' | jq .

# 5. 临时调试(覆盖启动命令)
kubectl run debug --image=<image> -it --rm --command -- sh

7.3 Service 无法访问

# 1. 检查 Endpoints
kubectl get endpoints <svc>
# 如果为空,说明没有 Pod 匹配 selector

# 2. 检查 selector 匹配
kubectl get pods --show-labels
kubectl get svc <svc> -o jsonpath='{.spec.selector}'

# 3. 检查 targetPort
kubectl get svc <svc> -o jsonpath='{.spec.ports}'

# 4. 在 Pod 中测试
kubectl exec -it <pod> -- curl http://<svc>:<port>

# 5. 检查 kube-proxy
kubectl get pods -n kube-system -l k8s-app=kube-proxy
kubectl logs -n kube-system -l k8s-app=kube-proxy --tail=50

# 6. 检查 iptables/ipvs
kubectl exec -it <pod> -- curl -v http://<svc-ip>:<port>

总结

kubectl 的强大之处不在于命令本身,而在于围绕它构建的生态工具链。回顾本文核心要点:

  1. 别名是零成本提效:把高频命令缩写为 2-3 个字符,每天节省大量键盘敲击。关键不是记住所有别名,而是找到你自己的高频操作模式并固化
  2. kubectx/kubens 是多集群标配:在多集群多命名空间环境下,快速切换上下文和命名空间是最频繁的操作,没有这两个工具效率会大打折扣
  3. k9s 改变交互方式:从"敲命令看结果"变成"交互式浏览",特别是日志查看、资源编辑、端口转发等操作,k9s 比纯命令行快一个量级
  4. krew 是插件市场:ctx/ns/whoami/neat/tail/tree 等插件覆盖了日常 80% 的场景。安装一个插件就是安装一个能力,比写自定义脚本高效
  5. 自定义插件填补空白:kubectl 插件机制极其简单——PATH 中的可执行文件就行。把团队常用的排障流程封装为插件,统一标准、提升效率
  6. 排障要有方法论:Pending 查调度→CrashLoop 查日志→Service 查 Endpoints,每种症状都有固定的排查路径。把这些路径固化为脚本,新人也能快速排障

kubectl 的生产力提升不是一次性的配置,而是一个持续优化的过程。每当你发现自己重复输入某个长命令时,就该加一个别名;每当你发现某个排障流程需要多步操作时,就该写一个插件。工具链的完善程度,直接决定了你管理 K8s 集群的效率上限。

参考资料与致谢

本文在撰写过程中参考了以下资料,感谢原作者的贡献:

  1. kubectl 官方文档 — Kubernetes 官方,参考了kubectl 官方文档相关内容
  2. krew 官网 — Kubernetes 官方,参考了krew 官网相关内容