henrygd / beszel

Lightweight server monitoring hub with historical data, docker stats, and alerts.
MIT License
3.19k stars 99 forks source link

Built-in agent on the hub #140

Open steveiliop56 opened 3 months ago

steveiliop56 commented 3 months ago

Hello,

It would be really nice to have the agent built-in on the huh and displayed by default on the dashboard so we don't have to run 2 docker containers on the server.

henrygd commented 3 months ago

That's a good idea.

Mostly for myself - here are initial thoughts on how to do this:

  1. Add option to NewAgent to disable the SSH server (or just disable if pubkey is empty).
  2. Add method to agent that exports stats directly.
  3. On first user creation, create system with specific host, like hub-system.
  4. In hub, on system update, check if host matches above. If so, use method on agent to directly fetch stats.
  5. Check for agent and create agent in system update function to make sure it's available after restart or prev system deletion.
  6. If the system is deleted, make sure to delete agent and references.

I'll experiment with this at some point, but no timeline as of now.

henrygd commented 1 month ago

Update: Did some work on this and got it working aside from bandwidth.

We'd need to make people run the hub in host network mode for it to work fully, and I don't want to do that. It's less of a problem for the agent, which is essentially standalone, but a lot of users are going to want the hub in a specific docker network to connect to their reverse proxy and whatnot.

There's a hacky workaround explained in this article where you can run a script (or I can make a docker version) that copies /proc/net/dev to a different location which you're able to mount in containers, but it's not ideal.

So I'm shelving this for the time being. If anyone knows of a better solution, let me know.

steveiliop56 commented 1 month ago

Hmm maybe the ideal solution is to make the agent not need the host network. Instead you could mount the required proc files and do all readings from there.

henrygd commented 1 month ago

Docker network isolation prevents you from mounting and reading directly from host /proc/net unfortunately.

The workaround requires you to run a separate tiny container in host network mode, which would just copy /proc/net/dev to /dev/shm/fakeproc/net/dev, then you could mount /dev/shm/fakeproc in hub or agent container. It's explained more in the article I linked above.

It's confusing and still requires you to run a second container, so I'm not sure it's worth it.

However, it would be more security positive, as you'd only need to run one container in host network mode, and that container wouldn't import any third party code.

steveiliop56 commented 1 month ago

Huh? Can't you just do:

volumes:
  - /proc:/host/proc

And read the files?

henrygd commented 1 month ago

Not for /proc/net unless you're in host network mode.

You can test it yourself by mounting /proc/net/dev in one of your containers that provides a shell.

First check the contents on your host machine:

cat /proc/net/dev

Then mount it in a container:

volumes:
  - /proc/net/dev:/tmp/dev:ro

Then exec into the container and run cat /tmp/dev. The contents will be different unless you're in host network mode.


The workaround is to copy the contents of /proc/net/dev to a different location. So on the host, you run:

cat /proc/net/dev > /tmp/dev

Then mount /tmp/dev in the container:

volumes:
  - /tmp/dev:/tmp/dev:ro

Now exec into the container and cat /tmp/dev will give you the host value at the point when you copied the contents.

So the workaround requires a standalone container in host network mode that copies the contents of /proc/net/dev to a different location every second or so.