从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: kafka

2. 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-pvc

3. 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:8081


Docker Compose vs Kubernetes 对比


维度Docker ComposeKubernetes
服务发现容器名互相访问Service + DNS
配置管理environment字段ConfigMap + Secret
存储volumes挂载PV + PVC
健康检查healthcheckliveness/readiness probe
滚动更新手动或脚本RollingUpdate策略
扩缩容手动改replicaskubectl scale / HPA
日志查看docker logskubectl 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


建议学习路径:

  1. 本地Minikube搭建 → 2. 无状态应用部署 → 3. 有状态应用部署 → 4. 配置管理 → 5. 存储管理 → 6. 生产环境进阶

从Docker Compose到Kubernetes,不是简单的工具替换,而是思维方式的转变。希望这篇笔记对正在学习K8s的你有所帮助。



关于作者:10年Java后端开发,正在从Docker Compose向K8s迁移数据平台,欢迎交流。

#k8s #minikube #devops #容器化

浏览 4
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报