feat: deploy microservices through traefik
This commit is contained in:
@@ -189,6 +189,7 @@ jobs:
|
|||||||
-e "tailscale_oauth_client_id=${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }}" \
|
-e "tailscale_oauth_client_id=${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }}" \
|
||||||
-e "tailscale_oauth_client_secret=${{ secrets.TAILSCALE_OAUTH_CLIENT_SECRET }}" \
|
-e "tailscale_oauth_client_secret=${{ secrets.TAILSCALE_OAUTH_CLIENT_SECRET }}" \
|
||||||
-e "doppler_hetznerterra_service_token=${{ secrets.DOPPLER_HETZNERTERRA_SERVICE_TOKEN }}" \
|
-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 "tailscale_api_key=${{ secrets.TAILSCALE_API_KEY }}" \
|
||||||
-e "grafana_admin_password=${{ secrets.GRAFANA_ADMIN_PASSWORD }}" \
|
-e "grafana_admin_password=${{ secrets.GRAFANA_ADMIN_PASSWORD }}" \
|
||||||
-e "cluster_name=k8s-cluster"
|
-e "cluster_name=k8s-cluster"
|
||||||
@@ -1208,6 +1209,7 @@ jobs:
|
|||||||
wait_for_kustomization_ready addon-observability-secrets 300s
|
wait_for_kustomization_ready addon-observability-secrets 300s
|
||||||
wait_for_kustomization_ready addon-observability 300s
|
wait_for_kustomization_ready addon-observability 300s
|
||||||
wait_for_kustomization_ready addon-observability-content 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
|
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}')"
|
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
|
if [ -n "${stalled_helmreleases}" ]; then
|
||||||
|
|||||||
@@ -17,6 +17,15 @@
|
|||||||
changed_when: true
|
changed_when: true
|
||||||
no_log: 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
|
- name: Note pending Doppler ClusterSecretStore bootstrap
|
||||||
debug:
|
debug:
|
||||||
msg: >-
|
msg: >-
|
||||||
|
|||||||
@@ -316,6 +316,7 @@
|
|||||||
- grafana
|
- grafana
|
||||||
- prometheus
|
- prometheus
|
||||||
- flux
|
- flux
|
||||||
|
- apps
|
||||||
tasks:
|
tasks:
|
||||||
- name: Delete stale devices only before service proxies exist
|
- name: Delete stale devices only before service proxies exist
|
||||||
include_role:
|
include_role:
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources: []
|
resources:
|
||||||
|
- microservices
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: microservices
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: microservices-strip-prefix
|
||||||
|
namespace: microservices
|
||||||
|
spec:
|
||||||
|
stripPrefix:
|
||||||
|
prefixes:
|
||||||
|
- /site-analyzer
|
||||||
|
- /scraper
|
||||||
@@ -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
|
||||||
@@ -12,6 +12,6 @@ spec:
|
|||||||
path: ./apps
|
path: ./apps
|
||||||
dependsOn:
|
dependsOn:
|
||||||
- name: infrastructure
|
- name: infrastructure
|
||||||
wait: true
|
wait: false
|
||||||
timeout: 5m
|
timeout: 5m
|
||||||
suspend: true
|
suspend: false
|
||||||
|
|||||||
+13
@@ -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
|
||||||
@@ -2,3 +2,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
|||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- clustersecretstore-doppler-hetznerterra.yaml
|
- clustersecretstore-doppler-hetznerterra.yaml
|
||||||
|
- clustersecretstore-doppler-openstaticfish-microservices.yaml
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
|||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- helmrelease-traefik.yaml
|
- helmrelease-traefik.yaml
|
||||||
|
- 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
|
||||||
@@ -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 "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" "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 "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"
|
||||||
|
|||||||
Reference in New Issue
Block a user