You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过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里已经定义了stdinstdinOncettytrue,但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/createpods/exec的RBAC权限,否则会被API服务器拒绝;
  • TTY配置:必须确保Pod容器的stdin: truestdinOnce: truetty: true这三个字段都正确设置,否则无法建立交互式会话;
  • WebSocket支持:如果你的环境无法使用wscat,也可以用socat或者其他支持WebSocket的工具替代。

内容的提问来源于stack exchange,提问作者vasant kumar chinnipilli

火山引擎 最新活动