diff --git a/kubernetes/apps/storage/external-secrets/app/helmrelease.yaml b/kubernetes/apps/external-secrets/external-secrets/app/helmrelease.yaml similarity index 100% rename from kubernetes/apps/storage/external-secrets/app/helmrelease.yaml rename to kubernetes/apps/external-secrets/external-secrets/app/helmrelease.yaml diff --git a/kubernetes/apps/storage/external-secrets/app/kustomization.yaml b/kubernetes/apps/external-secrets/external-secrets/app/kustomization.yaml similarity index 100% rename from kubernetes/apps/storage/external-secrets/app/kustomization.yaml rename to kubernetes/apps/external-secrets/external-secrets/app/kustomization.yaml diff --git a/kubernetes/apps/storage/external-secrets/ks.yaml b/kubernetes/apps/external-secrets/external-secrets/ks.yaml similarity index 100% rename from kubernetes/apps/storage/external-secrets/ks.yaml rename to kubernetes/apps/external-secrets/external-secrets/ks.yaml diff --git a/kubernetes/apps/storage/external-secrets/stores/clustersecretstore.yaml b/kubernetes/apps/external-secrets/external-secrets/stores/clustersecretstore.yaml similarity index 100% rename from kubernetes/apps/storage/external-secrets/stores/clustersecretstore.yaml rename to kubernetes/apps/external-secrets/external-secrets/stores/clustersecretstore.yaml diff --git a/kubernetes/apps/storage/external-secrets/stores/kustomization.yaml b/kubernetes/apps/external-secrets/external-secrets/stores/kustomization.yaml similarity index 100% rename from kubernetes/apps/storage/external-secrets/stores/kustomization.yaml rename to kubernetes/apps/external-secrets/external-secrets/stores/kustomization.yaml diff --git a/kubernetes/apps/storage/external-secrets/stores/secret.sops.yaml b/kubernetes/apps/external-secrets/external-secrets/stores/secret.sops.yaml similarity index 100% rename from kubernetes/apps/storage/external-secrets/stores/secret.sops.yaml rename to kubernetes/apps/external-secrets/external-secrets/stores/secret.sops.yaml diff --git a/kubernetes/apps/external-secrets/kustomization.yaml b/kubernetes/apps/external-secrets/kustomization.yaml new file mode 100644 index 000000000..8b5a7e346 --- /dev/null +++ b/kubernetes/apps/external-secrets/kustomization.yaml @@ -0,0 +1,9 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + # Pre Flux-Kustomizations + - ./namespace.yaml + # Flux-Kustomizations + - ./external-secrets/ks.yaml diff --git a/kubernetes/apps/external-secrets/namespace.yaml b/kubernetes/apps/external-secrets/namespace.yaml new file mode 100644 index 000000000..26718c2a6 --- /dev/null +++ b/kubernetes/apps/external-secrets/namespace.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: external-secrets + labels: + kustomize.toolkit.fluxcd.io/prune: disabled diff --git a/kubernetes/apps/network/cloudflared/app/configs/config.yaml b/kubernetes/apps/network/cloudflared/app/configs/config.yaml new file mode 100644 index 000000000..05bcef5cf --- /dev/null +++ b/kubernetes/apps/network/cloudflared/app/configs/config.yaml @@ -0,0 +1,10 @@ +--- +originRequest: + originServerName: "external.${SECRET_DOMAIN}" + +ingress: + - hostname: "${SECRET_DOMAIN}" + service: https://ingress-nginx-external-controller.network.svc.cluster.local:443 + - hostname: "*.${SECRET_DOMAIN}" + service: https://ingress-nginx-external-controller.network.svc.cluster.local:443 + - service: http_status:404 diff --git a/kubernetes/apps/network/cloudflared/app/dnsendpoint.yaml b/kubernetes/apps/network/cloudflared/app/dnsendpoint.yaml new file mode 100644 index 000000000..43d7d7b29 --- /dev/null +++ b/kubernetes/apps/network/cloudflared/app/dnsendpoint.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: externaldns.k8s.io/v1alpha1 +kind: DNSEndpoint +metadata: + name: cloudflared +spec: + endpoints: + - dnsName: "external.${SECRET_DOMAIN}" + recordType: CNAME + targets: ["${SECRET_CLOUDFLARE_TUNNEL_ID}.cfargotunnel.com"] diff --git a/kubernetes/apps/network/cloudflared/app/helmrelease.yaml b/kubernetes/apps/network/cloudflared/app/helmrelease.yaml new file mode 100644 index 000000000..7966258f3 --- /dev/null +++ b/kubernetes/apps/network/cloudflared/app/helmrelease.yaml @@ -0,0 +1,110 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: cloudflared +spec: + interval: 30m + chart: + spec: + chart: app-template + version: 3.1.0 + sourceRef: + kind: HelmRepository + name: bjw-s + namespace: flux-system + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + values: + controllers: + cloudflared: + replicas: 2 + strategy: RollingUpdate + annotations: + reloader.stakater.com/auto: "true" + containers: + app: + image: + repository: docker.io/cloudflare/cloudflared + tag: 2024.4.1 + env: + NO_AUTOUPDATE: true + TUNNEL_CRED_FILE: /etc/cloudflared/creds/credentials.json + TUNNEL_METRICS: 0.0.0.0:8080 + TUNNEL_ORIGIN_ENABLE_HTTP2: true + TUNNEL_TRANSPORT_PROTOCOL: quic + TUNNEL_POST_QUANTUM: true + TUNNEL_ID: + valueFrom: + secretKeyRef: + name: cloudflared-secret + key: TUNNEL_ID + args: + - tunnel + - --config + - /etc/cloudflared/config/config.yaml + - run + - "$(TUNNEL_ID)" + probes: + liveness: &probes + enabled: true + custom: true + spec: + httpGet: + path: /ready + port: &port 8080 + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readiness: *probes + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: { drop: ["ALL"] } + resources: + requests: + cpu: 10m + limits: + memory: 256Mi + defaultPodOptions: + securityContext: + runAsNonRoot: true + runAsUser: 65534 + runAsGroup: 65534 + seccompProfile: { type: RuntimeDefault } + service: + app: + controller: cloudflared + ports: + http: + port: *port + serviceMonitor: + app: + serviceName: cloudflared + endpoints: + - port: http + scheme: http + path: /metrics + interval: 1m + scrapeTimeout: 10s + persistence: + config: + type: configMap + name: cloudflared-configmap + globalMounts: + - path: /etc/cloudflared/config/config.yaml + subPath: config.yaml + readOnly: true + creds: + type: secret + name: cloudflared-secret + globalMounts: + - path: /etc/cloudflared/creds/credentials.json + subPath: credentials.json + readOnly: true diff --git a/kubernetes/apps/network/cloudflared/app/kustomization.yaml b/kubernetes/apps/network/cloudflared/app/kustomization.yaml new file mode 100644 index 000000000..891a864ad --- /dev/null +++ b/kubernetes/apps/network/cloudflared/app/kustomization.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./dnsendpoint.yaml + - ./secret.sops.yaml + - ./helmrelease.yaml +configMapGenerator: + - name: cloudflared-configmap + files: + - ./configs/config.yaml +generatorOptions: + disableNameSuffixHash: true diff --git a/kubernetes/apps/network/cloudflared/app/secret.sops.yaml b/kubernetes/apps/network/cloudflared/app/secret.sops.yaml new file mode 100644 index 000000000..82c411dce --- /dev/null +++ b/kubernetes/apps/network/cloudflared/app/secret.sops.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Secret +metadata: + name: cloudflared-secret + namespace: network +stringData: + TUNNEL_ID: ENC[AES256_GCM,data:ct4JXq4FwKYlXfDQCnVoXK06/Bi89hfnydOBCRheIJpvb9G0,iv:O+C4vRYivg0HSJthgcgh49is/9m/mANUwU/okhUUr4Y=,tag:XzJHO4mrtmbg63SipXYBbg==,type:str] + credentials.json: ENC[AES256_GCM,data:K44Flx1hhqgbae+St9EXkry3bqfc87EQumOmGAgudY1VC1iEziydJ6VxlKq3cleQh+8hLL2IsuaDz82l4fbwh+vgPXLDUcvuBktQDOMGB8njLWUrBBl9vtJ4w1dTL/4oewC8q+h9xVu6VOWAnTIk5rkvv27TlOCoR6emOLkDNhCPsbwOVHFxb/auNSwgRg+u5hYZH5d5mlJw/14507tW0YD7+nDgjsqFgFAOX5XQpw==,iv:HcxPjba2yVnpYwyV5R4Ye15vXLIBYAS5vsYXWdGvqfc=,tag:9gs/Sy4Knto1DXDS+gibjg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1wvlv68u3uadfpjvluuydng2xj726pa4j5lzfzrp5z4333c2tv5fsftppun + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMK3dnMnZVMEphaGhZUFJT + dzgyNFNpSVdJNWl0TGNCeU4veVV2VmFodTNNCmRWd1AzYWdtZCtmTm0wZEZTVzQ5 + RTU5ZWFLYWdhUHFrTEd1Ym0xOTVTT2cKLS0tIE1nMTk5V0d0UWdTc2kyZ1RxZEZ2 + SWl0VEd3MW9IaTlDNlJxbWFoU000NjQK7g3PCcaLxvJiiSCrtL6DM26i5261E3JC + H4BfsAeEe14SL6mJmQ7okYP2sG7zA+X1awDhZB5KiFRWRg+eX+d5/w== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-05-14T02:51:25Z" + mac: ENC[AES256_GCM,data:CV+tZAmooCiI0YtozdwbT4v+M5j6f8kO4PRzbF0zrI41gWAWyak305M0fvG4gBeTAmK9M/KetpJ3+BUgPgLwXHFyDbDz490pGpL5okShdb67fHew7spjC4GXltC5dE9OEE2mWdr/ClMJH4jG0nZ4RIIHoUbUcVoj8e7muV1jZ+g=,iv:cpN4XayKVmALhG/A5C4vUzaXYSb38G923bT10H3ZybA=,tag:xP+Jn4e3fY3rb7FJsx1XpA==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.8.1 diff --git a/kubernetes/apps/network/cloudflared/ks.yaml b/kubernetes/apps/network/cloudflared/ks.yaml new file mode 100644 index 000000000..eb8d8da0b --- /dev/null +++ b/kubernetes/apps/network/cloudflared/ks.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app cloudflared + namespace: flux-system +spec: + targetNamespace: network + commonMetadata: + labels: + app.kubernetes.io/name: *app + dependsOn: + - name: external-dns + path: ./kubernetes/apps/network/cloudflared/app + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m diff --git a/kubernetes/apps/network/echo-server/app/helmrelease.yaml b/kubernetes/apps/network/echo-server/app/helmrelease.yaml new file mode 100644 index 000000000..129bd3f9e --- /dev/null +++ b/kubernetes/apps/network/echo-server/app/helmrelease.yaml @@ -0,0 +1,91 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: echo-server +spec: + interval: 30m + chart: + spec: + chart: app-template + version: 3.1.0 + sourceRef: + kind: HelmRepository + name: bjw-s + namespace: flux-system + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + values: + controllers: + echo-server: + strategy: RollingUpdate + containers: + app: + image: + repository: ghcr.io/mendhak/http-https-echo + tag: 33 + env: + HTTP_PORT: &port 8080 + LOG_WITHOUT_NEWLINE: true + LOG_IGNORE_PATH: /healthz + PROMETHEUS_ENABLED: true + probes: + liveness: &probes + enabled: true + custom: true + spec: + httpGet: + path: /healthz + port: *port + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readiness: *probes + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: { drop: ["ALL"] } + resources: + requests: + cpu: 10m + limits: + memory: 64Mi + defaultPodOptions: + securityContext: + runAsNonRoot: true + runAsUser: 65534 + runAsGroup: 65534 + seccompProfile: { type: RuntimeDefault } + service: + app: + controller: echo-server + ports: + http: + port: *port + serviceMonitor: + app: + serviceName: echo-server + endpoints: + - port: http + scheme: http + path: /metrics + interval: 1m + scrapeTimeout: 10s + ingress: + app: + className: external + annotations: + external-dns.alpha.kubernetes.io/target: "external.${SECRET_DOMAIN}" + hosts: + - host: "{{ .Release.Name }}.${SECRET_DOMAIN}" + paths: + - path: / + service: + identifier: app + port: http diff --git a/kubernetes/apps/network/echo-server/app/kustomization.yaml b/kubernetes/apps/network/echo-server/app/kustomization.yaml new file mode 100644 index 000000000..c83d92a87 --- /dev/null +++ b/kubernetes/apps/network/echo-server/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: networking +resources: + - ./helmrelease.yaml diff --git a/kubernetes/apps/network/echo-server/ks.yaml b/kubernetes/apps/network/echo-server/ks.yaml new file mode 100644 index 000000000..2984f219c --- /dev/null +++ b/kubernetes/apps/network/echo-server/ks.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app echo-server + namespace: flux-system +spec: + targetNamespace: network + commonMetadata: + labels: + app.kubernetes.io/name: *app + path: ./kubernetes/apps/network/echo-server/app + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m diff --git a/kubernetes/apps/network/external-dns/app/helmrelease.yaml b/kubernetes/apps/network/external-dns/app/helmrelease.yaml new file mode 100644 index 000000000..80c31d184 --- /dev/null +++ b/kubernetes/apps/network/external-dns/app/helmrelease.yaml @@ -0,0 +1,48 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: &app external-dns +spec: + interval: 30m + chart: + spec: + chart: external-dns + version: 1.14.4 + sourceRef: + kind: HelmRepository + name: external-dns + namespace: flux-system + install: + crds: CreateReplace + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + crds: CreateReplace + remediation: + strategy: rollback + retries: 3 + values: + fullnameOverride: *app + provider: cloudflare + env: + - name: CF_API_TOKEN + valueFrom: + secretKeyRef: + name: external-dns-secret + key: api-token + extraArgs: + - --ingress-class=external + - --cloudflare-proxied + - --crd-source-apiversion=externaldns.k8s.io/v1alpha1 + - --crd-source-kind=DNSEndpoint + policy: sync + sources: ["crd", "ingress"] + txtPrefix: k8s. + txtOwnerId: default + domainFilters: ["${SECRET_DOMAIN}"] + serviceMonitor: + enabled: true + podAnnotations: + secret.reloader.stakater.com/reload: external-dns-secret diff --git a/kubernetes/apps/network/external-dns/app/kustomization.yaml b/kubernetes/apps/network/external-dns/app/kustomization.yaml new file mode 100644 index 000000000..95bf4747f --- /dev/null +++ b/kubernetes/apps/network/external-dns/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./secret.sops.yaml + - ./helmrelease.yaml diff --git a/kubernetes/apps/network/external-dns/app/secret.sops.yaml b/kubernetes/apps/network/external-dns/app/secret.sops.yaml new file mode 100644 index 000000000..44936a937 --- /dev/null +++ b/kubernetes/apps/network/external-dns/app/secret.sops.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: Secret +metadata: + name: external-dns-secret + namespace: network +stringData: + api-token: ENC[AES256_GCM,data:yinf990iIjcRy93mmjPpC2wzYYvjks92gJppCJ+rttBYUkyVhwleFg==,iv:JJRtJvpA3v7ziAVZdP3NEuwt6KDrMo1xPKeQoAVaScE=,tag:WPbi2bf04SylLsQpVaGswg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1wvlv68u3uadfpjvluuydng2xj726pa4j5lzfzrp5z4333c2tv5fsftppun + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmWFZNYkdpTER3WmUxWEJo + dWZ2Tm94d1B4Zzd0d05TTTRyZ1BBQUoyY1hVCmZxeWlBMkRIbzZMdjNOaFIybWl3 + MkQzQ3V2ODN4Y1RpWjJNWE50RjV4T2sKLS0tIGVEeGJWbld1d3NtU3BaTEh1akRZ + VTNpK093SUJKNnVWeUxZS0Eyd3pOQTQKIbThyyUVqNkyjKqIU49dbpc4LCegZj6u + IMazQqC93Pzk7QNhPLkBDYiI8O9NPyh3ssPavHl9xwg16jA3iGFaOw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2023-10-26T09:32:43Z" + mac: ENC[AES256_GCM,data:pM3qtJIuuAWkRaAr44aJFbZMHNywW8xOsY20KYbaNpKUSClT0zydn+Bdplaab+WevYjmvX5ZaSc7di7WGQ0MhefLHz85FvPGYWSbOZeeaia+cYIgBc2tAA02CjMLyFjzrMHXABuGVVzxe4pDHEnZeIQvKGQLd24hOjk3SkMswdE=,iv:+MlqqChG2m411bq5LFviqaUgRd6TsC2audKvq6FCiPc=,tag:OPf2DSgco9S5dpJ9x0TY/A==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.8.1 diff --git a/kubernetes/apps/network/external-dns/ks.yaml b/kubernetes/apps/network/external-dns/ks.yaml new file mode 100644 index 000000000..eaed4b566 --- /dev/null +++ b/kubernetes/apps/network/external-dns/ks.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app external-dns + namespace: flux-system +spec: + targetNamespace: network + commonMetadata: + labels: + app.kubernetes.io/name: *app + path: ./kubernetes/apps/network/external-dns/app + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + wait: true + interval: 30m + retryInterval: 1m + timeout: 5m diff --git a/kubernetes/apps/network/ingress-nginx/certificates/kustomization.yaml b/kubernetes/apps/network/ingress-nginx/certificates/kustomization.yaml new file mode 100644 index 000000000..e7892580d --- /dev/null +++ b/kubernetes/apps/network/ingress-nginx/certificates/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./staging.yaml diff --git a/kubernetes/apps/network/ingress-nginx/certificates/production.yaml b/kubernetes/apps/network/ingress-nginx/certificates/production.yaml new file mode 100644 index 000000000..b5afdf419 --- /dev/null +++ b/kubernetes/apps/network/ingress-nginx/certificates/production.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: "${SECRET_DOMAIN/./-}-production" +spec: + secretName: "${SECRET_DOMAIN/./-}-production-tls" + issuerRef: + name: letsencrypt-production + kind: ClusterIssuer + commonName: "${SECRET_DOMAIN}" + dnsNames: + - "${SECRET_DOMAIN}" + - "*.${SECRET_DOMAIN}" diff --git a/kubernetes/apps/network/ingress-nginx/certificates/staging.yaml b/kubernetes/apps/network/ingress-nginx/certificates/staging.yaml new file mode 100644 index 000000000..9c8694251 --- /dev/null +++ b/kubernetes/apps/network/ingress-nginx/certificates/staging.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: "${SECRET_DOMAIN/./-}-staging" +spec: + secretName: "${SECRET_DOMAIN/./-}-staging-tls" + issuerRef: + name: letsencrypt-staging + kind: ClusterIssuer + commonName: "${SECRET_DOMAIN}" + dnsNames: + - "${SECRET_DOMAIN}" + - "*.${SECRET_DOMAIN}" diff --git a/kubernetes/apps/network/ingress-nginx/external/helmrelease.yaml b/kubernetes/apps/network/ingress-nginx/external/helmrelease.yaml new file mode 100644 index 000000000..95095d2fc --- /dev/null +++ b/kubernetes/apps/network/ingress-nginx/external/helmrelease.yaml @@ -0,0 +1,87 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: ingress-nginx-external +spec: + interval: 30m + chart: + spec: + chart: ingress-nginx + version: 4.10.1 + sourceRef: + kind: HelmRepository + name: ingress-nginx + namespace: flux-system + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + dependsOn: + - name: cloudflared + namespace: network + values: + fullnameOverride: ingress-nginx-external + controller: + replicaCount: 1 + service: + annotations: + external-dns.alpha.kubernetes.io/hostname: "external.${SECRET_DOMAIN}" + io.cilium/lb-ipam-ips: "10.20.0.53" + externalTrafficPolicy: Cluster + ingressClassResource: + name: external + default: false + controllerValue: k8s.io/external + admissionWebhooks: + objectSelector: + matchExpressions: + - key: ingress-class + operator: In + values: ["external"] + config: + client-body-buffer-size: 100M + client-body-timeout: 120 + client-header-timeout: 120 + enable-brotli: "true" + enable-real-ip: "true" + hsts-max-age: 31449600 + keep-alive-requests: 10000 + keep-alive: 120 + log-format-escape-json: "true" + log-format-upstream: > + {"time": "$time_iso8601", "remote_addr": "$proxy_protocol_addr", "x_forwarded_for": "$proxy_add_x_forwarded_for", + "request_id": "$req_id", "remote_user": "$remote_user", "bytes_sent": $bytes_sent, "request_time": $request_time, + "status": $status, "vhost": "$host", "request_proto": "$server_protocol", "path": "$uri", "request_query": "$args", + "request_length": $request_length, "duration": $request_time, "method": "$request_method", "http_referrer": "$http_referer", + "http_user_agent": "$http_user_agent"} + proxy-body-size: 0 + proxy-buffer-size: 16k + ssl-protocols: TLSv1.3 TLSv1.2 + metrics: + enabled: true + serviceMonitor: + enabled: true + namespaceSelector: + any: true + extraArgs: + default-ssl-certificate: "network/${SECRET_DOMAIN/./-}-staging-tls" + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/instance: ingress-nginx-external + app.kubernetes.io/component: controller + resources: + requests: + cpu: 100m + limits: + memory: 500Mi + defaultBackend: + enabled: false diff --git a/kubernetes/apps/network/ingress-nginx/external/kustomization.yaml b/kubernetes/apps/network/ingress-nginx/external/kustomization.yaml new file mode 100644 index 000000000..5dd7baca7 --- /dev/null +++ b/kubernetes/apps/network/ingress-nginx/external/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml diff --git a/kubernetes/apps/network/ingress-nginx/internal/helmrelease.yaml b/kubernetes/apps/network/ingress-nginx/internal/helmrelease.yaml new file mode 100644 index 000000000..d4b3fe0a3 --- /dev/null +++ b/kubernetes/apps/network/ingress-nginx/internal/helmrelease.yaml @@ -0,0 +1,84 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: ingress-nginx-internal + namespace: network +spec: + interval: 30m + chart: + spec: + chart: ingress-nginx + version: 4.10.1 + sourceRef: + kind: HelmRepository + name: ingress-nginx + namespace: flux-system + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + values: + fullnameOverride: ingress-nginx-internal + controller: + replicaCount: 1 + service: + annotations: + io.cilium/lb-ipam-ips: "10.20.0.52" + externalTrafficPolicy: Cluster + ingressClassResource: + name: internal + default: true + controllerValue: k8s.io/internal + admissionWebhooks: + objectSelector: + matchExpressions: + - key: ingress-class + operator: In + values: ["internal"] + config: + client-body-buffer-size: 100M + client-body-timeout: 120 + client-header-timeout: 120 + enable-brotli: "true" + enable-real-ip: "true" + hsts-max-age: 31449600 + keep-alive-requests: 10000 + keep-alive: 120 + log-format-escape-json: "true" + log-format-upstream: > + {"time": "$time_iso8601", "remote_addr": "$proxy_protocol_addr", "x_forwarded_for": "$proxy_add_x_forwarded_for", + "request_id": "$req_id", "remote_user": "$remote_user", "bytes_sent": $bytes_sent, "request_time": $request_time, + "status": $status, "vhost": "$host", "request_proto": "$server_protocol", "path": "$uri", "request_query": "$args", + "request_length": $request_length, "duration": $request_time, "method": "$request_method", "http_referrer": "$http_referer", + "http_user_agent": "$http_user_agent"} + proxy-body-size: 0 + proxy-buffer-size: 16k + ssl-protocols: TLSv1.3 TLSv1.2 + metrics: + enabled: true + serviceMonitor: + enabled: true + namespaceSelector: + any: true + extraArgs: + default-ssl-certificate: "network/${SECRET_DOMAIN/./-}-staging-tls" + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/instance: ingress-nginx-internal + app.kubernetes.io/component: controller + resources: + requests: + cpu: 100m + limits: + memory: 500Mi + defaultBackend: + enabled: false diff --git a/kubernetes/apps/network/ingress-nginx/internal/kustomization.yaml b/kubernetes/apps/network/ingress-nginx/internal/kustomization.yaml new file mode 100644 index 000000000..5dd7baca7 --- /dev/null +++ b/kubernetes/apps/network/ingress-nginx/internal/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml diff --git a/kubernetes/apps/network/ingress-nginx/ks.yaml b/kubernetes/apps/network/ingress-nginx/ks.yaml new file mode 100644 index 000000000..99b1abb58 --- /dev/null +++ b/kubernetes/apps/network/ingress-nginx/ks.yaml @@ -0,0 +1,66 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app ingress-nginx-certificates + namespace: flux-system +spec: + targetNamespace: network + commonMetadata: + labels: + app.kubernetes.io/name: *app + dependsOn: + - name: cert-manager-issuers + path: ./kubernetes/apps/network/ingress-nginx/certificates + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + wait: true + interval: 30m + retryInterval: 1m + timeout: 5m +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app ingress-nginx-internal + namespace: flux-system +spec: + targetNamespace: network + commonMetadata: + labels: + app.kubernetes.io/name: *app + dependsOn: + - name: ingress-nginx-certificates + path: ./kubernetes/apps/network/ingress-nginx/internal + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app ingress-nginx-external + namespace: flux-system +spec: + targetNamespace: network + commonMetadata: + labels: + app.kubernetes.io/name: *app + dependsOn: + - name: ingress-nginx-certificates + path: ./kubernetes/apps/network/ingress-nginx/external + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m diff --git a/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml b/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml new file mode 100644 index 000000000..71bfc302f --- /dev/null +++ b/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml @@ -0,0 +1,33 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: k8s-gateway +spec: + interval: 30m + chart: + spec: + chart: k8s-gateway + version: 2.4.0 + sourceRef: + kind: HelmRepository + name: k8s-gateway + namespace: flux-system + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + values: + fullnameOverride: k8s-gateway + domain: "${SECRET_DOMAIN}" + ttl: 1 + service: + type: LoadBalancer + port: 53 + annotations: + io.cilium/lb-ipam-ips: "10.20.0.50" + externalTrafficPolicy: Cluster + watchedResources: ["Ingress", "Service"] diff --git a/kubernetes/apps/network/k8s-gateway/app/kustomization.yaml b/kubernetes/apps/network/k8s-gateway/app/kustomization.yaml new file mode 100644 index 000000000..5dd7baca7 --- /dev/null +++ b/kubernetes/apps/network/k8s-gateway/app/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml diff --git a/kubernetes/apps/network/k8s-gateway/ks.yaml b/kubernetes/apps/network/k8s-gateway/ks.yaml new file mode 100644 index 000000000..5193645fb --- /dev/null +++ b/kubernetes/apps/network/k8s-gateway/ks.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app k8s-gateway + namespace: flux-system +spec: + targetnamespace: network + commonMetadata: + labels: + app.kubernetes.io/name: *app + path: ./kubernetes/apps/networking/k8s-gateway/app + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m diff --git a/kubernetes/apps/network/kustomization.yaml b/kubernetes/apps/network/kustomization.yaml new file mode 100644 index 000000000..29a8fec3f --- /dev/null +++ b/kubernetes/apps/network/kustomization.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./namespace.yaml + - ./cloudflared/ks.yaml + - ./echo-server/ks.yaml + - ./external-dns/ks.yaml + - ./ingress-nginx/ks.yaml + - ./k8s-gateway/ks.yaml + # - ./tailscale/ks.yaml + - ./unifi/ks.yaml diff --git a/kubernetes/apps/network/namespace.yaml b/kubernetes/apps/network/namespace.yaml new file mode 100644 index 000000000..4d78d7b11 --- /dev/null +++ b/kubernetes/apps/network/namespace.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: network + labels: + kustomize.toolkit.fluxcd.io/prune: disabled diff --git a/kubernetes/apps/network/tailscale/app/externalsecret.yaml b/kubernetes/apps/network/tailscale/app/externalsecret.yaml new file mode 100644 index 000000000..daa39db1e --- /dev/null +++ b/kubernetes/apps/network/tailscale/app/externalsecret.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: tailscale-auth + namespace: network +spec: + secretStoreRef: + kind: ClusterSecretStore + name: doppler-secrets + target: + name: tailscale-auth + data: + - remoteRef: + key: TAILSCALE_AUTHKEY + secretKey: TS_AUTHKEY diff --git a/kubernetes/apps/network/tailscale/app/helmrelease.yaml b/kubernetes/apps/network/tailscale/app/helmrelease.yaml new file mode 100644 index 000000000..95c97d5a7 --- /dev/null +++ b/kubernetes/apps/network/tailscale/app/helmrelease.yaml @@ -0,0 +1,65 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: &app tailscale-gateway + namespace: vpn +spec: + interval: 15m + chart: + spec: + chart: app-template + version: 1.5.1 + sourceRef: + kind: HelmRepository + name: bjw-s + namespace: flux-system + install: + createNamespace: true + remediation: + retries: 5 + upgrade: + remediation: + retries: 5 + values: + serviceAccount: + name: tailscale + + image: + repository: ghcr.io/tailscale/tailscale + tag: v1.58.2 + env: + TZ: ${TIMEZONE} + PORT: &port ${SECRET_PUBLIC_PORT} + TS_KUBE_SECRET: "tailscale-auth" + SA_NAME: tailscale + TS_USERSPACE: "true" + TS_ROUTES: |- + ${SECRET_LAN_CIDR},${SECRET_IOT_CIDR} + TS_ACCEPT_DNS: "false" + TS_EXTRA_ARGS: "--advertise-exit-node" + envFrom: + - secretRef: + name: tailscale-auth + + service: + main: + ports: + http: + port: &port 45387 + + podSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + + ingress: + main: + enabled: false + + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false diff --git a/kubernetes/apps/network/tailscale/app/kustomization.yaml b/kubernetes/apps/network/tailscale/app/kustomization.yaml new file mode 100644 index 000000000..60107700e --- /dev/null +++ b/kubernetes/apps/network/tailscale/app/kustomization.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: network +resources: + - ./externalsecret.yaml + - ./helmrelease.yaml + - ./rbac.yaml diff --git a/kubernetes/apps/network/tailscale/app/rbac.yaml b/kubernetes/apps/network/tailscale/app/rbac.yaml new file mode 100644 index 000000000..2cd55404b --- /dev/null +++ b/kubernetes/apps/network/tailscale/app/rbac.yaml @@ -0,0 +1,35 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: tailscale + namespace: network +rules: + - apiGroups: [""] # "" indicates the core API group + resources: ["secrets"] + # Create can not be restricted to a resource name. + verbs: ["create"] + - apiGroups: [""] # "" indicates the core API group + resourceNames: ["tailscale-auth"] + resources: ["secrets"] + verbs: ["get", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: tailscale + namespace: network +subjects: + - kind: ServiceAccount + name: "tailscale" + namespace: network +roleRef: + kind: Role + name: tailscale + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: tailscale + namespace: network diff --git a/kubernetes/apps/network/tailscale/ks.yaml b/kubernetes/apps/network/tailscale/ks.yaml new file mode 100644 index 000000000..3b4b4356e --- /dev/null +++ b/kubernetes/apps/network/tailscale/ks.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: tailscale + namespace: flux-system +spec: + path: ./kubernetes/apps/networking/tailscale/app + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + healthChecks: + - apiVersion: helm.toolkit.fluxcd.io/v2beta2 + kind: HelmRelease + name: tailscale + namespace: network + interval: 15m + retryInterval: 1m + timeout: 5m diff --git a/kubernetes/apps/network/unifi/app/config-pvc.yaml b/kubernetes/apps/network/unifi/app/config-pvc.yaml new file mode 100644 index 000000000..13c4a2031 --- /dev/null +++ b/kubernetes/apps/network/unifi/app/config-pvc.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: unifi-config-v1 + namespace: network +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: ceph-block +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: unifi-config-v2 + namespace: network +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: local-path diff --git a/kubernetes/apps/network/unifi/app/helmrelease.yaml b/kubernetes/apps/network/unifi/app/helmrelease.yaml new file mode 100644 index 000000000..88f210c9b --- /dev/null +++ b/kubernetes/apps/network/unifi/app/helmrelease.yaml @@ -0,0 +1,128 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: unifi + namespace: network +spec: + interval: 30m + chart: + spec: + chart: app-template + version: 1.5.1 + interval: 30m + sourceRef: + kind: HelmRepository + name: bjw-s + namespace: flux-system + maxHistory: 3 + install: + createNamespace: true + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + uninstall: + keepHistory: false + + values: + # controller: + # type: statefulset + + image: + repository: jacobalberty/unifi + tag: v8.1.113 + + # podAnnotations: + # backup.velero.io/backup-volumes: data + # pre.hook.backup.velero.io/container: fsfreeze + # pre.hook.backup.velero.io/command: '["/sbin/fsfreeze", "--freeze", "/data"]' + # post.hook.backup.velero.io/container: fsfreeze + # post.hook.backup.velero.io/command: '["/sbin/fsfreeze", "--unfreeze", "/data"]' + + env: + RUNAS_UID0: "false" + UNIFI_UID: "999" + UNIFI_GID: "999" + UNIFI_STDOUT: "true" + JVM_INIT_HEAP_SIZE: + JVM_MAX_HEAP_SIZE: 1024M + TZ: ${TIMEZONE} + + service: + main: + type: LoadBalancer + annotations: + io.cilium/lb-ipam-ips: ${SVC_UNIFI_ADDR} + externalTrafficPolicy: Cluster + ports: + http: + port: 8443 + protocol: HTTPS + controller: + enabled: true + port: 8080 + protocol: TCP + portal-http: + enabled: false + port: 8880 + protocol: HTTP + portal-https: + enabled: false + port: 8843 + protocol: HTTPS + speedtest: + enabled: true + port: 6789 + protocol: TCP + stun: + enabled: true + port: 3478 + protocol: UDP + syslog: + enabled: true + port: 5514 + protocol: UDP + discovery: + enabled: true + port: 10001 + protocol: UDP + + ingress: + main: + enabled: true + ingressClassName: "internal" + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + hosts: + - host: &host "{{ .Release.Name }}.${SECRET_DOMAIN}" + paths: + - path: / + tls: + - hosts: + - *host + + resources: + requests: + cpu: 23m + memory: 1390M + limits: + memory: 1390M + + persistence: + data: + enabled: true + existingClaim: unifi + mountPath: /unifi + + # additionalContainers: + # fsfreeze: + # name: fsfreeze + # image: ghcr.io/k8s-at-home/fsfreeze:v2.37-r0 + # volumeMounts: + # - name: data + # mountPath: /data + # securityContext: + # privileged: true diff --git a/kubernetes/apps/network/unifi/app/hr.yaml b/kubernetes/apps/network/unifi/app/hr.yaml new file mode 100644 index 000000000..a641ce550 --- /dev/null +++ b/kubernetes/apps/network/unifi/app/hr.yaml @@ -0,0 +1,115 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2beta2.json +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: unifi +spec: + interval: 30m + chart: + spec: + chart: app-template + version: 2.4.0 + sourceRef: + kind: HelmRepository + name: bjw-s + namespace: flux-system + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + uninstall: + keepHistory: false + dependsOn: + - name: rook-ceph-cluster + namespace: rook-ceph + - name: volsync + namespace: storage + values: + controllers: + main: + annotations: + reloader.stakater.com/auto: "true" + containers: + main: + image: + repository: ghcr.io/jacobalberty/unifi-docker + tag: v8.0.26 + env: + TZ: "${TIMEZONE}" + RUNAS_UID0: "false" + UNIFI_UID: "999" + UNIFI_GID: "999" + UNIFI_STDOUT: "true" + JVM_INIT_HEAP_SIZE: + JVM_MAX_HEAP_SIZE: 1024M + + resources: + requests: + cpu: 23m + memory: 1390M + limits: + memory: 1390M + + service: + main: + type: LoadBalancer + annotations: + io.cilium/lb-ipam-ips: ${SVC_UNIFI_ADDR} + externalTrafficPolicy: Cluster + ports: + http: + port: 8443 + protocol: HTTPS + controller: + enabled: true + port: 8080 + protocol: TCP + portal-http: + enabled: false + port: 8880 + protocol: HTTP + portal-https: + enabled: false + port: 8843 + protocol: HTTPS + speedtest: + enabled: true + port: 6789 + protocol: TCP + stun: + enabled: true + port: 3478 + protocol: UDP + syslog: + enabled: true + port: 5514 + protocol: UDP + discovery: + enabled: true + port: 10001 + protocol: UDP + + ingress: + main: + enabled: true + className: internal + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + hosts: + - host: &host "{{ .Release.Name }}.${SECRET_DOMAIN}" + paths: + - path: / + tls: + - hosts: + - *host + + persistence: + data: + enabled: true + existingClaim: unifi-config-v2 + globalMounts: + - path: /unifi \ No newline at end of file diff --git a/kubernetes/apps/network/unifi/app/kustomization.yaml b/kubernetes/apps/network/unifi/app/kustomization.yaml new file mode 100644 index 000000000..79386f04f --- /dev/null +++ b/kubernetes/apps/network/unifi/app/kustomization.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: network +resources: + - ./config-pvc.yaml + - ./helmrelease.yaml + - ../../../../templates/volsync +labels: + - pairs: + app.kubernetes.io/name: unifi + app.kubernetes.io/instance: unifi diff --git a/kubernetes/apps/network/unifi/ks.yaml b/kubernetes/apps/network/unifi/ks.yaml new file mode 100644 index 000000000..e1f2c9dcf --- /dev/null +++ b/kubernetes/apps/network/unifi/ks.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app unifi + namespace: flux-system +spec: + targetnamespace: network + # commonMetadata: + # labels: + # app.kubernetes.io/name: *app + dependsOn: + - name: rook-ceph-cluster + path: ./kubernetes/apps/networking/unifi/app + prune: true + sourceRef: + kind: GitRepository + name: home-kubernetes + healthChecks: + - apiVersion: helm.toolkit.fluxcd.io/v2beta2 + kind: HelmRelease + name: unifi + namespace: network + interval: 15m + retryInterval: 1m + timeout: 5m + postBuild: + substitute: + APP: *app + VOLSYNC_CAPACITY: 5Gi