feat: up to hetzner cloud controller creation

This commit is contained in:
2025-12-31 16:19:17 -05:00
parent 9066a8e600
commit 9a323672bc
6 changed files with 298 additions and 29 deletions

View File

@@ -6,6 +6,7 @@ tasks:
tf:destroy: ansible-playbook playbooks/destroy.yml {{.CLI_ARGS}}
configure-nat: ansible-playbook playbooks/configure_nat.yml {{.CLI_ARGS}}
configure-servers: ansible-playbook playbooks/configure_servers.yml {{.CLI_ARGS}}
deploy: ansible-playbook playbooks/install_k8s.yml {{.CLI_ARGS}}
enter:
cmd: ssh -i {{.KEY}} -p 22 root@{{.IP}}

198
playbooks/install_k8s.yml Normal file
View File

@@ -0,0 +1,198 @@
# - name: Configure compute for the cluster.
# hosts: servers
# gather_facts: false
# vars:
# kubernetes_version: v1.30
# tasks:
# - name: Download Kubernetes key.
# ansible.builtin.apt_key:
# url: https://pkgs.k8s.io/core:/stable:/{{ kubernetes_version }}/deb/Release.key
# state: present
# - name: Download Kubernetes repository.
# ansible.builtin.apt_repository:
# repo: "deb https://pkgs.k8s.io/core:/stable:/{{ kubernetes_version }}/deb/ /"
# state: present
# - name: Download CRI-O key.
# ansible.builtin.apt_key:
# url: https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/Release.key
# state: present
# - name: Download CRI-O repository.
# ansible.builtin.apt_repository:
# repo: "deb https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/ /"
# state: present
# - name: Download Helm key.
# ansible.builtin.apt_key:
# url: https://packages.buildkite.com/helm-linux/helm-debian/gpgkey
# state: present
# - name: Download Helm repository.
# ansible.builtin.apt_repository:
# repo: "deb https://packages.buildkite.com/helm-linux/helm-debian/any/ any main"
# state: present
# - name: Install packages.
# ansible.builtin.apt:
# state: present
# update_cache: true
# name: [cri-o, kubelet, kubeadm, kubectl, python3-pip, helm]
# - name: Install Kubernetes Python packages.
# ansible.builtin.pip:
# name: [kubernetes, pyyaml]
# state: present
# break_system_packages: true
# - name: Enable IPv4 forwarding.
# ansible.posix.sysctl:
# name: net.ipv4.ip_forward
# value: '1'
# sysctl_set: true
# notify: Reboot the nodes.
# - name: Enable `br_netfilter` module.
# community.general.modprobe:
# name: br_netfilter
# state: present
# notify: Reboot the nodes.
# handlers:
# - name: Reboot the nodes.
# ansible.builtin.reboot:
# - name: Spawn new cluster on control node.
# hosts: control
# gather_facts: false
# vars:
# config_template: ../templates/InitConfiguration.yml.jinja2
# config:
# bootstrap_token: "{{ secrets.bootstrap_token }}"
# node_ip: 10.0.2.11
# node_name: control
# vars_files:
# - ../vault.yml
# tasks:
# - name: Test for cluster.
# kubernetes.core.k8s_cluster_info:
# register: api_status
# ignore_errors: true
# - name: Copy configuration over.
# ansible.builtin.template:
# src: "{{ config_template }}"
# dest: InitConfiguration.yml
# mode: preserve
# when: "api_status.failed"
# - name: Initialize cluster.
# ansible.builtin.command:
# kubeadm init --config InitConfiguration.yml
# changed_when: true
# when: "api_status.failed"
# - name: Apply the Kubernetes config to the shell.
# ansible.builtin.lineinfile:
# path: /etc/environment
# line: 'KUBECONFIG=/etc/kubernetes/admin.conf'
# when: "api_status.failed"
# - name: Join worker nodes to cluster.
# hosts: [node-a, node-b]
# vars:
# join_template: ../templates/JoinConfiguration.yml.jinja2
# join_control_ip: 10.0.2.11
# join_bootstrap_token: "{{ secrets.bootstrap_token }}"
# vars_files:
# - ../vault.yml
# tasks:
# - name: Copy join configuration over.
# vars:
# join_worker_ip: "{{ ansible_default_ipv4.address }}"
# join_worker_name: "{{ ansible_hostname }}"
# ansible.builtin.template:
# src: "{{ join_template }}"
# dest: JoinConfiguration.yml
# mode: preserve
# - name: Join the nodes.
# ansible.builtin.command:
# kubeadm join --config JoinConfiguration.yml
# changed_when: true
- name: Install CNI.
gather_facts: false
hosts: control
tasks:
- name: Create Flannel namespace.
kubernetes.core.k8s:
state: present
kind: Namespace
name: kube-flannel
- name: Add privilege to the namespace.
kubernetes.core.k8s:
state: patched
kind: Namespace
name: kube-flannel
definition:
metadata:
labels:
pod-security.kubernetes.io/enforce: privileged
- name: Add Flannel repository.
kubernetes.core.helm_repository:
name: flannel
url: https://flannel-io.github.io/flannel/
state: present
- name: Install Flannel.
kubernetes.core.helm:
name: flannel
chart_ref: flannel/flannel
namespace: kube-flannel
values:
podCidr: 10.244.0.0/16
state: present
- name: >
Patch CoreDNS deployment so it still runs, even though the nodes don't
have a external provider yet installed.
kubernetes.core.k8s:
name: coredns
namespace: kube-system
kind: Deployment
state: present
definition:
- op: add
path: /spec/template/spec/tolerations/-
value:
key: node.cloudprovider.kubernetes.io/uninitialized
value: "true"
effect: NoSchedule
- name: Install Hetzner Cloud Controller.
gather_facts: false
hosts: control
vars_files:
- ../vault.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 }}"
network: "{{ private_network_id.value }}"

View File

@@ -0,0 +1,42 @@
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: {{ config.bootstrap_token }}
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: {{ config.node_ip }}
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/crio/crio.sock
imagePullPolicy: IfNotPresent
kubeletExtraArgs:
cloud-provider: external
node-ip: {{ config.node_ip }}
name: {{ config.node_name }}
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
certSANs:
- {{ config.node_ip }}
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.k8s.io
kind: ClusterConfiguration
kubernetesVersion: 1.30.0
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16
scheduler: {}

View File

@@ -0,0 +1,18 @@
apiVersion: kubeadm.k8s.io/v1beta3
caCertPath: /etc/kubernetes/pki/ca.crt
discovery:
bootstrapToken:
apiServerEndpoint: {{ join_control_ip }}:6443
token: {{ join_bootstrap_token }}
unsafeSkipCAVerification: true
timeout: 5m0s
tlsBootstrapToken: {{ join_bootstrap_token }}
kind: JoinConfiguration
nodeRegistration:
criSocket: unix:///var/run/crio/crio.sock
imagePullPolicy: IfNotPresent
kubeletExtraArgs:
cloud-provider: external
node-ip: {{ join_worker_ip }}
name: {{ join_worker_name }}
taints: null

View File

@@ -1,3 +1,7 @@
output "nat_public_ip" {
value = hcloud_server.nat.ipv4_address
}
output "private_network_id" {
value = hcloud_network.net.id
}

View File

@@ -1,30 +1,36 @@
$ANSIBLE_VAULT;1.1;AES256
32616166653831353237663738383366656661383838313466316136333635373632343162353233
3134333132663938323164653335373234613139313865610a633133333538643364323038326564
32633061356166303362393262353035316164643936666435303363343839613236663764396164
6665363238613363320a633439613232633830646630393662666562616435646262643631313464
35386337363465393338363765393333376636663866613334363066336266623261316233656666
36376532653966346665613065623532636433363065643361303731373930383964383764653839
33333736653063383166626466653163336666336165613263383039643963323161346333316334
65323336653766333537626533313365343661396435643635336331306537346631373330613032
63656166656363356666663039373932333139663334626535643237366562656464656139376439
30653639393037646436383764323134313230646638646662333438656232396237376634363633
66656563316562346533373364646338636637626331623238386338333638323735326666383565
32653664646435373332376262393335666538383130363433343633636533313065663232336566
63306461666633383363633264626663313034306535656231666537353962303936313438323130
30333262393861303034653566306333613032353630373436313138363134383964353535663331
33386332333634336133343737323834383238613664633136373535356461383838626630663037
62636465633133323365386163633236393439633934386336643731336134373136613438383636
39383365323263333931363461313633386636303337356135313466313838613534333731633137
66366166303931333265356166376136373664616538343832343765633437643961626566643735
31616236313333333734666235633766613165336561383963326334323664303063343232303264
61633166326438623639626364336335383334626232636562343831353634633532646532616162
33656333663861393530643635356165633266653730626662313237383230613164373737393335
38316137353931366364356531343239313764323734376133343838626230346237646131363839
31383030303237316431666139646238323934353862333465316566363363626166643661393335
66346562363965393261346463306638353331393137323466386561363639353836303765313962
36353132623939633431376235666437636537336263636539326334363661343839643664313131
63643761386236316462633235373639653935333336613439656230633731303164306232643566
30613139313633663366326262313139343630613033346638343838373438656539303531303638
36393862336133373337393966633131356133663433393164396230656364313437396132653631
6534
65366334626132336336326139616239386137396633343835393031653436383330386334303638
3033623632333764343365383538353364336536363636620a663431306631303030343766666663
65343236393733356639613161613638363535636531353938343230666135373932393633633230
3061323439383137300a326130386262376461643931333766323634386562343135363761656265
37386430303238626265656539633730656665376333626537663432313632636235393033326231
65616130396632623162636430306662633261383934313561306565643965666561323135366131
32653938666339643461393665313339333239633866653038323338633031613666613438616537
39356463363231613664383363656437623862396535626661653832396432363961306263623739
32626234646435643466663432643734623164383637383561306132313437363665353264353561
63333836376463383765666235336531346635626130656564376337323932353532336663646364
36393661303065393566376338366662393662333032353533626161353035643136333139653538
38343065373364323437356636653733356566373238646661313765393131313332663339336232
32313530646530666634353961656565373562643031623738393362386166373539333239373062
38386261623330643636306537326364393335633333323933663735646130333639306331323361
38366131323636656235616361633734346438343238613463323330396662626165313336323437
34616239666132653730643465326562346538636138363739633731633439653239666131393565
63616531373533313263613032393661616433326661326461313834653531336637616539633530
35303561346632366339613632643164363432303366383831363431613932356630343165343365
62333438396263656130383934333531643665616637303665323264636238666134626332343836
32366361646162393662343330613334646462613762313766663264613734633732316439393333
37653732616138656131363039396465633531353434613461356166636633353637373534323262
63323966656631376464373261656235396265393564663333656534613766663764653636353631
32336536616561346661376164343066366335656637333466343533653430633636343131376534
33303631393638376530666131383463353934663562386366353330363836363132613537383332
65333330623130333334383639306166663962636233613534393662623733306433363665303130
63383432363761356562343437386133343262643233343663363036663136326566326636626530
33343764303932333366376132366265376462646332326662336361623464353362643533326233
32383837356234323665623364643463353066366366616662343432663466343631613930333131
38656665323664656436303961316462656139386138383165346331613863326133393631333132
39323861666433313364346461666132343834376562646531626438383832663364316461303165
37616666626234346261366663323239343734623963643730666233643864623234373765653737
38646630636261343839616237393066333564323437633230653261396539313634303263333437
61303066373164366333383238303961376138383836633961386566663964366337643435323433
34326261333564316534383564363166616430323666396634303265613364643862653637386532
386331383338343638343537316236366131