{"id":13928963,"url":"https://github.com/operate-first/hetzner-baremetal-openshift","last_synced_at":"2026-01-16T19:57:06.161Z","repository":{"id":43657659,"uuid":"319920514","full_name":"operate-first/hetzner-baremetal-openshift","owner":"operate-first","description":"OpenShift 4 on Hetzner BareMetal (dedicted server)","archived":false,"fork":false,"pushed_at":"2023-06-08T14:54:17.000Z","size":899,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-08-08T18:21:03.167Z","etag":null,"topics":["bare-metal","dedicated-server","hetzner","openshift"],"latest_commit_sha":null,"homepage":"","language":"YAML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/operate-first.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-12-09T10:27:48.000Z","updated_at":"2024-06-11T01:18:54.000Z","dependencies_parsed_at":"2022-08-23T04:20:55.983Z","dependency_job_id":null,"html_url":"https://github.com/operate-first/hetzner-baremetal-openshift","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operate-first%2Fhetzner-baremetal-openshift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operate-first%2Fhetzner-baremetal-openshift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operate-first%2Fhetzner-baremetal-openshift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operate-first%2Fhetzner-baremetal-openshift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/operate-first","download_url":"https://codeload.github.com/operate-first/hetzner-baremetal-openshift/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226588911,"owners_count":17655802,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bare-metal","dedicated-server","hetzner","openshift"],"created_at":"2024-08-07T18:02:01.066Z","updated_at":"2026-01-16T19:57:06.134Z","avatar_url":"https://github.com/operate-first.png","language":"YAML","funding_links":[],"categories":["others"],"sub_categories":[],"readme":"# OpenShift 4 on Hetzner BareMetal (dedicted server)\n\n## Network Overview\n\n![Network overview](docs/images/network-overview-v4.png)\n\n\n## Cluster design\n\nDeppends on the cluster.\n\nBut for all: One of the worker is used to be the bootstrap during installation.\n\n## Installation\n\nYou can run all playbooks inside a toolbox [![Docker Repository on Quay](https://quay.io/repository/operate-first/hetzner-baremetal-toolbox/status \"Docker Repository on Quay\")](https://quay.io/repository/operate-first/hetzner-baremetal-toolbox) :\n\n```bash\ntoolbox create --image quay.io/operate-first/hetzner-baremetal-toolbox hetzner-toolbox\ntoolbox enter hetzner-toolbox\n```\n\nSource of the toolbox [Containerfile](/Containerfile)\n\n\n### Create initial hosts.yaml based on hosts.yaml.example\n\n```bash\ncp -v hosts.yaml.example hosts.yaml\n$EDITOR hosts.yaml\n```\n\n### DNS \u0026 load balancer/router preperations\n\n  * Order a BareMetal Server as Load Balancer \u0026 Router.\n      * [Prepare RHEL 8 Image](https://keithtenzer.com/cloud/how%20-to-create-a-rhel-8-image-for-hetzner-root-servers/)\n      * Install Server with RHEL 8\n\n  * Configure Network (public \u0026 private)\n      * Coonfigure server as router between priavet and public (act as default gateway for alle nodes.)\n\n  * Configure load balancer:\n      * Public for api \u0026 ingress\n      * Private for api-int\n\n  * Configure DNS entries for\n      * `api.\u003ccluster_name\u003e.emea.operate-first.cloud`\n      * `api-int.\u003ccluster_name\u003e.emea.operate-first.cloud`\n      * `*.apps.\u003ccluster_name\u003e.emea.operate-first.cloud`\n\n\n### Hardware preperations\n\n  * Order a BareMetal Server - Issue for sizing: #6\n\n  * Configure DNS ( A \u0026 PTR ) for BareMetal Server\n      `\u003chostname\u003e.emea.operate-first.cloud`\n\n  * Create private vSwitch and add ID to `hosts.yaml`\n\n  * Attach server to private vSwitch\n\n  * [Install Centos 8 to determine the network interface name](docs/install-centos-8.md)\n\n  * Check network interface names on centos 8: `ansible -m shell -a \"ip link | grep enp | cut -f2 -d':'\" all`\n\n  * Add server to `hosts.yaml`\n\n  * Wipe all servers after Centos 8 installaion: `./wipe.yaml`\n    Please run `./wipe.yaml` again if some failed agure.\n\n  * Run a RH CoreOS Test installation with ssh-only ignition\n    ```bash\n    ./reset-server.yaml [-l hostname]\n    # SSh into rescue system and run coreos-install\n    #  command printed out at the end ot the playbook.\n    ```\n\n    Check installation, server boot? Can connect via SSH?\n\n  * Boot Rescue mode\n\n    ```bash\n    ./force-rescue-mode.yaml [-l hostname]\n    ```\n\n    Check if resecue system is booted:\n\n      **If NOT**: File a ticket to switch into EFI boot (Example Tickets: Ticket#2021050503020988, Ticket#2021050603003594, Ticket#2021051903013942)\n\n  * Check if you can switch between RH CoreOS and rescue mode.\n\n  * Configure firewall\n    ```bash\n    ./configure-hrobot-firewall.yaml [-l hostname]\n    ```\n\n### OpenShift installation\n\nPrerequisites:\n  * At least 4 prepared nodes (see Hardware preperations)\n  * DNS \u0026 load balancer preperations\n\n\n#### Reset server\n\nBoots into rescue mode and prepare rescue system to install Red Hat CoreOS\n\n```bash\n./reset-server.yaml\n```\n\n#### Wipe  server\n\nTo ensure nothing is on the disk wipe it:\n\n```bash\n./wipe-server.yaml\n```\n\n\n#### Create ignition config and transfer to hosts\n\n```bash\n./create-ignition.yaml\n```\n\n#### Run the installer\n\n\n```bash\n./run-installer.yaml\n```\n\nOptional split it into two steps:\n\n```bash\n./run-installer.yaml --skip-tags reboot\n# Check output\n./run-installer.yaml --tags reboot\n```\n\n#### During installation watch for CSR\n\nAccept pending CSR from your worker nodes\n\n```bash\noc get csr | awk '/Pending/ { print $1}' | xargs -n1 oc adm certificate approve\n```\n\n### Add bootstrap node as worker\n\n#### Adjust haproxy config\n\n```bash\nssh -l root -i \u003cprivate-key\u003e \u003cprivate lb vm\u003e\nvi /etc/haproxy/haproxy.cfg\nsystemctl reload haproxy\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eCheck a proxy stats\u003c/summary\u003e\n\n```bash\necho \"show stat\" | nc -U /var/lib/haproxy/stats | cut -d \",\" -f 1,2,18,57| column -s, -t;\n# pxname               svname                           status  last_chk\nmachine-config-server  FRONTEND                         OPEN\nmachine-config-server  host01.example.com  UP\nmachine-config-server  host02.example.com  UP\nmachine-config-server  host04.example.com  UP\nmachine-config-server  BACKEND                          UP\napi                    FRONTEND                         OPEN\napi                    host01.example.com  UP\napi                    host02.example.com  UP\napi                    host04.example.com  UP\napi                    BACKEND                          UP\n```\n\n\u003c/details\u003e\n\n#### Adjust `host.yaml`\n\nMove bootstrap node from bootstrap to worker hostgroup.\n\n#### Boot rescure mode\n\n```bash\n ./force-rescue-mode.yaml -l \u003cbootstrap-node\u003e\n```\n\n#### Prepare installation\n```bash\n./reset-server.yaml -l \u003cbootstrap-node\u003e\n```\n\n#### Preare ignition config\n```bash\n./create-ignition.yaml -l \u003cbootstrap-node\u003e\n```\n\n#### Wipe server\n\n```bash\n./wipe-server.yaml -l \u003cbootstrap-node\u003e\n```\n\n#### Run the installer\n\n\n```bash\n./run-installer.yaml -l \u003cbootstrap-node\u003e\n```\n\nOptional split it into two steps:\n\n```bash\n./run-installer.yaml --skip-tags reboot -l \u003cbootstrap-node\u003e\n# Check output\n./run-installer.yaml --tags reboot -l \u003cbootstrap-node\u003e\n```\n\n#### Watch for pending CSRs\n\nAccept pending CSR from your worker node.\n\n```bash\noc get csr | awk '/Pending/ { print $1}' | xargs -n1 oc adm certificate approve\n```\n\n### Post installation\n\n#### Remove worker label from master\n\n```\noc edit scheduler\n```\nChange `mastersSchedulable: true` to `mastersSchedulable: false`\n\n\n### OpenShift reinstallation\n\nIts recommended to wipe the disk with `wipe-server.yaml` playbook bevor reinstallation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foperate-first%2Fhetzner-baremetal-openshift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foperate-first%2Fhetzner-baremetal-openshift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foperate-first%2Fhetzner-baremetal-openshift/lists"}