kubectl 命令

常用命令整理

kubectl 切换集群

# 查看当前上下文
kubectl config current-context

# 查看所有上下文
kubectl config get-contexts

# 切换上下文
kubectl config use-context <context-name>

kubectl 获取集群 pvc 挂载情况

# 输出内容:命名空间  PVC名称  挂载该PVC的Pod列表
for pvc in $(kubectl get pvc --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}'); do 
    ns=${pvc%/*}; 
    name=${pvc#*/}; 
    pods=$(kubectl get pods -n $ns -o json 2>/dev/null | jq -r ".items[] | select(.spec.volumes[]?.persistentVolumeClaim.claimName==\"$name\") | .metadata.name" | tr '\n' ',' | sed 's/,$//'); 
    echo -e "$ns\t$name\t${pods:-<none>}"; 
done | column -t -s $'\t'

kubectl 获取 pod 根据时间排序

# 根据创建时间排序
kubectl get pods --all-namespaces --sort-by=.metadata.creationTimestamp

kubectl + for

# 检索所有节点的软锁死日志
for node_ip in $(kubectl get nodes --no-headers | awk '{print $1}'); do
    ssh ${node_ip} "hostname -I && grep -m 1 -e 'soft lockup' /var/log/messages | grep -v grep || echo '无'; echo ";
    done

# 同上,一行输出
# grep -m 1 (表示只匹配第一条记录) -e (表示使用正则表达式进行匹配,可以跟多个匹配多个)
for node_ip in $(kubectl get nodes --no-headers | awk '{print $1}'); do ssh -q ${node_ip} "host_ip=\$(hostname -I|awk '{print \$1}'); echo -n "\${host_ip}" ; grep -m 1 -e 'soft lockup' /var/log/messages | grep -v grep || echo ' 无'"; done

kubectl 根据镜像获取健康检查

⚠️: 该命令假设每个 pod 只有一个容器,如果有多个容器,可能需要调整索引 [0]

kubectl get pods --all-namespaces -o json | jq -r '.items[] | select(.spec.containers[].image | contains("grafana")) | "\(.metadata.namespace)|\(.metadata.name)|\(.spec.containers[0].livenessProbe // "null")|\(.spec.containers[0].readinessProbe // "null")"' | column -t -s "|"

kubectl 获取 deploy、sts 反亲和信息

# 反亲和(Pod Anti-Affinity)
echo "命名空间|负载名称|负载类型|副本数量|是否配置反亲和|反亲和配置" && \
kubectl get deploy,sts --all-namespaces -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,KIND:.kind,REPLICAS:.spec.replicas,PAA:.spec.template.spec.affinity.podAntiAffinity' --no-headers | \
awk '{
    ns = $1; name = $2; kind = $3; replicas = $4; paa = $5;
    gsub(/,.*/, "", replicas);  # 修复 replicas 可能拼接的问题
    if (paa == "<none>") {
        print ns "|" name "|" kind "|" replicas "|否|"
    } else {
        print ns "|" name "|" kind "|" replicas "|是|" paa
    }
}'

kubectl 获取指定镜像的负载

kubectl get pods --all-namespaces -o json | \
  jq -r '.items[] | 
    select(.spec.containers[].image | contains("grafana")) | 
    .metadata.namespace as $ns | 
    .metadata.name as $pod | 
    .spec.containers[] | 
    select(.image | contains("grafana")) | 
    "Namespace: \($ns) | Pod: \($pod) | Container: \(.name) | Command: \(.command // ["<none>"] | join(" "))"'

代码说明:

  1. kubectl get pods --all-namespaces -o json
    获取所有命名空间中的 Pod,并以 JSON 格式输出,便于后续解析。

  2. jq -r '...'
    使用 jq 工具处理 JSON 数据,-r 表示输出原始字符串(不带引号)。

  3. .items[]
    遍历 JSON 中的每个 Pod 对象。

  4. select(.spec.containers[].image | contains("grafana"))
    筛选出至少有一个容器镜像包含 "grafana" 的 Pod。

  5. .metadata.namespace as $ns
    将当前 Pod 的命名空间保存到变量 $ns,供后续使用。

  6. .metadata.name as $pod
    将 Pod 名称保存到变量 $pod

  7. .spec.containers[]
    展开该 Pod 的所有容器,逐个处理。

  8. select(.image | contains("grafana"))
    只保留镜像中包含 "grafana" 的容器(防止多容器 Pod 中误输出非目标容器)。

  9. "Namespace: \($ns) | Pod: \($pod) | ..."
    格式化输出结果,显示命名空间、Pod 名、容器名和启动命令;
    若未设置 command,则显示 <none>

  10. | join(" "))"'
    将容器的启动命令以空格连接成字符串输出。
    原始命令:["sh", "-c", "start"],使用 join(" ") 后变为 "sh -c start"

kubectl 不可调度查看

# 打印不可调度节点上的非 Deployment 和 StatefulSet 控制器的 Pod 信息
kubectl get nodes --field-selector spec.unschedulable=true -o name | cut -d/ -f2 | while read node; do
    kubectl get pods --all-namespaces --field-selector spec.nodeName=$node -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{" | 控制器: "}{.metadata.ownerReferences[0].kind}{"\n"}{end}' | \
    grep -vE "控制器: (Deployment|StatefulSet)" | \
    while read line; do
        echo "节点: $node | $line"
    done
    echo "---"
done

# 查看不可调度节点列表中只有 DaemonSet 控制器的节点
kubectl get nodes --field-selector spec.unschedulable=true -o name | cut -d/ -f2 | while read node; do
    if ! kubectl get pods --all-namespace --field-selector spec.nodeName=$node -o jsonpath='{range .items[*]}{.metadata.ownerReferences[0].kind}{"\n"}{end}' | \
    grep -iqE "^(Deployment|StatefulSet|ReplicaSet)$" ; then
        echo "节点 $node 上只有 DaemonSet 控制器的 Pod"
    fi
done

# 检查不可调度节点上的 pod 控制器类型
for node in $(kubectl get nodes --field-selector spec.unschedulable=true -o name | cut -d/ -f2); do
  echo "检查节点 $node 上的业务 Pod:"
  kubectl get pods --all-namespaces --field-selector spec.nodeName=$node -o json | \
    jq -r '.items[] | select(.metadata.ownerReferences[]?.kind != "DaemonSet") | .metadata.namespace + "/" + .metadata.name'
  echo
done

kubectl 日志查看

kubectl logs <pod-name> -n <namespace>

# 查看上一个容器的日志
kubectl logs <pod-name> -n <namespace> --previous

# 持续输出日志
kubectl logs <pod-name> -n <namespace> -f

# 指定行数
kubectl logs <pod-name> -n <namespace> --tail=<line-number>