容器编排:这次怎么落地的
容器编排相关的坑,多半出在边界条件上。
这次做容器化改造,从 Docker Swarm 迁移到 Kubernetes,也学到了不少。
Docker Swarm 的简单之处
Swarm 是 Docker 自带的容器编排工具,上手很快。
部署 Swarm 集群
# 初始化 Swarm 集群
docker swarm init
# 添加工作节点
docker swarm join --token <token> <manager-ip>:2377
# 查看集群状态
docker node ls
定义服务
# docker-compose.yml
version: '3'
services:
web:
image: nginx:latest
ports:
- "80:80"
deploy:
replicas: 3
networks:
- myapp-network
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: secret
volumes:
- db-data:/var/lib/postgresql/data
networks:
- myapp-network
networks:
myapp-network:
driver: overlay
volumes:
db-data:
部署应用
docker stack deploy -c docker-compose.yml myapp
就这么简单,应用就跑起来了。
什么时候需要 Kubernetes
Swarm 用着挺好,但有几个问题开始暴露:
功能限制:不支持滚动更新的高级策略、不支持复杂的调度策略
生态问题:Swarm 的生态不如 Kubernetes,很多工具只支持 K8s
团队技能:团队里更多人熟悉 K8s
监控运维:K8s 的监控生态更完善
Kubernetes 基础
Pod:最小部署单元
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: web
image: nginx:latest
ports:
- containerPort: 80
Deployment:管理副本
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:latest
ports:
- containerPort: 80
Service:稳定的访问入口
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
type: ClusterIP
配置管理
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.url: "postgres://db:5432/mydb"
cache.ttl: "3600"
使用:
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database.url
Secret
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
password: c3VwcmV0LXNljcmV0
实战中的对比
升级更新
Swarm:
docker service update --image myapp:v2 myapp
K8s:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 1
K8s 的滚动更新更可控。
健康检查
K8s:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
template:
spec:
containers:
- name: web
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
Swarm 的健康检查功能不如 K8s 完善。
踩过的坑
坑一:资源限制没配好
K8s 集群一开始没配置资源限制,结果一个容器吃光了机器资源,其他 Pod 没法调度。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: app
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
解决:为所有 Pod 配置资源限制和请求。
坑二:网络模式选错了
一开始用了 HostNetwork,结果端口冲突。
apiVersion: v1
kind: Pod
spec:
hostNetwork: true # 不要随便用
解决:使用 ClusterIP 或 NodePort,避免 HostNetwork。
坑三:PersistentVolume 配置问题
存储卷配置出错了,Pod 一直处于 Pending 状态。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
解决:先检查 StorageClass,确保存储类可用。
什么时候不该用 Kubernetes
Kubernetes 不是银弹,有些场景用了反而增加复杂度。
不适合用的场景:
- 容器数量少(<10)
- 不需要复杂的调度策略
- 团队没有 K8s 经验
- 对运维成本敏感
写在最后
容器编排这东西,Swarm 简单,Kubernetes 功能强大但复杂。
对于小团队,Swarm 可能就够用。对于大团队,K8s 的功能确实有价值。
选型之前先评估:项目规模、团队能力、运维复杂度。不是最先进的就好用,而是最合适的。
这次从 Swarm 迁移到 K8s 花了一个月,中间遇到过网络问题、存储问题、调度问题。但迁移完成后,K8s 的功能确实强大,特别是自动扩缩容、滚动更新这些功能,运维效率提升明显。
版权声明: 本文首发于 指尖魔法屋-容器编排:这次怎么落地的(https://blog.thinkmoon.cn/post/56-container-orchestration-swarm-kubernetes-practice/) 转载或引用必须申明原指尖魔法屋来源及源地址!
评论
使用 GitHub 账号登录后即可留言,支持 Markdown。