Compare commits

2 Commits

Author SHA1 Message Date
Max
44d59737c7 bug: stuck 2026-01-01 17:10:55 -05:00
Max
b04298adfb test: try doing the lb separately 2026-01-01 15:59:48 -05:00
8 changed files with 230 additions and 206 deletions

View File

@@ -4,7 +4,7 @@
vars_files: vars_files:
- ../vault.yml - ../vault.yml
tasks: tasks:
- name: Destroy - name: Destroy Terraform.
community.general.terraform: community.general.terraform:
project_path: '../terraform' project_path: '../terraform'
state: "absent" state: "absent"

View File

@@ -1,140 +1,154 @@
- name: Configure compute for the cluster. # - name: Configure compute for the cluster.
hosts: servers # hosts: servers
gather_facts: false # gather_facts: false
vars: # vars:
kubernetes_version: v1.30 # kubernetes_version: v1.30
tasks: # tasks:
- name: Download Kubernetes key. # - name: Download Kubernetes key.
ansible.builtin.apt_key: # ansible.builtin.apt_key:
url: https://pkgs.k8s.io/core:/stable:/{{ kubernetes_version }}/deb/Release.key # url: https://pkgs.k8s.io/core:/stable:/{{ kubernetes_version }}/deb/Release.key
state: present # state: present
- name: Download Kubernetes repository. # - name: Download Kubernetes repository.
ansible.builtin.apt_repository: # ansible.builtin.apt_repository:
repo: "deb https://pkgs.k8s.io/core:/stable:/{{ kubernetes_version }}/deb/ /" # repo: "deb https://pkgs.k8s.io/core:/stable:/{{ kubernetes_version }}/deb/ /"
state: present # state: present
- name: Download CRI-O key. # - name: Download CRI-O key.
ansible.builtin.apt_key: # ansible.builtin.apt_key:
url: https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/Release.key # url: https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/Release.key
state: present # state: present
- name: Download CRI-O repository. # - name: Download CRI-O repository.
ansible.builtin.apt_repository: # ansible.builtin.apt_repository:
repo: "deb https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/ /" # repo: "deb https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/ /"
state: present # state: present
- name: Download Helm key. # - name: Download Helm key.
ansible.builtin.apt_key: # ansible.builtin.apt_key:
url: https://packages.buildkite.com/helm-linux/helm-debian/gpgkey # url: https://packages.buildkite.com/helm-linux/helm-debian/gpgkey
state: present # state: present
- name: Download Helm repository. # - name: Download Helm repository.
ansible.builtin.apt_repository: # ansible.builtin.apt_repository:
repo: "deb https://packages.buildkite.com/helm-linux/helm-debian/any/ any main" # repo: "deb https://packages.buildkite.com/helm-linux/helm-debian/any/ any main"
state: present # state: present
- name: Install packages. # - name: Install packages.
ansible.builtin.apt: # ansible.builtin.apt:
state: present # state: present
update_cache: true # update_cache: true
name: [cri-o, kubelet, kubeadm, kubectl, python3-pip, helm, git] # name: [cri-o, kubelet, kubeadm, kubectl, python3-pip, helm, git]
- name: Install Kubernetes Python packages. # - name: Install Kubernetes Python packages.
ansible.builtin.pip: # ansible.builtin.pip:
name: [kubernetes, pyyaml] # name: [kubernetes, pyyaml]
state: present # state: present
break_system_packages: true # break_system_packages: true
- name: Enable IPv4 forwarding. # - name: Enable `br_netfilter` module.
ansible.posix.sysctl: # community.general.modprobe:
name: net.ipv4.ip_forward # name: br_netfilter
value: '1' # state: present
sysctl_set: true # notify: Reboot the nodes.
notify: Reboot the nodes.
- name: Enable `br_netfilter` module. # - name: Configure `sysctl` permanently.
community.general.modprobe: # ansible.posix.sysctl:
name: br_netfilter # name: '{{ item }}'
state: present # value: '1'
notify: Reboot the nodes. # state: present
# reload: true
# loop:
# - net.bridge.bridge-nf-call-iptables
# - net.ipv4.ip_forward
handlers: # handlers:
- name: Reboot the nodes. # - name: Reboot the nodes.
ansible.builtin.reboot: # ansible.builtin.reboot:
- name: Spawn new cluster on control node. # - name: Spawn new cluster on control node.
hosts: control # hosts: control
gather_facts: false # gather_facts: false
vars: # vars:
config_template: ../templates/InitConfiguration.yml.jinja2 # config_template: ../templates/InitConfiguration.yml.jinja2
config: # config:
bootstrap_token: "{{ secrets.bootstrap_token }}" # bootstrap_token: "{{ secrets.bootstrap_token }}"
node_ip: 10.0.2.11 # node_ip: 10.0.2.11
node_name: control # node_name: control
vars_files: # vars_files:
- ../vault.yml # - ../vault.yml
tasks: # tasks:
- name: Test for cluster. # - name: Test for cluster.
kubernetes.core.k8s_cluster_info: # kubernetes.core.k8s_cluster_info:
register: api_status # register: api_status
ignore_errors: true # ignore_errors: true
- name: Copy configuration over. # - name: Copy configuration over.
ansible.builtin.template: # ansible.builtin.template:
src: "{{ config_template }}" # src: "{{ config_template }}"
dest: InitConfiguration.yml # dest: InitConfiguration.yml
mode: preserve # mode: preserve
when: "api_status.failed" # when: "api_status.failed"
- name: Initialize cluster. # - name: Initialize cluster.
ansible.builtin.command: # ansible.builtin.command:
kubeadm init --config InitConfiguration.yml # kubeadm init --config InitConfiguration.yml
changed_when: true # changed_when: true
when: "api_status.failed" # when: "api_status.failed"
- name: Apply the Kubernetes config to the shell. # - name: Apply the Kubernetes config to the shell.
ansible.builtin.lineinfile: # ansible.builtin.lineinfile:
path: /etc/environment # path: /etc/environment
line: 'KUBECONFIG=/etc/kubernetes/admin.conf' # line: 'KUBECONFIG=/etc/kubernetes/admin.conf'
when: "api_status.failed" # when: "api_status.failed"
- name: Join worker nodes to cluster. # - name: Join worker nodes to cluster.
hosts: [node-a, node-b] # hosts: [node-a, node-b]
vars: # vars:
join_template: ../templates/JoinConfiguration.yml.jinja2 # join_template: ../templates/JoinConfiguration.yml.jinja2
join_control_ip: 10.0.2.11 # join_control_ip: 10.0.2.11
join_bootstrap_token: "{{ secrets.bootstrap_token }}" # join_bootstrap_token: "{{ secrets.bootstrap_token }}"
vars_files: # vars_files:
- ../vault.yml # - ../vault.yml
tasks: # tasks:
- name: Copy join configuration over. # - name: Copy join configuration over.
vars: # vars:
join_worker_ip: "{{ ansible_default_ipv4.address }}" # join_worker_ip: "{{ ansible_default_ipv4.address }}"
join_worker_name: "{{ ansible_hostname }}" # join_worker_name: "{{ ansible_hostname }}"
ansible.builtin.template: # ansible.builtin.template:
src: "{{ join_template }}" # src: "{{ join_template }}"
dest: JoinConfiguration.yml # dest: JoinConfiguration.yml
mode: preserve # mode: preserve
- name: Join the nodes. # - name: Join the nodes.
ansible.builtin.command: # ansible.builtin.command:
kubeadm join --config JoinConfiguration.yml # kubeadm join --config JoinConfiguration.yml
changed_when: true # changed_when: true
- name: Install Helm Diff. # - name: Install Helm Diff.
gather_facts: false # gather_facts: false
hosts: control # hosts: control
tasks: # tasks:
- name: Install it. # - name: Install it.
kubernetes.core.helm_plugin: # kubernetes.core.helm_plugin:
plugin_path: https://github.com/databus23/helm-diff # plugin_path: https://github.com/databus23/helm-diff
state: present # state: present
- name: Install CNI. - name: Install CNI.
gather_facts: false gather_facts: false
hosts: control hosts: control
tasks: tasks:
- name: Assign nodes as workers.
kubernetes.core.k8s:
state: patched
kind: Node
name: "{{ item }}"
definition:
metadata:
labels:
node-role.kubernetes.io/worker: worker
loop: [node-a, node-b]
- name: Create Flannel namespace. - name: Create Flannel namespace.
kubernetes.core.k8s: kubernetes.core.k8s:
state: present state: present
@@ -179,58 +193,12 @@
value: "true" value: "true"
effect: NoSchedule effect: NoSchedule
- name: Install Hetzner Cloud Controller. - name: Install `nginx` Controller.
gather_facts: false gather_facts: false
hosts: control hosts: control
vars_files: vars_files:
- ../vault.yml - ../vault.yml
- ../secrets/tf_outputs.yml - ../secrets/tf_outputs.yml
tasks:
- name: Create `hcloud` secret.
kubernetes.core.k8s:
name: hcloud
namespace: kube-system
kind: Secret
state: present
definition:
apiVersion: v1
kind: Secret
metadata:
name: hcloud
namespace: kube-system
type: Opaque
data:
token: "{{ secrets.hcloud_token | b64encode }}"
network: "{{ private_network_id.value | b64encode }}"
- name: Add Cloud Controller repository.
kubernetes.core.helm_repository:
name: hcloud
url: https://charts.hetzner.cloud
state: present
- name: Copy over values file.
vars:
values_template: ../templates/HCCMValues.yml.jinja2
ansible.builtin.template:
src: "{{ values_template }}"
dest: HCCMValues.yml
mode: preserve
- name: Install it.
kubernetes.core.helm:
name: hccm
chart_ref: hcloud/hcloud-cloud-controller-manager
namespace: kube-system
state: present
update_repo_cache: true
force: true
values_files: [HCCMValues.yml]
- name: Install `nginx` Controller.
gather_facts: false
hosts: control
tasks: tasks:
- name: Remove schedule taint to nodes. - name: Remove schedule taint to nodes.
kubernetes.core.k8s_taint: kubernetes.core.k8s_taint:
@@ -251,6 +219,9 @@
- name: Copy over values file. - name: Copy over values file.
vars: vars:
values_template: ../templates/IngressValues.yml.jinja2 values_template: ../templates/IngressValues.yml.jinja2
load_balancer_name: "{{ variables.load_balancer_name }}"
network_zone: "{{ variables.network_zone }}"
certificate_name: "test"
ansible.builtin.template: ansible.builtin.template:
src: "{{ values_template }}" src: "{{ values_template }}"
dest: IngressValues.yml dest: IngressValues.yml

View File

@@ -4,14 +4,13 @@ controller:
kind: DaemonSet kind: DaemonSet
service: service:
annotations: annotations:
load-balancer.hetzner.cloud/name: "hetzner-lb" load-balancer.hetzner.cloud/name: {{ load_balancer_name }}
load-balancer.hetzner.cloud/location: "fsn1"
load-balancer.hetzner.cloud/type: "lb11" load-balancer.hetzner.cloud/type: "lb11"
load-balancer.hetzner.cloud/ipv6-disabled: "true" load-balancer.hetzner.cloud/ipv6-disabled: "true"
load-balancer.hetzner.cloud/use-private-ip: "true" load-balancer.hetzner.cloud/use-private-ip: "true"
load-balancer.hetzner.cloud/protocol: "https" load-balancer.hetzner.cloud/protocol: "https"
load-balancer.hetzner.cloud/network-zone: "eu-central" load-balancer.hetzner.cloud/network-zone: {{ network_zone }}
load-balancer.hetzner.cloud/http-certificates: "managed_cert" load-balancer.hetzner.cloud/http-certificates: {{ certificate_name }}
load-balancer.hetzner.cloud/http-redirect-http: "true" load-balancer.hetzner.cloud/http-redirect-http: "true"
enableHttp: false enableHttp: false
targetPorts: targetPorts:

View File

@@ -51,3 +51,18 @@ resource "hcloud_server" "server" {
depends_on = [hcloud_network_subnet.subnet] depends_on = [hcloud_network_subnet.subnet]
} }
resource "hcloud_load_balancer" "lb" {
name = "lb-hetzner"
load_balancer_type = "lb11"
network_zone = "eu-central"
}
resource "hcloud_load_balancer_target" "load_balancer_target" {
for_each = hcloud_server.server
type = "server"
load_balancer_id = hcloud_load_balancer.lb.id
use_private_ip = true
server_id = each.value.id
}

View File

@@ -20,8 +20,9 @@ resource "hcloud_network_route" "gateway" {
gateway = local.nat-private-ip gateway = local.nat-private-ip
} }
// A managed certificate for the domain, to be used by the load balancer. // Attach the load blaancer to the private network.
resource "hcloud_managed_certificate" "managed_cert" { resource "hcloud_load_balancer_network" "attachment" {
name = "managed_cert" load_balancer_id = hcloud_load_balancer.lb.id
domain_names = ["*.${local.domain}", "${local.domain}"] subnet_id = hcloud_network_subnet.subnet.id
ip = local.lb-private-ip
} }

32
terraform/routing.tf Normal file
View File

@@ -0,0 +1,32 @@
data "hcloud_zone" "zone" {
name = local.domain
}
// Attach the load balancer to the domain.
resource "hcloud_zone_rrset" "records" {
for_each = toset(["@", "*"])
zone = data.hcloud_zone.zone.name
name = each.value
type = "A"
ttl = 60
records = [{ value = hcloud_load_balancer.lb.ipv4 }]
change_protection = false
}
// A managed certificate for the domain, to be used by the load balancer.
resource "hcloud_managed_certificate" "main" {
name = local.certificate_name
domain_names = ["*.${local.domain}", "${local.domain}"]
}
resource "hcloud_load_balancer_service" "load_balancer_service" {
load_balancer_id = hcloud_load_balancer.lb.id
protocol = "https"
http {
sticky_sessions = true
certificates = [hcloud_managed_certificate.main.id]
redirect_http = true
}
}

View File

@@ -11,6 +11,8 @@ locals {
} }
domain = "maximhutz.com" domain = "maximhutz.com"
certificate_name = "Main Certificate"
} }
variable "public_key_file" { variable "public_key_file" {

View File

@@ -1,36 +1,40 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
66346130316130363833656139333733306135303061323864643937636639326333316235303262 62656134326239313562396138346634316530303635353562616163323836666132616565366336
3236323131623963633431333334663933653665376635360a383561366230666365323732383032 3035353733653832316165356663303264396439393232390a666465306363356335383734616438
32643731613032616362313561633337336266633161326636366363346638613638643830316438 37313833663535356163616666343933303363383462353064633538333433373431663161626230
6130653230323362330a316231346462323366386539316566653139633937326364363030663631 3962303165346162360a626536313165643466343965633431343833653163656266396535656232
31343239663464363366363261616631383935323161636630646132316230646332613461323366 35653139613737336431323733616533363531616131613965663534343938396661336331376633
31393235623932636366373961313538663733363565663363346534363063396632336261356265 62306130323131626435303262326261376630616433613363363536663638306261643734363661
34633064383364393664336639653461636666393662633031616165396537396466643461393862 66366631393034653536343163313862623733316465376533313030393761363033376536643861
64613862616663343565393836333834393463623335643139373966366236363262646461666365 63313735343033656332333838343532343236623435303135383033306131313930316137613634
38373331613461376431343934333761333436373664623831366261363835323437363033386363 37386339313530353534343162613733333935333136656134623862323861653739353636366363
36633862343134323130656465386462646235393833376563343161313130333536333733636636 38656565643437663330353366636331316337626438323162393838346534393063386338326336
66353162393639343765396464666130306530333030386564363361356364616338363865636565 64373030336466376432386334653737313461626264396431613330393938316230623235663962
33393233636631643563316336653461343733313266653433316265383661653264626666393830 62323431626261386238363163646662336134373534376632653431396532626438613830396164
39666239333965383464653766333263306439653231653163323130333437336432353666366531 34663434656131336265353336633930666230323131633130373833396230313634646134353464
64613737346336643263306538353131343030356164323237623937633238666336306165646231 30373537623939316565393966376439336465623330353037303536306632646361643437306139
38383837313963626531653236376530313563363333313330653439393733396136333937313061 36393232623236613737336263396138376336396335316465663661613635636232383435666230
36386131396337313131333730326639366439373933626130626537353265306434666265373063 65333361656337653135363239346264613530626231636635303466326331323832383337626534
32313832613632346563346565656366336430663762316437376461656639346634306663326165 64306630306531393461356535336136323833643735353232343336623830656563616663353933
34653534623031396564326563303132626562326131666337643839633366306462643436323635 34656562626238343030383833326333323463306634616333303531633832326532316664383837
66666665383332336636356639373863663237303064386533653837636466313461376438383238 65343463323837376630323663323961636631376535313538646462626130653431306563323137
39616434363263646235336432323139326139346364616431626532313861666266373836396363 35616335333265306366376532353861643935663764326334313035323432343361306639643633
33356137363130396237353931316137653066303930353733356432356664636431306165646136 62643932303161326634656463633166643062363262303665633261303730353438633834326432
37643666373532393936333064306661363331666332336363623430366435313962646563616261 63386439653266333561336432653737316538333330613662356535363162633635663039646430
34613166393764343830303733333033643563333032303536326131323461383535353134643036 31363866396265613639333266636532373438366430663632633061663736366366623061313765
38306531383135633431633863346465613333663433343433363633636439326636643938373265 37313932613339643731616263656636303439633637623935333136353866303361396230393632
65643066646364613230396536623537663961356531653164303134383736323064363637353738 37316566303932336361653335353632353161353864616361326665393065363736363430666464
31356630376635633930353239306633326432383031373632346234373536666431653963653566 62656333393632313664653837393335353662363965313238633131313631373534313336613831
35353163373938383736396135386266653636383066636637376238316139346239653234363830 33313762316330653835616637323134656536626661343833373336363430633836663831643563
64663432663339346634323366366138306133326562643736373964326265393537326663386364 39303364656638306661616537623538663230326639643533306538353435626336383435633836
61373039313739343031623134613435656461616165386430366333346161666530376338663961 35656633313436623733666464346337343664393236336535616135333032363034666333316233
32353231656162393138653837663863653562626236393630316635363537306130346238313161 65363537633630356662353034613935366330643361393631353561643062376239343363646462
64613566363163363966653533333664643633656533613939616533336136376635333336333233 38633335356234396334313265393235636337663365646533343234323634646166623038343266
39373638363538636632656133363864653136613231613532313531643565396237306338353263 32646432653731383366616333633862643531303633613136386331383365376633343935666563
33616132666364663036643437326463633265316236323835323039336361393739653361373632 33363035356365626263646132353631653336383939646538393336393463626632663661663962
37336162353635643333373937346333373433346333613133633936616430666637613235623937 63656238353463356665633964316135646264333262633862643234313035386230666661643733
636334616134303130303561633437353736 65396534636365356130356463393634646136373362343334636138633531383135333637323635
35366131353261643661373366653838373238343732633430653862613134386565303765326166
32386465336231666564653361653235646231623065643738613939353439323430656236613633
63333034303863633036613662313238383430373365353637323062363363303461333766373164
393133613238363662663335626561393630