Initial commit
Label Sync / Label Sync (push) Failing after 1m7s
E2E / reject-invalid (bad-bgp-asn) (push) Skipped
E2E / reject-invalid (bad-mac-address) (push) Skipped
E2E / reject-invalid (bad-repo-url) (push) Skipped
E2E / reject-invalid (bad-vlan-tag) (push) Skipped
E2E / reject-invalid (duplicate-gateway-addrs) (push) Skipped
E2E / reject-invalid (duplicate-node-names) (push) Skipped
E2E / reject-invalid (gateway-node-collision) (push) Skipped
E2E / reject-invalid (missing-dns-token) (push) Skipped
E2E / reject-invalid (nested-cidr-overlap) (push) Skipped
E2E / reject-invalid (node-addr-outside-cidr) (push) Skipped
E2E / reject-invalid (tunnel-without-dns) (push) Skipped
E2E / accept-valid (selfhosted) (push) Skipped
E2E / reject-invalid (missing-known-hosts) (push) Skipped
E2E / reject-invalid (missing-schematic) (push) Skipped
E2E / reject-invalid (partial-bgp) (push) Skipped
E2E / accept-valid (internal) (push) Skipped
E2E / reject-invalid (missing-external-gateway) (push) Skipped
E2E / reject-invalid (node-uses-gateway-addr) (push) Skipped
E2E / reject-invalid (non-canonical-cidr) (push) Skipped
E2E / accept-valid (private) (push) Skipped
E2E / accept-valid (single-node) (push) Skipped
E2E / reject-invalid (overlapping-cidrs) (push) Skipped
E2E / reject-invalid (reserved-node-name) (push) Skipped
E2E / reject-invalid (tiny-svc-cidr) (push) Skipped
E2E / validator-tests (push) Skipped
E2E / accept-valid (direct) (push) Skipped
E2E / accept-valid (multi-controller) (push) Skipped
E2E / accept-valid (no-webhook) (push) Skipped
E2E / accept-valid (public) (push) Skipped

This commit is contained in:
2026-09-15 22:21:43 +03:00
committed by GitHub
commit e502e0ff76
171 changed files with 7520 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
# Talos Patching
Machine configs are assembled by [topf](https://postfinance.github.io/topf/) from
`topf.yaml` plus the strategic merge patches in this directory.
<https://www.talos.dev/latest/talos-guides/configuration/patching/>
## Patch Directories
Patches merge in this order, alphabetically within each directory, with later
patches taking precedence:
- `all/`: applied to every node
- `control-plane/`: applied to control-plane nodes
- `worker/`: applied to worker nodes
- `node/${hostname}/`: applied to the node with the specified name
Files ending in `.yaml.tpl` are Go-templated per node; see the
[topf configuration model](https://postfinance.github.io/topf/main/configuration-model/)
for the available template variables.
@@ -0,0 +1,9 @@
apiVersion: v1alpha1
kind: UnattendedInstallConfig
provisioning:
diskSelector:
{{- if .Node.Data.installDisk }}
match: disk.dev_path == "{{ .Node.Data.installDisk }}" || "{{ .Node.Data.installDisk }}" in disk.symlinks
{{- else }}
match: disk.serial == "{{ .Node.Data.installDiskSerial }}"
{{- end }}
@@ -0,0 +1,4 @@
apiVersion: v1alpha1
kind: HostnameConfig
auto: "off"
hostname: "{{ .Node.Host }}"
@@ -0,0 +1,10 @@
machine:
certSANs:
#% for item in cert_sans %#
- "#{ item }#"
#% endfor %#
---
apiVersion: v1alpha1
kind: KubeNetworkConfig
podSubnets: ["#{ kubernetes.pod_cidr }#"]
serviceSubnets: ["#{ kubernetes.svc_cidr }#"]
@@ -0,0 +1,41 @@
#| Node networking as Talos 1.13+ typed network documents. The MAC-matched
link is enslaved to a single-link active-backup bond so every consumer
(Cilium devices, VLANs, the VIP, metrics) sees a stable interface name,
bond0, regardless of kernel NIC naming; a second NIC can join the bond
later without renaming anything. The bond name is also referenced by
`devices` in the cilium HelmRelease. #|
#% set link = 'bond0.' ~ network.vlan_tag if network.vlan_tag else 'bond0' %#
---
apiVersion: v1alpha1
kind: LinkAliasConfig
name: ethSel0
selector:
match: glob("{{ .Node.Data.macAddr }}", mac(link.hardware_addr))
---
apiVersion: v1alpha1
kind: BondConfig
name: bond0
links:
- ethSel0
bondMode: active-backup
mtu: {{ .Node.Data.mtu }}
#% if network.vlan_tag %#
---
apiVersion: v1alpha1
kind: VLANConfig
name: #{ link }#
parent: bond0
vlanID: #{ network.vlan_tag }#
mtu: {{ .Node.Data.mtu }}
#% endif %#
addresses:
- address: "{{ .Node.IP }}/#{ network.node_cidr.split('/') | last }#"
routes:
- gateway: "#{ network.default_gateway }#"
{{- if eq .Node.Role "control-plane" }}
---
apiVersion: v1alpha1
kind: Layer2VIPConfig
link: #{ link }#
name: "#{ kubernetes.api.addr }#"
{{- end }}
@@ -0,0 +1,8 @@
apiVersion: v1alpha1
kind: ResolverConfig
nameservers:
#% for item in network.dns_servers %#
- address: #{ item }#
#% endfor %#
searchDomains:
disableDefault: true
@@ -0,0 +1,7 @@
apiVersion: v1alpha1
kind: TimeSyncConfig
ntp:
servers:
#% for item in network.ntp_servers %#
- #{ item }#
#% endfor %#
@@ -0,0 +1,16 @@
apiVersion: v1alpha1
kind: KubeletConfig
config:
crashLoopBackOff:
maxContainerRestartPeriod: 60s
imageMaximumGCAge: 168h
maxParallelImagePulls: 3
serializeImagePulls: false
shutdownGracePeriod: 90s
shutdownGracePeriodCriticalPods: 60s
---
apiVersion: v1alpha1
kind: KubeNodeConfig
nodeIP:
validSubnets:
- #{ network.node_cidr }#
@@ -0,0 +1,12 @@
apiVersion: v1alpha1
kind: SysctlConfig
params:
fs.inotify.max_user_watches: "1048576" # Watchdog
fs.inotify.max_user_instances: "8192" # Watchdog
net.core.rmem_max: "7500000" # Cloudflared | QUIC
net.core.wmem_max: "7500000" # Cloudflared | QUIC
net.ipv4.neigh.default.gc_thresh1: "4096" # Prevent ARP cache overflows
net.ipv4.neigh.default.gc_thresh2: "8192" # Prevent ARP cache overflows
net.ipv4.neigh.default.gc_thresh3: "16384" # Prevent ARP cache overflows
net.ipv4.tcp_slow_start_after_idle: "0" # Preserve congestion window after idle
user.max_user_namespaces: "11255" # User Namespaces
@@ -0,0 +1,8 @@
apiVersion: v1alpha1
kind: CRICustomizationConfig
name: containerd
content: |
[plugins."io.containerd.cri.v1.images"]
discard_unpacked_layers = false
[plugins."io.containerd.cri.v1.runtime"]
device_ownership_from_security_context = true
@@ -0,0 +1,20 @@
{{- if .Node.Data.encryptDisk }}
# Encrypt system disk with TPM
apiVersion: v1alpha1
kind: VolumeConfig
name: STATE
encryption:
provider: luks2
keys:
- slot: 0
tpm: {}
---
apiVersion: v1alpha1
kind: VolumeConfig
name: EPHEMERAL
encryption:
provider: luks2
keys:
- slot: 0
tpm: {}
{{- end }}
@@ -0,0 +1,6 @@
{{- range .Node.Data.kernelModules }}
---
apiVersion: v1alpha1
kind: KernelModuleConfig
name: {{ . }}
{{- end }}
@@ -0,0 +1,7 @@
# Talos 1.14 defaults to running kubelet and pods in a sandboxed PID/mount
# namespace, which breaks workloads that rely on hostPID or host mounts
# (node-exporter, GPU plugins, in-tree iSCSI). Set to true to opt in; on
# encrypted disks expect a second reboot the first time it is enabled.
apiVersion: v1alpha1
kind: SecurityProfileConfig
workloadIsolation: false
@@ -0,0 +1,9 @@
# Weekly online maintenance for XFS volumes: trim discards unused blocks
# (SSDs, thin provisioning) and scrub checks filesystem metadata.
apiVersion: v1alpha1
kind: FilesystemTrimConfig
interval: 168h0m0s
---
apiVersion: v1alpha1
kind: FilesystemScrubConfig
interval: 168h0m0s
@@ -0,0 +1,62 @@
cluster:
etcd:
extraArgs:
listen-metrics-urls: http://0.0.0.0:2381
advertisedSubnets:
- #{ network.node_cidr }#
---
# Allow scheduling on control-plane nodes
apiVersion: v1alpha1
kind: KubeNodeConfig
taints:
node-role.kubernetes.io/control-plane:
$patch: delete
---
apiVersion: v1alpha1
kind: KubeAdmissionControlConfig
name: PodSecurity
$patch: delete
---
apiVersion: v1alpha1
kind: KubeAPIServerConfig
certExtraSANs:
#% for item in cert_sans %#
- "#{ item }#"
#% endfor %#
extraArgs:
# https://kubernetes.io/docs/tasks/extend-kubernetes/configure-aggregation-layer/
enable-aggregator-routing: "true"
---
apiVersion: v1alpha1
kind: KubeControllerManagerConfig
extraArgs:
bind-address: 0.0.0.0
---
apiVersion: v1alpha1
kind: KubeCoreDNSConfig
enabled: false
---
# Disable built-in CNI and kube-proxy to use Cilium
apiVersion: v1alpha1
kind: KubeFlannelCNIConfig
$patch: delete
---
apiVersion: v1alpha1
kind: KubeProxyConfig
enabled: false
---
apiVersion: v1alpha1
kind: KubeSchedulerConfig
extraArgs:
bind-address: 0.0.0.0
config:
profiles:
- schedulerName: default-scheduler
pluginConfig:
- name: PodTopologySpread
args:
defaultingType: List
defaultConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
+64
View File
@@ -0,0 +1,64 @@
set quiet
set shell := ['bash', '-euo', 'pipefail', '-c']
set script-interpreter := ['bash', '-euo', 'pipefail']
set default-list
set default-script
# Day-2 apply/upgrade recipes rely on topf's built-in diff-and-confirm
# prompt; only the destructive reset recipes disable it in favour of just's
# own confirmation.
[doc('Apply Talos config to all nodes (shows a diff and asks first)')]
[group('talos')]
apply:
topf apply
[arg('mode', pattern='auto|reboot|no-reboot|staged|try')]
[doc('Apply Talos config to a node (shows a diff and asks first)')]
[group('talos')]
apply-node node mode='auto':
topf apply --nodes-filter "^{{ node }}$" --mode "{{ mode }}"
[doc('Show pending config changes without applying them')]
[group('talos')]
diff:
topf apply --dry-run
[doc('List all nodes and their current state')]
[group('talos')]
nodes:
topf nodes
[doc('Render Talos machine configs to ./rendered')]
[group('talos')]
render:
topf render --output ./rendered
[confirm("This will destroy your cluster and reset all nodes to maintenance mode — continue? [y/N]")]
[doc('Reset all nodes back to maintenance mode (DESTRUCTIVE)')]
[group('talos')]
reset:
topf reset --confirm=false
[confirm("This will reset node " + node + " to maintenance mode — continue? [y/N]")]
[doc('Reset a single node back to maintenance mode (DESTRUCTIVE)')]
[group('talos')]
reset-node node:
topf reset --nodes-filter "^{{ node }}$" --confirm=false
# topf intentionally does not manage Kubernetes upgrades
[doc('Upgrade Kubernetes')]
[group('talos')]
upgrade-k8s:
talosctl --nodes "$(yq '[.nodes[] | select(.role == "control-plane")][0].ip' topf.yaml)" \
upgrade-k8s --to "$(yq '.kubernetesVersion' topf.yaml)"
[doc('Upgrade Talos on all nodes, one at a time (asks first)')]
[group('talos')]
upgrade:
topf upgrade
[doc('Upgrade Talos on a single node (asks first)')]
[group('talos')]
upgrade-node node:
topf upgrade --nodes-filter "^{{ node }}$"
+33
View File
@@ -0,0 +1,33 @@
---
clusterName: kubernetes
clusterEndpoint: https://#{ kubernetes.api.addr }#:6443
# renovate: datasource=github-releases depName=siderolabs/talos
talosVersion: v1.14.0
# renovate: datasource=docker depName=ghcr.io/siderolabs/kubelet
kubernetesVersion: v1.37.0
secretsPath: secrets.sops.yaml
nodes:
#% for item in nodes %#
- host: "#{ item.name }#"
ip: "#{ item.address }#"
role: #{ 'control-plane' if item.controller else 'worker' }#
schematicId: "#{ item.schematic_id }#"
#% if item.secureboot %#
secureboot: true
#% endif %#
data:
#% if item.disk.startswith('/') %#
installDisk: "#{ item.disk }#"
installDiskSerial: ""
#% else %#
installDisk: ""
installDiskSerial: "#{ item.disk }#"
#% endif %#
macAddr: "#{ item.mac_addr | lower }#"
mtu: #{ item.mtu }#
encryptDisk: #{ item.encrypt_disk | string | lower }#
kernelModules: [#{ item.kernel_modules | join(', ') }#]
#% endfor %#