Kubernetes 部署
概览
掌握 Kubernetes 部署,用于大规模管理容器化应用程序,包括多容器服务、资源分配、健康检查和滚动部署策略。
使用场景
- 容器编排和管理
- 多环境部署(开发、测试、生产)
- 自动扩展微服务
- 滚动更新和蓝绿部署
- 服务发现和负载均衡
- 资源配额和限制管理
- Pod 网络和安全策略
实施示例
1. 完整的部署与资源管理
# kubernetes-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-service
namespace: production
labels:
app: api-service
version: v1
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: api-service
template:
metadata:
labels:
app: api-service
version: v1
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
spec:
# 服务账户用于 RBAC
serviceAccountName: api-service-sa
# 安全上下文
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
# Pod 调度
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- api-service
topologyKey: kubernetes.io/hostname
# Pod 终止宽限期
terminationGracePeriodSeconds: 30
# 初始化容器
initContainers:
- name: wait-for-db
image: busybox:1.35
command: ['sh', '-c', 'until nc -z postgres-service 5432; do echo waiting for db; sleep 2; done']
containers:
- name: api-service
image: myrepo/api-service:1.2.3
imagePullPolicy: IfNotPresent
# 端口
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: metrics
containerPort: 9090
protocol: TCP
# 环境变量
env:
- name: NODE_ENV
value: "production"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: api-secrets
key: database-url
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: api-config
key: log-level
- name: REPLICA_NUM
valueFrom:
fieldRef:
fieldPath: metadata.name
# 资源请求和限制
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
# 存活探针
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
# 就绪探针
readinessProbe:
httpGet:
path: /ready
port: 8080
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 2
# 卷挂载
volumeMounts:
- name: config
mountPath: /etc/config
readOnly: true
- name: cache
mountPath: /var/cache
- name: logs
mountPath: /var/log
# 安全上下文
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# 卷
volumes:
- name: config
configMap:
name: api-config
- name: cache
emptyDir:
sizeLimit: 1Gi
- name: logs
emptyDir:
sizeLimit: 2Gi
---
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: production
spec:
type: ClusterIP
selector:
app: api-service
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
- name: metrics
port: 9090
targetPort: 9090
protocol: TCP
---
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
namespace: production
data:
log-level: "INFO"
max-connections: "100"
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-service-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-service
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
2. 部署脚本
#!/bin/bash
# deploy-k8s.sh - 部署到 Kubernetes 集群
set -euo pipefail
NAMESPACE="${1:-production}"
DEPLOYMENT="${2:-api-service}"
IMAGE="${3:-myrepo/api-service:latest}"
echo "Deploying $DEPLOYMENT to namespace $NAMESPACE..."
# 检查集群连接
kubectl cluster-info
# 如果不存在则创建命名空间
kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f -
# 应用配置
kubectl apply -f kubernetes-deployment.yaml -n "$NAMESPACE"
# 等待滚动更新
echo "Waiting for deployment to rollout..."
kubectl rollout status deployment/"$DEPLOYMENT" -n "$NAMESPACE" --timeout=5m
# 验证 Pod 是否运行
echo "Verification:"
kubectl get pods -n "$NAMESPACE" -l "app=$DEPLOYMENT"
# 检查服务
kubectl get svc -n "$NAMESPACE" -l "app=$DEPLOYMENT"
echo "Deployment complete!"
3. 服务账户和 RBAC
apiVersion: v1
kind: ServiceAccount
metadata:
name: api-service-sa
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: api-service-role
namespace: production
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: api-service-rolebinding
namespace: production
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: api-service-role
subjects:
- kind: ServiceAccount
name: api-service-sa
namespace: production
部署模式
滚动更新
- 逐步替换旧的 Pod 为新的 Pod
- 零停机部署
- 失败时自动回滚
蓝绿部署
- 维护两个相同的环境
- 立即切换流量
- 更容易的回滚能力
金丝雀发布
- 首先部署到一部分用户
- 在全面推出前监控指标
- 减少不良部署的风险
最佳实践
✅ 应该做
- 使用资源请求和限制
- 实施健康检查(存活性、就绪性)
- 使用 ConfigMaps 进行配置
- 应用安全上下文限制
- 使用服务账户和 RBAC
- 实施 Pod 反亲和性
- 使用命名空间进行隔离
- 启用 Pod 安全策略
❌ 不应该做
- 在生产中使用最新镜像标签
- 以 root 用户运行容器
- 设置无限制的资源使用
- 跳过就绪探针
- 无资源限制地部署
- 在容器镜像中混合配置
- 使用默认服务账户