Provision a host
This guide gets a host ready for production use of tslink, on its own or as a Swarm node. Most of it is a checklist you do once per host, ideally in your configuration management.
What the host needs
tslink was tested on amd64 cloud VMs with Ubuntu 24.04 (kernel 6.8) and Docker 29.8 in Swarm mode. A host has to meet these requirements:
- Docker Engine, with iptables on nftables (the default on current distributions). The plugin image uses
iptables-nft. iptables --versionshowsnf_tables- A kernel with
tun,vethand nftables modinfo tun veth nf_tables- A synchronized clock: Tailscale rejects clocks that are far off
timedatectl show -p NTPSynchronizedshowsyes- Outbound TCP to port 443, for the control server and DERP
- Your firewall rules
- Outbound UDP, for STUN on port 3478 and for direct connections on any port
- Your firewall rules
- Containers can reach a DNS server
- See DNS
The host needs no inbound firewall rule, no Tailscale package and no access to pkgs.tailscale.com. If it runs a
tailscaled of its own, containers don’t use it. Without outbound UDP, traffic falls back to DERP relays, which is much
slower: see throughput.
Containers on hosts that share a network connect to each other directly over it. Containers that reach each other
only over public addresses also need inbound UDP on TSLINK_WIREGUARD_PORTS allowed by any firewall in front of the
host.
The drain drop-in and the preflight check below need a clone of the tslink repository, at the tag of the release you install.
Set it up
-
Match Docker’s MTU to the network. If the host network’s MTU is below 1500, as it often is on cloud providers’ private networks and on VPN or VXLAN underlays, set it in
/etc/docker/daemon.json:{ "mtu": 1450 }Restart Docker to apply it:
systemctl restart dockerThen create each tslink network with the same value:
--opt com.docker.network.driver.mtu=1450. -
Turn on UDP GRO forwarding on the host’s uplink. Without it, a container’s tailnet throughput was less than half of the host’s in our measurements: 1.2 against 2.8 Gbit/s. Make the setting persistent, for example with this systemd unit in
/etc/systemd/system/tslink-gro.service:[Unit] Description=Enable UDP GRO forwarding for tslink After=network-online.target Wants=network-online.target [Service] Type=oneshot ExecStart=/usr/sbin/ethtool -K <uplink> rx-udp-gro-forwarding on rx-gro-list off [Install] WantedBy=multi-user.targetReplace
<uplink>with the interface’s name, such aseth0, and enable the unit:systemctl daemon-reload systemctl enable --now tslink-gro.serviceThe kernel and the NIC driver both have to support the setting.
-
Log in to your registry, if it needs authentication:
docker login <registry> -
Install the plugin, as Install and upgrade tslink describes.
-
On a Swarm with one credential for all stacks, install the cluster credential, as Deploy on Swarm describes.
-
On a Swarm, share the certificate directory, so a Service’s certificate is issued once rather than once per host. Mount a filesystem every host shares and on which an exclusive create is atomic, such as NFS, and make it the source of the plugin’s
sharedmount:docker plugin disable tslink docker plugin set tslink shared.source=/mnt/shared/tslink docker plugin enable tslinkshared.sourceexplains what changes.WarningThe directory holds every Service’s private key. Make it owned by root with mode
0700, and available only to the hosts of the cluster (propertyE7in SECURITY.md). -
Install the drain drop-in, so Service backends are drained before Docker stops. See install the drain drop-in.
-
Run the preflight check, which tests the environment properties tslink’s security guarantees rely on. See run tslink diag.
-
Set up monitoring, so you hear about a node that isn’t running. See Monitor tslink.
Check that it works
UDP GRO forwarding is on:
ethtool -k <uplink> | grep rx-udp-gro-forwarding
The output is rx-udp-gro-forwarding: on. The plugin is enabled:
docker plugin ls --filter enabled=true
And the preflight check from step 8 exits with code 0.
Next steps
- Deploy on Swarm: run stacks, each with its own tags.
- Update without downtime: upgrade and restart hosts without dropping requests.
- Security model: what tslink protects, and what it relies on.