什么是 kubectl --raw?
kubectl --raw 是一个强大的底层工具,允许你直接访问 Kubernetes API Server 的 REST API,绕过 kubectl 的客户端逻辑、准入控制器(Admission Controllers)和 Webhook。
为什么需要 --raw?
标准 kubectl 的请求流程
kubectl 命令
↓
客户端验证和处理
↓
Admission Controllers
↓
Mutating Webhooks (修改请求)
↓
Validating Webhooks (验证请求)
↓
API Server 存储到 etcdkubectl --raw 的请求流程
kubectl --raw
↓
直接 HTTP 请求到 API Server
↓
绕过大部分中间件
↓
直接操作 etcd适用场景
- 绕过 Webhook 干扰 - 当 Mutating/Validating Webhook 阻止正常操作时
- 调试 API Server - 排查 kubectl 客户端与 API Server 的交互问题
- 访问特殊端点 - 访问 metrics、healthz 等非资源端点
- 绕过客户端限制 - kubectl 版本不支持某些新特性时
- 性能测试 - 直接测试 API Server 响应时间
- 修复僵尸资源 - 清理被控制器锁定的资源状态
基本语法
# 基本格式
kubectl get --raw <API-PATH>
# 或在某些版本中
kubectl --raw <API-PATH>常用操作示例
1. GET 请求 - 查询资源
查看集群级别资源
# 获取所有节点
kubectl get --raw /api/v1/nodes | jq .
# 获取特定节点
kubectl get --raw /api/v1/nodes/node-name | jq .
# 获取节点状态
kubectl get --raw /api/v1/nodes/node-name/status | jq .
# 获取所有命名空间
kubectl get --raw /api/v1/namespaces | jq .查看命名空间级别资源
# 获取 default 命名空间的所有 Pod
kubectl get --raw /api/v1/namespaces/default/pods | jq .
# 获取特定 Pod
kubectl get --raw /api/v1/namespaces/default/pods/pod-name | jq .
# 获取 Deployment
kubectl get --raw /apis/apps/v1/namespaces/default/deployments/deploy-name | jq .
# 获取 Service
kubectl get --raw /api/v1/namespaces/default/services/svc-name | jq .查看子资源
# Pod 日志
kubectl get --raw /api/v1/namespaces/default/pods/pod-name/log
# Pod 状态
kubectl get --raw /api/v1/namespaces/default/pods/pod-name/status | jq .
# Service 的 Endpoint
kubectl get --raw /api/v1/namespaces/default/endpoints/service-name | jq .2. PUT 请求 - 完整更新资源
# 更新节点(先获取,修改,再替换)
kubectl get --raw /api/v1/nodes/node-name > node.json
# 编辑 node.json 文件
vim node.json
# 替换(注意:不同版本语法可能不同)
kubectl replace --raw /api/v1/nodes/node-name -f node.json
# 或使用 kubectl proxy 方式
kubectl proxy --port=8001 &
curl -X PUT \
-H "Content-Type: application/json" \
-d @node.json \
http://localhost:8001/api/v1/nodes/node-name实战案例:清除节点僵尸条件
# 获取节点当前状态
kubectl get --raw /api/v1/nodes/node-name > /tmp/node.json
# 使用 jq 删除特定条件
jq 'del(.status.conditions[] | select(.type == "EtcdIsVoter"))' \
/tmp/node.json > /tmp/node-fixed.json
# 更新节点状态
kubectl replace --raw /api/v1/nodes/node-name/status -f /tmp/node-fixed.json3. POST 请求 - 创建资源
# 创建 Pod
cat > pod.json <<EOF
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "test-pod",
"namespace": "default"
},
"spec": {
"containers": [{
"name": "nginx",
"image": "nginx:latest"
}]
}
}
EOF
kubectl create --raw /api/v1/namespaces/default/pods -f pod.json4. DELETE 请求 - 删除资源
# 删除 Pod
kubectl delete --raw /api/v1/namespaces/default/pods/pod-name
# 使用 kubectl proxy 方式
kubectl proxy --port=8001 &
curl -X DELETE http://localhost:8001/api/v1/namespaces/default/pods/pod-name5. PATCH 请求 - 部分更新
# JSON Patch (精确的操作指令)
kubectl patch --raw /api/v1/nodes/node-name \
--type='json' \
-p='[
{"op": "add", "path": "/metadata/labels/new-label", "value": "new-value"},
{"op": "remove", "path": "/status/conditions/0"}
]'
# Strategic Merge Patch (合并式更新)
kubectl patch --raw /api/v1/nodes/node-name \
--type='merge' \
-p '{
"metadata": {
"labels": {
"environment": "production"
}
}
}'
# Merge Patch (简单合并)
kubectl patch --raw /api/v1/nodes/node-name \
--type='merge' \
-p '{"spec":{"unschedulable":true}}'API 路径规则
核心 API 组 (Core API Group)
# 格式
/api/v1/<resource-type> # 集群级别
/api/v1/namespaces/<namespace>/<resource-type> # 命名空间级别
# 示例
/api/v1/nodes
/api/v1/nodes/node-name
/api/v1/nodes/node-name/status
/api/v1/namespaces/default/pods
/api/v1/namespaces/default/pods/pod-name
/api/v1/namespaces/default/services命名 API 组 (Named API Groups)
# 格式
/apis/<group>/<version>/<resource-type>
/apis/<group>/<version>/namespaces/<ns>/<resource-type>
# 常用 API 组示例
/apis/apps/v1/deployments # Deployment
/apis/apps/v1/namespaces/default/deployments
/apis/batch/v1/cronjobs # CronJob
/apis/networking.k8s.io/v1/ingresses # Ingress
/apis/rbac.authorization.k8s.io/v1/clusterroles # ClusterRole
/apis/storage.k8s.io/v1/storageclasses # StorageClass子资源 (Subresources)
# 状态子资源
/api/v1/nodes/<name>/status
/apis/apps/v1/namespaces/<ns>/deployments/<name>/status
# 日志
/api/v1/namespaces/<ns>/pods/<name>/log
/api/v1/namespaces/<ns>/pods/<name>/log?container=container-name
# 执行命令
/api/v1/namespaces/<ns>/pods/<name>/exec
# 端口转发
/api/v1/namespaces/<ns>/pods/<name>/portforward
# 代理
/api/v1/nodes/<name>/proxy
/api/v1/namespaces/<ns>/pods/<name>/proxy
/api/v1/namespaces/<ns>/services/<name>/proxy特殊端点
查看 API 资源
# 列出所有 API 版本
kubectl get --raw /apis | jq '.groups[].name'
# 查看特定 API 组
kubectl get --raw /apis/apps/v1 | jq .
# 列出所有可用资源
kubectl get --raw /api/v1 | jq '.resources[].name'
# OpenAPI 规范
kubectl get --raw /openapi/v2 | jq . > openapi.json集群信息
# 版本信息
kubectl get --raw /version | jq .
# 健康检查
kubectl get --raw /healthz
kubectl get --raw /livez
kubectl get --raw /readyz
# API Server 标志
kubectl get --raw /debug/flags/v
# Metrics
kubectl get --raw /metrics认证和授权
# 检查当前用户权限
kubectl get --raw /apis/authorization.k8s.io/v1/selfsubjectaccessreviews \
-X POST \
-d '{
"apiVersion": "authorization.k8s.io/v1",
"kind": "SelfSubjectAccessReview",
"spec": {
"resourceAttributes": {
"namespace": "default",
"verb": "get",
"resource": "pods"
}
}
}'使用 kubectl proxy 的方式
当 kubectl --raw 不可用或语法复杂时,可以使用 proxy 方式:
# 启动代理
kubectl proxy --port=8001 &
# 使用 curl 访问
curl http://localhost:8001/api/v1/nodes | jq .
# GET 请求
curl http://localhost:8001/api/v1/namespaces/default/pods
# POST 请求
curl -X POST \
-H "Content-Type: application/json" \
-d @pod.json \
http://localhost:8001/api/v1/namespaces/default/pods
# PUT 请求
curl -X PUT \
-H "Content-Type: application/json" \
-d @node.json \
http://localhost:8001/api/v1/nodes/node-name/status
# DELETE 请求
curl -X DELETE \
http://localhost:8001/api/v1/namespaces/default/pods/pod-name
# 停止代理
pkill -f "kubectl proxy"实战案例
案例 1: 绕过 Webhook 修改节点标签
# 问题:Mutating Webhook 拦截标签修改
# 解决:直接通过 API 修改
# 1. 获取节点
kubectl get --raw /api/v1/nodes/node-name > node.json
# 2. 使用 jq 添加标签
jq '.metadata.labels["custom-label"] = "custom-value"' node.json > node-updated.json
# 3. 替换节点
kubectl replace --raw /api/v1/nodes/node-name -f node-updated.json案例 2: 清理僵尸 Finalizer
# 问题:资源因 finalizer 无法删除
# 解决:直接清空 finalizers
# 1. 获取资源
kubectl get --raw /api/v1/namespaces/stuck-namespace > ns.json
# 2. 清空 finalizers
jq '.spec.finalizers = []' ns.json > ns-clean.json
# 3. 更新
kubectl replace --raw /api/v1/namespaces/stuck-namespace/finalize -f ns-clean.json案例 3: 批量查询资源状态
#!/bin/bash
# 批量检查节点状态
for node in $(kubectl get nodes -o name | cut -d/ -f2); do
echo "=== Node: $node ==="
kubectl get --raw /api/v1/nodes/$node/status | \
jq -r '.status.conditions[] | select(.type=="Ready") |
"Status: \(.status), Reason: \(.reason)"'
done案例 4: 性能测试
#!/bin/bash
# 测试 API Server 响应时间
echo "Testing API Server performance..."
for i in {1..10}; do
time kubectl get --raw /api/v1/nodes > /dev/null 2>&1
done案例 5: 导出所有资源
#!/bin/bash
# 导出命名空间的所有资源
NAMESPACE="default"
OUTPUT_DIR="./k8s-backup"
mkdir -p $OUTPUT_DIR
# 导出 Pods
kubectl get --raw /api/v1/namespaces/$NAMESPACE/pods | \
jq . > $OUTPUT_DIR/pods.json
# 导出 Services
kubectl get --raw /api/v1/namespaces/$NAMESPACE/services | \
jq . > $OUTPUT_DIR/services.json
# 导出 Deployments
kubectl get --raw /apis/apps/v1/namespaces/$NAMESPACE/deployments | \
jq . > $OUTPUT_DIR/deployments.json
echo "Backup completed in $OUTPUT_DIR"注意事项
1. 权限要求
# 需要相应的 RBAC 权限
# 检查权限
kubectl auth can-i get nodes
kubectl auth can-i update nodes2. resourceVersion 冲突
# 更新时可能遇到冲突
# Error: the object has been modified; please apply your changes to the latest version
# 解决:重新获取最新版本
kubectl get --raw /api/v1/nodes/node-name > node-latest.json
# 重新修改并更新3. 数据格式验证
# 使用 jq 验证 JSON 格式
cat resource.json | jq . > /dev/null
# 如果有错误会提示4. 备份重要资源
# 在修改前务必备份
kubectl get --raw /api/v1/nodes/node-name > node-backup-$(date +%Y%m%d).json5. 只读操作优先
# 先用 GET 查看,确认无误后再 PUT/PATCH
kubectl get --raw /api/v1/nodes/node-name | jq .版本兼容性
Kubernetes 1.18+
kubectl get --raw /api/v1/nodes
kubectl create --raw /api/v1/namespaces/default/pods -f pod.json
kubectl replace --raw /api/v1/nodes/node-name -f node.json
kubectl patch --raw /api/v1/nodes/node-name --type=merge -p '{...}'
kubectl delete --raw /api/v1/namespaces/default/pods/pod-name早期版本或不支持时
# 使用 kubectl proxy
kubectl proxy --port=8001 &
curl http://localhost:8001/api/v1/nodes调试技巧
1. 查看完整请求
# 增加日志级别
kubectl get --raw /api/v1/nodes -v=82. 使用 jq 过滤输出
# 只查看节点名称
kubectl get --raw /api/v1/nodes | jq '.items[].metadata.name'
# 查看 Pod 状态
kubectl get --raw /api/v1/namespaces/default/pods | \
jq '.items[] | {name: .metadata.name, status: .status.phase}'3. 格式化时间戳
# 转换时间格式
kubectl get --raw /api/v1/nodes/node-name | \
jq '.metadata.creationTimestamp | fromdate | strftime("%Y-%m-%d %H:%M:%S")'总结
kubectl --raw 是 Kubernetes 的"瑞士军刀",提供了:
✅ 直接访问 API - 绕过客户端限制
✅ 调试工具 - 排查 kubectl 和 API Server 问题
✅ 应急修复 - 处理 Webhook 和控制器导致的问题
✅ 性能测试 - 直接测试 API Server
✅ 学习工具 - 理解 Kubernetes API 结构
⚠️ 使用场景: 作为最后的调试和修复手段
⚠️ 不推荐: 日常操作应使用标准 kubectl 命令
⚠️ 需谨慎: 直接操作可能破坏资源状态