Browse Source

add flatcar support for Hetzner (#9618)

pull/9624/head
florianow 1 year ago
committed by GitHub
parent
commit
8267922a16
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 346 additions and 3 deletions
  1. 17
      contrib/terraform/hetzner/README.md
  2. 2
      contrib/terraform/hetzner/default.tfvars
  3. 6
      contrib/terraform/hetzner/main.tf
  4. 202
      contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/main.tf
  5. 27
      contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/outputs.tf
  6. 16
      contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/templates/machine.yaml.tmpl
  7. 60
      contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/variables.tf
  8. 13
      contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/versions.tf
  9. 6
      contrib/terraform/hetzner/variables.tf

17
contrib/terraform/hetzner/README.md

@ -56,11 +56,24 @@ cd inventory/$CLUSTER
Edit `default.tfvars` to match your requirement.
Flatcar Container Linux instead of the basic Hetzner Images.
```bash
cd ../../contrib/terraform/hetzner
```
Edit `main.tf` and reactivate the module `source = "./modules/kubernetes-cluster-flatcar"`and
comment out the `#source = "./modules/kubernetes-cluster"`.
activate `ssh_private_key_path = var.ssh_private_key_path`. The VM boots into
Rescue-Mode with the selected image of the `var.machines` but installs Flatcar instead.
Run Terraform to create the infrastructure.
```bash
terraform init ../../contrib/terraform/hetzner
terraform apply --var-file default.tfvars ../../contrib/terraform/hetzner/
cd ./kubespray
terraform -chdir=./contrib/terraform/hetzner/ init
terraform -chdir=./contrib/terraform/hetzner/ apply --var-file=../../../inventory/$CLUSTER/default.tfvars
```
You should now have a inventory file named `inventory.ini` that you can use with kubespray.

2
contrib/terraform/hetzner/default.tfvars

@ -9,6 +9,8 @@ ssh_public_keys = [
"ssh-rsa I-did-not-read-the-docs 2",
]
ssh_private_key_path = "~/.ssh/id_rsa"
machines = {
"master-0" : {
"node_type" : "master",

6
contrib/terraform/hetzner/main.tf

@ -2,6 +2,7 @@ provider "hcloud" {}
module "kubernetes" {
source = "./modules/kubernetes-cluster"
#source = "./modules/kubernetes-cluster-flatcar"
prefix = var.prefix
@ -9,6 +10,9 @@ module "kubernetes" {
machines = var.machines
#only for flatcar
#ssh_private_key_path = var.ssh_private_key_path
ssh_public_keys = var.ssh_public_keys
network_zone = var.network_zone
@ -49,4 +53,4 @@ resource "null_resource" "inventories" {
triggers = {
template = data.template_file.inventory.rendered
}
}
}

202
contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/main.tf

@ -0,0 +1,202 @@
resource "hcloud_network" "kubernetes" {
name = "${var.prefix}-network"
ip_range = var.private_network_cidr
}
resource "hcloud_network_subnet" "kubernetes" {
type = "cloud"
network_id = hcloud_network.kubernetes.id
network_zone = var.network_zone
ip_range = var.private_subnet_cidr
}
resource "hcloud_ssh_key" "first" {
name = var.prefix
public_key = var.ssh_public_keys.0
}
resource "hcloud_server" "master" {
for_each = {
for name, machine in var.machines :
name => machine
if machine.node_type == "master"
}
name = "${var.prefix}-${each.key}"
ssh_keys = [hcloud_ssh_key.first.id]
# boot into rescue OS
rescue = "linux64"
# dummy value for the OS because Flatcar is not available
image = each.value.image
server_type = each.value.size
location = var.zone
connection {
host = self.ipv4_address
timeout = "5m"
private_key = file(var.ssh_private_key_path)
}
firewall_ids = [hcloud_firewall.machine.id]
provisioner "file" {
content = data.ct_config.machine-ignitions[each.key].rendered
destination = "/root/ignition.json"
}
provisioner "remote-exec" {
inline = [
"set -ex",
"apt update",
"apt install -y gawk",
"curl -fsSLO --retry-delay 1 --retry 60 --retry-connrefused --retry-max-time 60 --connect-timeout 20 https://raw.githubusercontent.com/kinvolk/init/flatcar-master/bin/flatcar-install",
"chmod +x flatcar-install",
"./flatcar-install -s -i /root/ignition.json",
"shutdown -r +1",
]
}
# optional:
provisioner "remote-exec" {
connection {
host = self.ipv4_address
timeout = "3m"
user = var.user_flatcar
}
inline = [
"sudo hostnamectl set-hostname ${self.name}",
]
}
}
resource "hcloud_server_network" "master" {
for_each = hcloud_server.master
server_id = each.value.id
subnet_id = hcloud_network_subnet.kubernetes.id
}
resource "hcloud_server" "worker" {
for_each = {
for name, machine in var.machines :
name => machine
if machine.node_type == "worker"
}
name = "${var.prefix}-${each.key}"
ssh_keys = [hcloud_ssh_key.first.id]
# boot into rescue OS
rescue = "linux64"
# dummy value for the OS because Flatcar is not available
image = each.value.image
server_type = each.value.size
location = var.zone
connection {
host = self.ipv4_address
timeout = "5m"
private_key = file(var.ssh_private_key_path)
}
firewall_ids = [hcloud_firewall.machine.id]
provisioner "file" {
content = data.ct_config.machine-ignitions[each.key].rendered
destination = "/root/ignition.json"
}
provisioner "remote-exec" {
inline = [
"set -ex",
"apt update",
"apt install -y gawk",
"curl -fsSLO --retry-delay 1 --retry 60 --retry-connrefused --retry-max-time 60 --connect-timeout 20 https://raw.githubusercontent.com/kinvolk/init/flatcar-master/bin/flatcar-install",
"chmod +x flatcar-install",
"./flatcar-install -s -i /root/ignition.json",
"shutdown -r +1",
]
}
# optional:
provisioner "remote-exec" {
connection {
host = self.ipv4_address
timeout = "3m"
user = var.user_flatcar
}
inline = [
"sudo hostnamectl set-hostname ${self.name}",
]
}
}
resource "hcloud_server_network" "worker" {
for_each = hcloud_server.worker
server_id = each.value.id
subnet_id = hcloud_network_subnet.kubernetes.id
}
data "ct_config" "machine-ignitions" {
for_each = {
for name, machine in var.machines :
name => machine
}
content = data.template_file.machine-configs[each.key].rendered
}
data "template_file" "machine-configs" {
for_each = {
for name, machine in var.machines :
name => machine
}
template = file("${path.module}/templates/machine.yaml.tmpl")
vars = {
ssh_keys = jsonencode(var.ssh_public_keys)
user_flatcar = jsonencode(var.user_flatcar)
name = each.key
}
}
resource "hcloud_firewall" "machine" {
name = "${var.prefix}-machine-firewall"
rule {
direction = "in"
protocol = "tcp"
port = "22"
source_ips = var.ssh_whitelist
}
rule {
direction = "in"
protocol = "tcp"
port = "6443"
source_ips = var.api_server_whitelist
}
}
resource "hcloud_firewall" "worker" {
name = "${var.prefix}-worker-firewall"
rule {
direction = "in"
protocol = "tcp"
port = "22"
source_ips = var.ssh_whitelist
}
rule {
direction = "in"
protocol = "tcp"
port = "80"
source_ips = var.ingress_whitelist
}
rule {
direction = "in"
protocol = "tcp"
port = "443"
source_ips = var.ingress_whitelist
}
rule {
direction = "in"
protocol = "tcp"
port = "30000-32767"
source_ips = var.nodeport_whitelist
}
}

27
contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/outputs.tf

@ -0,0 +1,27 @@
output "master_ip_addresses" {
value = {
for key, instance in hcloud_server.master :
instance.name => {
"private_ip" = hcloud_server_network.master[key].ip
"public_ip" = hcloud_server.master[key].ipv4_address
}
}
}
output "worker_ip_addresses" {
value = {
for key, instance in hcloud_server.worker :
instance.name => {
"private_ip" = hcloud_server_network.worker[key].ip
"public_ip" = hcloud_server.worker[key].ipv4_address
}
}
}
output "cluster_private_network_cidr" {
value = var.private_subnet_cidr
}
output "network_id" {
value = hcloud_network.kubernetes.id
}

16
contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/templates/machine.yaml.tmpl

@ -0,0 +1,16 @@
---
passwd:
users:
- name: ${user_flatcar}
ssh_authorized_keys: ${ssh_keys}
storage:
files:
- path: /home/core/works
filesystem: root
mode: 0755
contents:
inline: |
#!/bin/bash
set -euo pipefail
hostname="$(hostname)"
echo My name is ${name} and the hostname is $${hostname}

60
contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/variables.tf

@ -0,0 +1,60 @@
variable "zone" {
type = string
default = "fsn1"
}
variable "prefix" {
default = "k8s"
}
variable "user_flatcar" {
type = string
default = "core"
}
variable "machines" {
type = map(object({
node_type = string
size = string
image = string
}))
}
variable "ssh_public_keys" {
type = list(string)
}
variable "ssh_private_key_path" {
type = string
default = "~/.ssh/id_rsa"
}
variable "ssh_whitelist" {
type = list(string)
}
variable "api_server_whitelist" {
type = list(string)
}
variable "nodeport_whitelist" {
type = list(string)
}
variable "ingress_whitelist" {
type = list(string)
}
variable "private_network_cidr" {
default = "10.0.0.0/16"
}
variable "private_subnet_cidr" {
default = "10.0.10.0/24"
}
variable "network_zone" {
default = "eu-central"
}

13
contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/versions.tf

@ -0,0 +1,13 @@
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
}
ct = {
source = "poseidon/ct"
}
null = {
source = "hashicorp/null"
}
}
}

6
contrib/terraform/hetzner/variables.tf

@ -25,6 +25,12 @@ variable "ssh_public_keys" {
type = list(string)
}
variable "ssh_private_key_path" {
description = "Private SSH key which connect to the VMs."
type = string
default = "~/.ssh/id_rsa"
}
variable "ssh_whitelist" {
description = "List of IP ranges (CIDR) to whitelist for ssh"
type = list(string)

Loading…
Cancel
Save