从Docker Compose到Kubernetes
共 4669字,需浏览 10分钟
·
2026-06-04 10:05
为什么要迁移?
之前一直用Docker Compose管理本地开发环境(Flink + Kafka + MySQL + Paimon),但随着服务增多,Compose的局限性越来越明显:
- 服务发现:容器间靠容器名通信,不够灵活
- 资源管理:无法精细化控制每个服务的资源配额
- 健康检查:虽然有healthcheck,但缺乏完善的探针机制
- 扩缩容:手动改replicas,不够自动化
K8s恰好解决了这些问题。
环境搭建(CentOS 7)
1. 安装Minikube
bash
# 下载最新版
curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# 启动(普通用户,非root)
minikube start --memory 8192 --cpus 4 --driver=docker --image-mirror-country=cn踩坑点:Minikube不建议用root运行,需要创建普通用户并加入docker组。
2. 配置kubectl别名
bash
alias kubectl="minikube kubectl --"
echo 'alias kubectl="minikube kubectl --"' >> ~/.bashrc
source ~/.bashrc镜像拉取问题的解决
在国内使用Minikube,最大的坑是镜像拉取失败(ImagePullBackOff)。
解决方案:手动拉取镜像并加载到Minikube
bash
# 1. 宿主机拉取镜像
docker pull flink:1.17.2
docker pull confluentinc/cp-kafka:7.5.0
# 2. 加载到Minikube
minikube image load flink:1.17.2
minikube image load confluentinc/cp-kafka:7.5.0关键命令:minikube image load 将本地镜像导入Minikube的Docker守护进程。
服务部署实战
1. Namespace隔离
yaml
apiVersion: v1
kind: Namespace
metadata:
name: data-platform
---
apiVersion: v1
kind: Namespace
metadata:
name: flink
---
apiVersion: v1
kind: Namespace
metadata:
name: kafka2. MySQL部署(含PVC)
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: data-platform
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: data-platform
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
value: "123456"
volumeMounts:
- name: storage
mountPath: /var/lib/mysql
volumes:
- name: storage
persistentVolumeClaim:
claimName: mysql-pvc3. StatefulSet部署(Kafka + ZooKeeper)
有状态服务需要用StatefulSet,保证Pod的网络标识和存储稳定性:
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kafka
namespace: kafka
spec:
serviceName: kafka
replicas: 1
selector:
matchLabels:
app: kafka
template:
metadata:
labels:
app: kafka
spec:
containers:
- name: kafka
image: confluentinc/cp-kafka:7.5.0
env:
- name: KAFKA_ZOOKEEPER_CONNECT
value: "zookeeper.kafka:2181"
- name: KAFKA_ADVERTISED_LISTENERS
value: "PLAINTEXT://kafka.kafka:9092"4. Flink集群部署
JobManager和TaskManager分开部署:
yaml
# JobManager
apiVersion: apps/v1
kind: Deployment
metadata:
name: flink-jobmanager
namespace: flink
spec:
replicas: 1
template:
spec:
containers:
- name: jobmanager
image: flink:1.17.2
args: ["jobmanager"]
livenessProbe:
httpGet:
path: /overview
port: 8081
initialDelaySeconds: 60
yaml# TaskManager
apiVersion: apps/v1
kind: Deployment
metadata:
name: flink-taskmanager
namespace: flink
spec:
replicas: 2
template:
spec:
containers:
- name: taskmanager
image: flink:1.17.2
args: ["taskmanager"]健康检查配置要点
livenessProbe vs readinessProbe
| 探针类型 | 作用 | 失败后果 | 适用场景 |
|---|---|---|---|
| livenessProbe | 检测容器是否存活 | 重启容器 | 检测死锁、内存泄漏 |
| readinessProbe | 检测容器是否就绪 | 从Service端点移除 | 启动预热、依赖未就绪 |
最佳实践:
- initialDelaySeconds:给应用足够的启动时间(Java应用建议60秒)
- periodSeconds:检查间隔(生产环境建议30秒)
- failureThreshold:失败重试次数(默认3次)
常用kubectl命令速查
bash
# 查看资源
kubectl get pods -A
kubectl get svc -n flink
kubectl get pvc --all-namespaces
# 排查问题
kubectl describe pod <pod-name>
kubectl logs <pod-name> --tail=100
kubectl exec -it <pod-name> -- /bin/sh
# 资源操作
kubectl apply -f deployment.yaml
kubectl delete -f deployment.yaml
kubectl scale deployment/flink-taskmanager --replicas=4 -n flink
# 端口转发(本地访问)
kubectl port-forward -n flink svc/flink-jobmanager 8081:8081Docker Compose vs Kubernetes 对比
| 维度 | Docker Compose | Kubernetes |
|---|---|---|
| 服务发现 | 容器名互相访问 | Service + DNS |
| 配置管理 | environment字段 | ConfigMap + Secret |
| 存储 | volumes挂载 | PV + PVC |
| 健康检查 | healthcheck | liveness/readiness probe |
| 滚动更新 | 手动或脚本 | RollingUpdate策略 |
| 扩缩容 | 手动改replicas | kubectl scale / HPA |
| 日志查看 | docker logs | kubectl logs |
踩坑总结
坑1:kubectl找不到命令
解决:使用minikube kubectl --替代,或创建别名
坑2:镜像拉取失败(ImagePullBackOff)
解决:minikube image load <image-name>
坑3:Ingress插件超时
解决:暂时禁用,minikube addons disable ingress
坑4:PVC一直Pending
解决:检查storageClass,本地环境需要先创建PV
坑5:Pod间通信失败
解决:使用完整的Service域名,如mysql.data-platform.svc.cluster.local
建议学习路径:
- 本地Minikube搭建 → 2. 无状态应用部署 → 3. 有状态应用部署 → 4. 配置管理 → 5. 存储管理 → 6. 生产环境进阶
从Docker Compose到Kubernetes,不是简单的工具替换,而是思维方式的转变。希望这篇笔记对正在学习K8s的你有所帮助。
关于作者:10年Java后端开发,正在从Docker Compose向K8s迁移数据平台,欢迎交流。
#k8s #minikube #devops #容器化
