Name update

This commit is contained in:
Miles Ward
2026-04-29 02:47:00 -04:00
commit 3517c67831
66 changed files with 9016 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Namespace
metadata:
name: pxeforge
labels:
# Allow privileged pods (host-network) in this namespace only. The pod
# itself still runs non-root with only NET_BIND_SERVICE — privileged
# here is about namespace pod-security, not container privileges.
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/warn: privileged
pod-security.kubernetes.io/audit: privileged
+80
View File
@@ -0,0 +1,80 @@
---
# Custom SCC for PXEForge.
#
# The default `restricted-v2` SCC blocks host network and all capabilities,
# which PXE cannot tolerate: DHCPDISCOVER is an L2 broadcast that CNI overlays
# do not deliver into pod netns. We grant the minimum set needed:
#
# - allowHostNetwork: true — required to receive broadcast DHCP
# - allowHostPorts: true — exposes 67/69/4011/80 on the node
# - requiredDropCapabilities strips the usual dangerous caps
# - allowedCapabilities:
# NET_BIND_SERVICE — bind <1024 as non-root
# - runAsUser.type: MustRunAsRange — force non-root uid mapped via setcap
# - readOnlyRootFilesystem: true — binary is in / (set by image), data
# dirs are mounted elsewhere
#
# We do NOT grant NET_RAW / NET_ADMIN / SYS_ADMIN. Proxy-mode DHCP does not
# need raw sockets (see architecture memory).
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: pxeforge-scc
annotations:
kubernetes.io/description: >-
Minimal SCC for PXEForge: host network + NET_BIND_SERVICE only, no raw
sockets, no privileged mode.
allowPrivilegedContainer: false
allowPrivilegeEscalation: false
allowHostNetwork: true
allowHostPorts: true
allowHostPID: false
allowHostIPC: false
allowedCapabilities:
- NET_BIND_SERVICE
requiredDropCapabilities:
- ALL
defaultAddCapabilities: []
readOnlyRootFilesystem: true
runAsUser:
type: MustRunAsRange
seLinuxContext:
type: MustRunAs
fsGroup:
type: MustRunAs
supplementalGroups:
type: RunAsAny
volumes:
- configMap
- downwardAPI
- emptyDir
- persistentVolumeClaim
- projected
- secret
users: []
groups: []
---
# Bind the SCC to the pxeforge service account.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pxeforge-scc-use
rules:
- apiGroups: ["security.openshift.io"]
resources: ["securitycontextconstraints"]
resourceNames: ["pxeforge-scc"]
verbs: ["use"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pxeforge-scc-use
namespace: pxeforge
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pxeforge-scc-use
subjects:
- kind: ServiceAccount
name: pxeforge
namespace: pxeforge
+35
View File
@@ -0,0 +1,35 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: pxeforge
namespace: pxeforge
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pxeforge-config
namespace: pxeforge
data:
# Toggle DHCP proxy on or off. "proxy" = answer PXE clients alongside an
# existing DHCP server. "disabled" = require operator to point an external
# DHCP at us via next-server/filename.
PXEFORGE_DHCP_MODE: "proxy"
# Override if auto-detection picks the wrong NIC in multi-homed pods.
# Leave unset to auto-detect from the node's primary IPv4.
# PXEFORGE_PUBLIC_IP: "10.0.0.5"
PXEFORGE_LOG: "info,pxeforge=info"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pxeforge-isos
namespace: pxeforge
spec:
# ReadWriteOnce is fine — we deploy as a single replica since DHCP proxy
# coordination across replicas is not useful (clients hit whichever node
# hostNetwork catches their broadcast).
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 200Gi
+104
View File
@@ -0,0 +1,104 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pxeforge
namespace: pxeforge
labels:
app.kubernetes.io/name: pxeforge
spec:
# Single replica by design (see PVC comment). If HA is needed later, split
# the HTTP/web plane (scalable, stateless) from the DHCP-proxy/TFTP plane
# (anycast / per-node daemonset).
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: pxeforge
template:
metadata:
labels:
app.kubernetes.io/name: pxeforge
spec:
serviceAccountName: pxeforge
# L2 broadcast (DHCPDISCOVER) does not cross most CNI overlays into
# pod netns. Host network is the working path.
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
securityContext:
# setcap on the binary allows non-root <1024 binding. No need to
# run as root.
runAsNonRoot: true
runAsUser: 10001
fsGroup: 10001
containers:
- name: pxeforge
image: ghcr.io/casperadmin/pxeforge:0.1.0
imagePullPolicy: IfNotPresent
ports:
- name: dhcp
containerPort: 67
hostPort: 67
protocol: UDP
- name: tftp
containerPort: 69
hostPort: 69
protocol: UDP
- name: pxe
containerPort: 4011
hostPort: 4011
protocol: UDP
- name: http
containerPort: 80
hostPort: 80
protocol: TCP
- name: smb
containerPort: 445
hostPort: 445
protocol: TCP
envFrom:
- configMapRef:
name: pxeforge-config
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 10001
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
volumeMounts:
- name: isos
mountPath: /var/lib/pxeforge/isos
- name: work
mountPath: /var/lib/pxeforge/work
- name: tmp
mountPath: /tmp
readinessProbe:
httpGet:
path: /api/status
port: 80
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /api/status
port: 80
initialDelaySeconds: 15
periodSeconds: 15
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 512Mi
volumes:
- name: isos
persistentVolumeClaim:
claimName: pxeforge-isos
- name: work
emptyDir: {}
- name: tmp
emptyDir: {}
+43
View File
@@ -0,0 +1,43 @@
---
# Service for the web UI / API. Using host network means the pod IP is the
# node IP, so this Service is mostly useful for cluster-internal ingress to
# the management UI via Route below.
apiVersion: v1
kind: Service
metadata:
name: pxeforge
namespace: pxeforge
labels:
app.kubernetes.io/name: pxeforge
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: pxeforge
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
- name: smb
port: 445
targetPort: 445
protocol: TCP
---
# Expose the web UI through an OpenShift Route. Clients on the PXE network
# still talk to the node directly on UDP 67/69/4011 — the Route only covers
# the TCP/80 management plane.
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: pxeforge
namespace: pxeforge
spec:
to:
kind: Service
name: pxeforge
weight: 100
port:
targetPort: http
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect