mirror of
https://github.com/ghndrx/k8s-game-2048.git
synced 2026-02-10 06:45:07 +00:00
🚀 Complete automation pipeline with SSL, testing, and deployment
✨ Features: - Full SSL setup with Let's Encrypt for all environments - Automated CI/CD pipeline with GitHub Actions - Comprehensive smoke testing workflow - Auto-deploy to dev on main branch push - Manual staging/production deployments with confirmation - Istio + nginx SSL termination architecture 🔧 Infrastructure: - Migrated from Kourier to Istio for Knative ingress - nginx handles SSL termination and public traffic - Istio manages internal Knative service routing - Scale-to-zero configuration for all environments 🧪 Testing: - SSL certificate validation and expiry checks - Domain accessibility and content validation - Performance testing and redirect behavior validation - Automated smoke tests on every deployment 🌐 Domains: - Dev: https://2048-dev.wa.darknex.us - Staging: https://2048-staging.wa.darknex.us - Production: https://2048.wa.darknex.us 📦 Deployment: - Uses latest GHCR images with imagePullPolicy: Always - Automated secret management across namespaces - Environment-specific Knative service configurations - Clean manifest structure with proper labeling
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
apiVersion: networking.internal.knative.dev/v1alpha1
|
||||
kind: ClusterDomainClaim
|
||||
metadata:
|
||||
name: 2048-dev.wa.darknex.us
|
||||
spec:
|
||||
namespace: game-2048-dev
|
||||
---
|
||||
apiVersion: networking.internal.knative.dev/v1alpha1
|
||||
kind: ClusterDomainClaim
|
||||
metadata:
|
||||
name: 2048-staging.wa.darknex.us
|
||||
spec:
|
||||
namespace: game-2048-staging
|
||||
---
|
||||
apiVersion: networking.internal.knative.dev/v1alpha1
|
||||
kind: ClusterDomainClaim
|
||||
metadata:
|
||||
name: 2048.wa.darknex.us
|
||||
spec:
|
||||
namespace: game-2048-prod
|
||||
@@ -1,15 +0,0 @@
|
||||
apiVersion: serving.knative.dev/v1beta1
|
||||
kind: DomainMapping
|
||||
metadata:
|
||||
name: 2048-dev.wa.darknex.us
|
||||
namespace: game-2048-dev
|
||||
labels:
|
||||
app: game-2048
|
||||
environment: development
|
||||
spec:
|
||||
ref:
|
||||
name: game-2048-dev
|
||||
kind: Service
|
||||
apiVersion: serving.knative.dev/v1
|
||||
tls:
|
||||
secretName: game-2048-dev-cert-secret
|
||||
@@ -9,45 +9,18 @@ metadata:
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: game-2048
|
||||
environment: development
|
||||
annotations:
|
||||
# Scale to zero configuration
|
||||
autoscaling.knative.dev/minScale: "0"
|
||||
autoscaling.knative.dev/maxScale: "10"
|
||||
autoscaling.knative.dev/scaleDownDelay: "30s"
|
||||
autoscaling.knative.dev/target: "100"
|
||||
spec:
|
||||
containers:
|
||||
- name: game-2048
|
||||
image: ghcr.io/ghndrx/k8s-game-2048:latest
|
||||
- image: ghcr.io/ghndrx/k8s-game-2048:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
protocol: TCP
|
||||
- containerPort: 80
|
||||
env:
|
||||
- name: ENVIRONMENT
|
||||
value: "development"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 256Mi
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 8080
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
traffic:
|
||||
- percent: 100
|
||||
latestRevision: true
|
||||
imagePullSecrets:
|
||||
- name: ghcr-secret
|
||||
|
||||
20
manifests/istio-gateway.yaml
Normal file
20
manifests/istio-gateway.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: knative-ingress-gateway
|
||||
namespace: knative-serving
|
||||
labels:
|
||||
app.kubernetes.io/component: net-istio
|
||||
app.kubernetes.io/name: knative-serving
|
||||
app.kubernetes.io/version: 1.12.0
|
||||
networking.knative.dev/ingress-provider: istio
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway
|
||||
servers:
|
||||
- hosts:
|
||||
- '*'
|
||||
port:
|
||||
name: http
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
@@ -4,5 +4,13 @@ metadata:
|
||||
name: config-domain
|
||||
namespace: knative-serving
|
||||
data:
|
||||
wa.darknex.us: ""
|
||||
dev.wa.darknex.us: |
|
||||
selector:
|
||||
environment: development
|
||||
staging.wa.darknex.us: |
|
||||
selector:
|
||||
environment: staging
|
||||
wa.darknex.us: |
|
||||
selector:
|
||||
environment: production
|
||||
autocreate-cluster-domain-claims: "true"
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: config-kourier
|
||||
namespace: knative-serving
|
||||
data:
|
||||
_example: |
|
||||
################################
|
||||
# #
|
||||
# EXAMPLE CONFIGURATION #
|
||||
# #
|
||||
################################
|
||||
enable-service-links: "false"
|
||||
# Enable automatic HTTP to HTTPS redirect
|
||||
ssl-redirect: "true"
|
||||
40
manifests/nginx-certificate.yaml
Normal file
40
manifests/nginx-certificate.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: game-2048-dev-nginx-cert
|
||||
namespace: default
|
||||
spec:
|
||||
secretName: game-2048-dev-nginx-tls
|
||||
issuerRef:
|
||||
name: letsencrypt-prod
|
||||
kind: ClusterIssuer
|
||||
dnsNames:
|
||||
- "2048-dev.wa.darknex.us"
|
||||
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: game-2048-staging-nginx-cert
|
||||
namespace: default
|
||||
spec:
|
||||
secretName: game-2048-staging-nginx-tls
|
||||
issuerRef:
|
||||
name: letsencrypt-prod
|
||||
kind: ClusterIssuer
|
||||
dnsNames:
|
||||
- "2048-staging.wa.darknex.us"
|
||||
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: game-2048-prod-nginx-cert
|
||||
namespace: default
|
||||
spec:
|
||||
secretName: game-2048-prod-nginx-tls
|
||||
issuerRef:
|
||||
name: letsencrypt-prod
|
||||
kind: ClusterIssuer
|
||||
dnsNames:
|
||||
- "2048.wa.darknex.us"
|
||||
119
manifests/nginx-to-istio-proxy.yaml
Normal file
119
manifests/nginx-to-istio-proxy.yaml
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: game-2048-dev-proxy
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
proxy_set_header Host game-2048-dev.game-2048-dev.dev.wa.darknex.us;
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- 2048-dev.wa.darknex.us
|
||||
secretName: game-2048-dev-nginx-tls
|
||||
rules:
|
||||
- host: 2048-dev.wa.darknex.us
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: istio-nodeport-service
|
||||
port:
|
||||
number: 80
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: game-2048-staging-proxy
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
proxy_set_header Host game-2048-staging.game-2048-staging.staging.wa.darknex.us;
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- 2048-staging.wa.darknex.us
|
||||
secretName: game-2048-staging-nginx-tls
|
||||
rules:
|
||||
- host: 2048-staging.wa.darknex.us
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: istio-nodeport-service
|
||||
port:
|
||||
number: 80
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: game-2048-prod-proxy
|
||||
namespace: default
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
proxy_set_header Host game-2048-prod.game-2048-prod.wa.darknex.us;
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- 2048.wa.darknex.us
|
||||
secretName: game-2048-prod-nginx-tls
|
||||
rules:
|
||||
- host: 2048.wa.darknex.us
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: istio-nodeport-service
|
||||
port:
|
||||
number: 80
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: istio-nodeport-service
|
||||
namespace: default
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 32135
|
||||
protocol: TCP
|
||||
clusterIP: None
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Endpoints
|
||||
metadata:
|
||||
name: istio-nodeport-service
|
||||
namespace: default
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 192.168.4.134 # Your k3s node IP
|
||||
ports:
|
||||
- name: http
|
||||
port: 32135
|
||||
@@ -1,15 +0,0 @@
|
||||
apiVersion: serving.knative.dev/v1beta1
|
||||
kind: DomainMapping
|
||||
metadata:
|
||||
name: 2048.wa.darknex.us
|
||||
namespace: game-2048-prod
|
||||
labels:
|
||||
app: game-2048
|
||||
environment: production
|
||||
spec:
|
||||
ref:
|
||||
name: game-2048-prod
|
||||
kind: Service
|
||||
apiVersion: serving.knative.dev/v1
|
||||
tls:
|
||||
secretName: game-2048-prod-cert-secret
|
||||
@@ -9,45 +9,18 @@ metadata:
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: game-2048
|
||||
environment: production
|
||||
annotations:
|
||||
# Scale to zero configuration
|
||||
autoscaling.knative.dev/minScale: "0"
|
||||
autoscaling.knative.dev/maxScale: "50"
|
||||
autoscaling.knative.dev/scaleDownDelay: "300s"
|
||||
autoscaling.knative.dev/maxScale: "10"
|
||||
autoscaling.knative.dev/target: "100"
|
||||
spec:
|
||||
containers:
|
||||
- name: game-2048
|
||||
image: ghcr.io/ghndrx/k8s-game-2048:latest
|
||||
- image: ghcr.io/ghndrx/k8s-game-2048:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
protocol: TCP
|
||||
- containerPort: 80
|
||||
env:
|
||||
- name: ENVIRONMENT
|
||||
value: "production"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 1Gi
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 8080
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
traffic:
|
||||
- percent: 100
|
||||
latestRevision: true
|
||||
imagePullSecrets:
|
||||
- name: ghcr-secret
|
||||
|
||||
@@ -12,45 +12,3 @@ spec:
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: game-2048-dev-cert
|
||||
namespace: knative-serving
|
||||
spec:
|
||||
secretName: game-2048-dev-cert-secret
|
||||
issuerRef:
|
||||
name: letsencrypt-prod
|
||||
kind: ClusterIssuer
|
||||
dnsNames:
|
||||
- "2048-dev.wa.darknex.us"
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: game-2048-staging-cert
|
||||
namespace: knative-serving
|
||||
spec:
|
||||
secretName: game-2048-staging-cert-secret
|
||||
issuerRef:
|
||||
name: letsencrypt-prod
|
||||
kind: ClusterIssuer
|
||||
dnsNames:
|
||||
- "2048-staging.wa.darknex.us"
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: game-2048-prod-cert
|
||||
namespace: knative-serving
|
||||
spec:
|
||||
secretName: game-2048-prod-cert-secret
|
||||
issuerRef:
|
||||
name: letsencrypt-prod
|
||||
kind: ClusterIssuer
|
||||
dnsNames:
|
||||
- "2048.wa.darknex.us"
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
apiVersion: serving.knative.dev/v1beta1
|
||||
kind: DomainMapping
|
||||
metadata:
|
||||
name: 2048-staging.wa.darknex.us
|
||||
namespace: game-2048-staging
|
||||
labels:
|
||||
app: game-2048
|
||||
environment: staging
|
||||
spec:
|
||||
ref:
|
||||
name: game-2048-staging
|
||||
kind: Service
|
||||
apiVersion: serving.knative.dev/v1
|
||||
tls:
|
||||
secretName: game-2048-staging-cert-secret
|
||||
@@ -9,45 +9,18 @@ metadata:
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: game-2048
|
||||
environment: staging
|
||||
annotations:
|
||||
# Scale to zero configuration
|
||||
autoscaling.knative.dev/minScale: "0"
|
||||
autoscaling.knative.dev/maxScale: "20"
|
||||
autoscaling.knative.dev/scaleDownDelay: "60s"
|
||||
autoscaling.knative.dev/maxScale: "10"
|
||||
autoscaling.knative.dev/target: "100"
|
||||
spec:
|
||||
containers:
|
||||
- name: game-2048
|
||||
image: ghcr.io/ghndrx/k8s-game-2048:latest
|
||||
- image: ghcr.io/ghndrx/k8s-game-2048:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
protocol: TCP
|
||||
- containerPort: 80
|
||||
env:
|
||||
- name: ENVIRONMENT
|
||||
value: "staging"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 512Mi
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 8080
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
traffic:
|
||||
- percent: 100
|
||||
latestRevision: true
|
||||
imagePullSecrets:
|
||||
- name: ghcr-secret
|
||||
|
||||
Reference in New Issue
Block a user