Kubernetes Websockets API pod exec node.js client send method

12/12/2017

I'm having a very hard time sending commands to an interactive bash shell using a node.js websockets client. I'm running a cluster with kops and I'm able to establish the connection with a pod and get its prompt but I am unable to send commands and receive a response.

So my connection looks like:

const WebSocket = require('ws');
const fs = require('fs');
const readline = require('readline');
const unescape = require('querystring').unescape;
const escape = require('querystring').escape;

const channel = '0';
const access_token = "[the_api_token]";
const pod_name = 'nginx-726417742-s1nv2';
const host_address = 'wss://[the_api_url]';
const cmd = `${escape('/bin/bash')}&command=-i`;
const params = `stdout=1&stdin=1&stderr=1&tty=1&container=nginx&command=${cmd}`;
const url = `${host_address}/api/v1/namespaces/default/pods/${pod_name}/exec?${params}`;
const options = {
  headers: {
    'Authorization': `Bearer ${access_token}`
  },
  ca: fs.readFileSync('ca.crt'),
}
const ws = new WebSocket(url, options);
ws.on('open', () => {
  console.log('connected');
});
ws.on('message', (data, flags) => {
  process.stdout.write(data);
});
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
rl.on('line', function (cmd) {
  const data = channel + cmd;
  if (ws && ws.readyState === 1) {
    ws.send(data);
  }
});

The ws.on('message', (data, flags) part prints the shell prompt perfectly root@nginx-726417742-s1nv2:/# but then I can type whatever and it goes trough ws.send(data) but no message is ever received and no error is generated. I have already tried to convert the data to base64 and send char by char instead of the whole line, but the result and behaviour is always the same.

If I proxy the API through kubectl proxy --disable-filter=true --port=8080 and use https://github.com/kubernetes-ui/container-terminal pointing to ws://localhost:8080 and using /api/v1/namespaces/default/pods/${pod_name}/exec I can get a working terminal, but local proxying is not an option for me.

Any help will be much appreciated.

-- Marcelo Melo
kubernetes
node.js
websocket

0 Answers