# 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