Compare commits

...
10 Commits
Author SHA1 Message Date
Devin Buhl e55ae1a1f5 fix: apply-config task node arg order 2024-10-30 12:54:07 -04:00
Devin Buhl f7274e4ccc fix: talosctl apply-config mode is staged 2024-10-30 12:53:31 -04:00
Devin Buhl e895ba359f chore: mention external-dns in the README
Signed-off-by: Devin Buhl <devin@buhl.casa>
2024-10-29 12:18:27 -04:00
Devin Buhl 36f8a6c17b chore: improve apply-config task and update readme
Signed-off-by: Devin Buhl <devin@buhl.casa>
2024-10-29 10:58:40 -04:00
Devin Buhl a8f4b51b7f chore(scripts): format kubeconform script
Signed-off-by: Devin Buhl <devin@buhl.casa>
2024-10-29 10:34:41 -04:00
Devin Buhl fe0252bff0 fix(talos): update sysctls
Signed-off-by: Devin Buhl <devin@buhl.casa>
2024-10-29 10:19:50 -04:00
Devin Buhl 3e122b90fa feat(talos): add kube scheduler default topologyspreadcontraints
Signed-off-by: Devin Buhl <devin@buhl.casa>
2024-10-29 10:19:36 -04:00
Devin Buhl e5a7ba8da8 feat(bootstrap): static ips and default ntp/dns servers (#1618) 2024-10-29 10:10:31 -04:00
Devin Buhl 48a7a16f90 chore: only minijinja bin 2024-10-28 12:55:50 -04:00
Devin Buhl 535ea53fcf chore: add minijinja-cli-bin to Archfile (#1616) 2024-10-26 19:41:34 -04:00
14 changed files with 113 additions and 86 deletions

No files matched your search

+17 -4
View File
@@ -5,6 +5,7 @@ version: '3'
vars:
TALHELPER_CLUSTER_DIR: '{{.KUBERNETES_DIR}}/bootstrap/talos/clusterconfig'
TALHELPER_CONFIG_FILE: '{{.KUBERNETES_DIR}}/bootstrap/talos/talconfig.yaml'
TALHELPER_SECRET_FILE: '{{.KUBERNETES_DIR}}/bootstrap/talos/talsecret.sops.yaml'
TALOSCONFIG: '{{.TALHELPER_CLUSTER_DIR}}/talosconfig'
env:
@@ -12,11 +13,24 @@ env:
tasks:
generate-config:
desc: Generate Talos configuration
cmd: talhelper genconfig --config-file {{.TALHELPER_CONFIG_FILE}} --secret-file {{.TALHELPER_SECRET_FILE}} --out-dir {{.TALHELPER_CLUSTER_DIR}}
preconditions:
- msg: Missing talhelper config file
sh: test -f {{.TALHELPER_CONFIG_FILE}}
- msg: Missing Sops config file
sh: test -f {{.SOPS_CONFIG_FILE}}
- msg: Missing Sops Age key file
sh: test -f {{.SOPS_AGE_KEY_FILE}}
apply-config:
desc: Apply Talos configuration to a node
cmd: talosctl apply-config --mode={{.MODE}} --nodes {{.HOSTNAME}} --file {{.TALHELPER_CLUSTER_DIR}}/{{.CLUSTER_NAME}}-{{.HOSTNAME}}.yaml
cmds:
- talosctl --nodes {{.HOSTNAME}} apply-config --mode=staged --file {{.TALHELPER_CLUSTER_DIR}}/{{.CLUSTER_NAME}}-{{.HOSTNAME}}.yaml
- talosctl --nodes {{.HOSTNAME}} reboot
- talosctl --nodes {{.HOSTNAME}} health --wait-timeout=10m --server=false
vars:
MODE: '{{.MODE | default "no-reboot"}}'
CLUSTER_NAME:
sh: yq '.clusterName' {{.TALHELPER_CONFIG_FILE}}
requires:
@@ -71,8 +85,7 @@ tasks:
upgrade-k8s:
desc: Upgrade Kubernetes
cmds:
- talosctl --nodes {{.KUBERNETES_CONTROLLER}} upgrade-k8s --to {{.KUBERNETES_VERSION}}
cmd: talosctl --nodes {{.KUBERNETES_CONTROLLER}} upgrade-k8s --to {{.KUBERNETES_VERSION}}
vars:
KUBERNETES_CONTROLLER:
sh: talosctl config info --output json | jq --raw-output '.endpoints[]' | shuf -n 1
+1 -1
View File
@@ -10,7 +10,7 @@ jq
kubeconform
kubectl-bin
kustomize
minijinja
minijinja-cli-bin
moreutils
sops
stern-bin
+1
View File
@@ -70,6 +70,7 @@ tasks:
- cmd: curl -sSfL https://github.com/mitsuhiko/minijinja/releases/latest/download/minijinja-cli-installer.sh | bash
env:
MINIJINJA_CLI_INSTALL_DIR: '.'
MINIJINJA_CLI_UNMANAGED_INSTALL: 'true'
HELM_INSTALL_DIR: '.'
USE_SUDO: 'false'
+40 -22
View File
@@ -288,6 +288,42 @@ There might be a situation where you want to destroy your Kubernetes cluster. Th
task talos:reset # --force
```
## 🛠️ Talos and Kubernetes Maintenance
#### ⚙️ Updating Talos node configuration
📍 _Ensure you have updated `talconfig.yaml` and any patches with your updated configuration._
```sh
# (Re)generate the Talos config
task talos:generate-config
# Apply the config to the node
task talos:apply-config HOSTNAME=? MODE=?
# e.g. task talos:apply-config HOSTNAME=k8s-0 MODE=reboot
```
#### ⬆️ Updating Talos and Kubernetes versions
📍 _Ensure the `talosVersion` and `kubernetesVersion` in `talhelper.yaml` are up-to-date with the version you wish to upgrade to._
```sh
# Upgrade the whole cluster to a newer Talos version
task talos:upgrade-cluster
# e.g. task talos:upgrade-cluster
```
```sh
# Upgrade node to a newer Talos version
task talos:upgrade-node HOSTNAME=?
# e.g. task talos:upgrade HOSTNAME=k8s-0
```
```sh
# Upgrade cluster to a newer Kubernetes version
task talos:upgrade-k8s
# e.g. task talos:upgrade-k8s
```
## 🤖 Renovate
[Renovate](https://www.mend.io/renovate) is a tool that automates dependency management. It is designed to scan your repository around the clock and open PRs for out-of-date dependencies it finds. Common dependencies it can discover are Helm charts, container images, GitHub Actions, Ansible roles... even Flux itself! Merging a PR will cause Flux to apply the update to your cluster.
@@ -342,28 +378,6 @@ Below is a general guide on trying to debug an issue with an resource or applica
Resolving problems that you have could take some tweaking of your YAML manifests in order to get things working, other times it could be a external factor like permissions on NFS. If you are unable to figure out your problem see the help section below.
## ⬆️ Upgrading Talos and Kubernetes
📍 _Ensure the `talosVersion` and `kubernetesVersion` in `talhelper.yaml` are up-to-date with the version you wish to upgrade to._
```sh
# Upgrade the whole cluster to a newer Talos version
task talos:upgrade-cluster
# e.g. task talos:upgrade-cluster
```
```sh
# Upgrade node to a newer Talos version
task talos:upgrade-node HOSTNAME=?
# e.g. task talos:upgrade HOSTNAME=k8s-0
```
```sh
# Upgrade cluster to a newer Kubernetes version
task talos:upgrade-k8s
# e.g. task talos:upgrade-k8s
```
## 👉 Help
- Make a post in this repository's Github [Discussions](https://github.com/onedr0p/cluster-template/discussions).
@@ -377,6 +391,10 @@ The cluster is your oyster (or something like that). Below are some optional con
To browse or get ideas on applications people are running, community member [@whazor](https://github.com/whazor) created [Kubesearch](https://kubesearch.dev) as a creative way to search Flux HelmReleases across Github and Gitlab.
### DNS
Instead of using [k8s_gateway](https://github.com/ori-edge/k8s_gateway) to provide DNS for your applications you might want to check out [external-dns](https://github.com/kubernetes-sigs/external-dns), it has wide support for many different providers such as [Pi-hole](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/pihole.md), [UniFi](https://github.com/kashalls/external-dns-unifi-webhook), [Adguard Home](https://github.com/muhlba91/external-dns-provider-adguard), [Bind](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/rfc2136.md) and more.
### Storage
The included CSI (openebs in local-hostpath mode) is a great start for storage but soon you might find you need more features like replicated block storage, or to connect to a NFS/SMB/iSCSI server. If you need any of those features be sure to check out the projects like [rook-ceph](https://github.com/rook/rook), [longhorn](https://github.com/longhorn/longhorn), [openebs](https://github.com/openebs/openebs), [democratic-csi](https://github.com/democratic-csi/democratic-csi), [csi-driver-nfs](https://github.com/kubernetes-csi/csi-driver-nfs),
@@ -12,7 +12,7 @@ cgroup:
hostRoot: /sys/fs/cgroup
cluster:
id: 1
name: "#{ bootstrap_cluster_name|default('home-kubernetes', true) }#"
name: "#{ bootstrap_cluster_name | default('home-kubernetes', true) }#"
cni:
exclusive: false
# NOTE: devices might need to be set if you have more than one active NIC on your hosts
@@ -43,7 +43,7 @@ l2announcements:
#% endif %#
loadBalancer:
algorithm: maglev
mode: "#{ bootstrap_loadbalancer_mode|default('dsr', true) }#"
mode: "#{ bootstrap_loadbalancer_mode | default('dsr', true) }#"
localRedirectPolicy: true
operator:
replicas: 1
@@ -16,7 +16,7 @@ spec:
#% for item in bootstrap_bgp.peers %#
- peerAddress: "#{ item }#/32"
peerASN: #{ bootstrap_bgp.peer_asn }#
peerPort: #{ bootstrap_bgp.peer_port | default(179) }#
peerPort: #{ bootstrap_bgp.peer_port | default(179, true) }#
#% endfor %#
#% else %#
#% if bootstrap_node_default_gateway %#
@@ -10,3 +10,16 @@ cluster:
scheduler:
extraArgs:
bind-address: 0.0.0.0
config:
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
pluginConfig:
- name: PodTopologySpread
args:
defaultingType: List
defaultConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
@@ -0,0 +1,6 @@
machine:
network:
nameservers:
#% for item in bootstrap_dns_servers | default(["1.1.1.1","1.0.0.1"], true) %#
- #{ item }#
#% endfor %#
@@ -0,0 +1,7 @@
machine:
time:
disabled: false
servers:
#% for item in bootstrap_ntp_servers | default(["time.cloudflare.com"], true) %#
- #{ item }#
#% endfor %#
@@ -1,7 +1,6 @@
machine:
sysctls:
fs.inotify.max_queued_events: "65536"
fs.inotify.max_user_watches: "524288"
fs.inotify.max_user_watches: "1048576"
fs.inotify.max_user_instances: "8192"
net.core.rmem_max: "7500000"
net.core.wmem_max: "7500000"
@@ -36,9 +36,9 @@ nodes:
#% if bootstrap_secureboot.enabled %#
machineSpec:
secureboot: true
talosImageURL: factory.talos.dev/installer-secureboot/#{ item.schematic_id | default(bootstrap_schematic_id) }#
talosImageURL: factory.talos.dev/installer-secureboot/#{ item.schematic_id | default(bootstrap_schematic_id, true) }#
#% else %#
talosImageURL: factory.talos.dev/installer/#{ item.schematic_id | default(bootstrap_schematic_id) }#
talosImageURL: factory.talos.dev/installer/#{ item.schematic_id | default(bootstrap_schematic_id, true) }#
#% endif %#
controlPlane: #{ (item.controller) | string | lower }#
networkInterfaces:
@@ -49,7 +49,7 @@ nodes:
- vlanId: #{ bootstrap_vlan }#
addresses:
- "#{ item.address }#/#{ bootstrap_node_network.split('/') | last }#"
mtu: #{ item.mtu | default(1500) }#
mtu: #{ item.mtu | default(1500, true) }#
routes:
- network: 0.0.0.0/0
#% if bootstrap_node_default_gateway %#
@@ -62,7 +62,6 @@ nodes:
ip: "#{ bootstrap_controller_vip }#"
#% endif %#
#% else %#
#% if item.address %#
dhcp: false
addresses:
- "#{ item.address }#/#{ bootstrap_node_network.split('/') | last }#"
@@ -73,10 +72,7 @@ nodes:
#% else %#
gateway: "#{ bootstrap_node_network | nthhost(1) }#"
#% endif %#
#% else %#
dhcp: true
#% endif %#
mtu: #{ item.mtu | default(1500) }#
mtu: #{ item.mtu | default(1500, true) }#
#% if item.controller %#
vip:
ip: "#{ bootstrap_controller_vip }#"
@@ -116,27 +112,6 @@ nodes:
# Global patches
patches:
#% if bootstrap_dns_servers | length %#
- # Force nameserver
|-
machine:
network:
nameservers:
#% for item in bootstrap_dns_servers %#
- #{ item }#
#% endfor %#
#% endif %#
#% if bootstrap_ntp_servers | length %#
- # Configure NTP
|-
machine:
time:
disabled: false
servers:
#% for item in bootstrap_ntp_servers %#
- #{ item }#
#% endfor %#
#% endif %#
#% if bootstrap_secureboot.enabled and bootstrap_secureboot.encrypt_disk_with_tpm %#
- # Encrypt system disk with TPM
|-
@@ -12,7 +12,7 @@ spec:
name: github-deploy-key
#% endif %#
ref:
branch: "#{ bootstrap_github_branch|default('main', true) }#"
branch: "#{ bootstrap_github_branch | default('main', true) }#"
ignore: |
# exclude all
/*
+11 -14
View File
@@ -5,7 +5,7 @@
#
# (Optional) Cluster name; affects Cilium and Talos
# Default is "home-kubernetes"
# DEFAULT: "home-kubernetes"
bootstrap_cluster_name: ""
# (Required) Generated schematic id from https://factory.talos.dev/
@@ -18,12 +18,12 @@ bootstrap_node_network: ""
# Worker nodes are optional
bootstrap_node_inventory: []
# - name: "" # (Required) Name of the node (must match [a-z0-9-\]+)
# address: "" # (Optional) IP address of the node (Remove if node has a static DHCP reservation)
# address: "" # (Optional) IP address of the node
# controller: true # (Required) Set to true if this is a controller node
# disk: "" # (Required) Device path or serial number of the disk for this node (talosctl disks -n <ip> --insecure)
# mac_addr: "" # (Required) MAC address of the NIC for this node (talosctl get links -n <ip> --insecure)
# schematic_id: "" # (Optional) Override the 'bootstrap_schematic_id' with a node specific schematic ID from https://factory.talos.dev/
# mtu: "" # (Optional) MTU for the NIC, default is 1500
# mtu: "" # (Optional) MTU for the NIC. DEFAULT: 1500
# manifests: # (Optional) Additional manifests to include after MachineConfig
# - extra.yaml # Ref: https://www.talos.dev/v1.7/reference/configuration/extensions/extensionserviceconfig/
# extension_services: # (Optional) Additional talhelper ExtensionServices (supports talenv.sops.yaml envsubst)
@@ -36,18 +36,15 @@ bootstrap_node_inventory: []
# - key=value
# ...
# (Optional) The DNS servers to use for the cluster nodes.
# Default is pulled from your DHCP server.
# The DNS servers to use for the cluster nodes.
# DEFAULT: [1.1.1.1, 1.0.0.1]
# If using a local DNS server make sure it meets the following requirements:
# 1. your nodes can reach it
# 2. it is configured to forward requests to a public DNS server
# 3. you are not force redirecting DNS requests to it - this will break cert generation over DNS01
# If using multiple DNS servers make sure they are setup the same way, there is no
# guarantee that the first DNS server will always be used for every lookup.
bootstrap_dns_servers: []
# (Optional) The NTP servers to use for the cluster nodes.
# Default is pulled from your DHCP server.
# The NTP servers to use for the cluster nodes.
# DEFAULT: [time.cloudflare.com]
bootstrap_ntp_servers: []
# (Required) The pod CIDR for the cluster, this must NOT overlap with any
@@ -71,7 +68,7 @@ bootstrap_controller_vip: ""
bootstrap_tls_sans: []
# (Optional) The default gateway for the nodes
# Default is derrived from bootstrap_node_network (e.g. 192.168.1.1)
# DEFAULT: .1 derrived from bootstrap_node_network (e.g. 192.168.1.1)
bootstrap_node_default_gateway: ""
# (Optional) Add vlan tag to network master device, leave blank if you tag ports on your switch instead
@@ -90,13 +87,13 @@ bootstrap_age_pubkey: ""
bootstrap_bgp:
enabled: false
# (Optional) If using multiple BGP peers add them here.
# Default is .1 derrived from host_network: ['x.x.x.1']
# DEFAULT: .1 derrived from host_network: ['x.x.x.1']
peers: []
# (Required) Set the BGP Autonomous System Number for the router(s) and nodes.
# If these match, iBGP will be used. If not, eBGP will be used.
peer_asn: "" # Router(s) AS
local_asn: "" # Node(s) AS
peer_port: 179 # BGP Port - default is TCP port 179
peer_port: 179 # BGP Port. DEFAULT: 179
# (Required) The advertised CIDR for the cluster, this must NOT overlap with any
# existing networks and is usually a /16 (64K IPs).
# If you want to use IPv6 check the advanced flags below
@@ -112,7 +109,7 @@ bootstrap_secureboot:
encrypt_disk_with_tpm: false
# (Optional) Change Cilium load balancer mode
# Default is "dsr" (Direct Server Return)
# DEFAULT: "dsr"
# Ref: https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/
bootstrap_loadbalancer_mode: ""
+8 -10
View File
@@ -22,31 +22,29 @@ kubeconform_args=(
echo "=== Validating standalone manifests in ${KUBERNETES_DIR}/flux ==="
find "${KUBERNETES_DIR}/flux" -maxdepth 1 -type f -name '*.yaml' -print0 | while IFS= read -r -d $'\0' file;
do
do
kubeconform "${kubeconform_args[@]}" "${file}"
if [[ ${PIPESTATUS[0]} != 0 ]]; then
exit 1
exit 1
fi
done
echo "=== Validating kustomizations in ${KUBERNETES_DIR}/flux ==="
find "${KUBERNETES_DIR}/flux" -type f -name $kustomize_config -print0 | while IFS= read -r -d $'\0' file;
do
do
echo "=== Validating kustomizations in ${file/%$kustomize_config} ==="
kustomize build "${file/%$kustomize_config}" "${kustomize_args[@]}" | \
kubeconform "${kubeconform_args[@]}"
kustomize build "${file/%$kustomize_config}" "${kustomize_args[@]}" | kubeconform "${kubeconform_args[@]}"
if [[ ${PIPESTATUS[0]} != 0 ]]; then
exit 1
exit 1
fi
done
echo "=== Validating kustomizations in ${KUBERNETES_DIR}/apps ==="
find "${KUBERNETES_DIR}/apps" -type f -name $kustomize_config -print0 | while IFS= read -r -d $'\0' file;
do
do
echo "=== Validating kustomizations in ${file/%$kustomize_config} ==="
kustomize build "${file/%$kustomize_config}" "${kustomize_args[@]}" | \
kubeconform "${kubeconform_args[@]}"
kustomize build "${file/%$kustomize_config}" "${kustomize_args[@]}" | kubeconform "${kubeconform_args[@]}"
if [[ ${PIPESTATUS[0]} != 0 ]]; then
exit 1
exit 1
fi
done