数据库部署
数据库部署
本节我们将部署微服务应用的数据层:MongoDB 和 Redis。
MongoDB 部署
MongoDB 用于存储业务数据,需要持久化存储和高可用配置。
StatefulSet 配置
apiVersion: v1
kind: Service
metadata:
name: mongodb
namespace: ecommerce
labels:
app: mongodb
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None # Headless Service
selector:
app: mongodb
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
namespace: ecommerce
spec:
serviceName: mongodb
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo:6.0
ports:
- containerPort: 27017
name: mongodb
env:
- name: MONGO_INITDB_ROOT_USERNAME
value: "admin"
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: mongo-password
volumeMounts:
- name: mongo-data
mountPath: /data/db
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1000m"
livenessProbe:
exec:
command:
- mongosh
- --eval
- "db.adminCommand('ping')"
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- mongosh
- --eval
- "db.adminCommand('ping')"
initialDelaySeconds: 5
periodSeconds: 5
volumeClaimTemplates:
- metadata:
name: mongo-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "fast-ssd"
resources:
requests:
storage: 20Gi
初始化副本集
# 进入 MongoDB Pod
kubectl exec -it mongodb-0 -n ecommerce -- mongosh -u admin -p password
# 初始化副本集
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongodb-0.mongodb.ecommerce.svc.cluster.local:27017" },
{ _id: 1, host: "mongodb-1.mongodb.ecommerce.svc.cluster.local:27017" },
{ _id: 2, host: "mongodb-2.mongodb.ecommerce.svc.cluster.local:27017" }
]
})
# 查看副本集状态
rs.status()
创建应用数据库和用户
// 切换到 admin 数据库
use admin
// 创建应用用户
db.createUser({
user: "ecommerce",
pwd: "ecommerce-password",
roles: [
{ role: "readWrite", db: "ecommerce" }
]
})
// 创建数据库
use ecommerce
// 创建集合和索引
db.products.createIndex({ "name": "text" })
db.products.createIndex({ "category": 1 })
db.orders.createIndex({ "userId": 1, "createdAt": -1 })
备份策略
apiVersion: batch/v1
kind: CronJob
metadata:
name: mongodb-backup
namespace: ecommerce
spec:
schedule: "0 2 * * *" # 每天凌晨2点
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: mongo:6.0
command:
- /bin/sh
- -c
- |
mongodump \
--host=mongodb-0.mongodb \
--username=admin \
--password=$MONGO_PASSWORD \
--authenticationDatabase=admin \
--out=/backup/$(date +%Y%m%d-%H%M%S)
env:
- name: MONGO_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: mongo-password
volumeMounts:
- name: backup
mountPath: /backup
volumes:
- name: backup
persistentVolumeClaim:
claimName: mongodb-backup-pvc
restartPolicy: OnFailure
Redis 部署
Redis 用于缓存和会话存储,需要高性能和持久化。
Deployment 配置
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
namespace: ecommerce
data:
redis.conf: |
# 网络配置
bind 0.0.0.0
protected-mode yes
port 6379
# 持久化配置
save 900 1
save 300 10
save 60 10000
# AOF 持久化
appendonly yes
appendfsync everysec
# 内存配置
maxmemory 1gb
maxmemory-policy allkeys-lru
# 安全配置
requirepass ${REDIS_PASSWORD}
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: ecommerce
spec:
type: ClusterIP
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: ecommerce
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7.2-alpine
ports:
- containerPort: 6379
name: redis
command:
- redis-server
- /etc/redis/redis.conf
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: redis-password
volumeMounts:
- name: redis-config
mountPath: /etc/redis
- name: redis-data
mountPath: /data
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: redis-config
configMap:
name: redis-config
- name: redis-data
persistentVolumeClaim:
claimName: redis-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: ecommerce
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 10Gi
Redis 哨兵模式(高可用)
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-sentinel-config
namespace: ecommerce
data:
sentinel.conf: |
port 26379
sentinel monitor mymaster redis-0.redis 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-sentinel
namespace: ecommerce
spec:
serviceName: redis-sentinel
replicas: 3
selector:
matchLabels:
app: redis-sentinel
template:
metadata:
labels:
app: redis-sentinel
spec:
containers:
- name: sentinel
image: redis:7.2-alpine
command:
- redis-sentinel
- /etc/redis/sentinel.conf
ports:
- containerPort: 26379
name: sentinel
volumeMounts:
- name: sentinel-config
mountPath: /etc/redis
volumes:
- name: sentinel-config
configMap:
name: redis-sentinel-config
部署验证
MongoDB 验证
# 检查 Pod 状态
kubectl get pods -n ecommerce -l app=mongodb
# 查看日志
kubectl logs mongodb-0 -n ecommerce
# 测试连接
kubectl run -it --rm mongo-test --image=mongo:6.0 --restart=Never -n ecommerce -- \
mongosh mongodb://admin:password@mongodb-0.mongodb:27017/admin
# 查看副本集状态
kubectl exec mongodb-0 -n ecommerce -- mongosh -u admin -p password --eval "rs.status()"
Redis 验证
# 检查 Pod 状态
kubectl get pods -n ecommerce -l app=redis
# 查看日志
kubectl logs -l app=redis -n ecommerce
# 测试连接
kubectl run -it --rm redis-test --image=redis:7.2-alpine --restart=Never -n ecommerce -- \
redis-cli -h redis -a password ping
# 测试读写
kubectl run -it --rm redis-test --image=redis:7.2-alpine --restart=Never -n ecommerce -- \
redis-cli -h redis -a password set test "hello"
性能优化
MongoDB 优化
# 1. 使用 WiredTiger 存储引擎(默认)
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 1.5
# 2. 连接池配置
maxPoolSize: 50
minPoolSize: 10
# 3. 索引优化
db.collection.createIndex({ field: 1 }, { background: true })
Redis 优化
# 1. 禁用透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 2. 调整 TCP backlog
net.core.somaxconn=65535
# 3. 关闭 AOF
appendonly no # 如果可以接受少量数据丢失
监控配置
Prometheus Exporter
# MongoDB Exporter
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-exporter
namespace: ecommerce
spec:
replicas: 1
selector:
matchLabels:
app: mongodb-exporter
template:
metadata:
labels:
app: mongodb-exporter
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9216"
spec:
containers:
- name: exporter
image: percona/mongodb_exporter:0.40
ports:
- containerPort: 9216
env:
- name: MONGODB_URI
value: "mongodb://admin:password@mongodb:27017"
---
# Redis Exporter
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-exporter
namespace: ecommerce
spec:
replicas: 1
selector:
matchLabels:
app: redis-exporter
template:
metadata:
labels:
app: redis-exporter
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9121"
spec:
containers:
- name: exporter
image: oliver006/redis_exporter:latest
ports:
- containerPort: 9121
env:
- name: REDIS_ADDR
value: "redis:6379"
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: redis-password
小结
本节我们部署了微服务的数据层:
✅ MongoDB:3副本 StatefulSet,副本集配置,自动备份
✅ Redis:单实例 + 哨兵高可用方案
✅ 持久化:PVC 存储,定期备份
✅ 监控:Prometheus Exporter 集成
✅ 优化:性能调优和资源限制
下一节我们将部署微服务应用层。