diff --git a/Pihole/StatefulSet.yaml b/Pihole/StatefulSet.yaml new file mode 100644 index 0000000..30ca118 --- /dev/null +++ b/Pihole/StatefulSet.yaml @@ -0,0 +1,257 @@ +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 diff --git a/Pihole/nebula.yaml b/Pihole/nebula.yaml new file mode 100644 index 0000000..88598c4 --- /dev/null +++ b/Pihole/nebula.yaml @@ -0,0 +1,145 @@ +apiVersion: v1 +kind: Secret +metadata: + name: nebula-sync-secret + labels: + project: pihole + project: nebula-sync + +data: + # https + # echo -n "something" | base64 + PRIMARY: + REPLICAS: + + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nebula-sync-configmap + + labels: + project: pihole + project: nebula-sync + +data: + FULL_SYNC: "true" + CRON: "25 */3 * * *" + RUN_GRAVITY: "true" + TZ: Europe/Stockholm + CLIENT_SKIP_TLS_VERIFICATION: "true" + SYNC_GRAVITY_CLIENT: "true" + SYNC_CONFIG_DNS: "true" + SYNC_CONFIG_RESOLVER: "true" + SYNC_CONFIG_DATABASE: "true" + SYNC_CONFIG_MISC: "true" + SYNC_GRAVITY_GROUP: "true" + SYNC_GRAVITY_AD_LIST: "true" + SYNC_GRAVITY_DOMAIN_LIST: "true" + SYNC_GRAVITY_CLIENT: "true" + + + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nebula-sync-deployment + + labels: + project: pihole + project: nebula-sync + + +spec: + replicas: 1 + selector: + matchLabels: + pod-project: nebula-sync + template: + metadata: + labels: + pod-project: nebula-sync + # pod-project: doh + spec: + automountServiceAccountToken: false # Container doesn't need service account token + securityContext: + appArmorProfile: + type: RuntimeDefault + runAsNonRoot: true + # fsGroup: 1500 + runAsGroup: 1500 + runAsUser: 1500 + containers: + - name: nebula-sync + image: ghcr.io/lovelaze/nebula-sync + imagePullPolicy: IfNotPresent + envFrom: + - configMapRef: + name: nebula-sync-configmap + - secretRef: + name: nebula-sync-secret + resources: + requests: + memory: "152Mi" + cpu: "100m" + limits: + memory: "384Mi" + # cpu: "550m" + + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: nebula-sync-netwrokpolicy + + labels: + project: pihole + project: nebula-sync + +spec: + podSelector: + matchLabels: + pod-project: nebula-sync + egress: + # Allow connecting to CoreDNS + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + podSelector: + matchLabels: + k8s-app: kube-dns + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + + # - to: + # - namespaceSelector: + # matchLabels: + # kubernetes.io/metadata.name: + # podSelector: + # matchLabels: + # pod-project: pihole + ports: + - protocol: TCP + port: 443 + + ingress: + # - from: + # - namespaceSelector: + # matchLabels: + # kubernetes.io/metadata.name: private-srvc + # podSelector: + # matchLabels: + # pod-project: pihole + # project-ns-name: private-srvc + + + policyTypes: + - Ingress + - Egress \ No newline at end of file diff --git a/Pihole/netPolicy.yaml b/Pihole/netPolicy.yaml new file mode 100644 index 0000000..2353202 --- /dev/null +++ b/Pihole/netPolicy.yaml @@ -0,0 +1,94 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: pihole-config-data-netwrokpolicy + labels: + project: pihole + +spec: + podSelector: + matchLabels: + pod-project: pihole + egress: + # Allow all egress + # - {} + + # Allow egress only to public networks + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + podSelector: + matchLabels: + k8s-app: kube-dns + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + + - to: + - ipBlock: + cidr: 0.0.0.0/0 + except: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + + ingress: + # - from: + # - namespaceSelector: + # matchLabels: + # ns-name: + # podSelector: + # matchLabels: + # podDomain: + # ports: + # - protocol: TCP + # port: 80 + # - protocol: TCP + # port: 443 + + # - from: + # - namespaceSelector: + # matchLabels: + # ns-name: + # podSelector: + # matchLabels: + # pod-project: nebula-sync + # ports: + # - protocol: TCP + # port: 443 + # - protocol: TCP + # port: 80 + + - from: + - ipBlock: + cidr: 192.168.0.0/16 + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + + - from: + - ipBlock: + cidr: 10.0.0.0/8 + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + + - from: + - ipBlock: + cidr: 172.16.0.0/12 + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + + policyTypes: + - Ingress + - Egress \ No newline at end of file diff --git a/Pihole/pvc.yaml b/Pihole/pvc.yaml new file mode 100644 index 0000000..640724d --- /dev/null +++ b/Pihole/pvc.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: dnsmasq-extra-data-pvc + namespace: private-srvc + labels: + project: pihole +spec: + # https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes-1 + accessModes: + # - ReadOnlyMany + # - ReadWriteOnce + - ReadWriteMany + resources: + requests: + storage: 32Mi diff --git a/Pihole/service.yaml b/Pihole/service.yaml new file mode 100644 index 0000000..300f5c1 --- /dev/null +++ b/Pihole/service.yaml @@ -0,0 +1,91 @@ +# WebGUI +apiVersion: v1 +kind: Service +metadata: + name: pihole-statefulsets-webgui-service + + labels: + project: pihole + +spec: + selector: + pod-project: pihole + # This isn't used as Ingress is doing TLS termination + # type: LoadBalancer + type: ClusterIP + clusterIP: None + ports: + - name: pihole-webgui-https + protocol: TCP + port: 443 # <- port that will be exposed + targetPort: 443 + - name: pihole-webgui-http + protocol: TCP + port: 80 # <- port that will be exposed + targetPort: 80 + - name: pihole-dns-udp + protocol: UDP + port: 53 # <- port that will be exposed + targetPort: 53 + - name: pihole-dns-tcp + protocol: TCP + port: 53 # <- port that will be exposed + targetPort: 53 + +# Then use these for connecting to individual pods +# podName.headlessServiceName.nameSpace.svc.cluster.local +# ...svc.cluster.local + +--- + +# Main IP for DNS +apiVersion: v1 +kind: Service +metadata: + name: pihole-dns-service + + labels: + project: pihole + annotations: + metallb.io/loadBalancerIPs: 1.2.3.4 + + +spec: + selector: + pod-project: pihole + # This isn't used as Ingress is doing TLS termination + type: LoadBalancer + + # Preserve ips + externalTrafficPolicy: Local + + # type: ClusterIP + ports: + - name: pihole-dns-udp + protocol: UDP + port: 53 # <- port that will be exposed + targetPort: 53 + - name: pihole-dns-tcp + protocol: TCP + port: 53 # <- port that will be exposed + targetPort: 53 + + +# Node exporter +--- +apiVersion: v1 +kind: Service +metadata: + name: pihole-svc-prom-exporter + labels: + project: pihole +spec: + clusterIP: None # headless + selector: + pod-project: pihole # matches your exporter pods + ports: + - name: ngx-metrics + port: 50934 + targetPort: 50934 + +