Accessing a task through SSH

Secure Shell (SSH) keys are a pair of cryptographic keys used to authenticate a user on remote systems securely. They enhance security by eliminating the need for password-based logins, making unauthorized access more challenging. This tutorial will guide you through the process of creating and using SSH keys on both Windows and Linux systems, with a focus on using PuTTY for Windows users.

Using it on Qarnot can enable you to log in a running instance and use it as a worker.

Prerequisites

Before we begin, ensure you have the following:

Generating SSH Keys

Generating SSH Keys on Linux

Open the Terminal

Generate the SSH Key Pair: Type the following command and press Enter:

Generating SSH Keys on Windows Using PuTTY

Install PuTTY and PuTTYgen:

Open PuTTYgen:

Configure Key Parameters:

Generate SSH Key

Generate the Key:

Move your mouth to generate enthropy

Save the Keys:

Set a Passphrase:

Get SSH Key

Connecting to your Cluster

After generating your SSH keys, you can connect to your cloud HPC cluster to manage your simulation.

Using a simulation software (Ansys Fluent, Star-CCM+...) profile

During the simulation set up

Screenshot From 2025 03 10 12 31 30

Get the SSH Command:

Screenshot From 2025 03 10 14 13 53

Execute the SSH Command:

Using a Docker Profile

In addition to using docker-network-ssh profile, you must:

Here is a basic example. The following script will print the ssh command that you should run to connect to the instance. You can also run it automatically into a sub-process.

Python

#!/usr/bin/env python

import qarnot

conn = qarnot.Connection(client_token = '<<<MY_SECRET_TOKEN>>>')
task = conn.create_task('ssh-example', 'docker-network-ssh')

task.constants['DOCKER_SSH'] = '<<<MY_SSH_PUBLIC_KEY>>>'

task.constants['DOCKER_CMD'] = "/bin/bash -c 'mkdir -p ~/.ssh /run/sshd ;" \
                               "echo \"${DOCKER_SSH}\" >> ~/.ssh/authorized_keys ;" \
                               "/usr/sbin/sshd -D'"
task.submit()

last_state = ''
ssh_tunneling_done = False
while not ssh_tunneling_done:
    if task.state != last_state:
        last_state = task.state
        print("** {}".format(last_state))

    # Wait for the task to be FullyExecuting
    if task.state == 'FullyExecuting':
        # If the ssh connexion was not done yet and the list active_forward is available (len!=0)
        forward_list = task.status.running_instances_info.per_running_instance_info[0].active_forward
        if not ssh_tunneling_done and len(forward_list) != 0:
            ssh_forward_port = forward_list[0].forwarder_port
            ssh_forward_host = forward_list[0].forwarder_host
            cmd = f"ssh -o StrictHostKeyChecking=no root@{ssh_forward_host} -p {ssh_forward_port}"
            print(cmd)
            ssh_tunneling_done = True

    # Display errors on failure
    if task.state == 'Failure':
        print("** Errors: %s" % task.errors[0])
        ssh_tunneling_done = True

Bash

#Note that you have to install the jq JSON processor package installed in order to run the script.

export QARNOT_CLIENT_TOKEN = "<<<QARNOT_CLIENT_TOKEN>>>"

TASK_UUID=$(./qarnot task create \
  --profile docker-network-ssh \
  --name "Hello World - CLI" \
  --instance 1 \
  --constants DOCKER_SSH='YOUR_SSH_KEY' \
  --constants DOCKER_CMD="/bin/bash -c 'mkdir -p ~/.ssh /run/sshd ; echo ${DOCKER_SSH} >> ~/.ssh/authorized_keys ;/usr/sbin/sshd -D'" \
  --format JSON | tee /dev/tty | jq -r '.Task')

LAST_STATE=$(qarnot task info --id "$TASK_UUID" | jq -r .[].State)
SSH_TUNNELING_DONE='False'

while [ "$SSH_TUNNELING_DONE" != "True" ]
do
	NEW_STATE=$(qarnot task info --id "$TASK_UUID" | jq -r .[].State)
	sleep 15
    
    if [ "$NEW_STATE" != "$LAST_STATE" ]
        then
        echo "Task state: $NEW_STATE"
        LAST_STATE="$NEW_STATE"
        sleep 120
	fi
     # Wait for the task to be FullyExecuting
    if [ "$NEW_STATE" == "FullyExecuting" ]
        then
        # If the ssh connexion was not done yet and the list active_forward is available (len!=0)
		sleep 10
		FORWARD_LIST=$(qarnot task info --id "$TASK_UUID" | qarnot task info --id "$TASK_UUID" | jq '.[].Status.RunningInstancesInfo.PerRunningInstanceInfo | .[].ActiveForwards')

		if [ "$SSH_TUNNELING_DONE" != "True" ] && [ "$FORWARD_LIST" != "[]" ]
        then
            	ssh_forward_port=$(qarnot task info --id "$TASK_UUID" | jq '.[].Status.RunningInstancesInfo.PerRunningInstanceInfo | .[].ActiveForwards | .[].ForwarderPort')
            	ssh_forward_host=$(qarnot task info --id "$TASK_UUID" | jq '.[].Status.RunningInstancesInfo.PerRunningInstanceInfo | .[].ActiveForwards | .[].ForwarderHost')
            	CMD="ssh -o StrictHostKeyChecking=no root@$ssh_forward_host -p $ssh_forward_port"

	            echo $CMD

	            SSH_TUNNELING_DONE="True"
		fi
	fi

    # Display errors on failure
	if [ "$NEW_STATE" == "Failure" ]
    then
        echo "** Errors **"
        SSH_TUNNELING_DONE='True'
	fi 
done

Don't forget to delete the instance when you are done. Otherwise, you will be invoiced for time that you did not spend on computing. To do so, use Tasq or the SDK functions task.abort or task.delete

Bringing your own image

If you want to use your own image, make sure to install the openssh-server package and to create the /run/sshd folder.

In addition, if you want to ssh as a user that is not root make sure that the ~/.ssh folder is owned by the user, that its private key is not readable by other users (rights should be 600) and that the user's password is set (otherwise ssh won't allow you to connect because it will consider the user incompletely set).

Accessing a specific port

If you need to communicate with your worker through a specific port instead of just using ssh, you will need to create a tunnel between the instance's port and yours.

For example, if you are using a Qarnot instance as a runner for a jupyter notebook, you will need to access to the worker's port 8888 in your browser. To do that, you simply need to create a tunnel so that your port 8888 is redirected to the worker's one. The following schema shows the appropriate ssh command: