--- apiVersion: apps/v1 kind: Deployment metadata: name: openpxe namespace: openpxe labels: app.kubernetes.io/name: openpxe 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: openpxe template: metadata: labels: app.kubernetes.io/name: openpxe spec: serviceAccountName: openpxe # 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: openpxe image: gitea.milesward.dev/mward4/openpxe:0.3.2 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: openpxe-config securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 10001 capabilities: drop: ["ALL"] add: ["NET_BIND_SERVICE"] volumeMounts: - name: isos mountPath: /var/lib/openpxe/isos - name: work mountPath: /var/lib/openpxe/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: openpxe-isos - name: work emptyDir: {} - name: tmp emptyDir: {}