356 lines
8.3 KiB
Markdown
356 lines
8.3 KiB
Markdown
|
|
# 容器化部署最佳实践指南
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
容器化技术已经成为现代应用部署的标准方式,Docker 和 Kubernetes 的普及使得应用部署变得更加灵活、可靠和高效。本文将介绍容器化部署的最佳实践,帮助您构建稳定、可扩展的容器化应用。
|
|||
|
|
|
|||
|
|
## 容器化基础
|
|||
|
|
|
|||
|
|
### Docker 最佳实践
|
|||
|
|
|
|||
|
|
#### 镜像构建优化
|
|||
|
|
```dockerfile
|
|||
|
|
# 多阶段构建示例
|
|||
|
|
FROM node:18-alpine AS builder
|
|||
|
|
WORKDIR /app
|
|||
|
|
COPY package*.json ./
|
|||
|
|
RUN npm ci --only=production
|
|||
|
|
|
|||
|
|
FROM node:18-alpine AS runtime
|
|||
|
|
WORKDIR /app
|
|||
|
|
COPY --from=builder /app/node_modules ./node_modules
|
|||
|
|
COPY . .
|
|||
|
|
EXPOSE 3000
|
|||
|
|
CMD ["npm", "start"]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 镜像安全
|
|||
|
|
- **基础镜像选择**:使用官方镜像,定期更新安全补丁
|
|||
|
|
- **最小化镜像**:使用 Alpine Linux 等轻量级基础镜像
|
|||
|
|
- **非 root 用户**:避免使用 root 用户运行容器
|
|||
|
|
- **漏洞扫描**:定期扫描镜像中的安全漏洞
|
|||
|
|
|
|||
|
|
#### 镜像标签策略
|
|||
|
|
```bash
|
|||
|
|
# 语义化版本标签
|
|||
|
|
docker build -t myapp:1.2.3 .
|
|||
|
|
docker build -t myapp:latest .
|
|||
|
|
|
|||
|
|
# 多架构支持
|
|||
|
|
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 容器运行时优化
|
|||
|
|
- **资源限制**:设置 CPU 和内存限制
|
|||
|
|
- **健康检查**:配置健康检查端点
|
|||
|
|
- **日志管理**:使用结构化日志,避免日志文件过大
|
|||
|
|
- **环境变量**:敏感信息使用 secrets,配置信息使用 configmaps
|
|||
|
|
|
|||
|
|
## Kubernetes 部署策略
|
|||
|
|
|
|||
|
|
### 部署类型选择
|
|||
|
|
|
|||
|
|
#### Deployment
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: apps/v1
|
|||
|
|
kind: Deployment
|
|||
|
|
metadata:
|
|||
|
|
name: myapp
|
|||
|
|
spec:
|
|||
|
|
replicas: 3
|
|||
|
|
selector:
|
|||
|
|
matchLabels:
|
|||
|
|
app: myapp
|
|||
|
|
template:
|
|||
|
|
metadata:
|
|||
|
|
labels:
|
|||
|
|
app: myapp
|
|||
|
|
spec:
|
|||
|
|
containers:
|
|||
|
|
- name: myapp
|
|||
|
|
image: myapp:latest
|
|||
|
|
ports:
|
|||
|
|
- containerPort: 3000
|
|||
|
|
resources:
|
|||
|
|
requests:
|
|||
|
|
memory: "64Mi"
|
|||
|
|
cpu: "250m"
|
|||
|
|
limits:
|
|||
|
|
memory: "128Mi"
|
|||
|
|
cpu: "500m"
|
|||
|
|
livenessProbe:
|
|||
|
|
httpGet:
|
|||
|
|
path: /health
|
|||
|
|
port: 3000
|
|||
|
|
initialDelaySeconds: 30
|
|||
|
|
periodSeconds: 10
|
|||
|
|
readinessProbe:
|
|||
|
|
httpGet:
|
|||
|
|
path: /ready
|
|||
|
|
port: 3000
|
|||
|
|
initialDelaySeconds: 5
|
|||
|
|
periodSeconds: 5
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### StatefulSet
|
|||
|
|
- 适用于有状态应用(数据库、消息队列等)
|
|||
|
|
- 提供稳定的网络标识和存储
|
|||
|
|
- 支持有序部署和滚动更新
|
|||
|
|
|
|||
|
|
#### DaemonSet
|
|||
|
|
- 适用于节点级别的服务(日志收集、监控代理等)
|
|||
|
|
- 确保每个节点运行一个 Pod 副本
|
|||
|
|
|
|||
|
|
### 服务发现和负载均衡
|
|||
|
|
|
|||
|
|
#### Service 配置
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: v1
|
|||
|
|
kind: Service
|
|||
|
|
metadata:
|
|||
|
|
name: myapp-service
|
|||
|
|
spec:
|
|||
|
|
selector:
|
|||
|
|
app: myapp
|
|||
|
|
ports:
|
|||
|
|
- protocol: TCP
|
|||
|
|
port: 80
|
|||
|
|
targetPort: 3000
|
|||
|
|
type: ClusterIP
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Ingress 配置
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: networking.k8s.io/v1
|
|||
|
|
kind: Ingress
|
|||
|
|
metadata:
|
|||
|
|
name: myapp-ingress
|
|||
|
|
annotations:
|
|||
|
|
nginx.ingress.kubernetes.io/rewrite-target: /
|
|||
|
|
spec:
|
|||
|
|
rules:
|
|||
|
|
- host: myapp.example.com
|
|||
|
|
http:
|
|||
|
|
paths:
|
|||
|
|
- path: /
|
|||
|
|
pathType: Prefix
|
|||
|
|
backend:
|
|||
|
|
service:
|
|||
|
|
name: myapp-service
|
|||
|
|
port:
|
|||
|
|
number: 80
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 高可用性设计
|
|||
|
|
|
|||
|
|
### 多可用区部署
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: apps/v1
|
|||
|
|
kind: Deployment
|
|||
|
|
metadata:
|
|||
|
|
name: myapp
|
|||
|
|
spec:
|
|||
|
|
replicas: 6
|
|||
|
|
template:
|
|||
|
|
spec:
|
|||
|
|
affinity:
|
|||
|
|
podAntiAffinity:
|
|||
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
|||
|
|
- weight: 100
|
|||
|
|
podAffinityTerm:
|
|||
|
|
labelSelector:
|
|||
|
|
matchExpressions:
|
|||
|
|
- key: app
|
|||
|
|
operator: In
|
|||
|
|
values:
|
|||
|
|
- myapp
|
|||
|
|
topologyKey: kubernetes.io/hostname
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 自动扩缩容
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: autoscaling/v2
|
|||
|
|
kind: HorizontalPodAutoscaler
|
|||
|
|
metadata:
|
|||
|
|
name: myapp-hpa
|
|||
|
|
spec:
|
|||
|
|
scaleTargetRef:
|
|||
|
|
apiVersion: apps/v1
|
|||
|
|
kind: Deployment
|
|||
|
|
name: myapp
|
|||
|
|
minReplicas: 3
|
|||
|
|
maxReplicas: 10
|
|||
|
|
metrics:
|
|||
|
|
- type: Resource
|
|||
|
|
resource:
|
|||
|
|
name: cpu
|
|||
|
|
target:
|
|||
|
|
type: Utilization
|
|||
|
|
averageUtilization: 70
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 滚动更新策略
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: apps/v1
|
|||
|
|
kind: Deployment
|
|||
|
|
metadata:
|
|||
|
|
name: myapp
|
|||
|
|
spec:
|
|||
|
|
strategy:
|
|||
|
|
type: RollingUpdate
|
|||
|
|
rollingUpdate:
|
|||
|
|
maxSurge: 25%
|
|||
|
|
maxUnavailable: 25%
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 配置管理
|
|||
|
|
|
|||
|
|
### ConfigMap 和 Secret
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: v1
|
|||
|
|
kind: ConfigMap
|
|||
|
|
metadata:
|
|||
|
|
name: myapp-config
|
|||
|
|
data:
|
|||
|
|
database_url: "mysql://localhost:3306/myapp"
|
|||
|
|
redis_url: "redis://localhost:6379"
|
|||
|
|
log_level: "info"
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
apiVersion: v1
|
|||
|
|
kind: Secret
|
|||
|
|
metadata:
|
|||
|
|
name: myapp-secret
|
|||
|
|
type: Opaque
|
|||
|
|
data:
|
|||
|
|
database_password: bXlwYXNzd29yZA== # base64 encoded
|
|||
|
|
api_key: YXBpa2V5MTIzNA==
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 环境变量注入
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: apps/v1
|
|||
|
|
kind: Deployment
|
|||
|
|
metadata:
|
|||
|
|
name: myapp
|
|||
|
|
spec:
|
|||
|
|
template:
|
|||
|
|
spec:
|
|||
|
|
containers:
|
|||
|
|
- name: myapp
|
|||
|
|
image: myapp:latest
|
|||
|
|
env:
|
|||
|
|
- name: DATABASE_URL
|
|||
|
|
valueFrom:
|
|||
|
|
configMapKeyRef:
|
|||
|
|
name: myapp-config
|
|||
|
|
key: database_url
|
|||
|
|
- name: DATABASE_PASSWORD
|
|||
|
|
valueFrom:
|
|||
|
|
secretKeyRef:
|
|||
|
|
name: myapp-secret
|
|||
|
|
key: database_password
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 监控和日志
|
|||
|
|
|
|||
|
|
### 监控指标
|
|||
|
|
- **应用指标**:响应时间、错误率、吞吐量
|
|||
|
|
- **基础设施指标**:CPU、内存、网络、存储使用率
|
|||
|
|
- **业务指标**:用户活跃度、交易量、转化率
|
|||
|
|
|
|||
|
|
### 日志收集
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: v1
|
|||
|
|
kind: ConfigMap
|
|||
|
|
metadata:
|
|||
|
|
name: fluentd-config
|
|||
|
|
data:
|
|||
|
|
fluent.conf: |
|
|||
|
|
<source>
|
|||
|
|
@type tail
|
|||
|
|
path /var/log/containers/*.log
|
|||
|
|
pos_file /var/log/fluentd-containers.log.pos
|
|||
|
|
tag kubernetes.*
|
|||
|
|
read_from_head true
|
|||
|
|
<parse>
|
|||
|
|
@type json
|
|||
|
|
time_format %Y-%m-%dT%H:%M:%S.%NZ
|
|||
|
|
</parse>
|
|||
|
|
</source>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 安全最佳实践
|
|||
|
|
|
|||
|
|
### 网络安全
|
|||
|
|
- **网络策略**:使用 NetworkPolicy 限制 Pod 间通信
|
|||
|
|
- **服务网格**:使用 Istio 等工具实现细粒度流量控制
|
|||
|
|
- **TLS 终止**:在 Ingress 层终止 TLS 连接
|
|||
|
|
|
|||
|
|
### 访问控制
|
|||
|
|
- **RBAC**:配置适当的角色和权限
|
|||
|
|
- **Service Account**:为不同应用使用不同的 Service Account
|
|||
|
|
- **Pod Security Standards**:遵循 Pod 安全标准
|
|||
|
|
|
|||
|
|
### 镜像安全
|
|||
|
|
- **镜像签名**:使用 Notary 等工具签名镜像
|
|||
|
|
- **漏洞扫描**:集成 Trivy 等工具进行漏洞扫描
|
|||
|
|
- **镜像策略**:使用 OPA 等工具实施镜像策略
|
|||
|
|
|
|||
|
|
## CI/CD 集成
|
|||
|
|
|
|||
|
|
### 自动化部署流程
|
|||
|
|
```yaml
|
|||
|
|
# GitHub Actions 示例
|
|||
|
|
name: Deploy to Kubernetes
|
|||
|
|
on:
|
|||
|
|
push:
|
|||
|
|
branches: [ main ]
|
|||
|
|
jobs:
|
|||
|
|
deploy:
|
|||
|
|
runs-on: ubuntu-latest
|
|||
|
|
steps:
|
|||
|
|
- uses: actions/checkout@v3
|
|||
|
|
- name: Build and push Docker image
|
|||
|
|
run: |
|
|||
|
|
docker build -t myapp:${{ github.sha }} .
|
|||
|
|
docker push myapp:${{ github.sha }}
|
|||
|
|
- name: Deploy to Kubernetes
|
|||
|
|
run: |
|
|||
|
|
kubectl set image deployment/myapp myapp=myapp:${{ github.sha }}
|
|||
|
|
kubectl rollout status deployment/myapp
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### GitOps 实践
|
|||
|
|
- **声明式配置**:所有配置通过 Git 管理
|
|||
|
|
- **自动化同步**:使用 ArgoCD 等工具自动同步配置
|
|||
|
|
- **版本控制**:所有变更都有版本记录和回滚能力
|
|||
|
|
|
|||
|
|
## 故障排查
|
|||
|
|
|
|||
|
|
### 常见问题
|
|||
|
|
1. **Pod 启动失败**:检查镜像、配置、资源限制
|
|||
|
|
2. **服务无法访问**:检查 Service 和 Endpoints 配置
|
|||
|
|
3. **存储问题**:检查 PVC 和 StorageClass 配置
|
|||
|
|
4. **网络问题**:检查网络策略和 DNS 配置
|
|||
|
|
|
|||
|
|
### 调试工具
|
|||
|
|
- **kubectl**:基础调试命令
|
|||
|
|
- **kubectl exec**:进入容器调试
|
|||
|
|
- **kubectl logs**:查看容器日志
|
|||
|
|
- **kubectl describe**:查看资源详细信息
|
|||
|
|
|
|||
|
|
## 总结
|
|||
|
|
|
|||
|
|
容器化部署是现代应用部署的标准方式,通过遵循最佳实践,可以构建稳定、可扩展、安全的容器化应用。关键要点包括:
|
|||
|
|
|
|||
|
|
1. **镜像优化**:多阶段构建、安全加固、标签策略
|
|||
|
|
2. **部署策略**:选择合适的部署类型、配置资源限制、实施健康检查
|
|||
|
|
3. **高可用性**:多可用区部署、自动扩缩容、滚动更新
|
|||
|
|
4. **配置管理**:使用 ConfigMap 和 Secret、环境变量注入
|
|||
|
|
5. **监控日志**:收集关键指标、实施日志收集
|
|||
|
|
6. **安全加固**:网络安全、访问控制、镜像安全
|
|||
|
|
7. **CI/CD 集成**:自动化部署、GitOps 实践
|
|||
|
|
8. **故障排查**:掌握调试工具、了解常见问题
|
|||
|
|
|
|||
|
|
通过系统性地应用这些最佳实践,您可以构建企业级的容器化部署平台,支撑业务的快速发展。
|