kubernetes-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseKubernetes Patterns
Kubernetes 模式
Production-grade Kubernetes patterns for deploying, managing, and debugging workloads reliably.
用于可靠部署、管理和调试工作负载的生产级Kubernetes模式。
When to Activate
适用场景
- Writing Kubernetes manifests (Deployments, Services, Ingress, Jobs)
- Configuring resource requests/limits, liveness/readiness probes
- Setting up RBAC, namespaces, or ServiceAccounts
- Managing configuration and secrets in K8s
- Debugging CrashLoopBackOff, OOMKilled, pending pods, or image pull errors
- Configuring HPA (Horizontal Pod Autoscaler) or PodDisruptionBudgets
- Reviewing K8s YAML for security or correctness
- 编写Kubernetes清单(Deployments、Services、Ingress、Jobs)
- 配置资源请求/限制、存活/就绪探针
- 设置RBAC、命名空间或ServiceAccount
- 在K8s中管理配置与密钥
- 调试CrashLoopBackOff、OOMKilled、Pending Pod或镜像拉取错误
- 配置HPA(Horizontal Pod Autoscaler)或PodDisruptionBudgets
- 审核K8s YAML的安全性与正确性
When to Use
使用时机
Same as When to Activate above. This alias satisfies repo skill-format conventions. Use this skill any time you are writing, reviewing, or debugging Kubernetes YAML and workloads.
与上方的适用场景一致。此别名符合仓库技能格式规范。当你编写、审核或调试Kubernetes YAML和工作负载时,均可使用本技能。
How It Works
工作原理
This skill provides copy-pasteable, production-grade YAML patterns and kubectl debugging commands organized by task:
- Deployment template — A fully configured production with security context, rolling update strategy, all three probe types, resource limits, and environment injection from ConfigMap/Secret.
Deployment - Probes — Decision table for startup vs liveness vs readiness, with correct math.
failureThreshold × periodSeconds - Services & Ingress — ClusterIP, LoadBalancer, and TLS Ingress patterns with cert-manager annotations.
- ConfigMaps & Secrets — , file-mount, and external secrets guidance.
envFrom - Resource management — Requests vs limits rules of thumb by workload type (web API, JVM, worker, sidecar).
- RBAC — Least-privilege ServiceAccount → Role → RoleBinding chain.
- HPA & PDB — Autoscaling and node-drain safety configurations.
- Jobs & CronJobs — One-off and scheduled workload patterns with correct .
restartPolicy - kubectl cheatsheet — Logs, exec, rollback, port-forward, dry-run, and common error diagnosis commands.
- Anti-patterns & checklist — What NOT to do, and a security/reliability/observability checklist.
本技能提供按任务分类的可直接复制粘贴的生产级YAML模式和kubectl调试命令:
- Deployment模板 — 一个配置完整的生产级,包含安全上下文、滚动更新策略、三种探针类型、资源限制,以及从ConfigMap/Secret注入环境变量的配置。
Deployment - 探针 — 启动探针、存活探针与就绪探针的决策表,包含正确的计算逻辑。
failureThreshold × periodSeconds - 服务与Ingress — ClusterIP、LoadBalancer和带cert-manager注解的TLS Ingress模式。
- ConfigMap与Secret — 、文件挂载和外部密钥管理指南。
envFrom - 资源管理 — 按工作负载类型(Web API、JVM、Worker、Sidecar)划分的资源请求与限制经验规则。
- RBAC — 遵循最小权限原则的ServiceAccount → Role → RoleBinding链式配置。
- HPA与PDB — 自动扩缩容和节点排空安全配置。
- Jobs与CronJobs — 一次性和定时工作负载模式,包含正确的配置。
restartPolicy - kubectl速查表 — 日志查看、容器执行、回滚、端口转发、试运行和常见错误诊断命令。
- 反模式与检查清单 — 禁忌操作,以及安全性/可靠性/可观测性检查清单。
Examples
示例
See the sections below for complete, runnable examples. Quick references:
| Task | Jump to |
|---|---|
| Full production Deployment YAML | Core Workload Patterns |
| Probe configuration | Probes |
| RBAC least-privilege setup | RBAC |
| Debug a CrashLoopBackOff | kubectl Debugging Cheatsheet |
| Autoscaling | HPA |
查看以下章节获取完整可运行示例。快速参考:
| 任务 | 跳转至 |
|---|---|
| 完整生产级Deployment YAML | 核心工作负载模式 |
| 探针配置 | 探针 |
| RBAC最小权限配置 | RBAC |
| 调试CrashLoopBackOff | kubectl调试速查表 |
| 自动扩缩容 | HPA |
Core Workload Patterns
核心工作负载模式
Deployment — Production Template
Deployment — 生产级模板
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: my-namespace
labels:
app: my-app
version: "1.0.0"
spec:
replicas: 3
selector:
matchLabels:
app: my-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Allow 1 extra pod during update
maxUnavailable: 0 # Never reduce below desired count
template:
metadata:
labels:
app: my-app
version: "1.0.0"
spec:
# Security context at pod level
securityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 1001
# Graceful shutdown
terminationGracePeriodSeconds: 30
containers:
- name: my-app
image: ghcr.io/org/my-app:1.0.0 # Never use :latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
protocol: TCP
# Resource requests AND limits are both required
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
# Container security context
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# Probes (see Probes section below)
startupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 30
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 0
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 2
# Environment from ConfigMap and Secret
envFrom:
- configMapRef:
name: my-app-config
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-app-secrets
key: db-password
# Writable tmp directory when readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: my-namespace
labels:
app: my-app
version: "1.0.0"
spec:
replicas: 3
selector:
matchLabels:
app: my-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Allow 1 extra pod during update
maxUnavailable: 0 # Never reduce below desired count
template:
metadata:
labels:
app: my-app
version: "1.0.0"
spec:
# Security context at pod level
securityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 1001
# Graceful shutdown
terminationGracePeriodSeconds: 30
containers:
- name: my-app
image: ghcr.io/org/my-app:1.0.0 # Never use :latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
protocol: TCP
# Resource requests AND limits are both required
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
# Container security context
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# Probes (see Probes section below)
startupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 30
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 0
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 2
# Environment from ConfigMap and Secret
envFrom:
- configMapRef:
name: my-app-config
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-app-secrets
key: db-password
# Writable tmp directory when readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}Probes — Liveness, Readiness, Startup
探针 — 存活、就绪、启动
Understanding when to use each probe is critical:
| Probe | Failure Action | Use For |
|---|---|---|
| Kills container if slow to start | Slow-starting apps (JVM, Python) |
| Restarts container | Deadlock / hung process detection |
| Removes from Service endpoints | Temporary unavailability (DB reconnect) |
yaml
undefined理解何时使用每种探针至关重要:
| 探针 | 失败动作 | 适用场景 |
|---|---|---|
| 若启动缓慢则杀死容器 | 启动缓慢的应用(JVM、Python) |
| 重启容器 | 死锁/挂起进程检测 |
| 从Service端点移除 | 临时不可用场景(数据库重连) |
yaml
undefinedCorrect pattern: startupProbe covers slow startup,
Correct pattern: startupProbe covers slow startup,
then liveness/readiness take over
then liveness/readiness take over
startupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 30 # 30 * 5s = 150s max startup time
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8080
periodSeconds: 30
failureThreshold: 3 # 3 * 30s = 90s before restart
readinessProbe:
httpGet:
path: /ready # Separate endpoint: checks DB, cache, etc.
port: 8080
periodSeconds: 10
failureThreshold: 2
```yamlstartupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 30 # 30 * 5s = 150s max startup time
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8080
periodSeconds: 30
failureThreshold: 3 # 3 * 30s = 90s before restart
readinessProbe:
httpGet:
path: /ready # Separate endpoint: checks DB, cache, etc.
port: 8080
periodSeconds: 10
failureThreshold: 2
```yamlWRONG: initialDelaySeconds without startupProbe
WRONG: initialDelaySeconds without startupProbe
If the app takes 60s to start, set a startupProbe instead
If the app takes 60s to start, set a startupProbe instead
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 60 # BAD: Arbitrary wait, race condition
---livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 60 # BAD: Arbitrary wait, race condition
---Services and Ingress
服务与Ingress
Service Types
服务类型
yaml
undefinedyaml
undefinedClusterIP (default) — internal-only
ClusterIP (default) — internal-only
apiVersion: v1
kind: Service
metadata:
name: my-app
namespace: my-namespace
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
protocol: TCP
type: ClusterIP
```yamlapiVersion: v1
kind: Service
metadata:
name: my-app
namespace: my-namespace
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
protocol: TCP
type: ClusterIP
```yamlLoadBalancer — external traffic (cloud providers)
LoadBalancer — external traffic (cloud providers)
spec:
type: LoadBalancer
ports:
- port: 443
targetPort: 8080
undefinedspec:
type: LoadBalancer
ports:
- port: 443
targetPort: 8080
undefinedIngress with TLS
带TLS的Ingress
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
namespace: my-namespace
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: my-app-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
namespace: my-namespace
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: my-app-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80ConfigMaps and Secrets
ConfigMap与Secret
ConfigMap — Non-sensitive configuration
ConfigMap — 非敏感配置
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
namespace: my-namespace
data:
LOG_LEVEL: "info"
APP_ENV: "production"
MAX_CONNECTIONS: "100"
# Mount as a file for complex config
app.yaml: |
server:
port: 8080
timeout: 30syaml
undefinedyaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
namespace: my-namespace
data:
LOG_LEVEL: "info"
APP_ENV: "production"
MAX_CONNECTIONS: "100"
# Mount as a file for complex config
app.yaml: |
server:
port: 8080
timeout: 30syaml
undefinedMount ConfigMap as a file
Mount ConfigMap as a file
volumes:
- name: config configMap: name: my-app-config items: - key: app.yaml path: app.yaml volumeMounts:
- name: config mountPath: /etc/app readOnly: true
undefinedvolumes:
- name: config configMap: name: my-app-config items: - key: app.yaml path: app.yaml volumeMounts:
- name: config mountPath: /etc/app readOnly: true
undefinedSecrets — Sensitive data
Secret — 敏感数据
bash
undefinedbash
undefinedCreate secret from literal (CLI, then store in Vault/SOPS)
Create secret from literal (CLI, then store in Vault/SOPS)
kubectl create secret generic my-app-secrets
--from-literal=db-password='s3cr3t'
--namespace=my-namespace
--dry-run=client -o yaml | kubectl apply -f -
--from-literal=db-password='s3cr3t'
--namespace=my-namespace
--dry-run=client -o yaml | kubectl apply -f -
```yaml
apiVersion: v1
kind: Secret
metadata:
name: my-app-secrets
namespace: my-namespace
type: Opaquekubectl create secret generic my-app-secrets
--from-literal=db-password='s3cr3t'
--namespace=my-namespace
--dry-run=client -o yaml | kubectl apply -f -
--from-literal=db-password='s3cr3t'
--namespace=my-namespace
--dry-run=client -o yaml | kubectl apply -f -
```yaml
apiVersion: v1
kind: Secret
metadata:
name: my-app-secrets
namespace: my-namespace
type: OpaqueValues are base64-encoded (NOT encrypted — use Sealed Secrets or ESO for real encryption)
Values are base64-encoded (NOT encrypted — use Sealed Secrets or ESO for real encryption)
data:
db-password: czNjcjN0 # base64 of 's3cr3t'
> **Important:** Raw Kubernetes Secrets are only base64-encoded, not encrypted at rest unless your cluster has encryption configured. Use [Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets) or [External Secrets Operator](https://external-secrets.io) for production.
---data:
db-password: czNjcjN0 # base64 of 's3cr3t'
> **重要提示:** 原生Kubernetes Secret仅经过base64编码,并非加密存储,除非你的集群配置了加密功能。生产环境请使用[Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets)或[External Secrets Operator](https://external-secrets.io)。
---Resource Requests and Limits
资源请求与限制
yaml
resources:
requests: # Scheduler uses this to place the pod
cpu: "100m" # 100 millicores = 0.1 CPU
memory: "128Mi"
limits: # Container is killed/throttled above this
cpu: "500m"
memory: "256Mi"Rules of thumb:
| Workload Type | CPU Request | Memory Request | Notes |
|---|---|---|---|
| Web API | 100–250m | 128–256Mi | Set limits 2-4x requests |
| Worker/consumer | 250–500m | 256–512Mi | Memory limit = request for predictability |
| JVM app | 500m–1 | 512Mi–2Gi | Allow headroom above |
| Sidecar | 10–50m | 32–64Mi | Keep minimal |
yaml
undefinedyaml
resources:
requests: # Scheduler uses this to place the pod
cpu: "100m" # 100 millicores = 0.1 CPU
memory: "128Mi"
limits: # Container is killed/throttled above this
cpu: "500m"
memory: "256Mi"经验规则:
| 工作负载类型 | CPU请求 | 内存请求 | 说明 |
|---|---|---|---|
| Web API | 100–250m | 128–256Mi | 限制值设为请求值的2-4倍 |
| Worker/消费者 | 250–500m | 256–512Mi | 内存限制与请求值一致以保证可预测性 |
| JVM应用 | 500m–1 | 512Mi–2Gi | 为JVM预留超出 |
| Sidecar | 10–50m | 32–64Mi | 保持最小配置 |
yaml
undefinedWRONG: No requests or limits — unpredictable scheduling, OOM evictions
WRONG: No requests or limits — unpredictable scheduling, OOM evictions
containers:
- name: app
image: myapp:latest
Missing resources: {} — this is dangerous in production
containers:
- name: app
image: myapp:latest
Missing resources: {} — this is dangerous in production
WRONG: Limits without requests — requests default to limits, over-reserves capacity
WRONG: Limits without requests — requests default to limits, over-reserves capacity
resources:
limits:
cpu: "2"
memory: "1Gi"
requests missing — will default to limits values
---resources:
limits:
cpu: "2"
memory: "1Gi"
requests missing — will default to limits values
---RBAC — Roles and ServiceAccounts
RBAC — 角色与ServiceAccount
Principle of Least Privilege
最小权限原则
Two patterns depending on whether the app calls the Kubernetes API:
根据应用是否调用Kubernetes API分为两种模式:
Pattern A — App does NOT need the Kubernetes API (most apps)
模式A — 应用无需调用Kubernetes API(大多数应用)
Disable token automounting on the ServiceAccount. The Role/RoleBinding are not needed.
yaml
undefined禁用ServiceAccount的令牌自动挂载。无需配置Role/RoleBinding。
yaml
undefinedServiceAccount with token disabled — safest default
ServiceAccount with token disabled — safest default
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: my-namespace
automountServiceAccountToken: false # No K8s API token injected into pods
```yamlapiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: my-namespace
automountServiceAccountToken: false # No K8s API token injected into pods
```yamlReference in Deployment — no token, no API access
Reference in Deployment — no token, no API access
spec:
template:
spec:
serviceAccountName: my-app-sa
automountServiceAccountToken: false # Belt-and-suspenders: also set at pod level
undefinedspec:
template:
spec:
serviceAccountName: my-app-sa
automountServiceAccountToken: false # Belt-and-suspenders: also set at pod level
undefinedPattern B — App DOES need the Kubernetes API (operators, controllers, config watchers)
模式B — 应用需要调用Kubernetes API(Operator、控制器、配置监听器)
Enable the token and grant only the permissions actually required.
yaml
undefined启用令牌并仅授予实际需要的权限。
yaml
undefined1. ServiceAccount — enable token for this SA
1. ServiceAccount — enable token for this SA
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: my-namespace
automountServiceAccountToken: true # Token required: app calls K8s API
```yamlapiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: my-namespace
automountServiceAccountToken: true # Token required: app calls K8s API
```yaml2. Role — grant only what the app needs (namespace-scoped)
2. Role — grant only what the app needs (namespace-scoped)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-app-role
namespace: my-namespace
rules:
- apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list", "watch"] # Read-only, specific resource
- apiGroups: [""] resources: ["secrets"] resourceNames: ["my-app-secrets"] # Restrict to specific secret by name verbs: ["get"]
```yamlapiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-app-role
namespace: my-namespace
rules:
- apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list", "watch"] # Read-only, specific resource
- apiGroups: [""] resources: ["secrets"] resourceNames: ["my-app-secrets"] # Restrict to specific secret by name verbs: ["get"]
```yaml3. Bind Role to ServiceAccount
3. Bind Role to ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-app-rolebinding
namespace: my-namespace
subjects:
- kind: ServiceAccount name: my-app-sa namespace: my-namespace roleRef: kind: Role apiGroup: rbac.authorization.k8s.io name: my-app-role
```yamlapiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-app-rolebinding
namespace: my-namespace
subjects:
- kind: ServiceAccount name: my-app-sa namespace: my-namespace roleRef: kind: Role apiGroup: rbac.authorization.k8s.io name: my-app-role
```yaml4. Reference SA in Deployment
4. Reference SA in Deployment
spec:
template:
spec:
serviceAccountName: my-app-sa
# automountServiceAccountToken defaults to true from SA — token is injected
---spec:
template:
spec:
serviceAccountName: my-app-sa
# automountServiceAccountToken defaults to true from SA — token is injected
---Horizontal Pod Autoscaler (HPA)
Horizontal Pod Autoscaler (HPA)
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
namespace: my-namespace
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2 # Always at least 2 for HA
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # Scale up when avg CPU > 70%
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80HPA requiresto be set on all containers — it calculates utilization asresources.requests.current / request
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
namespace: my-namespace
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2 # Always at least 2 for HA
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # Scale up when avg CPU > 70%
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80HPA要求所有容器都设置— 它通过resources.requests计算资源使用率。当前值 / 请求值
PodDisruptionBudget (PDB)
PodDisruptionBudget (PDB)
Prevent too many pods going down during node drains or rolling updates:
yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
namespace: my-namespace
spec:
minAvailable: 2 # OR use maxUnavailable: 1
selector:
matchLabels:
app: my-app防止节点排空或滚动更新期间过多Pod下线:
yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
namespace: my-namespace
spec:
minAvailable: 2 # OR use maxUnavailable: 1
selector:
matchLabels:
app: my-appNamespaces and Multi-Tenancy
命名空间与多租户
bash
undefinedbash
undefinedCreate namespace with resource quotas
Create namespace with resource quotas
kubectl create namespace my-namespace
kubectl create namespace my-namespace
Apply ResourceQuota to limit namespace consumption
Apply ResourceQuota to limit namespace consumption
kubectl apply -f - <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
name: my-namespace-quota
namespace: my-namespace
spec:
hard:
requests.cpu: "4"
requests.memory: 4Gi
limits.cpu: "8"
limits.memory: 8Gi
pods: "20"
EOF
---kubectl apply -f - <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
name: my-namespace-quota
namespace: my-namespace
spec:
hard:
requests.cpu: "4"
requests.memory: 4Gi
limits.cpu: "8"
limits.memory: 8Gi
pods: "20"
EOF
---Jobs and CronJobs
Jobs与CronJobs
yaml
undefinedyaml
undefinedOne-off Job (DB migration, data processing)
One-off Job (DB migration, data processing)
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
namespace: my-namespace
spec:
backoffLimit: 3 # Retry up to 3 times on failure
ttlSecondsAfterFinished: 3600 # Auto-delete after 1h
template:
spec:
restartPolicy: OnFailure # Never for Jobs (not Always)
containers:
- name: migrate
image: ghcr.io/org/my-app:1.0.0
command: ["python", "manage.py", "migrate"]
resources:
requests:
cpu: "100m"
memory: "256Mi"
```yamlapiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
namespace: my-namespace
spec:
backoffLimit: 3 # Retry up to 3 times on failure
ttlSecondsAfterFinished: 3600 # Auto-delete after 1h
template:
spec:
restartPolicy: OnFailure # Never for Jobs (not Always)
containers:
- name: migrate
image: ghcr.io/org/my-app:1.0.0
command: ["python", "manage.py", "migrate"]
resources:
requests:
cpu: "100m"
memory: "256Mi"
```yamlCronJob
CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: cleanup-job
namespace: my-namespace
spec:
schedule: "0 2 * * *" # 2am daily
concurrencyPolicy: Forbid # Don't run if previous still running
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: cleanup
image: ghcr.io/org/cleanup:1.0.0
resources:
requests:
cpu: "50m"
memory: "64Mi"
---apiVersion: batch/v1
kind: CronJob
metadata:
name: cleanup-job
namespace: my-namespace
spec:
schedule: "0 2 * * *" # 2am daily
concurrencyPolicy: Forbid # Don't run if previous still running
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: cleanup
image: ghcr.io/org/cleanup:1.0.0
resources:
requests:
cpu: "50m"
memory: "64Mi"
---kubectl Debugging Cheatsheet
kubectl调试速查表
bash
undefinedbash
undefined--- Pod status and logs ---
--- Pod status and logs ---
kubectl get pods -n my-namespace
kubectl get pods -n my-namespace -o wide # Show node assignment
kubectl describe pod <pod-name> -n my-namespace # Events and state details
kubectl logs <pod-name> -n my-namespace # Current logs
kubectl logs <pod-name> -n my-namespace --previous # Logs from crashed container
kubectl logs <pod-name> -n my-namespace -c <container> # Multi-container pod
kubectl get pods -n my-namespace
kubectl get pods -n my-namespace -o wide # Show node assignment
kubectl describe pod <pod-name> -n my-namespace # Events and state details
kubectl logs <pod-name> -n my-namespace # Current logs
kubectl logs <pod-name> -n my-namespace --previous # Logs from crashed container
kubectl logs <pod-name> -n my-namespace -c <container> # Multi-container pod
--- Execute into a running container ---
--- Execute into a running container ---
kubectl exec -it <pod-name> -n my-namespace -- sh
kubectl exec -it <pod-name> -n my-namespace -- bash
kubectl exec -it <pod-name> -n my-namespace -- sh
kubectl exec -it <pod-name> -n my-namespace -- bash
--- Check resource usage ---
--- Check resource usage ---
kubectl top pods -n my-namespace
kubectl top nodes
kubectl top pods -n my-namespace
kubectl top nodes
--- Deployment operations ---
--- Deployment operations ---
kubectl rollout status deployment/my-app -n my-namespace
kubectl rollout history deployment/my-app -n my-namespace
kubectl rollout undo deployment/my-app -n my-namespace # Rollback
kubectl rollout undo deployment/my-app --to-revision=2 -n my-namespace
kubectl rollout status deployment/my-app -n my-namespace
kubectl rollout history deployment/my-app -n my-namespace
kubectl rollout undo deployment/my-app -n my-namespace # Rollback
kubectl rollout undo deployment/my-app --to-revision=2 -n my-namespace
--- Scale manually ---
--- Scale manually ---
kubectl scale deployment my-app --replicas=5 -n my-namespace
kubectl scale deployment my-app --replicas=5 -n my-namespace
--- Inspect events (cluster-wide issues) ---
--- Inspect events (cluster-wide issues) ---
kubectl get events -n my-namespace --sort-by='.lastTimestamp'
kubectl get events -n my-namespace --sort-by='.lastTimestamp'
--- Port-forward for local debugging ---
--- Port-forward for local debugging ---
kubectl port-forward pod/<pod-name> 8080:8080 -n my-namespace
kubectl port-forward svc/my-app 8080:80 -n my-namespace
kubectl port-forward pod/<pod-name> 8080:8080 -n my-namespace
kubectl port-forward svc/my-app 8080:80 -n my-namespace
--- Dry-run to validate YAML ---
--- Dry-run to validate YAML ---
kubectl apply -f deployment.yaml --dry-run=client
kubectl apply -f deployment.yaml --dry-run=server # Validates against live cluster
undefinedkubectl apply -f deployment.yaml --dry-run=client
kubectl apply -f deployment.yaml --dry-run=server # Validates against live cluster
undefinedDiagnosing Common Errors
常见错误诊断
bash
undefinedbash
undefinedCrashLoopBackOff: container keeps crashing
CrashLoopBackOff: container keeps crashing
kubectl logs <pod-name> --previous -n my-namespace # Check crash logs
kubectl describe pod <pod-name> -n my-namespace # Check exit code & OOMKilled
kubectl logs <pod-name> --previous -n my-namespace # Check crash logs
kubectl describe pod <pod-name> -n my-namespace # Check exit code & OOMKilled
ImagePullBackOff: can't pull image
ImagePullBackOff: can't pull image
kubectl describe pod <pod-name> -n my-namespace # Check Events section
kubectl describe pod <pod-name> -n my-namespace # Check Events section
Causes: wrong image tag, missing imagePullSecret, private registry
Causes: wrong image tag, missing imagePullSecret, private registry
Pending pod: not scheduled
Pending pod: not scheduled
kubectl describe pod <pod-name> -n my-namespace
kubectl describe pod <pod-name> -n my-namespace
Causes: insufficient resources, no matching node selector, taint/toleration mismatch
Causes: insufficient resources, no matching node selector, taint/toleration mismatch
OOMKilled: out of memory
OOMKilled: out of memory
Increase memory limits, check for memory leaks
Increase memory limits, check for memory leaks
kubectl describe pod <pod-name> -n my-namespace | grep -A5 "Last State"
---kubectl describe pod <pod-name> -n my-namespace | grep -A5 "Last State"
---Anti-Patterns
反模式
yaml
undefinedyaml
undefinedBAD: Using :latest tag — non-deterministic deployments
BAD: Using :latest tag — non-deterministic deployments
image: myapp:latest
image: myapp:latest
GOOD: Pin to a specific immutable tag (SHA or semver)
GOOD: Pin to a specific immutable tag (SHA or semver)
image: ghcr.io/org/myapp:1.4.2
image: ghcr.io/org/myapp:1.4.2
or
or
image: ghcr.io/org/myapp@sha256:abc123...
image: ghcr.io/org/myapp@sha256:abc123...
---
---
BAD: Running as root
BAD: Running as root
securityContext: {} # Defaults to root
securityContext: {} # Defaults to root
GOOD: Non-root with explicit UID
GOOD: Non-root with explicit UID
securityContext:
runAsNonRoot: true
runAsUser: 1001
securityContext:
runAsNonRoot: true
runAsUser: 1001
---
---
BAD: No resource limits — one pod can starve the entire node
BAD: No resource limits — one pod can starve the entire node
containers:
- name: app
image: myapp:1.0.0
No resources defined
containers:
- name: app
image: myapp:1.0.0
No resources defined
GOOD: Always set requests and limits
GOOD: Always set requests and limits
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
---
---
BAD: Storing plaintext secrets in ConfigMaps
BAD: Storing plaintext secrets in ConfigMaps
apiVersion: v1
kind: ConfigMap
data:
DB_PASSWORD: "mysecretpassword" # NEVER — use Secret or external secrets manager
apiVersion: v1
kind: ConfigMap
data:
DB_PASSWORD: "mysecretpassword" # NEVER — use Secret or external secrets manager
---
---
BAD: ClusterAdmin for application service accounts
BAD: ClusterAdmin for application service accounts
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
roleRef:
kind: ClusterRole
name: cluster-admin # Grants god-mode to your app
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
roleRef:
kind: ClusterRole
name: cluster-admin # Grants god-mode to your app
---
---
BAD: minAvailable: 0 in PDB — defeats the purpose
BAD: minAvailable: 0 in PDB — defeats the purpose
spec:
minAvailable: 0
spec:
minAvailable: 0
---
---
BAD: restartPolicy: Always in a Job (causes infinite restart loop)
BAD: restartPolicy: Always in a Job (causes infinite restart loop)
spec:
restartPolicy: Always # Use OnFailure or Never for Jobs
---spec:
restartPolicy: Always # Use OnFailure or Never for Jobs
---Best Practices Checklist
最佳实践检查清单
Security
安全性
- Container runs as non-root (,
runAsNonRoot: trueset)runAsUser - with
readOnlyRootFilesystem: truefor writable pathsemptyDir -
allowPrivilegeEscalation: false - All capabilities dropped ()
capabilities.drop: [ALL] - Dedicated ServiceAccount per app, not
default - unless needed
automountServiceAccountToken: false - RBAC follows least privilege (use , not
Roleunless needed)ClusterRole - Secrets managed via Sealed Secrets or External Secrets Operator
- 容器以非root用户运行(设置和
runAsNonRoot: true)runAsUser - 启用并为可写路径配置
readOnlyRootFilesystem: trueemptyDir - 设置
allowPrivilegeEscalation: false - 移除所有权限()
capabilities.drop: [ALL] - 每个应用使用独立的ServiceAccount,而非
default - 除非必要,禁用
automountServiceAccountToken - RBAC遵循最小权限原则(使用而非
Role,除非必要)ClusterRole - 通过Sealed Secrets或External Secrets Operator管理密钥
Reliability
可靠性
- All 3 probe types configured (startup + liveness + readiness)
- Resource requests AND limits set on every container
- for any production workload
minReplicas: 2+ - PodDisruptionBudget defined for stateful or critical services
- strategy with
RollingUpdatemaxUnavailable: 0 - HPA configured for variable-load services
- 配置三种探针类型(启动+存活+就绪)
- 每个容器都设置资源请求与限制
- 生产级工作负载的
minReplicas: 2+ - 为有状态或关键服务定义PodDisruptionBudget
- 配置策略并设置
RollingUpdatemaxUnavailable: 0 - 为可变负载服务配置HPA
Observability
可观测性
- App exposes (liveness) and
/health(readiness) endpoints/ready - Structured JSON logging (no PII in logs)
- Resource labels: ,
app,versionenvironment
- 应用暴露(存活)和
/health(就绪)端点/ready - 使用结构化JSON日志(日志中不包含PII)
- 设置资源标签:、
app、versionenvironment
Related Skills
相关技能
- — Multi-stage Dockerfiles and image security
docker-patterns - — CI/CD pipelines, rollback strategy, health check endpoints
deployment-patterns - — Broader security hardening context
security-review - — GitOps integration with K8s (ArgoCD / Flux patterns)
git-workflow
- — 多阶段Dockerfile与镜像安全
docker-patterns - — CI/CD流水线、回滚策略、健康检查端点
deployment-patterns - — 更全面的安全加固上下文
security-review - — K8s与GitOps的集成(ArgoCD / Flux模式)
git-workflow