WIP: separate traefik for public

This commit is contained in:
Alvin Wang 2026-04-20 16:36:57 -04:00
parent 888a3af835
commit 9bb83b459c
6 changed files with 38 additions and 10 deletions

View File

@ -10,5 +10,23 @@ I have a DNS rewrite pointing *.internal to 10.0.1.250 which is traefik-internal
/dogstore/ is a NFS path that's available to all nodes /dogstore/ is a NFS path that's available to all nodes
secrets are managed by sops secrets are managed by sops
## Load balancers
Two LB implementations coexist: k3s klipper (servicelb) and MetalLB. They are
separated by `loadBalancerClass` so they don't conflict.
- **klipper** handles services with NO `loadBalancerClass`. It creates svclb
DaemonSet pods that bind host ports directly on every node.
- **MetalLB** handles services with `loadBalancerClass: metallb`. Its pool has
`autoAssign: false`, so it only assigns IPs to services that explicitly
request a pool via the `metallb.io/address-pool` annotation.
| Service | loadBalancerClass | LB | External IPs |
|------------------|-------------------|----------|-------------------------|
| traefik | (none) | klipper | node IPs (10.0.1.2 etc) |
| traefik-internal | metallb | MetalLB | 10.0.1.250 |
`loadBalancerClass` is immutable on k8s Services. Changing it requires deleting
the Service first, then redeploying (`kubectl delete svc … && helm upgrade`).

View File

@ -4,6 +4,7 @@ kind: IPAddressPool
metadata: metadata:
name: {{ .Values.pool.name }} name: {{ .Values.pool.name }}
spec: spec:
autoAssign: false
addresses: addresses:
{{- range .Values.pool.addresses }} {{- range .Values.pool.addresses }}
- {{ . }} - {{ . }}

View File

@ -1,4 +1,5 @@
metallb: metallb:
loadBalancerClass: metallb
controller: controller:
nodeSelector: nodeSelector:
node-role.kubernetes.io/control-plane: "true" node-role.kubernetes.io/control-plane: "true"
@ -7,7 +8,7 @@ metallb:
effect: NoSchedule effect: NoSchedule
pool: pool:
enabled: false enabled: true
name: internal name: internal
addresses: addresses:
- "10.0.1.250-10.0.1.250" - "10.0.1.250-10.0.1.250"

View File

@ -5,9 +5,11 @@ metadata:
namespace: kube-system namespace: kube-system
spec: spec:
valuesContent: |- valuesContent: |-
service: nodeSelector:
spec: node-role.kubernetes.io/control-plane: "true"
loadBalancerClass: io.k3s.klipper tolerations:
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
logs: logs:
general: general:
level: WARN level: WARN
@ -35,7 +37,12 @@ spec:
secretKeyRef: secretKeyRef:
name: {{ .Values.cloudflare.secretName }} name: {{ .Values.cloudflare.secretName }}
key: {{ .Values.cloudflare.secretKey }} key: {{ .Values.cloudflare.secretKey }}
persistence: deployment:
enabled: true additionalVolumes:
storageClass: longhorn - name: acme
size: 128Mi hostPath:
path: /dogstore/service-data/.letsencrypt
type: DirectoryOrCreate
additionalVolumeMounts:
- name: acme
mountPath: /letsencrypt

View File

@ -9,4 +9,4 @@ cloudflare:
secretKey: CF_DNS_API_TOKEN secretKey: CF_DNS_API_TOKEN
letsencrypt: letsencrypt:
storagePath: /data/acme.json storagePath: /letsencrypt/acme.json

View File

@ -82,6 +82,7 @@ metadata:
metallb.io/address-pool: internal metallb.io/address-pool: internal
spec: spec:
type: LoadBalancer type: LoadBalancer
loadBalancerClass: metallb
loadBalancerIP: {{ .Values.loadBalancerIP }} loadBalancerIP: {{ .Values.loadBalancerIP }}
selector: selector:
app: traefik-internal app: traefik-internal