469 lines
9.7 KiB
YAML
469 lines
9.7 KiB
YAML
|
|
# Complete Application Example
|
||
|
|
# This demonstrates a full web application with database, API, and monitoring
|
||
|
|
|
||
|
|
# 1. Namespace
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Namespace
|
||
|
|
metadata:
|
||
|
|
name: complete-app
|
||
|
|
labels:
|
||
|
|
environment: production
|
||
|
|
team: backend
|
||
|
|
app: complete-app
|
||
|
|
---
|
||
|
|
# 2. ConfigMap for application configuration
|
||
|
|
apiVersion: v1
|
||
|
|
kind: ConfigMap
|
||
|
|
metadata:
|
||
|
|
name: app-config
|
||
|
|
namespace: complete-app
|
||
|
|
data:
|
||
|
|
DB_HOST: "postgres-service"
|
||
|
|
DB_PORT: "5432"
|
||
|
|
DB_NAME: "myapp"
|
||
|
|
REDIS_HOST: "redis-service"
|
||
|
|
REDIS_PORT: "6379"
|
||
|
|
ENVIRONMENT: "production"
|
||
|
|
LOG_LEVEL: "INFO"
|
||
|
|
|
||
|
|
application.properties: |
|
||
|
|
server.port=8080
|
||
|
|
logging.level=INFO
|
||
|
|
cache.enabled=true
|
||
|
|
session.timeout=3600
|
||
|
|
cors.allowed-origins=*
|
||
|
|
---
|
||
|
|
# 3. Secret for sensitive data
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Secret
|
||
|
|
metadata:
|
||
|
|
name: app-secrets
|
||
|
|
namespace: complete-app
|
||
|
|
type: Opaque
|
||
|
|
data:
|
||
|
|
DB_USERNAME: YWRtaW4= # admin
|
||
|
|
DB_PASSWORD: c2VjcmV0MTIz # secret123
|
||
|
|
API_KEY: bXktYXBpLWtleQ== # my-api-key
|
||
|
|
JWT_SECRET: bXktand0LXNlY3JldA== # my-jwt-secret
|
||
|
|
---
|
||
|
|
# 4. PVC for database
|
||
|
|
apiVersion: v1
|
||
|
|
kind: PersistentVolumeClaim
|
||
|
|
metadata:
|
||
|
|
name: postgres-pvc
|
||
|
|
namespace: complete-app
|
||
|
|
spec:
|
||
|
|
accessModes:
|
||
|
|
- ReadWriteOnce
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
storage: 10Gi
|
||
|
|
storageClassName: managed-premium
|
||
|
|
---
|
||
|
|
# 5. PVC for application data
|
||
|
|
apiVersion: v1
|
||
|
|
kind: PersistentVolumeClaim
|
||
|
|
metadata:
|
||
|
|
name: app-data-pvc
|
||
|
|
namespace: complete-app
|
||
|
|
spec:
|
||
|
|
accessModes:
|
||
|
|
- ReadWriteOnce
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
storage: 5Gi
|
||
|
|
storageClassName: managed-premium
|
||
|
|
---
|
||
|
|
# 6. PostgreSQL Database Deployment
|
||
|
|
apiVersion: apps/v1
|
||
|
|
kind: Deployment
|
||
|
|
metadata:
|
||
|
|
name: postgres
|
||
|
|
namespace: complete-app
|
||
|
|
labels:
|
||
|
|
app: postgres
|
||
|
|
component: database
|
||
|
|
spec:
|
||
|
|
replicas: 1
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app: postgres
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: postgres
|
||
|
|
component: database
|
||
|
|
spec:
|
||
|
|
securityContext:
|
||
|
|
runAsNonRoot: true
|
||
|
|
runAsUser: 999
|
||
|
|
fsGroup: 999
|
||
|
|
containers:
|
||
|
|
- name: postgres
|
||
|
|
image: postgres:13
|
||
|
|
ports:
|
||
|
|
- containerPort: 5432
|
||
|
|
env:
|
||
|
|
- name: POSTGRES_DB
|
||
|
|
value: "myapp"
|
||
|
|
- name: POSTGRES_USER
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: app-secrets
|
||
|
|
key: DB_USERNAME
|
||
|
|
- name: POSTGRES_PASSWORD
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: app-secrets
|
||
|
|
key: DB_PASSWORD
|
||
|
|
volumeMounts:
|
||
|
|
- name: postgres-data
|
||
|
|
mountPath: /var/lib/postgresql/data
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
memory: "256Mi"
|
||
|
|
cpu: "250m"
|
||
|
|
limits:
|
||
|
|
memory: "512Mi"
|
||
|
|
cpu: "500m"
|
||
|
|
livenessProbe:
|
||
|
|
exec:
|
||
|
|
command:
|
||
|
|
- pg_isready
|
||
|
|
- -U
|
||
|
|
- admin
|
||
|
|
initialDelaySeconds: 30
|
||
|
|
periodSeconds: 10
|
||
|
|
readinessProbe:
|
||
|
|
exec:
|
||
|
|
command:
|
||
|
|
- pg_isready
|
||
|
|
- -U
|
||
|
|
- admin
|
||
|
|
initialDelaySeconds: 5
|
||
|
|
periodSeconds: 5
|
||
|
|
volumes:
|
||
|
|
- name: postgres-data
|
||
|
|
persistentVolumeClaim:
|
||
|
|
claimName: postgres-pvc
|
||
|
|
---
|
||
|
|
# 7. Redis Cache Deployment
|
||
|
|
apiVersion: apps/v1
|
||
|
|
kind: Deployment
|
||
|
|
metadata:
|
||
|
|
name: redis
|
||
|
|
namespace: complete-app
|
||
|
|
labels:
|
||
|
|
app: redis
|
||
|
|
component: cache
|
||
|
|
spec:
|
||
|
|
replicas: 1
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app: redis
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: redis
|
||
|
|
component: cache
|
||
|
|
spec:
|
||
|
|
securityContext:
|
||
|
|
runAsNonRoot: true
|
||
|
|
runAsUser: 999
|
||
|
|
fsGroup: 999
|
||
|
|
containers:
|
||
|
|
- name: redis
|
||
|
|
image: redis:6-alpine
|
||
|
|
ports:
|
||
|
|
- containerPort: 6379
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
memory: "128Mi"
|
||
|
|
cpu: "100m"
|
||
|
|
limits:
|
||
|
|
memory: "256Mi"
|
||
|
|
cpu: "200m"
|
||
|
|
livenessProbe:
|
||
|
|
exec:
|
||
|
|
command:
|
||
|
|
- redis-cli
|
||
|
|
- ping
|
||
|
|
initialDelaySeconds: 30
|
||
|
|
periodSeconds: 10
|
||
|
|
readinessProbe:
|
||
|
|
exec:
|
||
|
|
command:
|
||
|
|
- redis-cli
|
||
|
|
- ping
|
||
|
|
initialDelaySeconds: 5
|
||
|
|
periodSeconds: 5
|
||
|
|
---
|
||
|
|
# 8. Web Application Deployment
|
||
|
|
apiVersion: apps/v1
|
||
|
|
kind: Deployment
|
||
|
|
metadata:
|
||
|
|
name: web-app
|
||
|
|
namespace: complete-app
|
||
|
|
labels:
|
||
|
|
app: web-app
|
||
|
|
component: frontend
|
||
|
|
spec:
|
||
|
|
replicas: 3
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app: web-app
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: web-app
|
||
|
|
component: frontend
|
||
|
|
spec:
|
||
|
|
securityContext:
|
||
|
|
runAsNonRoot: true
|
||
|
|
runAsUser: 1000
|
||
|
|
fsGroup: 2000
|
||
|
|
containers:
|
||
|
|
- name: web-app
|
||
|
|
image: nginx:latest
|
||
|
|
ports:
|
||
|
|
- containerPort: 80
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
memory: "64Mi"
|
||
|
|
cpu: "100m"
|
||
|
|
limits:
|
||
|
|
memory: "128Mi"
|
||
|
|
cpu: "200m"
|
||
|
|
livenessProbe:
|
||
|
|
httpGet:
|
||
|
|
path: /
|
||
|
|
port: 80
|
||
|
|
initialDelaySeconds: 30
|
||
|
|
periodSeconds: 10
|
||
|
|
readinessProbe:
|
||
|
|
httpGet:
|
||
|
|
path: /
|
||
|
|
port: 80
|
||
|
|
initialDelaySeconds: 5
|
||
|
|
periodSeconds: 5
|
||
|
|
securityContext:
|
||
|
|
allowPrivilegeEscalation: false
|
||
|
|
readOnlyRootFilesystem: true
|
||
|
|
capabilities:
|
||
|
|
drop:
|
||
|
|
- ALL
|
||
|
|
volumeMounts:
|
||
|
|
- name: tmp-volume
|
||
|
|
mountPath: /tmp
|
||
|
|
volumes:
|
||
|
|
- name: tmp-volume
|
||
|
|
emptyDir: {}
|
||
|
|
---
|
||
|
|
# 9. API Application Deployment
|
||
|
|
apiVersion: apps/v1
|
||
|
|
kind: Deployment
|
||
|
|
metadata:
|
||
|
|
name: api-app
|
||
|
|
namespace: complete-app
|
||
|
|
labels:
|
||
|
|
app: api-app
|
||
|
|
component: backend
|
||
|
|
spec:
|
||
|
|
replicas: 2
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app: api-app
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: api-app
|
||
|
|
component: backend
|
||
|
|
spec:
|
||
|
|
securityContext:
|
||
|
|
runAsNonRoot: true
|
||
|
|
runAsUser: 1000
|
||
|
|
fsGroup: 2000
|
||
|
|
containers:
|
||
|
|
- name: api-app
|
||
|
|
image: python:3.9-slim
|
||
|
|
ports:
|
||
|
|
- containerPort: 8080
|
||
|
|
env:
|
||
|
|
- name: DB_HOST
|
||
|
|
valueFrom:
|
||
|
|
configMapKeyRef:
|
||
|
|
name: app-config
|
||
|
|
key: DB_HOST
|
||
|
|
- name: DB_PORT
|
||
|
|
valueFrom:
|
||
|
|
configMapKeyRef:
|
||
|
|
name: app-config
|
||
|
|
key: DB_PORT
|
||
|
|
- name: DB_NAME
|
||
|
|
valueFrom:
|
||
|
|
configMapKeyRef:
|
||
|
|
name: app-config
|
||
|
|
key: DB_NAME
|
||
|
|
- name: DB_USERNAME
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: app-secrets
|
||
|
|
key: DB_USERNAME
|
||
|
|
- name: DB_PASSWORD
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: app-secrets
|
||
|
|
key: DB_PASSWORD
|
||
|
|
- name: REDIS_HOST
|
||
|
|
valueFrom:
|
||
|
|
configMapKeyRef:
|
||
|
|
name: app-config
|
||
|
|
key: REDIS_HOST
|
||
|
|
- name: REDIS_PORT
|
||
|
|
valueFrom:
|
||
|
|
configMapKeyRef:
|
||
|
|
name: app-config
|
||
|
|
key: REDIS_PORT
|
||
|
|
- name: API_KEY
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: app-secrets
|
||
|
|
key: API_KEY
|
||
|
|
- name: JWT_SECRET
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: app-secrets
|
||
|
|
key: JWT_SECRET
|
||
|
|
volumeMounts:
|
||
|
|
- name: app-data
|
||
|
|
mountPath: /app/data
|
||
|
|
- name: config-volume
|
||
|
|
mountPath: /app/config
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
memory: "256Mi"
|
||
|
|
cpu: "250m"
|
||
|
|
limits:
|
||
|
|
memory: "512Mi"
|
||
|
|
cpu: "500m"
|
||
|
|
livenessProbe:
|
||
|
|
httpGet:
|
||
|
|
path: /health
|
||
|
|
port: 8080
|
||
|
|
initialDelaySeconds: 30
|
||
|
|
periodSeconds: 10
|
||
|
|
readinessProbe:
|
||
|
|
httpGet:
|
||
|
|
path: /ready
|
||
|
|
port: 8080
|
||
|
|
initialDelaySeconds: 5
|
||
|
|
periodSeconds: 5
|
||
|
|
securityContext:
|
||
|
|
allowPrivilegeEscalation: false
|
||
|
|
readOnlyRootFilesystem: true
|
||
|
|
capabilities:
|
||
|
|
drop:
|
||
|
|
- ALL
|
||
|
|
volumes:
|
||
|
|
- name: app-data
|
||
|
|
persistentVolumeClaim:
|
||
|
|
claimName: app-data-pvc
|
||
|
|
- name: config-volume
|
||
|
|
configMap:
|
||
|
|
name: app-config
|
||
|
|
---
|
||
|
|
# 10. Services
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: postgres-service
|
||
|
|
namespace: complete-app
|
||
|
|
spec:
|
||
|
|
type: ClusterIP
|
||
|
|
selector:
|
||
|
|
app: postgres
|
||
|
|
ports:
|
||
|
|
- port: 5432
|
||
|
|
targetPort: 5432
|
||
|
|
protocol: TCP
|
||
|
|
---
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: redis-service
|
||
|
|
namespace: complete-app
|
||
|
|
spec:
|
||
|
|
type: ClusterIP
|
||
|
|
selector:
|
||
|
|
app: redis
|
||
|
|
ports:
|
||
|
|
- port: 6379
|
||
|
|
targetPort: 6379
|
||
|
|
protocol: TCP
|
||
|
|
---
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: web-app-service
|
||
|
|
namespace: complete-app
|
||
|
|
spec:
|
||
|
|
type: ClusterIP
|
||
|
|
selector:
|
||
|
|
app: web-app
|
||
|
|
ports:
|
||
|
|
- port: 80
|
||
|
|
targetPort: 80
|
||
|
|
protocol: TCP
|
||
|
|
---
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: api-app-service
|
||
|
|
namespace: complete-app
|
||
|
|
spec:
|
||
|
|
type: ClusterIP
|
||
|
|
selector:
|
||
|
|
app: api-app
|
||
|
|
ports:
|
||
|
|
- port: 8080
|
||
|
|
targetPort: 8080
|
||
|
|
protocol: TCP
|
||
|
|
---
|
||
|
|
# 11. Ingress
|
||
|
|
apiVersion: networking.k8s.io/v1
|
||
|
|
kind: Ingress
|
||
|
|
metadata:
|
||
|
|
name: complete-app-ingress
|
||
|
|
namespace: complete-app
|
||
|
|
annotations:
|
||
|
|
nginx.ingress.kubernetes.io/rewrite-target: /
|
||
|
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||
|
|
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
|
||
|
|
spec:
|
||
|
|
tls:
|
||
|
|
- hosts:
|
||
|
|
- myapp.example.com
|
||
|
|
- api.myapp.example.com
|
||
|
|
secretName: myapp-tls
|
||
|
|
rules:
|
||
|
|
- host: myapp.example.com
|
||
|
|
http:
|
||
|
|
paths:
|
||
|
|
- path: /
|
||
|
|
pathType: Prefix
|
||
|
|
backend:
|
||
|
|
service:
|
||
|
|
name: web-app-service
|
||
|
|
port:
|
||
|
|
number: 80
|
||
|
|
- host: api.myapp.example.com
|
||
|
|
http:
|
||
|
|
paths:
|
||
|
|
- path: /
|
||
|
|
pathType: Prefix
|
||
|
|
backend:
|
||
|
|
service:
|
||
|
|
name: api-app-service
|
||
|
|
port:
|
||
|
|
number: 8080
|