mirror of
https://github.com/Luzifer/hetzner-alpine-k8s.git
synced 2024-12-21 02:11:19 +00:00
101 lines
5.6 KiB
Markdown
101 lines
5.6 KiB
Markdown
|
This folder contains a modified copy of [MathiasPius/alpine-on-hetzner](https://github.com/MathiasPius/alpine-on-hetzner).
|
||
|
|
||
|
----
|
||
|
|
||
|
# alpine-hetzner
|
||
|
Tool for building cloud-init ready Alpine snapshots on Hetzner Cloud.
|
||
|
|
||
|
You can either run it as a docker container or as a regular packer build (see [entrypoint.sh](/entrypoint.sh) for hints on how), but this latter method is not officially supported.
|
||
|
|
||
|
# Examples
|
||
|
|
||
|
### Create an alpine image with the [default](/default.json) configuration
|
||
|
Running this will create an `alpine` snapshot within your Hetzner Cloud project, ready to use for creating new servers. See the [launching a server](#launching-a-server) section for how to test it!
|
||
|
```shell
|
||
|
docker run -it --rm -e "HCLOUD_TOKEN=<YourTokenHere>" ghcr.io/mathiaspius/alpine-on-hetzner:latest
|
||
|
```
|
||
|
|
||
|
### Default image, with `doas` installed, and `template.local` as default hostname
|
||
|
Configuration values can be overwritten by creating new configuration file with just the changes you want, and supplying the path as an argument when running it. See [Custom Configuration](#custom-configuration) for technical details on how the values are merged.
|
||
|
```shell
|
||
|
mkdir -p configs
|
||
|
echo '{
|
||
|
"packages": { "doas": "=6.8.1-r7" },
|
||
|
"hostname": "template.local"
|
||
|
}' > configs/my-override.json
|
||
|
|
||
|
|
||
|
export HCLOUD_TOKEN=myHetznerCloudToken
|
||
|
docker run -it --rm \
|
||
|
-e "HCLOUD_TOKEN" \
|
||
|
-v "$(pwd)/configs:/configs" \
|
||
|
ghcr.io/mathiaspius/alpine-on-hetzner:latest default.json /configs/my-override.json
|
||
|
```
|
||
|
|
||
|
There are a number of optional docker mounts you can use:
|
||
|
* `/manifests` contains the output manifests from the run.
|
||
|
* `/cache` used for caching the `apk-tools` package locally between runs.
|
||
|
* `/configs` used for providing [custom configuration files](#custom-configuration) to builds.
|
||
|
|
||
|
# Custom Configuration
|
||
|
Any command arguments passed to the docker run invocation will be treated as paths to configuration files to merge into a single combined configuration file which is then fed into the packer build.
|
||
|
|
||
|
The merge is a "deep merge", meaning you can only *add to* or *change* the configuration file not remove from it. If you want to remove a package from the default.json configuration for example you will have to create a copy of it without the package in question and use that as the basis for your build.
|
||
|
|
||
|
### Adding a custom package to your image
|
||
|
In order to add a custom package like `nginx` for example you can create the following config file `configs/nginx.json` in your local directory:
|
||
|
```json
|
||
|
{ "packages": { "nginx": "" } }
|
||
|
```
|
||
|
<sup><sub>`packages` is a map where the keys are package names and the value is the version selector. The map is passed directly to an `apk add` command, see [this link](https://wiki.alpinelinux.org/wiki/Package_management#Holding_a_specific_package_back) for version-pinning syntax.</sub></sup>
|
||
|
|
||
|
When the container is then run like so:
|
||
|
```shell
|
||
|
docker run -it --rm \
|
||
|
-e "HCLOUD_TOKEN" \
|
||
|
-v "$(pwd)/configs:/configs" \
|
||
|
ghcr.io/mathiaspius/alpine-on-hetzner:latest default.json /configs/nginx.json
|
||
|
```
|
||
|
The package will be appended to `packages` array, like so, immediately before the packer build runs:
|
||
|
```json
|
||
|
{
|
||
|
(...)
|
||
|
"packages": {
|
||
|
"openssh": "=8.8_p1-r1",
|
||
|
"syslinux": "=6.04_pre1-r9",
|
||
|
"linux-virt": "=5.15.16-r0",
|
||
|
"cloud-init": "@community=21.4-r0",
|
||
|
"nginx": ""
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
# What's in the finished snapshot?
|
||
|
See the [default.json](/default.json) config for a list of packages that will be installed into the snapshot if run without any arguments.
|
||
|
|
||
|
[playbook.yml](/playbook.yml) contains the entire ansible playbook used for generating the snapshot.
|
||
|
[alpine.pkr.hcl](/alpine.pkr.hcl) contains the packer build configuration which uses the playbook above via the [Ansible Provisioner](https://www.packer.io/plugins/provisioners/ansible/ansible)
|
||
|
|
||
|
# How it works
|
||
|
The docker image comes with packer, ansible and jq pre-installed (check labels for versions), and builds the [alpine.pkr.hcl](/alpine.pkr.hcl) build against your Hetzner Cloud project using your provided API key. The Packer build will boot a server in rescue mode, then format and install Alpine Linux onto the primary drive of the server. Once done, the server will be saved as a snapshot and shut down. You can then create Alpine Linux servers using the finished snapshot.
|
||
|
|
||
|
# Launching a server
|
||
|
Servers built from the snapshot won't be immediately accessible because the root user is locked by default, but can be configured using the Hetzner interface. Use the following cloud-init config to enable root access and select an ssh key when creating the server to allow login:
|
||
|
```yaml
|
||
|
#cloud-config
|
||
|
disable_root: false
|
||
|
users:
|
||
|
- name: root
|
||
|
lock-passwd: false
|
||
|
```
|
||
|
|
||
|
# Development
|
||
|
I have a number of ideas I would like to explore:
|
||
|
|
||
|
- [ ] Re-using or expanding this tool to provision Alpine Linux on dedicated servers, but maintaining the same configuration -interface. I've previously done a less refined version fo this project for dedicated servers [here](https://github.com/MathiasPius/hetzner-zfs-host)
|
||
|
- [ ] Splitting up configuration files so you can mix-and-match a little more. Would also allow optional *hardened* configurations for example which you could opt into for stricter security.
|
||
|
- [ ] Creating configuration files for older versions of Alpine Linux.
|
||
|
- [x] Pipelining alpine-on-hetzner docker image builds and perhaps more importantly..
|
||
|
- [ ] .. Testing that they work.
|
||
|
- [x] Add more customization abilities to the configuration file. Being able to enable openrc services with a simple array for example would be simple to implement and very useful.
|