From 5fac51cdf564c8bd7dbe71e69c1d9a8bcfb8ee7d Mon Sep 17 00:00:00 2001 From: Joerg Lehmann Date: Sat, 7 Nov 2026 19:34:31 +0100 Subject: [PATCH] added kube files to repo, should go to ~containers/.config/containers/systemd --- README.md | 421 ++++++++++++++++++++++ minibeielidev/onyx-dev-minibeielidev.kube | 17 + mqtt/mqtt.yaml | 137 ------- traefik/onyx-dev-traefik.kube | 16 + wobischdev/onyx-dev-wobischdev.kube | 17 + 5 files changed, 471 insertions(+), 137 deletions(-) create mode 100644 README.md create mode 100644 minibeielidev/onyx-dev-minibeielidev.kube delete mode 100644 mqtt/mqtt.yaml create mode 100644 traefik/onyx-dev-traefik.kube create mode 100644 wobischdev/onyx-dev-wobischdev.kube diff --git a/README.md b/README.md new file mode 100644 index 0000000..6d7afe4 --- /dev/null +++ b/README.md @@ -0,0 +1,421 @@ +# onyx-dev - Container Server of nbit Informatik GmbH + +onyx-dev.nbit.ch is used to run rootless Podman containers, using Traefik as a Reverse Proxy + +It is the Development Server, the main server is onyx.nbit.ch + +Additionally it acts as a primary nameserver ns1.nbit.ch + +In this directory (/data/onyx-dev_pods), you will find all configuration files to run the containers (with Podman and Kubernetes YAML files) + +Specs: +- Rocky Linux 10 +- Hetzner Cloud Server CX21 + - 2 vCPUs + - 4 GB RAM + - 40 GB Disk + - Location Nuremberg + +Persistent data is stored in /data + +## Create Server + +Name: onyx-dev.nbit.ch + +Set Root-Password (by hand) + +` +# dnf update +# init 6 (Reboot) +# groupadd containers +# useradd -m -g containers containers +# passwd containers + +For containers User, add the following to ~/.bash_profile: + +if [ -z "$XDG_RUNTIME_DIR" ] && [ -d "/run/user/$(id -u)" ]; then + export XDG_RUNTIME_DIR=/run/user/$(id -u) +fi + +# hostnamectl set-hostname onyx-dev.nbit.ch +# timedatectl set-timezone Europe/Zurich +# dnf install glibc-langpack-de +# localectl set-locale LANG=en_US.UTF-8 +# localectl set-locale LC_TIME=de_CH.UTF-8 + +Set Journalctl-Config to persistent Storage: +cp /usr/lib/systemd/journald.conf /etc/systemd +/etc/systemd/journald.conf: +Storage=persistent + +# Enable Selinux in Enforcing Mode: change /etc/selinux/config +# dnf install setroubleshoot-server + +Disable kdump: +systemctl disable --now kdump +grubby --update-kernel=ALL --remove-args="crashkernel" +reboot +` + +enable EPEL Repo (for instance because of fail2ban): +` +# dnf install epel-release +` + +## Firewall + +```bash +# dnf install firewalld +# systemctl enable --now firewalld +# firewall-cmd --add-service={http,https} --permanent +# firewall-cmd --remove-service=cockpit --permanent +# firewall-cmd --add-port=25/tcp --permanent ; for Postfix +# firewall-cmd --reload + +List Rules: +# firewall-cmd --list-all +``` + +## fail2ban on Host for ssh + +```bash +# dnf install fail2ban +# cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local +edit /etc/fail2ban/jail.local: +enabled = true => below [sshd] + +# systemctl enable fail2ban +# systemctl restart fail2ban + +command to check who is banned: +# fail2ban-client status sshd +``` + +## Install Software + +```bash +# dnf install passt +# dnf install git +# dnf install podman +# dnf install jq +# dnf install sysstat +# dnf install lftp +# dnf install telnet +# dnf install binutils +``` + +## Setup Mail + +```bash +# dnf install s-nail procmail msmtp +# cp /usr/share/doc/msmtp/msmtprc-system.example /etc/msmtprc +``` + +## Backup Server + +```bash +# dnf install restic +# mkdir /backup +# mkdir /backup-restic +# restic init --repo /backup-restic/restic-repo-$(hostname --short) # Passwort in Keepass + +SSH Keypaar fuer User root erstellen und auf Hetzner Storagebox hinterlegen: + +# ssh-keygen + +Restic Script: + +/usr/local/bin/backup-to-disk.sh +#!/bin/bash +# Backup der wichtigsten Verzeichnisse nach einem Verzeichnis +# +# Es wird restic verwendet. +# +PATH=$PATH:/usr/local/bin +export RESTIC_PASSWORD="$(hostname --short)7355" +restic backup --quiet --repo /backup-restic/restic-repo-$(hostname --short) /home /etc /var /opt /data /usr/local/bin /backup --exclude=/var/log + +if [ $? -eq 0 ]; then + restic forget --quiet --repo /backup-restic/restic-repo-$(hostname --short) --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 20 --prune +else + >&2 echo "Problem with restic Backup $(hostname --short)" +fi + +/etc/cron.d/backup-to-disk: +# +# Backup important Files to Disk +# +55 6 * * * root /usr/local/bin/backup-to-disk.sh >/dev/null + +Backup auf Storag Box: + +# cat > /etc/cron.d/rsync-backup-to-other-host </dev/null +HERE +``` + + +List Usage on Storage Box: + +``` +# ssh -p 23 u152662@u152662.your-storagebox.de du -h -d 1 +261G ./arq-backup-mbp +8.3G ./moby-backup-restic-rsync +650M ./onyx-dev-backup-restic-rsync +1.6G ./mb2-backup-rsync +1.2G ./wobisch2-backup-rsync +1.6G ./mb1-backup-rsync +11G ./mail-backup-restic-rsync +20G ./onyx-backup-restic-rsync +44G ./cinnamon.nbit.ch +10K ./.ssh +348G . +``` + + + +### Setup Env for Podman + +```bash +# mkdir /data +# chown containers:containers /data + +Set Defaults: + +containers$ cat ~/.config/containers/containers.conf +[network] +network_backend = "netavark" + + +Credentials for Docker Registry should be available after Reboot + +# echo 'net.ipv4.ip_unprivileged_port_start=80' >> /etc/sysctl.d/containers.conf +# loginctl enable-linger containers +[containers@onyx-dev ~]$ podman login git.nbit.ch +Username: jlehmann +Password: +Login Succeeded! + +[containers@onyx-dev ~]$ mkdir ~/.config/containers +[containers@onyx-dev ~]$ cp /run/user/1000/containers/auth.json ~/.config/containers/auth.json + + +``` + +### Setup Traefik + +Traefik will be started with podman play kube (with yaml file) and attach to HostNetwork (hostNetwork: true in yaml). +Backends will map there port and will be accessed on localhost: + +we do not use the dynamic config using docker provider, but rather the file provider (one file per backend) +```bash +Example Backend Service File: + +[containers@onyx onyx_pods]$ cat traefik/configuration/nbitwebsite.yml +http: + routers: + nbitwebsite: + entrypoints: + - websecure + tls: + certresolver: "myresolver" + domains: + - main: "www.linux-freelancer.ch" + sans: "linux-freelancer.ch" + rule: "Host(`linux-freelancer.ch`,`www.linux-freelancer.ch`)" + service: nbitwebsite + + services: + nbitwebsite: + loadBalancer: + servers: + - url: http://127.0.0.1:9000/ + passHostHeader: false +``` + +```bash +# echo 'net.ipv4.ip_unprivileged_port_start=80' >> /etc/sysctl.d/containers.conf +# loginctl enable-linger containers +# The following fixes "Failed to connect to bus: No medium found" +export XDG_RUNTIME_DIR=/run/user/$(id -u) + +containers$ touch /data/traefik/acme.json +containers$ chmod 0600 /data/traefik/acme.json + +Important: set SELinux Context on /data for containers: + + +[root@onyx-dev named]# semanage fcontext -a -s unconfined_u -t container_file_t "/data(/.*)?" +[root@onyx-dev named]# restorecon -r -v /data + +Check: +find /data ! -context '*:container_file_t:*' + + +/etc/subgid:containers:100000:65536 +/etc/subuid:containers:100000:65536 + +!!!!!!!!!!!!!! +IMPORTANT: we changed the startup Method to Quadlets, put into +~containers/.config/containers/systemd/ + +See also https://www.redhat.com/sysadmin/quadlet-podman + +Example of such a quadlet config (Network=pasta is not to be used for Traefik): + +[containers@onyx-dev ~]$ more ~containers/.config/containers/systemd/onyx-dev-mqtt.kube +[Unit] +Description=MQTT +Before=local-fs.target + +[Kube] +Yaml=/home/containers/onyx-dev_pods/mqtt/mqtt.yaml +LogDriver=journald +Network=pasta + +[Service] +Restart=always +RestartSec=15 +TimeoutStartSec=300 + +[Install] +# Start by default on boot +WantedBy=multi-user.target default.target +!!!!!!!!!!!!!! + +containers$ mkdir -p ~/.config/systemd/user/ + +``` + +### Setup Backend Services + +```bash +Create Kubernetes YAML File: + +backendservice=nbitwebsite +containers$ mkdir ~/onyx_pods/${backendservice} + +Create File ~/onyx_pods/${backendservice}/${backendservice}.yaml + +``` + +## Postfix + +```bash +# dnf install postfix + +We do not want to accept emails from outside, so we do not change the config (we only listen on localhost) + +# systemctl enable postfix +# systemctl start postfix + +Creat DNS Records: +mx1.nbit.ch and mx2.nbit.ch (A/AAAA Records to the same IPs as onyx and onyx-dev) + +Change SPF Records to include mx1 and mx2 +``` + +## Primary Nameserver + +```bash +# dnf install bind bind-utils +# systemctl enable --now named +# firewall-cmd --add-service=dns --permanent +# firewall-cmd --reload + +Adopt /etc/named.conf: + +Important => recursion no + +[root@onyx-dev etc]# diff named.conf named.conf.6nov2026 +11,12c11,12 +< listen-on port 53 { any; }; +< listen-on-v6 port 53 { any; }; +--- +> listen-on port 53 { 127.0.0.1; }; +> listen-on-v6 port 53 { ::1; }; +19,20c19 +< allow-query { any; }; +< version "You are too curious"; +--- +> allow-query { localhost; }; +32c31 +< recursion no; +--- +> recursion yes; +61,124d59 +< acl slaves { +< 95.216.148.212; +< 2a01:4f9:c010:5dd::1; +< 23.88.33.113; +< 2a01:4f8:c010:90e1::1; +< 5.75.251.111; +< 2a01:4f8:c012:c21c::1; +< 127.0.0.1; +< ::1; +< }; +< +< zone "nbit.ch" IN { +< type master; +< file "master/nbit.ch.zone"; +< allow-update { none; }; +< allow-transfer { +< slaves; +< }; +< }; +< +< zone "mini-beieli.ch" IN { +< type master; +< file "master/mini-beieli.ch.zone"; +< allow-update { none; }; +< allow-transfer { +< slaves; +< }; +< }; +< +< zone "wo-bisch.ch" IN { +< type master; +< file "master/wo-bisch.ch.zone"; +< allow-update { none; }; +< allow-transfer { +< slaves; +< }; +< }; +< +< zone "ch-wirth.ch" IN { +< type master; +< file "master/ch-wirth.ch.zone"; +< allow-update { none; }; +< allow-transfer { +< slaves; +< }; +< }; +< +< zone "cmoag.com" IN { +< type master; +< file "master/cmoag.com.zone"; +< allow-update { none; }; +< allow-transfer { +< slaves; +< }; +< }; +< +< zone "acmoag.com" IN { +< type master; +< file "master/acmoag.com.zone"; +< allow-update { none; }; +< allow-transfer { +< slaves; +< }; +< }; + + +on master: + +[root@onyx-dev named]# semanage fcontext -a -t named_cache_t "/var/named/master(/.*)?" +[root@onyx-dev named]# restorecon -r -v /var/named/master +... +``` diff --git a/minibeielidev/onyx-dev-minibeielidev.kube b/minibeielidev/onyx-dev-minibeielidev.kube new file mode 100644 index 0000000..e453862 --- /dev/null +++ b/minibeielidev/onyx-dev-minibeielidev.kube @@ -0,0 +1,17 @@ +[Unit] +Description=minibeieli +Before=local-fs.target + +[Kube] +Yaml=/data/onyx-dev_pods/minibeielidev/minibeielidev.yaml +LogDriver=journald +Network=pasta:-T,25:25 + +[Service] +Restart=always +RestartSec=15 +TimeoutStartSec=300 + +[Install] +# Start by default on boot +WantedBy=multi-user.target default.target diff --git a/mqtt/mqtt.yaml b/mqtt/mqtt.yaml deleted file mode 100644 index 84837db..0000000 --- a/mqtt/mqtt.yaml +++ /dev/null @@ -1,137 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - annotations: - io.kubernetes.cri-o.TTY/mqtt: "false" - io.podman.annotations.autoremove/mqtt: "FALSE" - io.podman.annotations.init/mqtt: "FALSE" - io.podman.annotations.label/mqtt: type:container_runtime_t - io.podman.annotations.privileged/mqtt: "FALSE" - io.podman.annotations.publish-all/mqtt: "FALSE" - labels: - app: mqtt-pod - name: mqtt-pod -spec: - containers: - - name: mosquitto - image: docker.io/library/eclipse-mosquitto:latest - env: - - name: TZ - value: Europe/Zurich - ports: - - containerPort: 1883 - hostPort: 9080 - resources: {} - securityContext: - capabilities: - drop: - - CAP_MKNOD - - CAP_NET_RAW - - CAP_AUDIT_WRITE - volumeMounts: - - mountPath: /mosquitto/config - name: mosquittoconfig - - mountPath: /mosquitto/data - name: mosquittodata - - mountPath: /mosquitto/log - name: mosquittolog - - name: mqtt2log - image: git.nbit.ch/drpuur/mqtt2log:2024101902 - env: - - name: TZ - value: Europe/Zurich - resources: {} - securityContext: - capabilities: - drop: - - CAP_MKNOD - - CAP_NET_RAW - - CAP_AUDIT_WRITE - volumeMounts: - - mountPath: /data - name: datashellies - - name: mqtt2prometheus - command: ["/mqtt2prometheus"] - args: ["-listen-port","9641","-log-level","warn"] - image: ghcr.io/hikhvar/mqtt2prometheus:latest - env: - - name: TZ - value: Europe/Zurich - ports: - - containerPort: 9641 - hostPort: 9081 - resources: {} - securityContext: - capabilities: - drop: - - CAP_MKNOD - - CAP_NET_RAW - - CAP_AUDIT_WRITE - volumeMounts: - - mountPath: /config.yaml - name: mqtt2prometheusconfig - - name: mqtt2prometheustasmota - command: ["/mqtt2prometheus"] - args: ["-listen-port","9642","-log-level","warn"] - image: ghcr.io/hikhvar/mqtt2prometheus:latest - env: - - name: TZ - value: Europe/Zurich - ports: - - containerPort: 9642 - hostPort: 9082 - resources: {} - securityContext: - capabilities: - drop: - - CAP_MKNOD - - CAP_NET_RAW - - CAP_AUDIT_WRITE - volumeMounts: - - mountPath: /config.yaml - name: tasmotamqtt2prometheusconfig - - name: prometheus - image: registry.hub.docker.com/prom/prometheus:latest - env: - - name: TZ - value: Europe/Zurich - resources: {} - securityContext: - capabilities: - drop: - - CAP_MKNOD - - CAP_NET_RAW - - CAP_AUDIT_WRITE - volumeMounts: - - mountPath: /etc/prometheus/prometheus.yml - name: prometheusconfig - restartPolicy: Always - volumes: - - hostPath: - path: /data/mqtt/data - type: Directory - name: mosquittodata - - hostPath: - path: /data/mqtt/config - type: Directory - name: mosquittoconfig - - hostPath: - path: /data/mqtt/log - type: Directory - name: mosquittolog - - hostPath: - path: /data/mqtt/data-shellies - type: Directory - name: datashellies - - hostPath: - path: /data/mqtt/config/mqtt2prometheus-config.yaml - type: File - name: mqtt2prometheusconfig - - hostPath: - path: /data/mqtt/config/tasmotamqtt2prometheus-config.yaml - type: File - name: tasmotamqtt2prometheusconfig - - hostPath: - path: /data/mqtt/config/prometheus.yml - type: File - name: prometheusconfig diff --git a/traefik/onyx-dev-traefik.kube b/traefik/onyx-dev-traefik.kube new file mode 100644 index 0000000..e0b91bd --- /dev/null +++ b/traefik/onyx-dev-traefik.kube @@ -0,0 +1,16 @@ +[Unit] +Description=Traefik +Before=local-fs.target + +[Kube] +Yaml=/data/onyx-dev_pods/traefik/traefik.yaml +LogDriver=journald + +[Service] +Restart=always +RestartSec=15 +TimeoutStartSec=300 + +[Install] +# Start by default on boot +WantedBy=multi-user.target default.target diff --git a/wobischdev/onyx-dev-wobischdev.kube b/wobischdev/onyx-dev-wobischdev.kube new file mode 100644 index 0000000..f067833 --- /dev/null +++ b/wobischdev/onyx-dev-wobischdev.kube @@ -0,0 +1,17 @@ +[Unit] +Description=wobisch +Before=local-fs.target + +[Kube] +Yaml=/data/onyx-dev_pods/wobischdev/wobischdev.yaml +LogDriver=journald +Network=pasta:-T,25:25 + +[Service] +Restart=always +RestartSec=15 +TimeoutStartSec=300 + +[Install] +# Start by default on boot +WantedBy=multi-user.target default.target