DNS
Catch-owned service discovery for yeet services and VMs.
Catch runs a small DNS server for yeet-managed service discovery on the
private service network. It lets services and VMs on svc networking reach
each other by service name instead of hard-coding private IP addresses.
The resolver listens on the service-network gateway:
192.168.100.1:53
For yeet-managed names, it answers A records for:
- short service names, such as
web - fully qualified names under
yeet.internal, such asweb.yeet.internal
Both forms resolve to the service's svc network address. Queries for
ordinary external names are forwarded through the catch host's resolver from
/etc/resolv.conf. Tailnet names under *.ts.net are forwarded directly to
Tailscale DNS.
dig @192.168.100.1 web A +short
dig @192.168.100.1 web.yeet.internal A +short
dig @192.168.100.1 example.com A +short
Yeet DNS is scoped to yeet-managed hosts and the service network. It is not meant to replace your LAN DNS or public DNS; it acts as the single resolver that knows yeet-local names and forwards everything else.
In v1, yeet requires exclusive use of 192.168.100.0/24 for the private
service network. Catch hard-errors if another host interface or route already
uses an overlapping subnet. A future release may make this range configurable.
DNS records come from catch's service registry. A name resolves only when the
service has a svc network address.
- For a VM, the answer is the VM's private
svcmanagement IP. - For a Docker Compose service in a service network namespace, the answer is
the netns
svcIP. - For services without
svcnetworking, there is no yeet DNS record.
For example, if api is a compose service deployed with --net=svc and
worker is a VM using the default VM network, then api,
api.yeet.internal, worker, and worker.yeet.internal resolve from other
svc services and VMs.
When a container-backed service uses --net=svc, catch creates a service
network namespace and writes a generated resolv.conf for that namespace.
By default it contains:
nameserver 192.168.100.1
search yeet.internal
That means application code inside the service can normally use short names:
postgres://db:5432/app
http://api:8080
If you combine service networking with Tailscale, such as --net=svc,ts,
yeet DNS still provides service-network discovery while the Tailscale
interface provides tailnet reachability for that service.
Docker Compose containers normally still see Docker's embedded resolver at
127.0.0.11. For compose payloads that use --net=svc, yeet writes a generated
compose overlay that points each service at catch DNS and adds yeet.internal
as a search domain. Services that already set dns: or dns_search: keep their
own resolver configuration.
Compose payloads without svc networking do not get yeet DNS. Use --net=svc
for private yeet service discovery, or --net=svc,lan when a service needs both
yeet names and LAN reachability.
VMs use svc networking by default, so new VMs get yeet DNS automatically.
The guest metadata configures the VM's svc interface with the yeet resolver
and the yeet.internal search domain.
From inside a VM, these forms are equivalent for another svc service named
api:
ping api
ping api.yeet.internal
For VMs with both svc and lan, yeet keeps the svc resolver scoped to
yeet names so LAN-provided DNS can still handle ordinary external names. This
lets the VM appear on the LAN while keeping the stable yeet management and
service-discovery path.
DNS labels follow the same practical shape as service names used for network discovery:
- lower-case letters, digits, and hyphens
- starts and ends with a letter or digit
- one label only for the short form
Names are resolved case-insensitively. Use simple service names such as
web, api, db, or worker.
The DNS server is catch-owned. During catch startup, catch reconciles the network namespace service and the DNS unit:
yeet-ns.serviceowns the service-network gateway.yeet-dns.servicerunscatch dns.yeet-dns.serviceis part of the catch lifecycle, so catch upgrades also refresh the DNS process.
This keeps the resolver present after yeet init, after catch upgrades, and
after host restarts.
Check that both catch and DNS are active:
sudo systemctl is-active catch yeet-dns.service
Check that the resolver is listening on the service-network gateway:
sudo ss -lunp 'sport = :53'
Query it directly from the catch host:
dig @192.168.100.1 <svc> A +short
dig @192.168.100.1 <svc>.yeet.internal A +short
If a service name does not resolve:
- confirm the service uses
svcnetworking - confirm
yeet info <svc>shows a service-network IP - restart catch so it reconciles the DNS unit and service registry state
sudo systemctl restart catch
Existing services or VMs created before yeet DNS support may need to be
recreated or have their networking metadata refreshed before their guest or
netns resolver config points at 192.168.100.1.