378 lines
8.9 KiB
Markdown
378 lines
8.9 KiB
Markdown
|
|
# Kubernetes Workloads
|
||
|
|
|
||
|
|
## Deployment Pattern
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: apps/v1
|
||
|
|
kind: Deployment
|
||
|
|
metadata:
|
||
|
|
name: web-app
|
||
|
|
namespace: production
|
||
|
|
labels:
|
||
|
|
app: web-app
|
||
|
|
tier: frontend
|
||
|
|
spec:
|
||
|
|
replicas: 3
|
||
|
|
revisionHistoryLimit: 10
|
||
|
|
strategy:
|
||
|
|
type: RollingUpdate
|
||
|
|
rollingUpdate:
|
||
|
|
maxSurge: 1
|
||
|
|
maxUnavailable: 0
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app: web-app
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: web-app
|
||
|
|
tier: frontend
|
||
|
|
version: v1.2.0
|
||
|
|
annotations:
|
||
|
|
prometheus.io/scrape: "true"
|
||
|
|
prometheus.io/port: "8080"
|
||
|
|
spec:
|
||
|
|
serviceAccountName: web-app-sa
|
||
|
|
securityContext:
|
||
|
|
runAsNonRoot: true
|
||
|
|
runAsUser: 1000
|
||
|
|
fsGroup: 2000
|
||
|
|
containers:
|
||
|
|
- name: app
|
||
|
|
image: myregistry.io/web-app:v1.2.0
|
||
|
|
imagePullPolicy: IfNotPresent
|
||
|
|
ports:
|
||
|
|
- name: http
|
||
|
|
containerPort: 8080
|
||
|
|
protocol: TCP
|
||
|
|
env:
|
||
|
|
- name: ENVIRONMENT
|
||
|
|
value: production
|
||
|
|
- name: DB_HOST
|
||
|
|
valueFrom:
|
||
|
|
configMapKeyRef:
|
||
|
|
name: app-config
|
||
|
|
key: database.host
|
||
|
|
- name: DB_PASSWORD
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: app-secrets
|
||
|
|
key: db-password
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
cpu: 100m
|
||
|
|
memory: 128Mi
|
||
|
|
limits:
|
||
|
|
cpu: 500m
|
||
|
|
memory: 512Mi
|
||
|
|
livenessProbe:
|
||
|
|
httpGet:
|
||
|
|
path: /health
|
||
|
|
port: http
|
||
|
|
initialDelaySeconds: 30
|
||
|
|
periodSeconds: 10
|
||
|
|
timeoutSeconds: 5
|
||
|
|
failureThreshold: 3
|
||
|
|
readinessProbe:
|
||
|
|
httpGet:
|
||
|
|
path: /ready
|
||
|
|
port: http
|
||
|
|
initialDelaySeconds: 10
|
||
|
|
periodSeconds: 5
|
||
|
|
timeoutSeconds: 3
|
||
|
|
failureThreshold: 2
|
||
|
|
volumeMounts:
|
||
|
|
- name: config
|
||
|
|
mountPath: /etc/config
|
||
|
|
readOnly: true
|
||
|
|
- name: cache
|
||
|
|
mountPath: /var/cache
|
||
|
|
volumes:
|
||
|
|
- name: config
|
||
|
|
configMap:
|
||
|
|
name: app-config
|
||
|
|
- name: cache
|
||
|
|
emptyDir: {}
|
||
|
|
```
|
||
|
|
|
||
|
|
## StatefulSet Pattern
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: apps/v1
|
||
|
|
kind: StatefulSet
|
||
|
|
metadata:
|
||
|
|
name: postgres
|
||
|
|
namespace: database
|
||
|
|
spec:
|
||
|
|
serviceName: postgres-headless
|
||
|
|
replicas: 3
|
||
|
|
podManagementPolicy: OrderedReady
|
||
|
|
updateStrategy:
|
||
|
|
type: RollingUpdate
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app: postgres
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: postgres
|
||
|
|
spec:
|
||
|
|
serviceAccountName: postgres-sa
|
||
|
|
securityContext:
|
||
|
|
runAsUser: 999
|
||
|
|
fsGroup: 999
|
||
|
|
containers:
|
||
|
|
- name: postgres
|
||
|
|
image: postgres:15-alpine
|
||
|
|
ports:
|
||
|
|
- name: postgres
|
||
|
|
containerPort: 5432
|
||
|
|
env:
|
||
|
|
- name: POSTGRES_PASSWORD
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: postgres-secrets
|
||
|
|
key: password
|
||
|
|
- name: PGDATA
|
||
|
|
value: /var/lib/postgresql/data/pgdata
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
cpu: 500m
|
||
|
|
memory: 1Gi
|
||
|
|
limits:
|
||
|
|
cpu: 2000m
|
||
|
|
memory: 4Gi
|
||
|
|
volumeMounts:
|
||
|
|
- name: data
|
||
|
|
mountPath: /var/lib/postgresql/data
|
||
|
|
livenessProbe:
|
||
|
|
exec:
|
||
|
|
command:
|
||
|
|
- pg_isready
|
||
|
|
- -U
|
||
|
|
- postgres
|
||
|
|
initialDelaySeconds: 30
|
||
|
|
periodSeconds: 10
|
||
|
|
readinessProbe:
|
||
|
|
exec:
|
||
|
|
command:
|
||
|
|
- pg_isready
|
||
|
|
- -U
|
||
|
|
- postgres
|
||
|
|
initialDelaySeconds: 10
|
||
|
|
periodSeconds: 5
|
||
|
|
volumeClaimTemplates:
|
||
|
|
- metadata:
|
||
|
|
name: data
|
||
|
|
spec:
|
||
|
|
accessModes: ["ReadWriteOnce"]
|
||
|
|
storageClassName: fast-ssd
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
storage: 50Gi
|
||
|
|
```
|
||
|
|
|
||
|
|
## DaemonSet Pattern
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: apps/v1
|
||
|
|
kind: DaemonSet
|
||
|
|
metadata:
|
||
|
|
name: node-exporter
|
||
|
|
namespace: monitoring
|
||
|
|
spec:
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app: node-exporter
|
||
|
|
updateStrategy:
|
||
|
|
type: RollingUpdate
|
||
|
|
rollingUpdate:
|
||
|
|
maxUnavailable: 1
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: node-exporter
|
||
|
|
spec:
|
||
|
|
hostNetwork: true
|
||
|
|
hostPID: true
|
||
|
|
serviceAccountName: node-exporter-sa
|
||
|
|
tolerations:
|
||
|
|
- effect: NoSchedule
|
||
|
|
operator: Exists
|
||
|
|
containers:
|
||
|
|
- name: node-exporter
|
||
|
|
image: prom/node-exporter:latest
|
||
|
|
args:
|
||
|
|
- --path.procfs=/host/proc
|
||
|
|
- --path.sysfs=/host/sys
|
||
|
|
- --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)
|
||
|
|
ports:
|
||
|
|
- name: metrics
|
||
|
|
containerPort: 9100
|
||
|
|
protocol: TCP
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
cpu: 50m
|
||
|
|
memory: 64Mi
|
||
|
|
limits:
|
||
|
|
cpu: 200m
|
||
|
|
memory: 128Mi
|
||
|
|
volumeMounts:
|
||
|
|
- name: proc
|
||
|
|
mountPath: /host/proc
|
||
|
|
readOnly: true
|
||
|
|
- name: sys
|
||
|
|
mountPath: /host/sys
|
||
|
|
readOnly: true
|
||
|
|
volumes:
|
||
|
|
- name: proc
|
||
|
|
hostPath:
|
||
|
|
path: /proc
|
||
|
|
- name: sys
|
||
|
|
hostPath:
|
||
|
|
path: /sys
|
||
|
|
```
|
||
|
|
|
||
|
|
## Job Pattern
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: batch/v1
|
||
|
|
kind: Job
|
||
|
|
metadata:
|
||
|
|
name: db-migration-20231214
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
backoffLimit: 3
|
||
|
|
ttlSecondsAfterFinished: 3600
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: db-migration
|
||
|
|
spec:
|
||
|
|
restartPolicy: OnFailure
|
||
|
|
serviceAccountName: migration-sa
|
||
|
|
containers:
|
||
|
|
- name: migrate
|
||
|
|
image: myregistry.io/migrations:v1.2.0
|
||
|
|
command: ["/bin/sh", "-c"]
|
||
|
|
args:
|
||
|
|
- |
|
||
|
|
echo "Starting migration..."
|
||
|
|
/app/migrate up
|
||
|
|
echo "Migration complete"
|
||
|
|
env:
|
||
|
|
- name: DATABASE_URL
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: db-secrets
|
||
|
|
key: connection-string
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
cpu: 100m
|
||
|
|
memory: 128Mi
|
||
|
|
limits:
|
||
|
|
cpu: 500m
|
||
|
|
memory: 512Mi
|
||
|
|
```
|
||
|
|
|
||
|
|
## CronJob Pattern
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: batch/v1
|
||
|
|
kind: CronJob
|
||
|
|
metadata:
|
||
|
|
name: backup-database
|
||
|
|
namespace: production
|
||
|
|
spec:
|
||
|
|
schedule: "0 2 * * *" # Daily at 2 AM
|
||
|
|
timeZone: "America/New_York"
|
||
|
|
successfulJobsHistoryLimit: 3
|
||
|
|
failedJobsHistoryLimit: 1
|
||
|
|
concurrencyPolicy: Forbid
|
||
|
|
jobTemplate:
|
||
|
|
spec:
|
||
|
|
backoffLimit: 2
|
||
|
|
ttlSecondsAfterFinished: 86400
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: backup
|
||
|
|
spec:
|
||
|
|
restartPolicy: OnFailure
|
||
|
|
serviceAccountName: backup-sa
|
||
|
|
containers:
|
||
|
|
- name: backup
|
||
|
|
image: myregistry.io/backup-tool:latest
|
||
|
|
command: ["/usr/local/bin/backup.sh"]
|
||
|
|
env:
|
||
|
|
- name: S3_BUCKET
|
||
|
|
valueFrom:
|
||
|
|
configMapKeyRef:
|
||
|
|
name: backup-config
|
||
|
|
key: s3-bucket
|
||
|
|
- name: AWS_ACCESS_KEY_ID
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: backup-secrets
|
||
|
|
key: aws-access-key
|
||
|
|
- name: AWS_SECRET_ACCESS_KEY
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: backup-secrets
|
||
|
|
key: aws-secret-key
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
cpu: 200m
|
||
|
|
memory: 256Mi
|
||
|
|
limits:
|
||
|
|
cpu: 1000m
|
||
|
|
memory: 1Gi
|
||
|
|
volumeMounts:
|
||
|
|
- name: backup-volume
|
||
|
|
mountPath: /backup
|
||
|
|
volumes:
|
||
|
|
- name: backup-volume
|
||
|
|
emptyDir:
|
||
|
|
sizeLimit: 10Gi
|
||
|
|
```
|
||
|
|
|
||
|
|
## Init Containers
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
spec:
|
||
|
|
initContainers:
|
||
|
|
- name: wait-for-db
|
||
|
|
image: busybox:latest
|
||
|
|
command: ['sh', '-c']
|
||
|
|
args:
|
||
|
|
- |
|
||
|
|
until nc -z postgres-service 5432; do
|
||
|
|
echo "Waiting for database..."
|
||
|
|
sleep 2
|
||
|
|
done
|
||
|
|
echo "Database is ready"
|
||
|
|
- name: migrate-schema
|
||
|
|
image: myregistry.io/migrations:latest
|
||
|
|
command: ["/app/migrate", "up"]
|
||
|
|
env:
|
||
|
|
- name: DATABASE_URL
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: db-secrets
|
||
|
|
key: url
|
||
|
|
containers:
|
||
|
|
- name: app
|
||
|
|
image: myregistry.io/app:latest
|
||
|
|
```
|
||
|
|
|
||
|
|
## Best Practices
|
||
|
|
|
||
|
|
1. **Resource Management**: Always set requests and limits
|
||
|
|
2. **Health Checks**: Include both liveness and readiness probes
|
||
|
|
3. **Security**: Use non-root users, read-only filesystems when possible
|
||
|
|
4. **Labels**: Consistent labeling for organization and selection
|
||
|
|
5. **Update Strategy**: Choose appropriate strategy (RollingUpdate, Recreate)
|
||
|
|
6. **Service Accounts**: Never use default, create specific SAs
|
||
|
|
7. **Image Tags**: Use specific versions, not `latest` in production
|
||
|
|
8. **Cleanup**: Set TTL for Jobs to auto-cleanup completed pods
|