Accessing the serial console of your Nova servers
One of the new features available in the Juno release of OpenStack is support for serial console access to your Nova servers. This post looks into how to configure the serial console feature and then how to access the serial consoles of your Nova servers.
Configuring serial console support⌗
In previous release of OpenStack, read-only access to the serial
console of your servers was available through the
os-getConsoleOutput
server action (exposed via nova console-log
on
the command line). Most cloud-specific Linux images are configured
with a command line that includes something like console=tty0 console=ttyS0,115200n81
, which ensures that kernel output and other
messages are available on the serial console. This is a useful
mechanism for diagnosing problems in the event that you do not have
network access to a server.
In Juno, you can exchange this read-only view of the console for
read-write access by setting enabled=true
in the [serial_console]
section of your nova.conf
file:
[serial_console]
enabled=true
This enables the new os-getSerialConsole
server action.
Much like the configuration for graphical console access, you will also
probably need to provide values for base_url
, listen
, and
proxyclient_address
:
[serial_console]
enabled=true
# Location of serial console proxy. (string value)
base_url=ws://127.0.0.1:6083/
# IP address on which instance serial console should listen
# (string value)
listen=127.0.0.1
# The address to which proxy clients (like nova-serialproxy)
# should connect (string value)
proxyclient_address=127.0.0.1
The base_url
setting is what gets passed to clients, so this will
probably be the address of one of your “front-end” controllers (e.g.,
wherever you are running other public APIs or services like Horizon).
The listen
address is used by nova-compute
to control on which
address the virtual console will listen (this can be set to 0.0.0.0
to listen on all available addresses). The proxyclient_address
controls to which address the nova-serialproxy
service will connect.
In other words: a remote client request a serial console will receive
a websocket URL prefixed by base_url
. This URL will connect the
client to the nova-serialproxy
service. The nova-serialproxy
service will look up the proxyclient_address
associated with the
requested server, and will connect to the appropriate port at that
address.
Enabling serial console support will result in an entry similar to the following in the XML description of libvirt guests started by Nova:
<console type='tcp'>
<source mode='bind' host='127.0.0.1' service='10000'/>
<protocol type='raw'/>
<target type='serial' port='0'/>
<alias name='serial0'/>
</console>
Accessing the serial console⌗
You can use the nova get-serial-proxy
command to retrieve the
websocket URL for a server’s serial console, like this:
$ nova get-serial-console my-server
+--------+-----------------------------------------------------------------+
| Type | Url |
+--------+-----------------------------------------------------------------+
| serial | ws://127.0.0.1:6083/?token=18510769-71ad-4e5a-8348-4218b5613b3d |
+--------+-----------------------------------------------------------------+
Or through the REST API like this:
curl -i 'http://127.0.0.1:8774/v2/<tenant_uuid>/servers/<server_uuid>/action' \
-X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Auth-Project-Id: <project_id>" \
-H "X-Auth-Token: <auth_token>" \
-d '{"os-getSerialConsole": {"type": "serial"}}'
But now that you have a websocket URL, what do you do with it? It turns out that there aren’t all that many out-of-the-box tools that will let you connect interactively to this URL from the command line. While I’m sure that a future version of Horizon will provide a web-accessible console access mechanism, it is often convenient to have a command-line tool for this sort of thing because that permits you to log or otherwise process the output.
Fortunately, it’s not too difficult to write a simple client. The
Python websocket-client
module has the necessary support; given the
above URL, you can open a connection like this:
import websocket
ws = websocket.create_connection(
'ws://127.0.0.1:6083/?token=18510769-71ad-4e5a-8348-4218b5613b3d',
subprotocols=['binary', 'base64'])
This gets you a WebSocket
object with .send
and .recv
methods
for sending and receiving data (and a .fileno
method for use in
event loops).
I was told there would be no programming⌗
If you don’t feel like writing your own websocket client, have no fear! I have put together a simple client called novaconsole. Assuming that you have valid credentials in your environment, you can provide it with a server name or UUID:
$ novaconsole my-server
You can also provide a verbatim websocket URL (in which case you don’t need to bother with OpenStack authentication):
$ novaconsole --url ws://127.0.0.1:6083/?token=18510769-71ad-4e5a-8348-4218b5613b3d
In either case, you will have an interactive session to the specified
serial console. You can exit the session by typing ~.
at the
beginning of a line.
You can only have a single active console connection at a time. Other connections will block until you disconnect from the active session.
But everything is not roses and sunshine⌗
One disadvantage to the serial console support is that it replaces
the console log available via nova console-log
. This means that if,
for example, a server were to encounter problems configuring
networking and emit errors on the console, you would not be able to
see this information unless you happened to be connected to the
console at the time the errors were generated.
It would be nice to have both mechanisms available – serial console support for interactive access, and console logs for retroactive debugging.