Kubernetes Pod无法响应发送到其“ exec” websocket的消息

时间:2018-07-11 19:12:29

标签: node.js express websocket kubernetes

我们目前正在开发一个通过Kubernetes管理服务的平台。作为其中的一部分,我们希望添加功能,以允许客户端(通过我们的UI)针对Pod发出Shell命令(使用两者之间的WebSocket)。我们正在尝试利用Kubernetes /exec API端点来打开到Pod的连接。问题是,虽然套接字的初始设置看起来工作良好,但从UI向容器发出后续命令却无法从容器中获得任何响应-就像容器未收到消息一样。 / p>

我们目前有一个Node.js Express REST服务,作为UI和Kubernetes之间的中间人。 REST服务负责管理两个Web套接字-一个从UI到服务,另一个从服务到Kubernetes。该服务负责在发生交互时通过一个套接字向另一个套接字发送消息。

当UI需要将shell命令发送到Pod时,它通过调用REST服务来启动打开套接字的过程,然后通过以下Kubernetes API调用来打开Pod的套接字

  

/ api / v1 /命名空间/命名空间-xxxxxx / pods / hello-world-xxxxxxxx / exec?stdin = true&stderr = true&stdout = true&tty = true&command = sh

而Express管理从REST服务到UI的套接字。

REST服务具有一个“管道”功能,该功能具有每个套接字的句柄,并在必要时在两个套接字之间传递数据(为简便起见,删除了调试语句):

    const pipe = (podSocket, clientSocket) => {

        podSocket.onopen = function (event) {
            debug(`podSocket.onopen(event): opened websocket connection at ${new Date()}.  Event is ${circularJson.stringify(event)}`);
        };

        podSocket.onmessage = function (event) {
            if (clientSocket.readyState === 1) {
                const text = Buffer.from(event.data, 'binary').toString('utf-8');
                clientSocket.send(text);
            }
        };

        podSocket.onerror = function (err) {
            clientSocket.close(1000);
            podSocket.close();
        };

        podSocket.onclose = function (event) {
            debug(`podSocket.onclose(): instance closed connection at ${new Date()} with code ${event.code}, reason [${event.reason}]`);
        };

        clientSocket.onmessage = function (event) {
            const text = Buffer.from(event.data, 'binary').toString('utf-8');
            if (clientSocket.readyState === 1) {
                if (podSocket.readyState === 3)
                    clientSocket.send(`Connection to instance has been closed`);
                else {
                    podSocket.send(text);   // <----------- Issue seems to be here
                }
            }
        };

        clientSocket.onerror = function (err) {
            clientSocket.close(1000);
            podSocket.close(1000);
        };

        clientSocket.onclose = function (event) {
            debug(`clientSocket.onclose(): instance closed connection at ${new Date()} with code ${event.code}, reason [${event.reason}]`);
            podSocket.close(1000);
        };

    };

如上所示,当REST服务检测到已从客户端接收到一条消息(shell命令)时,它将尝试将该消息转发到打开到容器的套接字。但是我们无法从Pod在其套接字的onmessage()回调中获得任何响应。

上面未出现的部分调试语句确实表明REST服务正在接收要执行的命令,并且该命令正在通过另一个套接字发送到Pod。我还进行了调试,显示当两个套接字都打开时,两个套接字都显示为“就绪”状态。

这是我们看到的一小段内容:

enter image description here

/app #是Pod的默认目录,它是websocket初始设置的响应,因此我们知道初始连接是正确的。但是,随后的两个命令完全没有响应,直到套接字超时并且连接被关闭。

我们在这里缺少什么?为什么我们无法将套接字绑定到Pod以响应发送给它的消息?

0 个答案:

没有答案