--- apiVersion: v1 kind: Namespace metadata: name: fc-dns labels: app.kubernetes.io/part-of: flowercore --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: dns-web-data namespace: fc-dns spec: accessModes: - ReadWriteOnce storageClassName: local-path resources: requests: storage: 1Gi --- apiVersion: v1 kind: ConfigMap metadata: name: dns-web-config namespace: fc-dns data: appsettings.Production.json: | { "FlowerCore": { "Auth": { "Enabled": true, "Oidc": { "Enabled": true, "Audience": "dns", "RequireHttpsMetadata": true } }, "Database": { "Provider": "Sqlite", "ConnectionStrings": { "Sqlite": "Data Source=/data/dns.db" } }, "Tenant": { "DefaultTenantId": "default", "JwtClaimsEnabled": true, "DefaultTenantHosts": [ "dns.iamworkin.lan" ] }, "Audit": { "HashChain": { "BridgeSensitivity": { "Distribution": "Warn" } } }, "Dns": { "RateLimits": { "PermitLimit": 60, "WindowSeconds": 60, "QueueLimit": 0 } } } } --- apiVersion: v1 kind: ServiceAccount metadata: name: dns-web namespace: fc-dns --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: dns-web rules: - apiGroups: - "" resources: - namespaces - pods - services - secrets - configmaps verbs: - get - list - watch - apiGroups: - cert-manager.io resources: - certificates verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: dns-web subjects: - kind: ServiceAccount name: dns-web namespace: fc-dns roleRef: kind: ClusterRole name: dns-web apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: Deployment metadata: name: dns-web namespace: fc-dns labels: app: dns-web app.kubernetes.io/name: dns-web app.kubernetes.io/part-of: flowercore spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: dns-web template: metadata: labels: app: dns-web app.kubernetes.io/name: dns-web app.kubernetes.io/part-of: flowercore annotations: prometheus.io/scrape: "true" prometheus.io/port: "5320" prometheus.io/path: "/metrics/prometheus" flowercore.io/source-sha: "8b4c1fcdcf25b476fa6fad76309ba69e38c21e8b" spec: serviceAccountName: dns-web securityContext: runAsNonRoot: true runAsUser: 1654 runAsGroup: 1654 fsGroup: 1654 fsGroupChangePolicy: OnRootMismatch containers: - name: dns-web image: localhost/fc-dns-web:v20260617-gx10-f3-8b4c1fc imagePullPolicy: Never securityContext: readOnlyRootFilesystem: true allowPrivilegeEscalation: false capabilities: drop: - ALL ports: - containerPort: 5320 name: http env: - name: ASPNETCORE_URLS value: http://+:5320 - name: ASPNETCORE_ENVIRONMENT value: Production - name: FlowerCore__Dns__Providers__PfSenseUnbound__FallbackPassword valueFrom: secretKeyRef: name: pfsense-admin key: password - name: FlowerCore__Auth__Oidc__Authority valueFrom: secretKeyRef: name: dns-oidc-client key: issuer_url optional: true - name: FlowerCore__Auth__Oidc__ClientId valueFrom: secretKeyRef: name: dns-oidc-client key: client_id optional: true - name: FlowerCore__Auth__Oidc__ClientSecret valueFrom: secretKeyRef: name: dns-oidc-client key: client_secret optional: true - name: FlowerCore__Auth__ApiKey valueFrom: secretKeyRef: name: dns-api-keys key: api_key optional: true - name: FlowerCore__Mcp__ApiKey__Key valueFrom: secretKeyRef: name: dns-api-keys key: api_key optional: true - name: FlowerCore__Mcp__ServiceName value: flowercore.dns - name: FlowerCore__Auth__Enabled value: "true" - name: FlowerCore__Auth__Oidc__Enabled value: "true" - name: FlowerCore__Auth__Oidc__Audience value: dns volumeMounts: - name: data mountPath: /data - name: tmp mountPath: /tmp - name: logs mountPath: /app/logs - name: config mountPath: /app/appsettings.Production.json subPath: appsettings.Production.json readOnly: true resources: requests: cpu: 50m memory: 96Mi limits: cpu: 300m memory: 384Mi readinessProbe: httpGet: path: /healthz port: 5320 initialDelaySeconds: 10 periodSeconds: 10 livenessProbe: httpGet: path: /healthz port: 5320 initialDelaySeconds: 20 periodSeconds: 30 volumes: - name: data persistentVolumeClaim: claimName: dns-web-data - name: tmp emptyDir: {} - name: logs emptyDir: {} - name: config configMap: name: dns-web-config --- apiVersion: v1 kind: Service metadata: name: dns-web namespace: fc-dns spec: selector: app: dns-web ports: - port: 5320 targetPort: 5320 name: http type: ClusterIP --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: dns-web-ingress-isolation namespace: fc-dns spec: podSelector: matchLabels: app: dns-web policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: traefik-system podSelector: matchLabels: app.kubernetes.io/name: traefik - namespaceSelector: matchLabels: kubernetes.io/metadata.name: fc-dns - ipBlock: cidr: 10.42.0.0/16 - ipBlock: cidr: 10.0.56.0/24 - ipBlock: cidr: 10.0.57.0/24 - ipBlock: cidr: 10.0.58.0/24 - ipBlock: cidr: 10.0.68.0/27 ports: - port: 5320 protocol: TCP --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: dns-web-cert namespace: fc-dns spec: secretName: dns-web-tls issuerRef: name: step-ca-acme kind: ClusterIssuer dnsNames: - dns.iamworkin.lan --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: dns-web namespace: fc-dns spec: entryPoints: - websecure routes: - match: Host(`dns.iamworkin.lan`) kind: Rule priority: 100 services: - name: dns-web port: 5320 tls: secretName: dns-web-tls --- apiVersion: v1 kind: ServiceAccount metadata: name: dns-acme-webhook namespace: fc-dns --- apiVersion: apps/v1 kind: Deployment metadata: name: dns-acme-webhook namespace: fc-dns labels: app: dns-acme-webhook app.kubernetes.io/name: dns-acme-webhook app.kubernetes.io/part-of: flowercore spec: replicas: 1 selector: matchLabels: app: dns-acme-webhook template: metadata: labels: app: dns-acme-webhook app.kubernetes.io/name: dns-acme-webhook app.kubernetes.io/part-of: flowercore annotations: flowercore.io/source-sha: "8b4c1fcdcf25b476fa6fad76309ba69e38c21e8b" spec: serviceAccountName: dns-acme-webhook securityContext: runAsNonRoot: true runAsUser: 1654 runAsGroup: 1654 fsGroup: 1654 fsGroupChangePolicy: OnRootMismatch containers: - name: dns-acme-webhook image: localhost/fc-dns-acme-webhook:v20260617-gx10-f3-8b4c1fc imagePullPolicy: Never securityContext: readOnlyRootFilesystem: true allowPrivilegeEscalation: false capabilities: drop: - ALL ports: - containerPort: 9443 name: https env: - name: ASPNETCORE_URLS value: https://+:9443 - name: ASPNETCORE_ENVIRONMENT value: Production - name: Kestrel__Certificates__Default__Path value: /tls/tls.crt - name: Kestrel__Certificates__Default__KeyPath value: /tls/tls.key - name: FlowerCore__Dns__AcmeWebhook__ServiceBaseUrl value: http://dns-web:5320 - name: FlowerCore__Dns__AcmeWebhook__ApiKey valueFrom: secretKeyRef: name: dns-api-keys key: api_key optional: true - name: FlowerCore__Dns__AcmeWebhook__GroupName value: acme.flowercore.io - name: FlowerCore__Dns__AcmeWebhook__SolverName value: flowercore-dns - name: FlowerCore__Dns__AcmeWebhook__Version value: v1alpha1 volumeMounts: - name: tls mountPath: /tls readOnly: true - name: tmp mountPath: /tmp - name: logs mountPath: /app/logs resources: requests: cpu: 25m memory: 64Mi limits: cpu: 200m memory: 256Mi readinessProbe: httpGet: scheme: HTTPS path: /readyz port: https initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 livenessProbe: httpGet: scheme: HTTPS path: /healthz port: https initialDelaySeconds: 10 periodSeconds: 20 timeoutSeconds: 5 volumes: - name: tls secret: secretName: dns-acme-webhook-tls - name: tmp emptyDir: {} - name: logs emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: dns-acme-webhook namespace: fc-dns spec: selector: app: dns-acme-webhook ports: - port: 443 targetPort: https name: https type: ClusterIP --- apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: dns-acme-webhook-selfsigned namespace: fc-dns spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: dns-acme-webhook-ca namespace: fc-dns spec: secretName: dns-acme-webhook-ca duration: 43800h issuerRef: name: dns-acme-webhook-selfsigned commonName: ca.dns-acme-webhook.fc-dns isCA: true --- apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: dns-acme-webhook-ca-issuer namespace: fc-dns spec: ca: secretName: dns-acme-webhook-ca --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: dns-acme-webhook-serving-cert namespace: fc-dns spec: secretName: dns-acme-webhook-tls duration: 8760h issuerRef: name: dns-acme-webhook-ca-issuer dnsNames: - dns-acme-webhook - dns-acme-webhook.fc-dns - dns-acme-webhook.fc-dns.svc --- apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: name: v1alpha1.acme.flowercore.io annotations: cert-manager.io/inject-ca-from: fc-dns/dns-acme-webhook-serving-cert spec: group: acme.flowercore.io groupPriorityMinimum: 1000 service: name: dns-acme-webhook namespace: fc-dns version: v1alpha1 versionPriority: 15 --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: dns-acme-webhook-solver rules: - apiGroups: - acme.flowercore.io resources: - flowercore-dns verbs: - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: dns-acme-webhook-solver subjects: - kind: ServiceAccount name: cert-manager namespace: cert-manager roleRef: kind: ClusterRole name: dns-acme-webhook-solver apiGroup: rbac.authorization.k8s.io