specweave 0.3.13 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +17 -1
- package/README.md +1 -1
- package/bin/install-all.sh +9 -2
- package/bin/install-hooks.sh +57 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +55 -0
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/core/agent-model-manager.d.ts +52 -0
- package/dist/core/agent-model-manager.d.ts.map +1 -0
- package/dist/core/agent-model-manager.js +120 -0
- package/dist/core/agent-model-manager.js.map +1 -0
- package/dist/core/cost-tracker.d.ts +108 -0
- package/dist/core/cost-tracker.d.ts.map +1 -0
- package/dist/core/cost-tracker.js +281 -0
- package/dist/core/cost-tracker.js.map +1 -0
- package/dist/core/model-selector.d.ts +57 -0
- package/dist/core/model-selector.d.ts.map +1 -0
- package/dist/core/model-selector.js +115 -0
- package/dist/core/model-selector.js.map +1 -0
- package/dist/core/phase-detector.d.ts +62 -0
- package/dist/core/phase-detector.d.ts.map +1 -0
- package/dist/core/phase-detector.js +229 -0
- package/dist/core/phase-detector.js.map +1 -0
- package/dist/types/cost-tracking.d.ts +43 -0
- package/dist/types/cost-tracking.d.ts.map +1 -0
- package/dist/types/cost-tracking.js +8 -0
- package/dist/types/cost-tracking.js.map +1 -0
- package/dist/types/model-selection.d.ts +53 -0
- package/dist/types/model-selection.d.ts.map +1 -0
- package/dist/types/model-selection.js +12 -0
- package/dist/types/model-selection.js.map +1 -0
- package/dist/utils/cost-reporter.d.ts +58 -0
- package/dist/utils/cost-reporter.d.ts.map +1 -0
- package/dist/utils/cost-reporter.js +224 -0
- package/dist/utils/cost-reporter.js.map +1 -0
- package/dist/utils/pricing-constants.d.ts +70 -0
- package/dist/utils/pricing-constants.d.ts.map +1 -0
- package/dist/utils/pricing-constants.js +71 -0
- package/dist/utils/pricing-constants.js.map +1 -0
- package/package.json +1 -1
- package/src/agents/architect/AGENT.md +3 -0
- package/src/agents/code-reviewer.md +156 -0
- package/src/agents/data-scientist/AGENT.md +181 -0
- package/src/agents/database-optimizer/AGENT.md +147 -0
- package/src/agents/devops/AGENT.md +3 -0
- package/src/agents/diagrams-architect/AGENT.md +3 -0
- package/src/agents/docs-writer/AGENT.md +3 -0
- package/src/agents/kubernetes-architect/AGENT.md +142 -0
- package/src/agents/ml-engineer/AGENT.md +150 -0
- package/src/agents/mlops-engineer/AGENT.md +201 -0
- package/src/agents/network-engineer/AGENT.md +149 -0
- package/src/agents/observability-engineer/AGENT.md +213 -0
- package/src/agents/payment-integration/AGENT.md +35 -0
- package/src/agents/performance/AGENT.md +3 -0
- package/src/agents/performance-engineer/AGENT.md +153 -0
- package/src/agents/pm/AGENT.md +3 -0
- package/src/agents/qa-lead/AGENT.md +3 -0
- package/src/agents/security/AGENT.md +3 -0
- package/src/agents/sre/AGENT.md +3 -0
- package/src/agents/tdd-orchestrator/AGENT.md +169 -0
- package/src/agents/tech-lead/AGENT.md +3 -0
- package/src/commands/specweave.costs.md +261 -0
- package/src/commands/specweave.ml-pipeline.md +292 -0
- package/src/commands/specweave.monitor-setup.md +501 -0
- package/src/commands/specweave.slo-implement.md +1055 -0
- package/src/commands/specweave.sync-github.md +1 -1
- package/src/commands/specweave.tdd-cycle.md +199 -0
- package/src/commands/specweave.tdd-green.md +842 -0
- package/src/commands/specweave.tdd-red.md +135 -0
- package/src/commands/specweave.tdd-refactor.md +165 -0
- package/src/skills/SKILLS-INDEX.md +18 -10
- package/src/skills/billing-automation/SKILL.md +559 -0
- package/src/skills/distributed-tracing/SKILL.md +438 -0
- package/src/skills/e2e-playwright/README.md +1 -1
- package/src/skills/e2e-playwright/package.json +1 -1
- package/src/skills/gitops-workflow/SKILL.md +285 -0
- package/src/skills/gitops-workflow/references/argocd-setup.md +134 -0
- package/src/skills/gitops-workflow/references/sync-policies.md +131 -0
- package/src/skills/grafana-dashboards/SKILL.md +369 -0
- package/src/skills/helm-chart-scaffolding/SKILL.md +544 -0
- package/src/skills/helm-chart-scaffolding/assets/Chart.yaml.template +42 -0
- package/src/skills/helm-chart-scaffolding/assets/values.yaml.template +185 -0
- package/src/skills/helm-chart-scaffolding/references/chart-structure.md +500 -0
- package/src/skills/helm-chart-scaffolding/scripts/validate-chart.sh +244 -0
- package/src/skills/k8s-manifest-generator/SKILL.md +511 -0
- package/src/skills/k8s-manifest-generator/assets/configmap-template.yaml +296 -0
- package/src/skills/k8s-manifest-generator/assets/deployment-template.yaml +203 -0
- package/src/skills/k8s-manifest-generator/assets/service-template.yaml +171 -0
- package/src/skills/k8s-manifest-generator/references/deployment-spec.md +753 -0
- package/src/skills/k8s-manifest-generator/references/service-spec.md +724 -0
- package/src/skills/k8s-security-policies/SKILL.md +334 -0
- package/src/skills/k8s-security-policies/assets/network-policy-template.yaml +177 -0
- package/src/skills/k8s-security-policies/references/rbac-patterns.md +187 -0
- package/src/skills/ml-pipeline-workflow/SKILL.md +245 -0
- package/src/skills/paypal-integration/SKILL.md +467 -0
- package/src/skills/pci-compliance/SKILL.md +466 -0
- package/src/skills/prometheus-configuration/SKILL.md +392 -0
- package/src/skills/slo-implementation/SKILL.md +329 -0
- package/src/skills/stripe-integration/SKILL.md +442 -0
- package/src/skills/tdd-workflow/SKILL.md +378 -0
- package/src/templates/README.md.template +1 -1
- package/src/skills/bmad-method-expert/SKILL.md +0 -626
- package/src/skills/bmad-method-expert/scripts/analyze-project.js +0 -318
- package/src/skills/bmad-method-expert/scripts/check-setup.js +0 -208
- package/src/skills/bmad-method-expert/scripts/generate-template.js +0 -1149
- package/src/skills/bmad-method-expert/scripts/validate-documents.js +0 -340
- package/src/skills/context-optimizer/SKILL.md +0 -588
- package/src/skills/figma-designer/SKILL.md +0 -149
- package/src/skills/figma-implementer/SKILL.md +0 -148
- package/src/skills/figma-mcp-connector/SKILL.md +0 -136
- package/src/skills/figma-to-code/SKILL.md +0 -128
- package/src/skills/spec-kit-expert/SKILL.md +0 -1010
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
# Kubernetes Deployment Specification Reference
|
|
2
|
+
|
|
3
|
+
Comprehensive reference for Kubernetes Deployment resources, covering all key fields, best practices, and common patterns.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
A Deployment provides declarative updates for Pods and ReplicaSets. It manages the desired state of your application, handling rollouts, rollbacks, and scaling operations.
|
|
8
|
+
|
|
9
|
+
## Complete Deployment Specification
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
apiVersion: apps/v1
|
|
13
|
+
kind: Deployment
|
|
14
|
+
metadata:
|
|
15
|
+
name: my-app
|
|
16
|
+
namespace: production
|
|
17
|
+
labels:
|
|
18
|
+
app.kubernetes.io/name: my-app
|
|
19
|
+
app.kubernetes.io/version: "1.0.0"
|
|
20
|
+
app.kubernetes.io/component: backend
|
|
21
|
+
app.kubernetes.io/part-of: my-system
|
|
22
|
+
annotations:
|
|
23
|
+
description: "Main application deployment"
|
|
24
|
+
contact: "backend-team@example.com"
|
|
25
|
+
spec:
|
|
26
|
+
# Replica management
|
|
27
|
+
replicas: 3
|
|
28
|
+
revisionHistoryLimit: 10
|
|
29
|
+
|
|
30
|
+
# Pod selection
|
|
31
|
+
selector:
|
|
32
|
+
matchLabels:
|
|
33
|
+
app: my-app
|
|
34
|
+
version: v1
|
|
35
|
+
|
|
36
|
+
# Update strategy
|
|
37
|
+
strategy:
|
|
38
|
+
type: RollingUpdate
|
|
39
|
+
rollingUpdate:
|
|
40
|
+
maxSurge: 1
|
|
41
|
+
maxUnavailable: 0
|
|
42
|
+
|
|
43
|
+
# Minimum time for pod to be ready
|
|
44
|
+
minReadySeconds: 10
|
|
45
|
+
|
|
46
|
+
# Deployment will fail if it doesn't progress in this time
|
|
47
|
+
progressDeadlineSeconds: 600
|
|
48
|
+
|
|
49
|
+
# Pod template
|
|
50
|
+
template:
|
|
51
|
+
metadata:
|
|
52
|
+
labels:
|
|
53
|
+
app: my-app
|
|
54
|
+
version: v1
|
|
55
|
+
annotations:
|
|
56
|
+
prometheus.io/scrape: "true"
|
|
57
|
+
prometheus.io/port: "9090"
|
|
58
|
+
spec:
|
|
59
|
+
# Service account for RBAC
|
|
60
|
+
serviceAccountName: my-app
|
|
61
|
+
|
|
62
|
+
# Security context for the pod
|
|
63
|
+
securityContext:
|
|
64
|
+
runAsNonRoot: true
|
|
65
|
+
runAsUser: 1000
|
|
66
|
+
fsGroup: 1000
|
|
67
|
+
seccompProfile:
|
|
68
|
+
type: RuntimeDefault
|
|
69
|
+
|
|
70
|
+
# Init containers run before main containers
|
|
71
|
+
initContainers:
|
|
72
|
+
- name: init-db
|
|
73
|
+
image: busybox:1.36
|
|
74
|
+
command: ['sh', '-c', 'until nc -z db-service 5432; do sleep 1; done']
|
|
75
|
+
securityContext:
|
|
76
|
+
allowPrivilegeEscalation: false
|
|
77
|
+
runAsNonRoot: true
|
|
78
|
+
runAsUser: 1000
|
|
79
|
+
|
|
80
|
+
# Main containers
|
|
81
|
+
containers:
|
|
82
|
+
- name: app
|
|
83
|
+
image: myapp:1.0.0
|
|
84
|
+
imagePullPolicy: IfNotPresent
|
|
85
|
+
|
|
86
|
+
# Container ports
|
|
87
|
+
ports:
|
|
88
|
+
- name: http
|
|
89
|
+
containerPort: 8080
|
|
90
|
+
protocol: TCP
|
|
91
|
+
- name: metrics
|
|
92
|
+
containerPort: 9090
|
|
93
|
+
protocol: TCP
|
|
94
|
+
|
|
95
|
+
# Environment variables
|
|
96
|
+
env:
|
|
97
|
+
- name: POD_NAME
|
|
98
|
+
valueFrom:
|
|
99
|
+
fieldRef:
|
|
100
|
+
fieldPath: metadata.name
|
|
101
|
+
- name: POD_NAMESPACE
|
|
102
|
+
valueFrom:
|
|
103
|
+
fieldRef:
|
|
104
|
+
fieldPath: metadata.namespace
|
|
105
|
+
- name: DATABASE_URL
|
|
106
|
+
valueFrom:
|
|
107
|
+
secretKeyRef:
|
|
108
|
+
name: db-credentials
|
|
109
|
+
key: url
|
|
110
|
+
|
|
111
|
+
# ConfigMap and Secret references
|
|
112
|
+
envFrom:
|
|
113
|
+
- configMapRef:
|
|
114
|
+
name: app-config
|
|
115
|
+
- secretRef:
|
|
116
|
+
name: app-secrets
|
|
117
|
+
|
|
118
|
+
# Resource requests and limits
|
|
119
|
+
resources:
|
|
120
|
+
requests:
|
|
121
|
+
memory: "256Mi"
|
|
122
|
+
cpu: "250m"
|
|
123
|
+
limits:
|
|
124
|
+
memory: "512Mi"
|
|
125
|
+
cpu: "500m"
|
|
126
|
+
|
|
127
|
+
# Liveness probe
|
|
128
|
+
livenessProbe:
|
|
129
|
+
httpGet:
|
|
130
|
+
path: /health/live
|
|
131
|
+
port: http
|
|
132
|
+
httpHeaders:
|
|
133
|
+
- name: Custom-Header
|
|
134
|
+
value: Awesome
|
|
135
|
+
initialDelaySeconds: 30
|
|
136
|
+
periodSeconds: 10
|
|
137
|
+
timeoutSeconds: 5
|
|
138
|
+
successThreshold: 1
|
|
139
|
+
failureThreshold: 3
|
|
140
|
+
|
|
141
|
+
# Readiness probe
|
|
142
|
+
readinessProbe:
|
|
143
|
+
httpGet:
|
|
144
|
+
path: /health/ready
|
|
145
|
+
port: http
|
|
146
|
+
initialDelaySeconds: 5
|
|
147
|
+
periodSeconds: 5
|
|
148
|
+
timeoutSeconds: 3
|
|
149
|
+
successThreshold: 1
|
|
150
|
+
failureThreshold: 3
|
|
151
|
+
|
|
152
|
+
# Startup probe (for slow-starting containers)
|
|
153
|
+
startupProbe:
|
|
154
|
+
httpGet:
|
|
155
|
+
path: /health/startup
|
|
156
|
+
port: http
|
|
157
|
+
initialDelaySeconds: 0
|
|
158
|
+
periodSeconds: 10
|
|
159
|
+
timeoutSeconds: 3
|
|
160
|
+
successThreshold: 1
|
|
161
|
+
failureThreshold: 30
|
|
162
|
+
|
|
163
|
+
# Volume mounts
|
|
164
|
+
volumeMounts:
|
|
165
|
+
- name: data
|
|
166
|
+
mountPath: /var/lib/app
|
|
167
|
+
- name: config
|
|
168
|
+
mountPath: /etc/app
|
|
169
|
+
readOnly: true
|
|
170
|
+
- name: tmp
|
|
171
|
+
mountPath: /tmp
|
|
172
|
+
|
|
173
|
+
# Security context for container
|
|
174
|
+
securityContext:
|
|
175
|
+
allowPrivilegeEscalation: false
|
|
176
|
+
readOnlyRootFilesystem: true
|
|
177
|
+
runAsNonRoot: true
|
|
178
|
+
runAsUser: 1000
|
|
179
|
+
capabilities:
|
|
180
|
+
drop:
|
|
181
|
+
- ALL
|
|
182
|
+
|
|
183
|
+
# Lifecycle hooks
|
|
184
|
+
lifecycle:
|
|
185
|
+
postStart:
|
|
186
|
+
exec:
|
|
187
|
+
command: ["/bin/sh", "-c", "echo Container started > /tmp/started"]
|
|
188
|
+
preStop:
|
|
189
|
+
exec:
|
|
190
|
+
command: ["/bin/sh", "-c", "sleep 15"]
|
|
191
|
+
|
|
192
|
+
# Volumes
|
|
193
|
+
volumes:
|
|
194
|
+
- name: data
|
|
195
|
+
persistentVolumeClaim:
|
|
196
|
+
claimName: app-data
|
|
197
|
+
- name: config
|
|
198
|
+
configMap:
|
|
199
|
+
name: app-config
|
|
200
|
+
- name: tmp
|
|
201
|
+
emptyDir: {}
|
|
202
|
+
|
|
203
|
+
# DNS configuration
|
|
204
|
+
dnsPolicy: ClusterFirst
|
|
205
|
+
dnsConfig:
|
|
206
|
+
options:
|
|
207
|
+
- name: ndots
|
|
208
|
+
value: "2"
|
|
209
|
+
|
|
210
|
+
# Scheduling
|
|
211
|
+
nodeSelector:
|
|
212
|
+
disktype: ssd
|
|
213
|
+
|
|
214
|
+
affinity:
|
|
215
|
+
podAntiAffinity:
|
|
216
|
+
preferredDuringSchedulingIgnoredDuringExecution:
|
|
217
|
+
- weight: 100
|
|
218
|
+
podAffinityTerm:
|
|
219
|
+
labelSelector:
|
|
220
|
+
matchExpressions:
|
|
221
|
+
- key: app
|
|
222
|
+
operator: In
|
|
223
|
+
values:
|
|
224
|
+
- my-app
|
|
225
|
+
topologyKey: kubernetes.io/hostname
|
|
226
|
+
|
|
227
|
+
tolerations:
|
|
228
|
+
- key: "app"
|
|
229
|
+
operator: "Equal"
|
|
230
|
+
value: "my-app"
|
|
231
|
+
effect: "NoSchedule"
|
|
232
|
+
|
|
233
|
+
# Termination
|
|
234
|
+
terminationGracePeriodSeconds: 30
|
|
235
|
+
|
|
236
|
+
# Image pull secrets
|
|
237
|
+
imagePullSecrets:
|
|
238
|
+
- name: regcred
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Field Reference
|
|
242
|
+
|
|
243
|
+
### Metadata Fields
|
|
244
|
+
|
|
245
|
+
#### Required Fields
|
|
246
|
+
- `apiVersion`: `apps/v1` (current stable version)
|
|
247
|
+
- `kind`: `Deployment`
|
|
248
|
+
- `metadata.name`: Unique name within namespace
|
|
249
|
+
|
|
250
|
+
#### Recommended Metadata
|
|
251
|
+
- `metadata.namespace`: Target namespace (defaults to `default`)
|
|
252
|
+
- `metadata.labels`: Key-value pairs for organization
|
|
253
|
+
- `metadata.annotations`: Non-identifying metadata
|
|
254
|
+
|
|
255
|
+
### Spec Fields
|
|
256
|
+
|
|
257
|
+
#### Replica Management
|
|
258
|
+
|
|
259
|
+
**`replicas`** (integer, default: 1)
|
|
260
|
+
- Number of desired pod instances
|
|
261
|
+
- Best practice: Use 3+ for production high availability
|
|
262
|
+
- Can be scaled manually or via HorizontalPodAutoscaler
|
|
263
|
+
|
|
264
|
+
**`revisionHistoryLimit`** (integer, default: 10)
|
|
265
|
+
- Number of old ReplicaSets to retain for rollback
|
|
266
|
+
- Set to 0 to disable rollback capability
|
|
267
|
+
- Reduces storage overhead for long-running deployments
|
|
268
|
+
|
|
269
|
+
#### Update Strategy
|
|
270
|
+
|
|
271
|
+
**`strategy.type`** (string)
|
|
272
|
+
- `RollingUpdate` (default): Gradual pod replacement
|
|
273
|
+
- `Recreate`: Delete all pods before creating new ones
|
|
274
|
+
|
|
275
|
+
**`strategy.rollingUpdate.maxSurge`** (int or percent, default: 25%)
|
|
276
|
+
- Maximum pods above desired replicas during update
|
|
277
|
+
- Example: With 3 replicas and maxSurge=1, up to 4 pods during update
|
|
278
|
+
|
|
279
|
+
**`strategy.rollingUpdate.maxUnavailable`** (int or percent, default: 25%)
|
|
280
|
+
- Maximum pods below desired replicas during update
|
|
281
|
+
- Set to 0 for zero-downtime deployments
|
|
282
|
+
- Cannot be 0 if maxSurge is 0
|
|
283
|
+
|
|
284
|
+
**Best practices:**
|
|
285
|
+
```yaml
|
|
286
|
+
# Zero-downtime deployment
|
|
287
|
+
strategy:
|
|
288
|
+
type: RollingUpdate
|
|
289
|
+
rollingUpdate:
|
|
290
|
+
maxSurge: 1
|
|
291
|
+
maxUnavailable: 0
|
|
292
|
+
|
|
293
|
+
# Fast deployment (can have brief downtime)
|
|
294
|
+
strategy:
|
|
295
|
+
type: RollingUpdate
|
|
296
|
+
rollingUpdate:
|
|
297
|
+
maxSurge: 2
|
|
298
|
+
maxUnavailable: 1
|
|
299
|
+
|
|
300
|
+
# Complete replacement
|
|
301
|
+
strategy:
|
|
302
|
+
type: Recreate
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
#### Pod Template
|
|
306
|
+
|
|
307
|
+
**`template.metadata.labels`**
|
|
308
|
+
- Must include labels matching `spec.selector.matchLabels`
|
|
309
|
+
- Add version labels for blue/green deployments
|
|
310
|
+
- Include standard Kubernetes labels
|
|
311
|
+
|
|
312
|
+
**`template.spec.containers`** (required)
|
|
313
|
+
- Array of container specifications
|
|
314
|
+
- At least one container required
|
|
315
|
+
- Each container needs unique name
|
|
316
|
+
|
|
317
|
+
#### Container Configuration
|
|
318
|
+
|
|
319
|
+
**Image Management:**
|
|
320
|
+
```yaml
|
|
321
|
+
containers:
|
|
322
|
+
- name: app
|
|
323
|
+
image: registry.example.com/myapp:1.0.0
|
|
324
|
+
imagePullPolicy: IfNotPresent # or Always, Never
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Image pull policies:
|
|
328
|
+
- `IfNotPresent`: Pull if not cached (default for tagged images)
|
|
329
|
+
- `Always`: Always pull (default for :latest)
|
|
330
|
+
- `Never`: Never pull, fail if not cached
|
|
331
|
+
|
|
332
|
+
**Port Declarations:**
|
|
333
|
+
```yaml
|
|
334
|
+
ports:
|
|
335
|
+
- name: http # Named for referencing in Service
|
|
336
|
+
containerPort: 8080
|
|
337
|
+
protocol: TCP # TCP (default), UDP, or SCTP
|
|
338
|
+
hostPort: 8080 # Optional: Bind to host port (rarely used)
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
#### Resource Management
|
|
342
|
+
|
|
343
|
+
**Requests vs Limits:**
|
|
344
|
+
|
|
345
|
+
```yaml
|
|
346
|
+
resources:
|
|
347
|
+
requests:
|
|
348
|
+
memory: "256Mi" # Guaranteed resources
|
|
349
|
+
cpu: "250m" # 0.25 CPU cores
|
|
350
|
+
limits:
|
|
351
|
+
memory: "512Mi" # Maximum allowed
|
|
352
|
+
cpu: "500m" # 0.5 CPU cores
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**QoS Classes (determined automatically):**
|
|
356
|
+
|
|
357
|
+
1. **Guaranteed**: requests = limits for all containers
|
|
358
|
+
- Highest priority
|
|
359
|
+
- Last to be evicted
|
|
360
|
+
|
|
361
|
+
2. **Burstable**: requests < limits or only requests set
|
|
362
|
+
- Medium priority
|
|
363
|
+
- Evicted before Guaranteed
|
|
364
|
+
|
|
365
|
+
3. **BestEffort**: No requests or limits set
|
|
366
|
+
- Lowest priority
|
|
367
|
+
- First to be evicted
|
|
368
|
+
|
|
369
|
+
**Best practices:**
|
|
370
|
+
- Always set requests in production
|
|
371
|
+
- Set limits to prevent resource monopolization
|
|
372
|
+
- Memory limits should be 1.5-2x requests
|
|
373
|
+
- CPU limits can be higher for bursty workloads
|
|
374
|
+
|
|
375
|
+
#### Health Checks
|
|
376
|
+
|
|
377
|
+
**Probe Types:**
|
|
378
|
+
|
|
379
|
+
1. **startupProbe** - For slow-starting applications
|
|
380
|
+
```yaml
|
|
381
|
+
startupProbe:
|
|
382
|
+
httpGet:
|
|
383
|
+
path: /health/startup
|
|
384
|
+
port: 8080
|
|
385
|
+
initialDelaySeconds: 0
|
|
386
|
+
periodSeconds: 10
|
|
387
|
+
failureThreshold: 30 # 5 minutes to start (10s * 30)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
2. **livenessProbe** - Restarts unhealthy containers
|
|
391
|
+
```yaml
|
|
392
|
+
livenessProbe:
|
|
393
|
+
httpGet:
|
|
394
|
+
path: /health/live
|
|
395
|
+
port: 8080
|
|
396
|
+
initialDelaySeconds: 30
|
|
397
|
+
periodSeconds: 10
|
|
398
|
+
timeoutSeconds: 5
|
|
399
|
+
failureThreshold: 3 # Restart after 3 failures
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
3. **readinessProbe** - Controls traffic routing
|
|
403
|
+
```yaml
|
|
404
|
+
readinessProbe:
|
|
405
|
+
httpGet:
|
|
406
|
+
path: /health/ready
|
|
407
|
+
port: 8080
|
|
408
|
+
initialDelaySeconds: 5
|
|
409
|
+
periodSeconds: 5
|
|
410
|
+
failureThreshold: 3 # Remove from service after 3 failures
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
**Probe Mechanisms:**
|
|
414
|
+
|
|
415
|
+
```yaml
|
|
416
|
+
# HTTP GET
|
|
417
|
+
httpGet:
|
|
418
|
+
path: /health
|
|
419
|
+
port: 8080
|
|
420
|
+
httpHeaders:
|
|
421
|
+
- name: Authorization
|
|
422
|
+
value: Bearer token
|
|
423
|
+
|
|
424
|
+
# TCP Socket
|
|
425
|
+
tcpSocket:
|
|
426
|
+
port: 3306
|
|
427
|
+
|
|
428
|
+
# Command execution
|
|
429
|
+
exec:
|
|
430
|
+
command:
|
|
431
|
+
- cat
|
|
432
|
+
- /tmp/healthy
|
|
433
|
+
|
|
434
|
+
# gRPC (Kubernetes 1.24+)
|
|
435
|
+
grpc:
|
|
436
|
+
port: 9090
|
|
437
|
+
service: my.service.health.v1.Health
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
**Probe Timing Parameters:**
|
|
441
|
+
|
|
442
|
+
- `initialDelaySeconds`: Wait before first probe
|
|
443
|
+
- `periodSeconds`: How often to probe
|
|
444
|
+
- `timeoutSeconds`: Probe timeout
|
|
445
|
+
- `successThreshold`: Successes needed to mark healthy (1 for liveness/startup)
|
|
446
|
+
- `failureThreshold`: Failures before taking action
|
|
447
|
+
|
|
448
|
+
#### Security Context
|
|
449
|
+
|
|
450
|
+
**Pod-level security context:**
|
|
451
|
+
```yaml
|
|
452
|
+
spec:
|
|
453
|
+
securityContext:
|
|
454
|
+
runAsNonRoot: true
|
|
455
|
+
runAsUser: 1000
|
|
456
|
+
runAsGroup: 1000
|
|
457
|
+
fsGroup: 1000
|
|
458
|
+
fsGroupChangePolicy: OnRootMismatch
|
|
459
|
+
seccompProfile:
|
|
460
|
+
type: RuntimeDefault
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
**Container-level security context:**
|
|
464
|
+
```yaml
|
|
465
|
+
containers:
|
|
466
|
+
- name: app
|
|
467
|
+
securityContext:
|
|
468
|
+
allowPrivilegeEscalation: false
|
|
469
|
+
readOnlyRootFilesystem: true
|
|
470
|
+
runAsNonRoot: true
|
|
471
|
+
runAsUser: 1000
|
|
472
|
+
capabilities:
|
|
473
|
+
drop:
|
|
474
|
+
- ALL
|
|
475
|
+
add:
|
|
476
|
+
- NET_BIND_SERVICE # Only if needed
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
**Security best practices:**
|
|
480
|
+
- Always run as non-root (`runAsNonRoot: true`)
|
|
481
|
+
- Drop all capabilities and add only needed ones
|
|
482
|
+
- Use read-only root filesystem when possible
|
|
483
|
+
- Enable seccomp profile
|
|
484
|
+
- Disable privilege escalation
|
|
485
|
+
|
|
486
|
+
#### Volumes
|
|
487
|
+
|
|
488
|
+
**Volume Types:**
|
|
489
|
+
|
|
490
|
+
```yaml
|
|
491
|
+
volumes:
|
|
492
|
+
# PersistentVolumeClaim
|
|
493
|
+
- name: data
|
|
494
|
+
persistentVolumeClaim:
|
|
495
|
+
claimName: app-data
|
|
496
|
+
|
|
497
|
+
# ConfigMap
|
|
498
|
+
- name: config
|
|
499
|
+
configMap:
|
|
500
|
+
name: app-config
|
|
501
|
+
items:
|
|
502
|
+
- key: app.properties
|
|
503
|
+
path: application.properties
|
|
504
|
+
|
|
505
|
+
# Secret
|
|
506
|
+
- name: secrets
|
|
507
|
+
secret:
|
|
508
|
+
secretName: app-secrets
|
|
509
|
+
defaultMode: 0400
|
|
510
|
+
|
|
511
|
+
# EmptyDir (ephemeral)
|
|
512
|
+
- name: cache
|
|
513
|
+
emptyDir:
|
|
514
|
+
sizeLimit: 1Gi
|
|
515
|
+
|
|
516
|
+
# HostPath (avoid in production)
|
|
517
|
+
- name: host-data
|
|
518
|
+
hostPath:
|
|
519
|
+
path: /data
|
|
520
|
+
type: DirectoryOrCreate
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
#### Scheduling
|
|
524
|
+
|
|
525
|
+
**Node Selection:**
|
|
526
|
+
|
|
527
|
+
```yaml
|
|
528
|
+
# Simple node selector
|
|
529
|
+
nodeSelector:
|
|
530
|
+
disktype: ssd
|
|
531
|
+
zone: us-west-1a
|
|
532
|
+
|
|
533
|
+
# Node affinity (more expressive)
|
|
534
|
+
affinity:
|
|
535
|
+
nodeAffinity:
|
|
536
|
+
requiredDuringSchedulingIgnoredDuringExecution:
|
|
537
|
+
nodeSelectorTerms:
|
|
538
|
+
- matchExpressions:
|
|
539
|
+
- key: kubernetes.io/arch
|
|
540
|
+
operator: In
|
|
541
|
+
values:
|
|
542
|
+
- amd64
|
|
543
|
+
- arm64
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Pod Affinity/Anti-Affinity:**
|
|
547
|
+
|
|
548
|
+
```yaml
|
|
549
|
+
# Spread pods across nodes
|
|
550
|
+
affinity:
|
|
551
|
+
podAntiAffinity:
|
|
552
|
+
requiredDuringSchedulingIgnoredDuringExecution:
|
|
553
|
+
- labelSelector:
|
|
554
|
+
matchLabels:
|
|
555
|
+
app: my-app
|
|
556
|
+
topologyKey: kubernetes.io/hostname
|
|
557
|
+
|
|
558
|
+
# Co-locate with database
|
|
559
|
+
affinity:
|
|
560
|
+
podAffinity:
|
|
561
|
+
preferredDuringSchedulingIgnoredDuringExecution:
|
|
562
|
+
- weight: 100
|
|
563
|
+
podAffinityTerm:
|
|
564
|
+
labelSelector:
|
|
565
|
+
matchLabels:
|
|
566
|
+
app: database
|
|
567
|
+
topologyKey: kubernetes.io/hostname
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
**Tolerations:**
|
|
571
|
+
|
|
572
|
+
```yaml
|
|
573
|
+
tolerations:
|
|
574
|
+
- key: "node.kubernetes.io/unreachable"
|
|
575
|
+
operator: "Exists"
|
|
576
|
+
effect: "NoExecute"
|
|
577
|
+
tolerationSeconds: 30
|
|
578
|
+
- key: "dedicated"
|
|
579
|
+
operator: "Equal"
|
|
580
|
+
value: "database"
|
|
581
|
+
effect: "NoSchedule"
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
## Common Patterns
|
|
585
|
+
|
|
586
|
+
### High Availability Deployment
|
|
587
|
+
|
|
588
|
+
```yaml
|
|
589
|
+
spec:
|
|
590
|
+
replicas: 3
|
|
591
|
+
strategy:
|
|
592
|
+
type: RollingUpdate
|
|
593
|
+
rollingUpdate:
|
|
594
|
+
maxSurge: 1
|
|
595
|
+
maxUnavailable: 0
|
|
596
|
+
template:
|
|
597
|
+
spec:
|
|
598
|
+
affinity:
|
|
599
|
+
podAntiAffinity:
|
|
600
|
+
requiredDuringSchedulingIgnoredDuringExecution:
|
|
601
|
+
- labelSelector:
|
|
602
|
+
matchLabels:
|
|
603
|
+
app: my-app
|
|
604
|
+
topologyKey: kubernetes.io/hostname
|
|
605
|
+
topologySpreadConstraints:
|
|
606
|
+
- maxSkew: 1
|
|
607
|
+
topologyKey: topology.kubernetes.io/zone
|
|
608
|
+
whenUnsatisfiable: DoNotSchedule
|
|
609
|
+
labelSelector:
|
|
610
|
+
matchLabels:
|
|
611
|
+
app: my-app
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Sidecar Container Pattern
|
|
615
|
+
|
|
616
|
+
```yaml
|
|
617
|
+
spec:
|
|
618
|
+
template:
|
|
619
|
+
spec:
|
|
620
|
+
containers:
|
|
621
|
+
- name: app
|
|
622
|
+
image: myapp:1.0.0
|
|
623
|
+
volumeMounts:
|
|
624
|
+
- name: shared-logs
|
|
625
|
+
mountPath: /var/log
|
|
626
|
+
- name: log-forwarder
|
|
627
|
+
image: fluent-bit:2.0
|
|
628
|
+
volumeMounts:
|
|
629
|
+
- name: shared-logs
|
|
630
|
+
mountPath: /var/log
|
|
631
|
+
readOnly: true
|
|
632
|
+
volumes:
|
|
633
|
+
- name: shared-logs
|
|
634
|
+
emptyDir: {}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### Init Container for Dependencies
|
|
638
|
+
|
|
639
|
+
```yaml
|
|
640
|
+
spec:
|
|
641
|
+
template:
|
|
642
|
+
spec:
|
|
643
|
+
initContainers:
|
|
644
|
+
- name: wait-for-db
|
|
645
|
+
image: busybox:1.36
|
|
646
|
+
command:
|
|
647
|
+
- sh
|
|
648
|
+
- -c
|
|
649
|
+
- |
|
|
650
|
+
until nc -z database-service 5432; do
|
|
651
|
+
echo "Waiting for database..."
|
|
652
|
+
sleep 2
|
|
653
|
+
done
|
|
654
|
+
- name: run-migrations
|
|
655
|
+
image: myapp:1.0.0
|
|
656
|
+
command: ["./migrate", "up"]
|
|
657
|
+
env:
|
|
658
|
+
- name: DATABASE_URL
|
|
659
|
+
valueFrom:
|
|
660
|
+
secretKeyRef:
|
|
661
|
+
name: db-credentials
|
|
662
|
+
key: url
|
|
663
|
+
containers:
|
|
664
|
+
- name: app
|
|
665
|
+
image: myapp:1.0.0
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
## Best Practices
|
|
669
|
+
|
|
670
|
+
### Production Checklist
|
|
671
|
+
|
|
672
|
+
- [ ] Set resource requests and limits
|
|
673
|
+
- [ ] Implement all three probe types (startup, liveness, readiness)
|
|
674
|
+
- [ ] Use specific image tags (not :latest)
|
|
675
|
+
- [ ] Configure security context (non-root, read-only filesystem)
|
|
676
|
+
- [ ] Set replica count >= 3 for HA
|
|
677
|
+
- [ ] Configure pod anti-affinity for spread
|
|
678
|
+
- [ ] Set appropriate update strategy (maxUnavailable: 0 for zero-downtime)
|
|
679
|
+
- [ ] Use ConfigMaps and Secrets for configuration
|
|
680
|
+
- [ ] Add standard labels and annotations
|
|
681
|
+
- [ ] Configure graceful shutdown (preStop hook, terminationGracePeriodSeconds)
|
|
682
|
+
- [ ] Set revisionHistoryLimit for rollback capability
|
|
683
|
+
- [ ] Use ServiceAccount with minimal RBAC permissions
|
|
684
|
+
|
|
685
|
+
### Performance Tuning
|
|
686
|
+
|
|
687
|
+
**Fast startup:**
|
|
688
|
+
```yaml
|
|
689
|
+
spec:
|
|
690
|
+
minReadySeconds: 5
|
|
691
|
+
strategy:
|
|
692
|
+
rollingUpdate:
|
|
693
|
+
maxSurge: 2
|
|
694
|
+
maxUnavailable: 1
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
**Zero-downtime updates:**
|
|
698
|
+
```yaml
|
|
699
|
+
spec:
|
|
700
|
+
minReadySeconds: 10
|
|
701
|
+
strategy:
|
|
702
|
+
rollingUpdate:
|
|
703
|
+
maxSurge: 1
|
|
704
|
+
maxUnavailable: 0
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
**Graceful shutdown:**
|
|
708
|
+
```yaml
|
|
709
|
+
spec:
|
|
710
|
+
template:
|
|
711
|
+
spec:
|
|
712
|
+
terminationGracePeriodSeconds: 60
|
|
713
|
+
containers:
|
|
714
|
+
- name: app
|
|
715
|
+
lifecycle:
|
|
716
|
+
preStop:
|
|
717
|
+
exec:
|
|
718
|
+
command: ["/bin/sh", "-c", "sleep 15 && kill -SIGTERM 1"]
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
## Troubleshooting
|
|
722
|
+
|
|
723
|
+
### Common Issues
|
|
724
|
+
|
|
725
|
+
**Pods not starting:**
|
|
726
|
+
```bash
|
|
727
|
+
kubectl describe deployment <name>
|
|
728
|
+
kubectl get pods -l app=<app-name>
|
|
729
|
+
kubectl describe pod <pod-name>
|
|
730
|
+
kubectl logs <pod-name>
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
**ImagePullBackOff:**
|
|
734
|
+
- Check image name and tag
|
|
735
|
+
- Verify imagePullSecrets
|
|
736
|
+
- Check registry credentials
|
|
737
|
+
|
|
738
|
+
**CrashLoopBackOff:**
|
|
739
|
+
- Check container logs
|
|
740
|
+
- Verify liveness probe is not too aggressive
|
|
741
|
+
- Check resource limits
|
|
742
|
+
- Verify application dependencies
|
|
743
|
+
|
|
744
|
+
**Deployment stuck in progress:**
|
|
745
|
+
- Check progressDeadlineSeconds
|
|
746
|
+
- Verify readiness probes
|
|
747
|
+
- Check resource availability
|
|
748
|
+
|
|
749
|
+
## Related Resources
|
|
750
|
+
|
|
751
|
+
- [Kubernetes Deployment API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#deployment-v1-apps)
|
|
752
|
+
- [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
|
|
753
|
+
- [Resource Management](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)
|