Skip to content

Commit 8f7895d

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feature/csi-configuration
2 parents db5c47a + 3b9541d commit 8f7895d

File tree

8 files changed

+180
-24
lines changed

8 files changed

+180
-24
lines changed

README.md

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div align="center">
22

3-
<img src="https://avatars.githubusercontent.com/u/182015181" alt="logo" width="200" height="auto" />
3+
<img src="https://avatars.githubusercontent.com/u/182015181" alt="logo" width="225" height="auto" />
44
<h1>Hcloud Kubernetes</h1>
55

66
<p>
@@ -43,7 +43,7 @@
4343

4444
<!-- About the Project -->
4545
## :star2: About the Project
46-
Hcloud Kubernetes is a Terraform module for deploying a fully declarative, managed Kubernetes cluster on Hetzner Cloud. It utilizes Talos, a secure, immutable, and minimal operating system specifically designed for Kubernetes, featuring a streamlined architecture with just 12 binaries and managed entirely through an API.
46+
Hcloud Kubernetes is a Terraform module for deploying a fully declarative, managed Kubernetes cluster on Hetzner Cloud. It utilizes Talos, a secure, immutable, and minimal operating system specifically designed for Kubernetes, featuring a streamlined architecture with only a handful of binaries and shared libraries. Just enough to run containerd and a small set of system services.
4747

4848
This project is committed to production-grade configuration and lifecycle management, ensuring all components are set up for high availability. It includes a curated selection of widely used and officially recognized Kubernetes components. If you encounter any issues, suboptimal settings, or missing elements, please file an [issue](https://github.com/hcloud-k8s/terraform-hcloud-kubernetes/issues) to help us improve this project.
4949

@@ -126,7 +126,7 @@ Talos Linux is a secure, minimal, and immutable OS for Kubernetes, removing SSH
126126

127127
**Firewall Protection:** This module uses [Hetzner Cloud Firewalls](https://docs.hetzner.com/cloud/firewalls/) to manage external access to nodes. For internal pod-to-pod communication, support for Kubernetes Network Policies is provided through [Cilium CNI](https://docs.cilium.io/en/stable/network/kubernetes/policy/).
128128

129-
**Encryption in Transit:** In this module, all pod network traffic is encrypted by default using [WireGuard via Cilium CNI](https://cilium.io/use-cases/transparent-encryption/). It includes automatic key rotation and efficient in-kernel encryption, covering all traffic types.
129+
**Encryption in Transit:** In this module, all pod network traffic is encrypted by default using [WireGuard (Default) or IPSec via Cilium CNI](https://cilium.io/use-cases/transparent-encryption/). It includes automatic key rotation and efficient in-kernel encryption, covering all traffic types.
130130

131131
**Encryption at Rest:** In this module, the [STATE](https://www.talos.dev/latest/learn-more/architecture/#file-system-partitions) and [EPHEMERAL](https://www.talos.dev/latest/learn-more/architecture/#file-system-partitions) partitions are encrypted by default with [Talos Disk Encryption](https://www.talos.dev/latest/talos-guides/configuration/disk-encryption/) using LUKS2. Each node is secured with individual encryption keys derived from its unique `nodeID`.
132132

@@ -429,6 +429,46 @@ kubectl delete storageclass hcloud-volumes
429429
storageclass.storage.k8s.io "hcloud-volumes" deleted
430430
```
431431

432+
<!-- Cilium Advanced Configuration -->
433+
<details>
434+
<summary><b>Cilium Advanced Configuration</b></summary>
435+
436+
#### Cilium Transparent Encryption
437+
438+
This module enables [Cilium Transparent Encryption](https://cilium.io/use-cases/transparent-encryption/) feature by default.
439+
440+
All pod network traffic is encrypted using WireGuard (Default) or protocols, includes automatic key rotation and efficient in-kernel encryption, covering all traffic types.
441+
442+
:bulb: Although WireGuard is the default option, Hetzner Cloud VMs supports AES-NI instruction set, making IPSec encryption more CPU-efficient compared to WireGuard. Consider enabling IPSec for CPU savings through hardware acceleration.
443+
444+
IPSec mode supports RFC4106 AES-GCM encryption with 128, 192 and 256 bits key sizes.
445+
446+
447+
**:warning: IPSec encryption has the following limitations:**
448+
449+
- No transparent encryption when chaining Cilium with other CNI plugins
450+
- Host Policies not supported with IPSec
451+
- Incompatible with BPF Host Routing (automatically disabled on switch)
452+
- IPv6-only clusters not supported
453+
- Maximum 65,535 nodes per cluster/clustermesh
454+
- Single CPU core limitation per IPSec tunnel may affect high-throughput scenarios
455+
456+
*Source: [Cilium Documentation](https://docs.cilium.io/en/stable/security/network/encryption-ipsec/#limitations)*
457+
458+
Example `kubernetes.tf` configuration:
459+
460+
```hcl
461+
cilium_encryption_enabled = true # Default true
462+
cilium_encryption_type = "wireguard" # wireguard (Default) | ipsec
463+
cilium_ipsec_algorithm = "rfc4106(gcm(aes))" # IPSec AES key algorithm (Default rfc4106(gcm(aes)))
464+
cilium_ipsec_key_size = 256 # IPSec AES key size (Default 256)
465+
cilium_ipsec_key_id = 1 # IPSec key ID (Default 1)
466+
```
467+
468+
##### IPSec Key Rotation
469+
470+
Keys automatically rotate when `cilium_ipsec_key_id` is incremented (1-15 range, resets to 1 after 15).
471+
432472
</details>
433473

434474
<!-- Egress Gateway -->
@@ -800,11 +840,12 @@ The [Talos Terraform Provider](https://registry.terraform.io/providers/siderolab
800840
### :white_check_mark: Version Compatibility Matrix
801841
| Hcloud K8s | K8s | Talos | Talos CCM | Hcloud CCM | Hcloud CSI | Long-horn | Cilium | Ingress NGINX | Cert Mgr. | Auto-scaler |
802842
| :--------: | :---: | :---: | :-------: | :--------: | :--------: | :-------: | :----: | :-----------: | :-------: | :---------: |
803-
| (**2**) | 1.32 | 1.9 | 1.9 | 1.23 | 2.12 | 1.8.1 | 1.17 | 4.12 | 1.17 | 9.45 |
843+
| **(3)** | 1.33 | 1.10 | 1.10 | 1.26 | 2.14 | 1.8.2 | (1.18) | 4.13 | 1.18 | 9.47 |
844+
| **2** | 1.32 | 1.9 | 1.9 | 1.23 | 2.12 | 1.8.1 | 1.17 | 4.12 | 1.17 | 9.45 |
804845
| **1** | 1.31 | 1.8 | 1.8 | 1.21 | 2.10 | 1.8 | 1.17 | 4.12 | 1.15 | 9.38 |
805846
| **0** | 1.30 | 1.7 | 1.6 | 1.20 | 2.9 | 1.7.1 | 1.16 | 4.10.1 | 1.14 | 9.37 |
806847

807-
In this module, upgrades are conducted with care and conservatism. You will consistently receive the most tested and compatible releases of all components, avoiding the latest untested or incompatible releases that could disrupt your cluster.
848+
In this module, upgrades are conducted with care. You will consistently receive the most tested and compatible releases of all components, avoiding the latest untested or incompatible releases that could disrupt your cluster.
808849

809850
> [!WARNING]
810851
> Do not change any software versions in this project on your own. Each component is tailored to ensure compatibility with new Kubernetes releases. This project specifies versions that are supported and have been thoroughly tested to work together.
@@ -823,12 +864,10 @@ In this module, upgrades are conducted with care and conservatism. You will cons
823864

824865
<!-- Roadmap -->
825866
## :compass: Roadmap
826-
* [ ] **Upgrade to Talos 1.9 and Kubernetes 1.32**<br>
867+
* [ ] **Upgrade to Talos 1.10 and Kubernetes 1.33**<br>
827868
Once all components have compatible versions, the upgrade can be performed.
828-
* [x] **Upgrade to Talos 1.8 and Kubernetes 1.31**<br>
869+
* [x] **Upgrade to Talos 1.9 and Kubernetes 1.32**<br>
829870
Once all components have compatible versions, the upgrade can be performed.
830-
* [ ] **Integrate native IPv6 for pod traffic**<br>
831-
Completion requires Hetzner's addition of IPv6 support to cloud networks, expected at the beginning of 2025 as announced at Hetzner Summit 2024.
832871

833872
<!-- Contributing -->
834873
## :wave: Contributing

autoscaler.tf

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ data "helm_template" "cluster_autoscaler" {
2828
kube_version = var.kubernetes_version
2929

3030
set = [
31-
{
32-
name = "image.tag"
33-
value = "v1.31.1"
34-
},
3531
{
3632
name = "cloudProvider"
3733
value = "hetzner"

cilium.tf

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
locals {
2+
# Cilium IPSec Configuration
3+
cilium_ipsec_enabled = var.cilium_encryption_enabled && var.cilium_encryption_type == "ipsec"
4+
5+
# Key configuration when IPSec is enabled
6+
cilium_ipsec_key_config = local.cilium_ipsec_enabled ? {
7+
next_id = var.cilium_ipsec_key_id % 15 + 1
8+
format = "${var.cilium_ipsec_key_id}+ ${var.cilium_ipsec_algorithm} ${random_bytes.cilium_ipsec_key[0].hex} 128"
9+
} : null
10+
11+
# Kubernetes Secret manifest
12+
cilium_ipsec_keys_manifest = local.cilium_ipsec_enabled ? {
13+
apiVersion = "v1"
14+
kind = "Secret"
15+
type = "Opaque"
16+
17+
metadata = {
18+
name = "cilium-ipsec-keys"
19+
namespace = "kube-system"
20+
21+
annotations = {
22+
"cilium.io/key-id" = tostring(var.cilium_ipsec_key_id)
23+
"cilium.io/key-algorithm" = var.cilium_ipsec_algorithm
24+
"cilium.io/key-size" = tostring(var.cilium_ipsec_key_size)
25+
}
26+
}
27+
28+
data = {
29+
keys = base64encode(local.cilium_ipsec_key_config.format)
30+
}
31+
} : null
32+
}
33+
34+
# Generate random key when IPSec is enabled
35+
resource "random_bytes" "cilium_ipsec_key" {
36+
count = local.cilium_ipsec_enabled ? 1 : 0
37+
length = ((var.cilium_ipsec_key_size / 8) + 4) # AES Key + 4 bytes salt
38+
39+
# Keepers to force regeneration when key_id changes
40+
keepers = {
41+
key_id = var.cilium_ipsec_key_id
42+
}
43+
}
44+
45+
146
data "helm_template" "cilium" {
247
name = "cilium"
348
namespace = "kube-system"
@@ -40,11 +85,10 @@ data "helm_template" "cilium" {
4085
name = "bpf.masquerade"
4186
value = true
4287
},
43-
# Netkit requires kernel >= 6.8
44-
# {
45-
# name = "bpf.datapathMode"
46-
# value = "netkit"
47-
# },
88+
{
89+
name = "bpf.datapathMode"
90+
value = "netkit"
91+
},
4892
{
4993
name = "loadBalancer.acceleration"
5094
value = "native"
@@ -53,7 +97,15 @@ data "helm_template" "cilium" {
5397
name = "installNoConntrackIptablesRules"
5498
value = true
5599
},
56-
100+
# IPSec
101+
{
102+
name = "bpf.hostLegacyRouting"
103+
value = local.cilium_ipsec_enabled
104+
},
105+
{
106+
name = "dnsProxy.enableTransparentMode"
107+
value = true
108+
},
57109
{
58110
name = "egressGateway.enabled"
59111
value = var.cilium_egress_gateway_enabled
@@ -93,7 +145,7 @@ data "helm_template" "cilium" {
93145
yamlencode({
94146
encryption = {
95147
enabled = var.cilium_encryption_enabled
96-
type = "wireguard"
148+
type = var.cilium_encryption_type
97149
}
98150
hubble = {
99151
enabled = var.cilium_hubble_enabled
@@ -125,6 +177,10 @@ data "helm_template" "cilium" {
125177
locals {
126178
cilium_manifest = var.cilium_enabled ? {
127179
name = "cilium"
128-
contents = data.helm_template.cilium.manifest
180+
contents = <<-EOF
181+
${yamlencode(local.cilium_ipsec_keys_manifest)}
182+
---
183+
${data.helm_template.cilium.manifest}
184+
EOF
129185
} : null
130186
}

image.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ locals {
3636

3737
talos_image_extensions = distinct(
3838
concat(
39+
["siderolabs/qemu-guest-agent"],
3940
var.talos_image_extensions,
4041
var.longhorn_enabled ? local.talos_image_extentions_longhorn : []
4142
)

outputs.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,20 @@ output "worker_public_ipv6_list" {
6868
description = "Public IPv6 addresses of all worker nodes"
6969
value = local.worker_public_ipv6_list
7070
}
71+
72+
output "cilium_encryption_info" {
73+
description = "Information about Cilium traffic encryption"
74+
value = {
75+
encryption_enabled = var.cilium_encryption_enabled
76+
encryption_type = var.cilium_encryption_type
77+
78+
ipsec = local.cilium_ipsec_enabled ? {
79+
current_key_id = var.cilium_ipsec_key_id
80+
next_key_id = local.cilium_ipsec_key_config["next_id"]
81+
algorithm = var.cilium_ipsec_algorithm
82+
key_size_bits = var.cilium_ipsec_key_size
83+
secret_name = local.cilium_ipsec_keys_manifest.metadata["name"]
84+
namespace = local.cilium_ipsec_keys_manifest.metadata["namespace"]
85+
} : {}
86+
}
87+
}

packer/image_amd64.pkr.hcl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ build {
5252
<<-EOT
5353
set -euo pipefail
5454
55+
# Discard the entire /dev/sda to free up space and make the snapshot smaller
56+
echo 'Zeroing disk first before writing Talos image'
57+
blkdiscard /dev/sda 2>/dev/null
58+
5559
echo 'Download Talos ${var.talos_version} image (${var.talos_schematic_id})'
5660
5761
wget \

packer/image_arm64.pkr.hcl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ build {
5252
<<-EOT
5353
set -euo pipefail
5454
55+
# Discard the entire /dev/sda to free up space and make the snapshot smaller
56+
echo 'Zeroing disk first before writing Talos image'
57+
blkdiscard /dev/sda 2>/dev/null
58+
5559
echo 'Download Talos ${var.talos_version} image (${var.talos_schematic_id})'
5660
5761
wget \

variables.tf

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ variable "cluster_autoscaler_helm_chart" {
421421

422422
variable "cluster_autoscaler_helm_version" {
423423
type = string
424-
default = "9.45.1"
424+
default = "9.46.6"
425425
description = "Version of the Cluster Autoscaler Helm chart to deploy."
426426
}
427427

@@ -527,7 +527,7 @@ variable "packer_arm64_builder" {
527527
# Talos
528528
variable "talos_version" {
529529
type = string
530-
default = "v1.8.4"
530+
default = "v1.9.6"
531531
description = "Specifies the version of Talos to be used in generated machine configurations."
532532
}
533533

@@ -808,7 +808,7 @@ variable "talos_backup_schedule" {
808808
# Kubernetes
809809
variable "kubernetes_version" {
810810
type = string
811-
default = "v1.31.4"
811+
default = "v1.32.4"
812812
description = "Specifies the Kubernetes version to deploy."
813813
}
814814

@@ -1080,6 +1080,45 @@ variable "cilium_encryption_enabled" {
10801080
description = "Enables transparent network encryption using Cilium within the Kubernetes cluster. When enabled, this feature provides added security for network traffic."
10811081
}
10821082

1083+
variable "cilium_encryption_type" {
1084+
type = string
1085+
default = "wireguard"
1086+
description = "Type of encryption to use for Cilium network encryption. Options: 'wireguard' or 'ipsec'."
1087+
1088+
validation {
1089+
condition = contains(["wireguard", "ipsec"], var.cilium_encryption_type)
1090+
error_message = "Encryption type must be either 'wireguard' or 'ipsec'."
1091+
}
1092+
}
1093+
1094+
variable "cilium_ipsec_algorithm" {
1095+
type = string
1096+
default = "rfc4106(gcm(aes))"
1097+
description = "Cilium IPSec key algorithm."
1098+
}
1099+
1100+
variable "cilium_ipsec_key_size" {
1101+
type = number
1102+
default = 256
1103+
description = "AES key size in bits for IPSec encryption (128, 192, or 256). Only used when cilium_encryption_type is 'ipsec'."
1104+
1105+
validation {
1106+
condition = contains([128, 192, 256], var.cilium_ipsec_key_size)
1107+
error_message = "IPSec key size must be 128, 192 or 256 bits."
1108+
}
1109+
}
1110+
1111+
variable "cilium_ipsec_key_id" {
1112+
type = number
1113+
default = 1
1114+
description = "IPSec key ID (1-15, increment manually for rotation). Only used when cilium_encryption_type is 'ipsec'."
1115+
1116+
validation {
1117+
condition = var.cilium_ipsec_key_id >= 1 && var.cilium_ipsec_key_id <= 15 && floor(var.cilium_ipsec_key_id) == var.cilium_ipsec_key_id
1118+
error_message = "The IPSec key_id must be between 1 and 15."
1119+
}
1120+
}
1121+
10831122
variable "cilium_egress_gateway_enabled" {
10841123
type = bool
10851124
default = false

0 commit comments

Comments
 (0)