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
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:
name: {{ .Values.pool.name }}
spec:
autoAssign: false
addresses:
{{- range .Values.pool.addresses }}
- {{ . }}

View File

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

View File

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

View File

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