如何通过Curl POST请求在Kubernetes中获取Shell?
问题分析与解决方案
我来帮你拆解下这个问题:你用kubectl run加--overrides能顺利拿到节点的交互式Shell,但换成curl直接调用K8s API创建Pod时,不仅Pod可能卡在Pending状态,还没法建立Shell会话。这主要和K8s交互式会话的实现机制以及API请求的完整性有关,下面给你一步步解决的方法:
为什么kubectl run能成功?
kubectl run不只是帮你提交了Pod配置,还做了两件关键的事:
- 它自动处理了交互式会话的后续连接:创建Pod后,立即通过K8s的
exec接口和容器建立TTY会话; - 虽然你在
--overrides里已经定义了stdin、stdinOnce、tty为true,但kubectl还会自动补充一些和会话相关的隐式配置,比如确保Pod的restartPolicy正确设置。
而curl只是单纯发送了Pod创建的POST请求,既不会处理后续的会话连接,也不会帮你补全可能缺失的配置字段,这就是问题的核心。
第一步:先解决Pod Pending的问题
先检查你的api.json配置,确保和kubectl run使用的overrides完全一致,尤其是要加上restartPolicy: Never(和kubectl run的--restart=Never对应),完整的api.json应该是这样:
{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "admin-shell" }, "spec": { "containers": [ { "name": "admin-shell", "securityContext": { "privileged": true }, "image": "alpine:latest", "args": ["chroot", "/kdet", "/bin/bash"], "stdin": true, "stdinOnce": true, "tty": true, "volumeMounts": [{ "name": "kdet", "mountPath": "/kdet" }] } ], "volumes": [{ "name": "kdet", "hostPath": { "path": "/", "type": "Directory" } }], "restartPolicy": "Never" } }
重新用curl提交这个配置,Pod应该能正常进入Running状态了。
第二步:通过K8s Exec API建立交互式Shell
curl本身不支持持续的TTY交互,所以我们需要用K8s的execAPI配合WebSocket工具(比如wscat)来建立会话,步骤如下:
1. 构造WebSocket连接URL
先确认Pod已经处于Running状态,然后构造exec接口的WebSocket地址:
WS_URL="$APISERVER/api/v1/namespaces/default/pods/admin-shell/exec?command=/bin/bash&stdin=true&stdout=true&stderr=true&tty=true"
把$APISERVER替换成你的K8s API服务器地址。
2. 用wscat连接WebSocket会话
安装wscat(如果没装的话,用npm install -g wscat),然后执行:
wscat --insecure --header "Authorization: Bearer $TOKEN" $WS_URL
--insecure是忽略自签名证书的检查(如果你的API服务器用的是正式证书可以去掉);- 连接成功后,你就能获得和
kubectl run一样的交互式Shell了,退出后Pod会自动删除(因为restartPolicy: Never)。
替代方案:用kubectl attach配合curl创建的Pod
如果你的环境允许使用kubectl,也可以先创建Pod,再用kubectl attach连接:
# 1. 创建Pod curl -k $APISERVER/api/v1/namespaces/default/pods \ -XPOST -H 'Content-Type: application/json' \ -d@api.json \ --header "Authorization: Bearer $TOKEN" # 2. 等待Pod进入Running状态 until curl -k --header "Authorization: Bearer $TOKEN" $APISERVER/api/v1/namespaces/default/pods/admin-shell | grep -q '"phase": "Running"'; do sleep 1; done # 3. 建立交互式会话 kubectl attach admin-shell -ti
关键注意事项
- 权限检查:你的
$TOKEN必须拥有pods/create和pods/exec的RBAC权限,否则会被API服务器拒绝; - TTY配置:必须确保Pod容器的
stdin: true、stdinOnce: true、tty: true这三个字段都正确设置,否则无法建立交互式会话; - WebSocket支持:如果你的环境无法使用
wscat,也可以用socat或者其他支持WebSocket的工具替代。
内容的提问来源于stack exchange,提问作者vasant kumar chinnipilli




