Docker Swarm 简单易用,但 Kubernetes(K8s)已成为容器编排的事实标准,拥有更丰富的生态和更强的扩展性。如果你已经从 Swarm 起步,现在考虑迁移到 K8s,本文将为你梳理核心概念对比、迁移步骤,以及使用 kompose 工具转换 Compose 文件的方法。同时,我们也会讨论 Docker 作为容器运行时在 K8s 中的演进(CRI 接口)。
一、Docker Swarm vs Kubernetes:核心差异

选择建议:
如果你已有 Swarm 并且运行良好,不需要复杂的自动伸缩、服务网格、多云部署,继续使用 Swarm 也足够。
如果需要更细粒度的策略、庞大的社区支持、跨云部署,或者招聘方便,K8s 是更好的选择。
二、从 Docker Compose 到 Kubernetes:使用 kompose
许多 Swarm 用户使用 docker-compose.yml 定义应用。kompose 工具可以将 Compose 文件转换为 K8s 资源 YAML。
2.1 安装 kompose
bash
# Linux
curl -L https://github.com/kubernetes/kompose/releases/download/v1.31.2/kompose-linux-amd64 -o kompose
chmod +x kompose
sudo mv kompose /usr/local/bin/
# macOS
brew install kompose
2.2 转换示例
假设有 docker-compose.yml:
yaml
version: '3'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
redis:
image: redis:alpine
运行转换:
bash
kompose convert
生成文件:web-deployment.yaml, web-service.yaml, redis-deployment.yaml, redis-service.yaml。
2.3 直接部署到 K8s
bash
kompose up
这会转换并应用资源到当前 K8s 集群(需要预先配置好 kubectl)。
注意:kompose 不是万能的,某些 Compose 特性(如 depends_on、healthcheck 的部分参数)映射不完美,需要手动调整。
三、核心概念映射对照表

四、迁移步骤示例:WordPress 从 Swarm 到 K8s
原 Swarm stack.yml(简化):
yaml
version: '3.8'
services:
wordpress:
image: wordpress:latest
ports:
- "80:80"
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_PASSWORD: secret
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
K8s 迁移步骤:
创建 Namespace(可选):
bash
kubectl create namespace wordpress
创建 Secret 存储密码:
bash
kubectl create secret generic mysql-pass --from-literal=password=secret -n wordpress
创建 MySQL Deployment 和 Service(mysql.yaml):
yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: wordpress
spec:
ports:
- port: 3306
selector:
app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
创建 WordPress Deployment 和 Service(wordpress.yaml):
yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
namespace: wordpress
spec:
type: NodePort
ports:
- port: 80
nodePort: 30080
selector:
app: wordpress
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
namespace: wordpress
spec:
replicas: 3
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress:latest
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
部署到 K8s:
bash
kubectl apply -f mysql.yaml
kubectl apply -f wordpress.yaml
访问:http://:30080
五、Docker 作为 Kubernetes 运行时的变迁
早期 K8s 通过 dockershim 直接与 Docker Engine 通信。但自 K8s 1.20 起,官方逐步弃用 dockershim,推荐使用符合 CRI(容器运行时接口) 的运行时,如 containerd(K8s 1.24+ 默认不再支持 dockershim)。
对用户的影响:
如果你的集群使用 containerd(或 cri-o),仍然可以运行 Docker 构建的镜像,因为镜像是 OCI 标准格式。
你依然可以在开发环境中使用 Docker 构建镜像,只需将镜像推送到仓库,K8s 从中拉取。
docker 命令行工具仍然可用于本地构建和调试。
六、迁移的最佳实践
从开发和测试环境开始:先将非核心应用迁移到 K8s,积累经验。
使用 Helm 打包应用:Helm Charts 类似 Compose,但更强大,支持模板化配置。
拥抱 GitOps:将 K8s 资源清单存入 Git,使用 ArgoCD 或 Flux 自动化部署。
替换存储:Swarm 的本地卷迁移到 K8s 需要 CSI 或云存储(如 AWS EBS、GCE Persistent Disk)。
网络策略:K8s 默认所有 Pod 互通,如需隔离,配置 NetworkPolicy(需要 CNI 支持)。
日志和监控:部署 EFK(Elasticsearch-Fluentd-Kibana)或 Prometheus + Grafana。
七、小结
从 Swarm 迁移到 K8s 需要学习曲线,但能带来更强大的生态和扩展性。kompose 可以辅助转换,但复杂场景仍需手动调整。记住:K8s 并非万能,适合规模和需求增长后的场景。