Settle on v1 setup method. Test run completed successfully from bootstrap to service setup.

- Refactor dnsmasq configuration and scripts for improved variable handling and clarity
- Updated dnsmasq configuration files to use direct variable references instead of data source functions for better readability.
- Modified setup scripts to ensure they are run from the correct environment and directory, checking for the WC_HOME variable.
- Changed paths in README and scripts to reflect the new directory structure.
- Enhanced error handling in setup scripts to provide clearer guidance on required configurations.
- Adjusted kernel and initramfs URLs in boot.ipxe to use the updated variable references.
This commit is contained in:
2025-06-24 15:12:53 -07:00
parent 335cca1eba
commit f1fe4f9cc2
165 changed files with 15838 additions and 1003 deletions

View File

@@ -5,3 +5,27 @@
Ingress RDs can be create for any service. The routes specificed in the Ingress are added automatically to the Traefik proxy.
Traefik serves all incoming network traffic on ports 80 and 443 to their appropriate services based on the route.
## Notes
These kustomize templates were created with:
```bash
helm-chart-to-kustomize traefik/traefik traefik traefik values.yaml
```
With values.yaml being:
```yaml
ingressRoute:
dashboard:
enabled: true
matchRule: Host(`dashboard.localhost`)
entryPoints:
- web
providers:
kubernetesGateway:
enabled: true
gateway:
namespacePolicy: All
```

View File

@@ -0,0 +1,44 @@
#!/bin/bash
set -e
if [ -z "${WC_HOME}" ]; then
echo "Please source the wildcloud environment first. (e.g., \`source ./env.sh\`)"
exit 1
fi
CLUSTER_SETUP_DIR="${WC_HOME}/setup/cluster"
TRAEFIK_DIR="${CLUSTER_SETUP_DIR}/traefik"
echo "Setting up Traefik ingress controller..."
# Install required CRDs first
echo "Installing Gateway API CRDs..."
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
echo "Installing Traefik CRDs..."
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.4/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
echo "Waiting for CRDs to be established..."
kubectl wait --for condition=established crd/gateways.gateway.networking.k8s.io --timeout=60s
kubectl wait --for condition=established crd/gatewayclasses.gateway.networking.k8s.io --timeout=60s
kubectl wait --for condition=established crd/ingressroutes.traefik.io --timeout=60s
kubectl wait --for condition=established crd/middlewares.traefik.io --timeout=60s
# Process templates with wild-compile-template-dir
echo "Processing Traefik templates..."
wild-compile-template-dir --clean ${TRAEFIK_DIR}/kustomize.template ${TRAEFIK_DIR}/kustomize
# Apply Traefik using kustomize
echo "Deploying Traefik..."
kubectl apply -k ${TRAEFIK_DIR}/kustomize
# Wait for Traefik to be ready
echo "Waiting for Traefik to be ready..."
kubectl wait --for=condition=Available deployment/traefik -n traefik --timeout=120s
echo "✅ Traefik setup complete!"
echo ""
echo "To verify the installation:"
echo " kubectl get pods -n traefik"
echo " kubectl get svc -n traefik"

View File

@@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- templates/deployment.yaml
- templates/gatewayclass.yaml
- templates/gateway.yaml
- templates/ingressclass.yaml
- templates/ingressroute.yaml
- templates/rbac/clusterrolebinding.yaml
- templates/rbac/clusterrole.yaml
- templates/rbac/serviceaccount.yaml
- templates/service.yaml

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: traefik

View File

@@ -0,0 +1,130 @@
---
# Source: traefik/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
annotations:
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
minReadySeconds: 0
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: "9100"
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
spec:
serviceAccountName: traefik
automountServiceAccountToken: true
terminationGracePeriodSeconds: 60
hostNetwork: false
containers:
- image: docker.io/traefik:v3.4.1
imagePullPolicy: IfNotPresent
name: traefik
resources:
readinessProbe:
httpGet:
path: /ping
port: 8080
scheme: HTTP
failureThreshold: 1
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /ping
port: 8080
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
lifecycle:
ports:
- name: metrics
containerPort: 9100
protocol: TCP
- name: traefik
containerPort: 8080
protocol: TCP
- name: web
containerPort: 8000
protocol: TCP
- name: websecure
containerPort: 8443
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- name: data
mountPath: /data
- name: tmp
mountPath: /tmp
args:
- "--global.checkNewVersion"
- "--entryPoints.metrics.address=:9100/tcp"
- "--entryPoints.traefik.address=:8080/tcp"
- "--entryPoints.web.address=:8000/tcp"
- "--entryPoints.websecure.address=:8443/tcp"
- "--api.dashboard=true"
- "--ping=true"
- "--metrics.prometheus=true"
- "--metrics.prometheus.entrypoint=metrics"
- "--providers.kubernetescrd"
- "--providers.kubernetescrd.allowEmptyServices=true"
- "--providers.kubernetesingress"
- "--providers.kubernetesingress.allowEmptyServices=true"
- "--providers.kubernetesingress.ingressendpoint.publishedservice=traefik/traefik"
- "--providers.kubernetesgateway"
- "--providers.kubernetesgateway.statusaddress.service.name=traefik"
- "--providers.kubernetesgateway.statusaddress.service.namespace=traefik"
- "--entryPoints.websecure.http.tls=true"
- "--log.level=INFO"
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumes:
- name: data
emptyDir: {}
- name: tmp
emptyDir: {}
securityContext:
runAsGroup: 65532
runAsNonRoot: true
runAsUser: 65532

View File

@@ -0,0 +1,18 @@
---
# Source: traefik/templates/gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: traefik-gateway
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
spec:
gatewayClassName: traefik
listeners:
- name: web
port: 8000
protocol: HTTP

View File

@@ -0,0 +1,13 @@
---
# Source: traefik/templates/gatewayclass.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
spec:
controllerName: traefik.io/gateway-controller

View File

@@ -0,0 +1,15 @@
---
# Source: traefik/templates/ingressclass.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
name: traefik
spec:
controller: traefik.io/ingress-controller

View File

@@ -0,0 +1,21 @@
---
# Source: traefik/templates/ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
spec:
entryPoints:
- web
routes:
- match: Host(`dashboard.localhost`)
kind: Rule
services:
- kind: TraefikService
name: api@internal

View File

@@ -0,0 +1,108 @@
---
# Source: traefik/templates/rbac/clusterrole.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
rules:
- apiGroups:
- ""
resources:
- configmaps
- nodes
- services
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingressclasses
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.io
resources:
- ingressroutes
- ingressroutetcps
- ingressrouteudps
- middlewares
- middlewaretcps
- serverstransports
- serverstransporttcps
- tlsoptions
- tlsstores
- traefikservices
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
- secrets
- configmaps
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- backendtlspolicies
- gatewayclasses
- gateways
- grpcroutes
- httproutes
- referencegrants
- tcproutes
- tlsroutes
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- backendtlspolicies/status
- gatewayclasses/status
- gateways/status
- grpcroutes/status
- httproutes/status
- tcproutes/status
- tlsroutes/status
verbs:
- update

View File

@@ -0,0 +1,19 @@
---
# Source: traefik/templates/rbac/clusterrolebinding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-traefik
subjects:
- kind: ServiceAccount
name: traefik
namespace: traefik

View File

@@ -0,0 +1,14 @@
---
# Source: traefik/templates/rbac/serviceaccount.yaml
kind: ServiceAccount
apiVersion: v1
metadata:
name: traefik
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
annotations:
automountServiceAccountToken: false

View File

@@ -0,0 +1,27 @@
---
# Source: traefik/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
annotations:
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
ports:
- port: 80
name: web
targetPort: web
protocol: TCP
- port: 443
name: websecure
targetPort: websecure
protocol: TCP

View File

@@ -14,7 +14,7 @@ metadata:
app.kubernetes.io/name: traefik
spec:
type: LoadBalancer
loadBalancerIP: 192.168.8.240
loadBalancerIP: { { .cluster.loadBalancerIP } }
selector:
app.kubernetes.io/instance: traefik-kube-system
app.kubernetes.io/name: traefik
@@ -22,8 +22,7 @@ spec:
- name: web
port: 80
targetPort: web
- name: websecure
- name: websecure
port: 443
targetPort: websecure
externalTrafficPolicy: Local

View File

@@ -0,0 +1,13 @@
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: internal-only
namespace: kube-system
spec:
ipWhiteList:
# Restrict to local private network ranges - adjust these to match your network
sourceRange:
- 127.0.0.1/32 # localhost
- 10.0.0.0/8 # Private network
- 172.16.0.0/12 # Private network
- 192.168.0.0/16 # Private network

View File

@@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- templates/deployment.yaml
- templates/gatewayclass.yaml
- templates/gateway.yaml
- templates/ingressclass.yaml
- templates/ingressroute.yaml
- templates/rbac/clusterrolebinding.yaml
- templates/rbac/clusterrole.yaml
- templates/rbac/serviceaccount.yaml
- templates/service.yaml

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: traefik

View File

@@ -0,0 +1,130 @@
---
# Source: traefik/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
annotations:
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
minReadySeconds: 0
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: "9100"
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
spec:
serviceAccountName: traefik
automountServiceAccountToken: true
terminationGracePeriodSeconds: 60
hostNetwork: false
containers:
- image: docker.io/traefik:v3.4.1
imagePullPolicy: IfNotPresent
name: traefik
resources:
readinessProbe:
httpGet:
path: /ping
port: 8080
scheme: HTTP
failureThreshold: 1
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /ping
port: 8080
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
lifecycle:
ports:
- name: metrics
containerPort: 9100
protocol: TCP
- name: traefik
containerPort: 8080
protocol: TCP
- name: web
containerPort: 8000
protocol: TCP
- name: websecure
containerPort: 8443
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- name: data
mountPath: /data
- name: tmp
mountPath: /tmp
args:
- "--global.checkNewVersion"
- "--entryPoints.metrics.address=:9100/tcp"
- "--entryPoints.traefik.address=:8080/tcp"
- "--entryPoints.web.address=:8000/tcp"
- "--entryPoints.websecure.address=:8443/tcp"
- "--api.dashboard=true"
- "--ping=true"
- "--metrics.prometheus=true"
- "--metrics.prometheus.entrypoint=metrics"
- "--providers.kubernetescrd"
- "--providers.kubernetescrd.allowEmptyServices=true"
- "--providers.kubernetesingress"
- "--providers.kubernetesingress.allowEmptyServices=true"
- "--providers.kubernetesingress.ingressendpoint.publishedservice=traefik/traefik"
- "--providers.kubernetesgateway"
- "--providers.kubernetesgateway.statusaddress.service.name=traefik"
- "--providers.kubernetesgateway.statusaddress.service.namespace=traefik"
- "--entryPoints.websecure.http.tls=true"
- "--log.level=INFO"
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumes:
- name: data
emptyDir: {}
- name: tmp
emptyDir: {}
securityContext:
runAsGroup: 65532
runAsNonRoot: true
runAsUser: 65532

View File

@@ -0,0 +1,18 @@
---
# Source: traefik/templates/gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: traefik-gateway
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
spec:
gatewayClassName: traefik
listeners:
- name: web
port: 8000
protocol: HTTP

View File

@@ -0,0 +1,13 @@
---
# Source: traefik/templates/gatewayclass.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
spec:
controllerName: traefik.io/gateway-controller

View File

@@ -0,0 +1,15 @@
---
# Source: traefik/templates/ingressclass.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
name: traefik
spec:
controller: traefik.io/ingress-controller

View File

@@ -0,0 +1,21 @@
---
# Source: traefik/templates/ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
spec:
entryPoints:
- web
routes:
- match: Host(`dashboard.localhost`)
kind: Rule
services:
- kind: TraefikService
name: api@internal

View File

@@ -0,0 +1,108 @@
---
# Source: traefik/templates/rbac/clusterrole.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
rules:
- apiGroups:
- ""
resources:
- configmaps
- nodes
- services
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingressclasses
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.io
resources:
- ingressroutes
- ingressroutetcps
- ingressrouteudps
- middlewares
- middlewaretcps
- serverstransports
- serverstransporttcps
- tlsoptions
- tlsstores
- traefikservices
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
- secrets
- configmaps
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- backendtlspolicies
- gatewayclasses
- gateways
- grpcroutes
- httproutes
- referencegrants
- tcproutes
- tlsroutes
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- backendtlspolicies/status
- gatewayclasses/status
- gateways/status
- grpcroutes/status
- httproutes/status
- tcproutes/status
- tlsroutes/status
verbs:
- update

View File

@@ -0,0 +1,19 @@
---
# Source: traefik/templates/rbac/clusterrolebinding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-traefik
subjects:
- kind: ServiceAccount
name: traefik
namespace: traefik

View File

@@ -0,0 +1,14 @@
---
# Source: traefik/templates/rbac/serviceaccount.yaml
kind: ServiceAccount
apiVersion: v1
metadata:
name: traefik
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
annotations:
automountServiceAccountToken: false

View File

@@ -0,0 +1,27 @@
---
# Source: traefik/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: traefik
labels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
helm.sh/chart: traefik-36.1.0
app.kubernetes.io/managed-by: Helm
annotations:
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-traefik
ports:
- port: 80
name: web
targetPort: web
protocol: TCP
- port: 443
name: websecure
targetPort: websecure
protocol: TCP

View File

@@ -0,0 +1,28 @@
---
# Traefik service configuration with static LoadBalancer IP
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: kube-system
annotations:
# Get a stable IP from MetalLB
metallb.universe.tf/address-pool: production
metallb.universe.tf/allow-shared-ip: traefik-lb
labels:
app.kubernetes.io/instance: traefik-kube-system
app.kubernetes.io/name: traefik
spec:
type: LoadBalancer
loadBalancerIP: { { .cluster.loadBalancerIP } }
selector:
app.kubernetes.io/instance: traefik-kube-system
app.kubernetes.io/name: traefik
ports:
- name: web
port: 80
targetPort: web
- name: websecure
port: 443
targetPort: websecure
externalTrafficPolicy: Local