From c62364fe672e1261c9bec5e3e15fb2cf33949991 Mon Sep 17 00:00:00 2001 From: MichaelFisher1997 Date: Tue, 5 May 2026 01:28:59 +0000 Subject: [PATCH] feat: deploy microservices through traefik --- .gitea/workflows/deploy.yml | 2 + .../roles/doppler-bootstrap/tasks/main.yml | 9 +++ ansible/site.yml | 1 + apps/kustomization.yaml | 3 +- .../ingressroute-microservices.yaml | 23 ++++++ apps/microservices/kustomization.yaml | 11 +++ apps/microservices/namespace.yaml | 4 + apps/microservices/scraper-deployment.yaml | 63 +++++++++++++++ apps/microservices/scraper-service.yaml | 14 ++++ .../site-analyzer-deployment.yaml | 79 +++++++++++++++++++ apps/microservices/site-analyzer-service.yaml | 14 ++++ .../traefik-middleware-strip-prefix.yaml | 10 +++ .../webshare-api-externalsecret.yaml | 29 +++++++ .../prod/flux-system/kustomization-apps.yaml | 4 +- ...-doppler-openstaticfish-microservices.yaml | 13 +++ .../external-secrets-store/kustomization.yaml | 1 + .../addons/traefik/kustomization.yaml | 1 + .../traefik-apps-tailscale-service.yaml | 20 +++++ scripts/smoke-check-tailnet-services.sh | 1 + 19 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 apps/microservices/ingressroute-microservices.yaml create mode 100644 apps/microservices/kustomization.yaml create mode 100644 apps/microservices/namespace.yaml create mode 100644 apps/microservices/scraper-deployment.yaml create mode 100644 apps/microservices/scraper-service.yaml create mode 100644 apps/microservices/site-analyzer-deployment.yaml create mode 100644 apps/microservices/site-analyzer-service.yaml create mode 100644 apps/microservices/traefik-middleware-strip-prefix.yaml create mode 100644 apps/microservices/webshare-api-externalsecret.yaml create mode 100644 infrastructure/addons/external-secrets-store/clustersecretstore-doppler-openstaticfish-microservices.yaml create mode 100644 infrastructure/addons/traefik/traefik-apps-tailscale-service.yaml diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 740d458..da9eb27 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -189,6 +189,7 @@ jobs: -e "tailscale_oauth_client_id=${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }}" \ -e "tailscale_oauth_client_secret=${{ secrets.TAILSCALE_OAUTH_CLIENT_SECRET }}" \ -e "doppler_hetznerterra_service_token=${{ secrets.DOPPLER_HETZNERTERRA_SERVICE_TOKEN }}" \ + -e "doppler_openstaticfish_microservices_service_token=${{ secrets.DOPPLER_MICROSERVICES_SERVICE_TOKEN }}" \ -e "tailscale_api_key=${{ secrets.TAILSCALE_API_KEY }}" \ -e "grafana_admin_password=${{ secrets.GRAFANA_ADMIN_PASSWORD }}" \ -e "cluster_name=k8s-cluster" @@ -1208,6 +1209,7 @@ jobs: wait_for_kustomization_ready addon-observability-secrets 300s wait_for_kustomization_ready addon-observability 300s wait_for_kustomization_ready addon-observability-content 300s + wait_for_kustomization_ready apps 300s if ! kubectl -n flux-system wait --for=condition=Ready helmrelease --all --timeout=120s; then stalled_helmreleases="$(kubectl -n flux-system get helmreleases -o jsonpath='{range .items[*]}{.metadata.name}{" "}{.status.conditions[?(@.type=="Stalled")].status}{"\n"}{end}' | awk '$2 == "True" {print $1}')" if [ -n "${stalled_helmreleases}" ]; then diff --git a/ansible/roles/doppler-bootstrap/tasks/main.yml b/ansible/roles/doppler-bootstrap/tasks/main.yml index c8ecc89..9393867 100644 --- a/ansible/roles/doppler-bootstrap/tasks/main.yml +++ b/ansible/roles/doppler-bootstrap/tasks/main.yml @@ -17,6 +17,15 @@ changed_when: true no_log: true +- name: Apply OpenStaticFish MicroServices Doppler service token secret + shell: >- + kubectl -n external-secrets create secret generic doppler-openstaticfish-microservices-service-token + --from-literal=dopplerToken='{{ doppler_openstaticfish_microservices_service_token | default("") }}' + --dry-run=client -o yaml | kubectl apply -f - + changed_when: true + no_log: true + when: doppler_openstaticfish_microservices_service_token | default("") | length > 0 + - name: Note pending Doppler ClusterSecretStore bootstrap debug: msg: >- diff --git a/ansible/site.yml b/ansible/site.yml index 51ff6b2..cb6fb6e 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -316,6 +316,7 @@ - grafana - prometheus - flux + - apps tasks: - name: Delete stale devices only before service proxies exist include_role: diff --git a/apps/kustomization.yaml b/apps/kustomization.yaml index b83b23e..878569c 100644 --- a/apps/kustomization.yaml +++ b/apps/kustomization.yaml @@ -1,3 +1,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -resources: [] +resources: + - microservices diff --git a/apps/microservices/ingressroute-microservices.yaml b/apps/microservices/ingressroute-microservices.yaml new file mode 100644 index 0000000..5c923df --- /dev/null +++ b/apps/microservices/ingressroute-microservices.yaml @@ -0,0 +1,23 @@ +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: microservices + namespace: microservices +spec: + entryPoints: + - web + routes: + - match: Host(`apps.silverside-gopher.ts.net`) && PathPrefix(`/site-analyzer`) + kind: Rule + middlewares: + - name: microservices-strip-prefix + services: + - name: site-analyzer + port: 8090 + - match: Host(`apps.silverside-gopher.ts.net`) && PathPrefix(`/scraper`) + kind: Rule + middlewares: + - name: microservices-strip-prefix + services: + - name: scraper + port: 8080 diff --git a/apps/microservices/kustomization.yaml b/apps/microservices/kustomization.yaml new file mode 100644 index 0000000..b772406 --- /dev/null +++ b/apps/microservices/kustomization.yaml @@ -0,0 +1,11 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - namespace.yaml + - webshare-api-externalsecret.yaml + - site-analyzer-deployment.yaml + - site-analyzer-service.yaml + - scraper-deployment.yaml + - scraper-service.yaml + - traefik-middleware-strip-prefix.yaml + - ingressroute-microservices.yaml diff --git a/apps/microservices/namespace.yaml b/apps/microservices/namespace.yaml new file mode 100644 index 0000000..956fe4f --- /dev/null +++ b/apps/microservices/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: microservices diff --git a/apps/microservices/scraper-deployment.yaml b/apps/microservices/scraper-deployment.yaml new file mode 100644 index 0000000..26ff474 --- /dev/null +++ b/apps/microservices/scraper-deployment.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: scraper + namespace: microservices + labels: + app: scraper +spec: + replicas: 1 + selector: + matchLabels: + app: scraper + template: + metadata: + labels: + app: scraper + spec: + containers: + - name: scraper + image: ghcr.io/openstaticfish/microservices/scraper:main + imagePullPolicy: Always + ports: + - containerPort: 8080 + env: + - name: PORT + value: "8080" + - name: WEBSHARE_API_KEY + valueFrom: + secretKeyRef: + name: webshare-api + key: api-key + optional: true + - name: WEBSHARE_PROXY_USERNAME + valueFrom: + secretKeyRef: + name: webshare-api + key: proxy-username + optional: true + - name: WEBSHARE_PROXY_PASSWORD + valueFrom: + secretKeyRef: + name: webshare-api + key: proxy-password + optional: true + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 500m + memory: 256Mi + livenessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 2 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 2 + periodSeconds: 5 diff --git a/apps/microservices/scraper-service.yaml b/apps/microservices/scraper-service.yaml new file mode 100644 index 0000000..b29cb63 --- /dev/null +++ b/apps/microservices/scraper-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: scraper + namespace: microservices +spec: + type: ClusterIP + selector: + app: scraper + ports: + - name: http + protocol: TCP + port: 8080 + targetPort: 8080 diff --git a/apps/microservices/site-analyzer-deployment.yaml b/apps/microservices/site-analyzer-deployment.yaml new file mode 100644 index 0000000..3344c15 --- /dev/null +++ b/apps/microservices/site-analyzer-deployment.yaml @@ -0,0 +1,79 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: site-analyzer + namespace: microservices + labels: + app: site-analyzer +spec: + replicas: 1 + selector: + matchLabels: + app: site-analyzer + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + template: + metadata: + labels: + app: site-analyzer + spec: + terminationGracePeriodSeconds: 30 + containers: + - name: site-analyzer + image: ghcr.io/openstaticfish/microservices/site-analyzer:main + imagePullPolicy: Always + ports: + - containerPort: 8090 + env: + - name: PORT + value: "8090" + - name: MAX_CONCURRENT_ANALYSES + value: "20" + - name: ANALYSIS_TIMEOUT + value: 15s + - name: FETCH_TIMEOUT + value: 10s + - name: MAX_REQUEST_BYTES + value: "4096" + - name: MAX_RESPONSE_BYTES + value: "2097152" + - name: READ_HEADER_TIMEOUT + value: 2s + - name: READ_TIMEOUT + value: 5s + - name: WRITE_TIMEOUT + value: 20s + - name: IDLE_TIMEOUT + value: 60s + - name: SHUTDOWN_TIMEOUT + value: 25s + - name: MAX_IDLE_CONNS + value: "200" + - name: MAX_IDLE_CONNS_PER_HOST + value: "20" + resources: + requests: + cpu: 250m + memory: 128Mi + limits: + cpu: "1" + memory: 512Mi + livenessProbe: + httpGet: + path: /health + port: 8090 + initialDelaySeconds: 2 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /ready + port: 8090 + initialDelaySeconds: 2 + periodSeconds: 3 + timeoutSeconds: 1 + failureThreshold: 2 diff --git a/apps/microservices/site-analyzer-service.yaml b/apps/microservices/site-analyzer-service.yaml new file mode 100644 index 0000000..2ccf5b7 --- /dev/null +++ b/apps/microservices/site-analyzer-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: site-analyzer + namespace: microservices +spec: + type: ClusterIP + selector: + app: site-analyzer + ports: + - name: http + protocol: TCP + port: 8090 + targetPort: 8090 diff --git a/apps/microservices/traefik-middleware-strip-prefix.yaml b/apps/microservices/traefik-middleware-strip-prefix.yaml new file mode 100644 index 0000000..b03f2d6 --- /dev/null +++ b/apps/microservices/traefik-middleware-strip-prefix.yaml @@ -0,0 +1,10 @@ +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: microservices-strip-prefix + namespace: microservices +spec: + stripPrefix: + prefixes: + - /site-analyzer + - /scraper diff --git a/apps/microservices/webshare-api-externalsecret.yaml b/apps/microservices/webshare-api-externalsecret.yaml new file mode 100644 index 0000000..c9ccb32 --- /dev/null +++ b/apps/microservices/webshare-api-externalsecret.yaml @@ -0,0 +1,29 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: webshare-api + namespace: microservices +spec: + refreshInterval: 1h + secretStoreRef: + name: doppler-openstaticfish-microservices + kind: ClusterSecretStore + target: + name: webshare-api + creationPolicy: Owner + template: + type: Opaque + data: + api-key: "{{ .webshareApiKey }}" + proxy-username: "{{ .webshareProxyUsername }}" + proxy-password: "{{ .webshareProxyPassword }}" + data: + - secretKey: webshareApiKey + remoteRef: + key: WEBSHARE_API_KEY + - secretKey: webshareProxyUsername + remoteRef: + key: WEBSHARE_PROXY_USERNAME + - secretKey: webshareProxyPassword + remoteRef: + key: WEBSHARE_PROXY_PASSWORD diff --git a/clusters/prod/flux-system/kustomization-apps.yaml b/clusters/prod/flux-system/kustomization-apps.yaml index ad14056..2a1fe01 100644 --- a/clusters/prod/flux-system/kustomization-apps.yaml +++ b/clusters/prod/flux-system/kustomization-apps.yaml @@ -12,6 +12,6 @@ spec: path: ./apps dependsOn: - name: infrastructure - wait: true + wait: false timeout: 5m - suspend: true + suspend: false diff --git a/infrastructure/addons/external-secrets-store/clustersecretstore-doppler-openstaticfish-microservices.yaml b/infrastructure/addons/external-secrets-store/clustersecretstore-doppler-openstaticfish-microservices.yaml new file mode 100644 index 0000000..c7ce6b2 --- /dev/null +++ b/infrastructure/addons/external-secrets-store/clustersecretstore-doppler-openstaticfish-microservices.yaml @@ -0,0 +1,13 @@ +apiVersion: external-secrets.io/v1 +kind: ClusterSecretStore +metadata: + name: doppler-openstaticfish-microservices +spec: + provider: + doppler: + auth: + secretRef: + dopplerToken: + name: doppler-openstaticfish-microservices-service-token + key: dopplerToken + namespace: external-secrets diff --git a/infrastructure/addons/external-secrets-store/kustomization.yaml b/infrastructure/addons/external-secrets-store/kustomization.yaml index 15238f5..2f6ef12 100644 --- a/infrastructure/addons/external-secrets-store/kustomization.yaml +++ b/infrastructure/addons/external-secrets-store/kustomization.yaml @@ -2,3 +2,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - clustersecretstore-doppler-hetznerterra.yaml + - clustersecretstore-doppler-openstaticfish-microservices.yaml diff --git a/infrastructure/addons/traefik/kustomization.yaml b/infrastructure/addons/traefik/kustomization.yaml index af74dd9..ae5c0b4 100644 --- a/infrastructure/addons/traefik/kustomization.yaml +++ b/infrastructure/addons/traefik/kustomization.yaml @@ -2,3 +2,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - helmrelease-traefik.yaml + - traefik-apps-tailscale-service.yaml diff --git a/infrastructure/addons/traefik/traefik-apps-tailscale-service.yaml b/infrastructure/addons/traefik/traefik-apps-tailscale-service.yaml new file mode 100644 index 0000000..99b1b89 --- /dev/null +++ b/infrastructure/addons/traefik/traefik-apps-tailscale-service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: traefik-apps-tailscale + namespace: kube-system + annotations: + tailscale.com/hostname: apps + tailscale.com/proxy-class: infra-stable + tailscale.com/tags: tag:prod +spec: + type: LoadBalancer + loadBalancerClass: tailscale + selector: + app.kubernetes.io/instance: kube-system-traefik-kube-system + app.kubernetes.io/name: traefik + ports: + - name: web + protocol: TCP + port: 80 + targetPort: web diff --git a/scripts/smoke-check-tailnet-services.sh b/scripts/smoke-check-tailnet-services.sh index c6d9b65..9f719fb 100644 --- a/scripts/smoke-check-tailnet-services.sh +++ b/scripts/smoke-check-tailnet-services.sh @@ -209,3 +209,4 @@ restart_unhealthy_tailscale_proxies check_service "cattle-system" "rancher-tailscale" "rancher.silverside-gopher.ts.net" "https://rancher.silverside-gopher.ts.net/" check_service "observability" "grafana-tailscale" "grafana.silverside-gopher.ts.net" "http://grafana.silverside-gopher.ts.net/" check_service "observability" "prometheus-tailscale" "prometheus.silverside-gopher.ts.net" "http://prometheus.silverside-gopher.ts.net:9090/" +check_service "kube-system" "traefik-apps-tailscale" "apps.silverside-gopher.ts.net" "http://apps.silverside-gopher.ts.net/site-analyzer/health"