5 ms·
On my home server (refurbished ThinkPad X201 with a Core i5-520M, 8GB of memory, 1TB internal SSD sync'd nightly to an external 1TB HDD) I run a single-node Kub
by ricardbejarano 7y ago
On my home server (refurbished ThinkPad X201 with a Core i5-520M, 8GB of memory, 1TB internal SSD sync'd nightly to an external 1TB HDD) I run a single-node Kubernetes cluster with the following stuff:
* MinIO: for access to my storage over the S3 API, I use it with restic for device backups and to share files with friends and family
* CoreDNS: DNS cache with blacklisted domains (like Pihole), gives DNS-over-TLS to the home network and to my phone when I'm outside
* A backup of my S3-hosted sites, just in case (bejarano.io, blog.bejarano.io, mta-sts.bejarano.io and prefers-color-scheme.bejarano.io)
* https://ideas.bejarano.io https://ideas.bejarano.io, a simple "pick-one-at-random" site for 20,000 startup ideas (https://news.ycombinator.com/item?id=21112345 https://news.ycombinator.com/item?id=21112345)
* MediaWiki instance for systems administration stuff
* An internal (only accessible from my home network) picture gallery for family pictures
* TeamSpeak server
* Cron jobs: dynamic DNS, updating the domain blacklist nightly, recursively checking my websites for broken links, keeping an eye on any new release of a bunch of software packages I use
* Prometheus stack + a bunch of exporters for all the stuff above
* IPsec/L2TP VPN for remote access to internal services (picture gallery and Prometheus)
* And a bunch of internal Kubernetes stuff for monitoring and such
I still have to figure out log aggregation (probably going to use fluentd), I want to add some web-based automation framework like NodeRED or n8n.io for random stuff. I'd also like to host some password manager but I still have to study that.
I also plan on rewriting wormhol.org into supporting any S3 backend, so that I can bind it's storage with MinIO.
And finally, I'd like to move off single-disk storage and get a decent RAID solution to provide NFS for my cluster, as well as a couple more nodes to add redundancy and more compute.
Edit: formatting.
- devthane 7y agoYou might take a look at https://github.com/grafana/loki https://github.com/grafana/loki if you haven’t seen it yet for logs. It’s still really new but it’s been working for me great.
- ricardbejarano 7y agoThanks for the heads up, I'll check it out!
- jamieweb 7y agoGood job for using MTA-STS. :)
- mpnordland 7y agoI've been wanting to do a kubernetes setup with my home server, but most tutorials are aimed at multi node clusters. Do you have any links on how to setup such a system?
- gravypod 7y agoIf you follow a multi node cluster tutorial all you should need to do is remove the master taint from the node and normal pods will spawn on it
- ricardbejarano 7y agoThat's essentially it, yes. FYI: the control plane takes about 150m (milli-cpu) and ~1.5GiB of memory in a host with my specs.
- lbotos 7y agoI'm trialling k3s right now. https://k3s.io/ https://k3s.io/
- ricardbejarano 7y agoI've seen it, never tried it. The thing is, I don't use Kubernetes for convenience or because I need it, I use to learn it. I was just fine with Docker Swarm before switching, but I wanted to learn Kubernetes as a valuable skill, and I know no better way of learning something than using it every day. And the thing about Kubernetes distros is that they usually all apply a new layer of "turning Kubernetes' complexity into a turn-key process", and I don't want that. If you know the ins and outs of K8s, sure, use any distro you like, but if you want to learn something, better learn the fundamentals first. It's like learning Linux's internals instead of learning how Ubuntu is, one applies to a single distro and the other will apply for every distro ever.
- lbotos 7y agoI was like you, I knew about the "concept" of a pod, and nothing more. k3s is not very far from the fundamentals. It's really just "one binary" instead of many for the space savings/ simple deployment. That said, consider Kubernetes in Action by Manning. I'm about 75% done now, was a great help, and I'm continuing with k3s after doing it.
- magicfractal 7y agoCould you share a bit about your picture gallery?
- ricardbejarano 7y agoSure! Here's the source code: https://github.com/ricardbejarano/pyctures https://github.com/ricardbejarano/pyctures I could set up a demo if you want to. It's a cheap Flask app that scans a given "library" directory for "album" subdirectories, which contain the pictures you want to display. It has a big issue with image size (16 images per page, my phone takes 5MB pictures, 80MB per page is HUUUGE). Thumbnailing would be great. I'm open for PRs ;)! If anyone knows about a better alternative... I set this up when we got back from one vacation for my relatives to easily see the pictures (without social media).
- nc30 7y agoSigal https://github.com/saimn/sigal https://github.com/saimn/sigal seems to do pretty much you have described there. And it is written in python too :)
- thequailman 7y agoHow are you doing multi tenant MinIO?
- ricardbejarano 7y agoI don't :) Right now I have public (read-only) and private buckets only, and I'm the only who writes into any of them. Public buckets contain files I didn't even create myself and that friends might find useful (Windows ISO, movies, VirtualBox VMs...). Privates have, well, private data, and can only be accessed using my admin account's credentials. IIRC MinIO has access control through users, but I'm still very new to MinIO to the point where I discover new features every time I use it. If I were to give someone else their own buckets I'd probably run a second instance to keep things separate, though. I'm even considering running another one myself to keep private buckets only accessible from my home network... (right now the entire instance is reachable from WAN, regardless of whether they are public or not).
- whycombagator 7y ago> * CoreDNS: DNS cache with blacklisted domains (like Pihole), gives DNS-over-TLS to the home network and to my phone when I'm outside I would be _very_ interested in a write up/explanation of this set up
- ricardbejarano 7y agoThere you go! Essentially, this setup achieves 5 features I wanted my DNS to have: - Confidentiality: from my ISP; and from anyone listening to the air for plain-text DNS questions when I'm on public WiFi. Solution: DNS-over-TLS[1] - Integrity: of the answers I get. Solution: DNS-over-TLS authenticates the server - Privacy: from web trackers, ads, etc. Solution: domain name blacklist - Speed: as in, fast resolution times. Solution: caching and cache prefetching[2] - Observability: my previous DNS was Dnsmasq[3], AFAIK Dnsmasq doesn't log requests, only gives a couple stats[4], etc. Solution: a Prometheus endpoint CoreDNS ticks all of the above, and a couple others I found interesting to have. To set it up, I wrote my own (better) CoreDNS Docker image[7] to run on my Kubernetes cluster; mounted my Corefile[8] and my certificates as volumes, and exposed it via a Kubernetes Service. The Corefile[8] essentially sets up CoreDNS to: - Log all requests and errors - Forward DNS questions to Cloudflare's DNS-over-TLS servers - Cache questions for min(TTL, 24h), prefetching any domains requested more than 5 times over the last 10 minutes before they expire - If a domain resolves to more than one address, it automatically round-robins between them to distribute load - Serve Prometheus-style metrics on 9153/TCP, and provide readiness and liveness checks for Kubernetes - Load the /etc/hosts.blacklist hosts file (which has just short of 1M domains resolved to 0.0.0.0), reloads it every hour, and does not provide reverse lookups for performance reasons - Listens on 53/UDP for regular plain-text DNS questions (LAN only), and on 853/TCP for DNS-over-TLS questions, which I have NAT'd so that I can use it when I'm outside The domain blacklist I generate nightly with a Kubernetes CronJob that runs a Bash script[9]. It essentially pulls and deduplicates the domains in the "safe to use" domain blacklists compiled by https://firebog.net/ https://firebog.net/, as well as removing (whitelisting) a couple hosts at the end. That's pretty much it. The only downside to this set up is that CoreDNS takes just short of 400MiB of memory (I guess it keeps the resolve table on memory, but 400MiB!?) and lately I'm seeing some OOM restarts by Kubernetes, as it surpasses the 500MiB hard memory limit I have on it. A possible solution might be to keep the resolve table on Redis, which might take up less memory space, but I'm still to try that out. [1] Which I find MUCH superior to DNS-over-HTTPS. The latter is simply a L7 hack to speed up adoption, but the correct technical solution is DoT, and operating systems should already support it by now (AFAIK, the only OS that supports DoT natively is Android 9+). [2] It was when I discovered CoreDNS' cache prefetching that I convinced myself to switch to CoreDNS. [3] http://www.thekelleys.org.uk/dnsmasq/doc.html http://www.thekelleys.org.uk/dnsmasq/doc.html [4] It gives you very few stats. I also had to write my own Prometheus expoter[5] because Google's[6] had a fatal flaw and no one answered to the issue. In fact, they closed the Issues tab on GitHub a couple months after my request, so fuck you, Google! [5] https://github.com/ricardbejarano/dnsmasq_exporter https://github.com/ricardbejarano/dnsmasq_exporter [6] https://github.com/google/dnsmasq_exporter https://github.com/google/dnsmasq_exporter (as you can see the Issues tab is no longer present) [7] https://github.com/ricardbejarano/coredns https://github.com/ricardbejarano/coredns, less bloat than the official image, runs as non-root user, auditable build pipeline, compiled from source during build time. These are all nice to have and to comply with my non-root PodSecurityPolicy. I also like to run my own images just so that I know what's under the hood. [8] local:65535 { ready health } (global) { log errors cache 86400 { prefetch 5 10m 10% } dnssec loadbalance prometheus :9153 } (cloudflare) { forward . tls://1.1.1.1 tls://1.0.0.1 { tls_servername cloudflare-dns.com } } (blacklist) { hosts /etc/hosts.blacklist { reload 3600s no_reverse fallthrough } } .:53 { import global import blacklist import cloudflare } tls://.:853 { import global import blacklist import cloudflare tls /etc/tls/fullchain.pem /etc/tls/privkey.pem } [9] #!/bin/bash HOSTS_FILE="/tmp/hosts.blacklist" HOSTS_FILES="$HOSTS_FILE.d" mkdir -p "$HOSTS_FILES" download() { echo "download($1)" curl \ --location --max-redirs 3 \ --max-time 20 --retry 3 --retry-delay 0 --retry-max-time 60 \ "$1" > "$(mktemp "$HOSTS_FILES"/XXXXXX)" } # https://firebog.net/ ## suspicious domains download "https://hosts-file.net/grm.txt" download "https://reddestdream.github.io/Projects/MinimalHosts/etc/MinimalHostsBlocker/minimalhosts" download "https://raw.githubusercontent.com/StevenBlack/hosts/master/data/KADhosts/hosts" download "https://raw.githubusercontent.com/StevenBlack/hosts/master/data/add.Spam/hosts" download "https://v.firebog.net/hosts/static/w3kbl.txt" ## advertising domains download "https://adaway.org/hosts.txt" download "https://v.firebog.net/hosts/AdguardDNS.txt" download "https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt" download "https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt" download "https://hosts-file.net/ad_servers.txt" download "https://v.firebog.net/hosts/Easylist.txt" download "https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts;showintro=0" download "https://raw.githubusercontent.com/StevenBlack/hosts/master/data/UncheckyAds/hosts" download "https://www.squidblacklist.org/downloads/dg-ads.acl" ## tracking & telemetry domains download "https://v.firebog.net/hosts/Easyprivacy.txt" download "https://v.firebog.net/hosts/Prigent-Ads.txt" download "https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-blocklist.txt" download "https://raw.githubusercontent.com/StevenBlack/hosts/master/data/add.2o7Net/hosts" download "https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt" ## malicious domains download "https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt" download "https://mirror1.malwaredomains.com/files/justdomains" download "https://hosts-file.net/exp.txt" download "https://hosts-file.net/emd.txt" download "https://hosts-file.net/psh.txt" download "https://mirror.cedia.org.ec/malwaredomains/immortal_domains.txt" download "https://www.malwaredomainlist.com/hostslist/hosts.txt" download "https://bitbucket.org/ethanr/dns-blacklists/raw/8575c9f96e5b4a1308f2f12394abd86d0927a4a0/bad_lists/Mandiant_APT1_Report_Appendix_D.txt" download "https://v.firebog.net/hosts/Prigent-Malware.txt" download "https://v.firebog.net/hosts/Prigent-Phishing.txt" download "https://phishing.army/download/phishing_army_blocklist_extended.txt" download "https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-malware.txt" download "https://ransomwaretracker.abuse.ch/downloads/RW_DOMBL.txt" download "https://ransomwaretracker.abuse.ch/downloads/CW_C2_DOMBL.txt" download "https://ransomwaretracker.abuse.ch/downloads/LY_C2_DOMBL.txt" download "https://ransomwaretracker.abuse.ch/downloads/TC_C2_DOMBL.txt" download "https://ransomwaretracker.abuse.ch/downloads/TL_C2_DOMBL.txt" download "https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist" download "https://v.firebog.net/hosts/Shalla-mal.txt" download "https://raw.githubusercontent.com/StevenBlack/hosts/master/data/add.Risk/hosts" download "https://www.squidblacklist.org/downloads/dg-malicious.acl" cat "$HOSTS_FILES"/* | \ sed \ -e 's/0.0.0.0//g' \ -e 's/127.0.0.1//g' \ -e '/255.255.255.255/d' \ -e '/::/d' \ -e '/#/d' \ -e 's/ //g' \ -e 's/ //g' \ -e '/^$/d' \ -e 's/^/0.0.0.0 /g' | \ awk '!a[$0]++' | \ sed \ -e '/gamovideo.com/d' \ -e '/openload.co/d' > "$HOSTS_FILE" rm -rf "$HOSTS_FILES"
- bpye 7y agoHey - I'm not the only one using CoreDNS like this! I'm just abusing the hosts plugin - do you have something more elegant?
- ricardbejarano 7y agoI'm throwing it the hosts blacklist as a file. For performance reasons I turn off reverse lookups and limit reloading to once every hour: (blacklist) { hosts /etc/hosts.blacklist { reload 3600s no_reverse fallthrough } } .:53 { import blacklist ... (more config) }
- bluegreyred 7y agonice to see somebody using a thinkpad as a homeserver. I remember comparing low power homeservers, consumer NAS and a refurb Thinkpad and the latter won when considering the price/performance and idle power consumption (<5W). You also get a built screen & keyboard for debugging and a efficient DC-UPS if you're brave enough to leave the batteries in. That's of course assuming you don't need multiple terabytes of storage or run programs that load the CPU 24/7, which I don't. These days a rPi 4 would probably suffice for my needs but I still think the refurb thinkpad is a smart idea.
- ricardbejarano 7y agoI don't overload the CPU and my storage requirements are low. 95% of my used storage is stuff I wouldn't care if it got lost, but just nice to have around. I only have around 2GB of data I don't want to lose. I do leave the batteries in. Is it dangerous? I read some time ago that it is not dangerous, but the capacity of the battery drops significantly, I don't care about capacity, and safe shutdowns are important to me. In the past I used an HP DL380 Gen. 7 (which I still own, and wouldn't mind selling as I don't use it), but I had to find a solution for the noise. And power consumption was at around 18EUR for my EUR/kWh. Cramming down what ran on 12 cores and 48GiB of RAM on a 2-core, 4GiB (I only upgraded the memory 2 months ago) machine was a real challenge. The ThinkPad cost me 90EUR (IBM refurbished), we bought two of them, the other one burnt. The recent upgrades (8GiB kit + Samsung Evo 1TB) cost me around 150EUR. Overall a really nice value both in compute per EUR spent and in compute per Wh spent. Really happy with it, I just feel it is not very reliable as it is old.
- Havoc 7y ago>I do leave the batteries in. Is it dangerous? Should be fine if they're not swollen / getting very hot
- bluegreyred 7y ago>I do leave the batteries in. Is it dangerous? I read some time ago that it is not dangerous, but the capacity of the battery drops significantly, I don't care about capacity, and safe shutdowns are important to me. It's not necessarily dangerous but lithium batteries have a chance to fail and in very rare cases even explode, making them a potential fire hazard. I'm not an expert, maybe someone else can expand on this. If I were to run an old laptop of unknown provenance with a LiIon battery 24/7 completely unattended I'd at least want to make sure that it is on a non-flammable surface without any flammable items nearby. >In the past I used an HP DL380 Gen. 7 (which I still own, and wouldn't mind selling as I don't use it), but I had to find a solution for the noise. And power consumption was at around 18EUR for my EUR/kWh. Yes, I am surprised how many people leave power consumption out of the equation. These days you can rent a decent VPS for the power cost of an old refurb server alone.