Container send/receive

osctld has support for moving and cloning containers between different vpsAdminOS nodes with SSH used as a transport channel. Each vpsAdminOS node has a system user called osctl-ct-receive. The source node is connecting to the osctl-ct-receive user on the destination node. Authentication is based on public/private keys.

Setup

On the source node, a public/private key pair is needed. It can be generated by osctl send key gen, or the keys can be manually installed to paths given by osctl send key path public and osctl send key path private.

source-node $ osctl send key gen -t ecdsa

source-node $ osctl send key path public
/tank/conf/send-receive/key.pub

source-node $ cat /tank/conf/send-receive/key.pub
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYT... root@source-node

Through another communication channel, picked at your discretion, the public key of the source node must be transfered to the destination node and authorized to send containers to that node. Once transfered, the key can be authorized using osctl receive authorized-keys add, the key is entered on a single line to the standard input:

destination-node $ osctl receive authorized-keys add
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYT... root@source-node

Now the source node is authorized to send containers to the destination node. You can verify that by running SSH directly:

source-node $ ssh -T -i `osctl send key path private` -l osctl-ct-receive destination-node
Usage:
  receive skel [pool]
  receive base [pool:]<id> <dataset> [snapshot]
  receive incremental [pool:]<id> <dataset> [snapshot]
  receive transfer [pool:]<id> [start]
  receive cancel [pool:]<id>

As you can see, the SSH connection is limited to several commands that are handled by osctld. The meaning of those commands will become clearer once you read the section below, but it's enough to know the shell is restricted for container send/receive only.

Moving containers

The container move itself consists of several steps:

  • osctl ct send config is used to prepare environment on the destination node and copy configuration
  • osctl ct send rootfs sends over the container's rootfs
  • osctl ct send sync optionally synchronizes the source and destination rootfs
  • osctl ct send state stops the container on the source node, performs another rootfs sync and finally starts the container on the destination node
  • osctl ct send cleanup is used to remove the container from the source node

Up until osctl ct send state, the send can be cancelled using osctl ct send cancel, which resets the container's send state on the source node and removes the partially transfered container from the destination node.

osctl ct send will perform all necessary steps in succession. Use this when you don't care when is a particular send step run. Otherwise, you can choose when to run specific send steps to optimize for minimum downtime at reasonable hours. Consider the following example:

# 1) Prepare the send
source-node $ osctl ct send config myct01 destination-node

# 2) Make an initial copy the container's rootfs, this will be the most
#    time-consuming operation
source-node $ osctl ct send rootfs myct01

# 3) Regularly synchronize rootfs while waiting for optimal time to transfer the
#    container, which will cause a downtime depending on how much data has changed
#    since `osctl ct send rootfs` or the last `osctl ct send sync`
source-node $ osctl ct send sync myct01

# 4) When the downtime will be least unwelcome, finally transfer the container
source-node $ osctl ct send state myct01

# 5) Cleanup is executed only on the source node, the destination node is already
#    finished
source-node $ osctl ct send cleanup myct01

Cloning containers

osctl ct send by defaults moves containers from one node to another, but it can be used to clone containers to remote nodes as well. Cloning works in the same way as moving, except that osctl ct send state will not keep the source container down and osctl ct send cleanup will not remove it.

Use option --clone to make a clone instead of moving the container:

osctl ct send --clone myct01 destination-node
# or in steps
osctl ct send config myct01 destination-node
osctl ct send rootfs myct01
osctl ct send state --clone myct01
osctl ct send cleanup myct01

There are several useful options when cloning containers (although they can be used when moving containers as well):

  • --no-start to keep the moved/cloned container on the target node stopped
  • --no-restart to keep the moved/cloned container on the source node stopped
  • --no-network-interfaces to remove network interfaces from the container's config