r/nbd-server: Deploy nbd-server

The *nbd-server* role configures a machine as a Network Block Device
(NDB) server, using the reference `nbd-server` implementation.  It
configures a systemd socket unit to listen on the port and accept
incoming connections, and a template service unit for systemd to
instantiate and pass each incoming connection.

The reference `nbd-server` is actually not very good.  It does not clean
up closed connections reliably, especially if the client disconnects
unexpectedly.  Fortunately, systemd provides the necessary tools to work
around these bugs.  Specifically, spawning one process per connection
allows processes to be killed externally.  Further, since systemd
creates the listening socket, it can control the keep-alive interval.
By setting this to a rather low value, we can clean up server processes
for disconnected clients more quickly.

Configuration of the server itself is minimal; most of the configuration
is done on a per-export basis using drop-in configuration files.  Other
Ansible roles should create these configuration files to configure
application-specific exports.  Nothing needs to be reloaded or restarted
for changes to take effect; the next incoming connection will spawn a
new process, which will use the latest configuration file automatically.
btop
Dustin 2022-03-17 15:14:02 -05:00
parent cfffd1d782
commit 14bfddd0ee
6 changed files with 134 additions and 0 deletions

View File

@ -0,0 +1 @@
nbd_server_allow_list: true

View File

@ -0,0 +1,13 @@
[Unit]
Description=Network Block Device Server socket
[Socket]
# NBD clients cannot handle their addresses changing, which happens
# frequently for IPv6. Only bind to the IPv4 socket to work around this.
ListenStream=0.0.0.0:10809
Accept=yes
KeepAlive=yes
KeepAliveTimeSec=5m
[Install]
WantedBy=sockets.target

View File

@ -0,0 +1,11 @@
[Unit]
Description=Network Block Device Server
CollectMode=inactive-or-failed
After=network.target
[Service]
ExecStart=/usr/bin/nbd-server -d
User=nbd
Group=nbd
StandardInput=socket
StandardOutput=journal

View File

@ -0,0 +1,9 @@
- name: reload systemd
systemd:
daemon_reload: true
changed_when: true
- name: restart nbd-server
systemd:
name: nbd-server.socket
state: restarted

View File

@ -0,0 +1,96 @@
- name: ensure nbd is installed
package:
name: nbd
state: present
tags:
- install
- name: ensure nbd user group exists
group:
name: nbd
system: true
state: present
tags:
- user
- group
- name: ensure nbd user exists
user:
name: nbd
system: true
group: nbd
home: /var/lib/nbd
create_home: false
shell: /sbin/nologin
state: present
tags:
- user
- name: ensure nbd data directory exists
file:
path: /var/lib/nbd
mode: ug=rwx,o=rx
owner: nbd
group: nbd
state: directory
- name: ensure nbd-server configuration directory exists
file:
path: /etc/nbd-server
mode: u=rwx,go=rx
owner: root
group: root
state: directory
tags:
- config
- name: ensure nbd-server configuration drop-in directory exists
file:
path: /etc/nbd-server/config.d
mode: u=rwx,go=rx
owner: root
group: root
state: directory
tags:
- config
- name: ensure nbd-server is configured
template:
src: nbd-server.config.j2
dest: /etc/nbd-server/config
mode: u=rw,go=r
owner: root
group: root
notify:
- restart nbd-server
tags:
- config
- name: ensure nbd-server unit files exist
copy:
src: '{{ item }}'
dest: /etc/systemd/system/
mode: u=rw,go=r
owner: root
group: root
loop:
- nbd-server.socket
- nbd-server@.service
notify:
- reload systemd
- restart nbd-server
tags:
- systemd
- name: ensure nbd-server socket is listening
systemd:
name: nbd-server.socket
state: started
tags:
- service
- name: ensure firewall is configured for nbd-server
firewalld:
service: nbd
state: enabled
permanent: true
immediate: true
tags:
- firewall

View File

@ -0,0 +1,4 @@
[generic]
port = 0
allowlist = {{ nbd_server_allow_list|bool|string|lower }}
includedir = /etc/nbd-server/config.d