apiVersion: v1 kind: Secret metadata: name: pihole-dns-secret labels: project: pihole data: # Needs to be base64 encoded as stated here https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#secret-v1-core # echo -n '' | base64 FTLCONF_webserver_api_password: --- apiVersion: apps/v1 kind: StatefulSet metadata: name: pihole-dns-statefulset labels: project: pihole spec: replicas: 3 selector: matchLabels: pod-project: pihole serviceName: pihole-statefulsets-webgui-service minReadySeconds: 10 template: metadata: labels: pod-project: pihole project-ns-name: private-srvc # pod-project: doh spec: terminationGracePeriodSeconds: 10 automountServiceAccountToken: false # Container doesn't need service account token securityContext: appArmorProfile: type: RuntimeDefault # runAsNonRoot: true fsGroup: 1500 # runAsGroup: 1500 # runAsUser: 1500 containers: - name: pihole-dns image: pihole/pihole:latest imagePullPolicy: IfNotPresent volumeMounts: - name: pihole-statefulset-data mountPath: /etc/pihole - name: dnsmasq-extra-data mountPath: /etc/dnsmasq.d ports: - name: dns-tcp containerPort: 53 protocol: TCP - name: dns-udp containerPort: 53 protocol: UDP - name: webgui-https containerPort: 443 protocol: TCP - name: webgui-http containerPort: 80 protocol: TCP env: - name: TZ value: Europe/Stockholm - name: FTLCONF_dns_listeningMode value: all - name: FTLCONF_webserver_port value: "80,443s" - name: DNSMASQ_LISTENING value: all - name: PIHOLE_UID value: "1500" - name: PIHOLE_GID value: "1500" envFrom: - secretRef: name: pihole-dns-secret startupProbe: tcpSocket: port: 53 # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] initialDelaySeconds: 5 periodSeconds: 5 failureThreshold: 60 livenessProbe: exec: command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] periodSeconds: 5 failureThreshold: 4 readinessProbe: exec: command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] periodSeconds: 10 failureThreshold: 6 resources: requests: memory: "256Mi" cpu: "200m" limits: memory: "512Mi" # cpu: "550m" # https://github.com/eko/pihole-exporter - name: prom-exporter image: ekofr/pihole-exporter:v1.2.0 imagePullPolicy: IfNotPresent ports: - name: prom-export containerPort: 50934 protocol: TCP env: - name: PIHOLE_HOSTNAME value: "127.0.0.1" - name: PIHOLE_PASSWORD value: "YOURPASSWORDHERE" - name: PORT value: "50934" - name: cloudflare-1-1-1-1 image: visibilityspots/cloudflared:v2025.7.0 imagePullPolicy: IfNotPresent ports: - name: doh-unseiso-udp containerPort: 5051 protocol: UDP env: - name: PORT value: "5051" - name: UPSTREAM1 value: https://1.1.1.1/dns-query - name: UPSTREAM2 value: https://1.0.0.1/dns-query - name: METRICS value: "127.0.0.1:8081" # startupProbe: # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] # initialDelaySeconds: 6 # periodSeconds: 4 # failureThreshold: 6 # livenessProbe: # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] # readinessProbe: # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] resources: requests: memory: "48Mi" cpu: "100m" # limits: # memory: "96Mi" # cpu: "150m" - name: cloudflare-1-1-1-2 image: visibilityspots/cloudflared:v2025.7.0 imagePullPolicy: IfNotPresent ports: - name: doh-no-virus containerPort: 5052 protocol: UDP env: - name: PORT value: "5052" - name: UPSTREAM1 value: https://1.1.1.2/dns-query - name: UPSTREAM2 value: https://1.0.0.2/dns-query - name: METRICS value: "127.0.0.1:8082" # startupProbe: # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] # initialDelaySeconds: 6 # periodSeconds: 4 # failureThreshold: 6 # livenessProbe: # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] # readinessProbe: # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] resources: requests: memory: "48Mi" cpu: "100m" # limits: # memory: "96Mi" # cpu: "150m" - name: cloudflare-1-1-1-3 image: visibilityspots/cloudflared:v2025.7.0 imagePullPolicy: IfNotPresent ports: - name: doh-seiso-udp containerPort: 5053 protocol: UDP env: - name: PORT value: "5053" - name: UPSTREAM1 value: https://1.1.1.3/dns-query - name: UPSTREAM2 value: https://1.0.0.3/dns-query - name: METRICS value: "127.0.0.1:8083" # startupProbe: # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] # initialDelaySeconds: 6 # periodSeconds: 4 # failureThreshold: 6 # livenessProbe: # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] # readinessProbe: # exec: # command: ["sh","-c","nslookup -timeout=2 google.com 127.0.0.1 >/dev/null"] resources: requests: memory: "48Mi" cpu: "100m" # limits: # memory: "96Mi" # cpu: "150m" volumes: - name: dnsmasq-extra-data persistentVolumeClaim: claimName: dnsmasq-extra-data-pvc volumeClaimTemplates: - metadata: name: pihole-statefulset-data # spec: accessModes: # - ReadOnlyMany - ReadWriteOnce # - ReadWriteMany resources: requests: storage: 4Gi