尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Docker Compose 项目迁移至 K8s 实战

Docker Compose 项目迁移至 K8s 实战 前言这周核心工作就是把原有 Docker Compose 维护的整套业务服务完整迁移到 Kubernetes 集群。平时开发测试用 Compose 非常顺手配置少、上手快但真正往 K8s 迁移的时候会发现概念变多、配置项成倍增加很多人直接复制转换后的 YAML 上线直接踩坑。我这边把完整思考、实操、排错全部整理出来尽量还原真实迁移的完整流程。一、迁移前思考什么场景才需要从 Compose 迁移 K8sDocker Compose 仅仅适用于单机环境所有服务都运行在同一台服务器。Compose 优势配置简单几行 yaml 就可以启动一整套服务本地开发、小测试环境非常友好。Compose 短板没有多节点调度、没有故障自愈、没有滚动更新机器一旦故障所有服务全部停止无法实现弹性扩缩容没有统一健康检查机制。K8s 能力跨多台机器调度 Pod节点故障自动把业务调度到正常节点支持灰度滚动更新可以配置 CPU 内存限制探针检测业务存活配合 Service 实现服务发现。重要提醒不是所有项目都必须上 K8s。如果只是单机小工具访问量很低Compose 完全够用不要为了技术而强行上 K8s会增加维护成本。适合迁移场景业务需要多机器部署、需要高可用、后续会扩容实例、生产业务。二、Docker Compose 和 K8s 资源对应关系搞懂两者的映射迁移就有思路不会对着大量 yaml 无从下手。Docker ComposeK8s 对应资源说明servicesDeployment无状态业务web、后端服务可多副本servicesStatefulSet有状态服务MySQL、Redis需要稳定网络标识、持久存储portsService(NodePort/ClusterIP/LoadBalancer)负责流量转发pod 销毁重建 IP 会变service 提供稳定访问入口volumesPV PVCCompose 数据卷K8s 通过 PVC 申请存储资源PV 后端对接存储environmentspec.containers[].env容器环境变量配置账号、地址、时区等restart: alwaysDeployment 默认 restartPolicy:Always容器异常自动重启depends_on无直接等价Compose 仅控制启动顺序K8s 没有该能力需要应用层做等待原始 docker‑compose.yaml 示例version: 3.8 services: web: image: nginx:1.24 ports: - 8080:80 environment: - TZAsia/Shanghai restart: always volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf redis: image: redis:6 restart: always volumes: - redis-data:/data volumes: redis-data:上面这个 Compose 配置直接复制到 K8s 是无法运行格式完全不兼容需要转换、手动优化。三、完整实操迁移步骤步骤 1安装 kompose 转换工具kompose 可以读取 compose 文件自动输出 K8s 的 Deployment、Service、PVC 模板只做模板生成绝对不能直接部署上线必须人工修改。Linux 安装命令#下载二进制程序 curl -L https://github.com/kubernetes/kompose/releases/download/v1.31.2/kompose-linux-amd64 -o kompose #赋予执行权限 chmod x kompose #移动到全局命令目录 mv ./kompose /usr/local/bin/kompose #验证是否安装成功 kompose version执行转换#基于docker‑compose.yaml生成k8s yaml文件 kompose convert -f docker-compose.yaml执行完毕当前目录会生成web-deployment.yaml、web-service.yaml、redis-deployment.yaml、redis-persistentvolumeclaim.yaml等文件。运维小提示kompose 工具的缺陷不会自动添加资源限制、存活 / 就绪探针镜像拉取策略默认 Always存储部分配置经常不符合内网生产规范全部需要人工修改。步骤 2优化无状态服务 Deploymentweb 示例kompose 生成出来的配置缺少生产必备配置需要手动补齐resources资源配额、livenessProbe存活探针、readinessProbe就绪探针、imagePullPolicy镜像拉取策略。web-deployment.yaml 优化后完整内容apiVersion: apps/v1 kind: Deployment metadata: name: web namespace: default #指定命名空间业务建议分开不同namespace隔离 spec: replicas: 2 #业务副本数量根据业务压力调整 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: web image: nginx:1.24 #内网环境节点本地已有镜像优先使用本地镜像避免外网拉取失败 imagePullPolicy: IfNotPresent env: - name: TZ value: Asia/Shanghai #资源限制防止单个服务占满节点CPU内存导致集群雪崩 resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 128Mi #就绪探针判断服务是否准备好接收流量没就绪不会接入service流量 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 3 #存活探针业务卡死无响应自动重启Pod livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 15 periodSeconds: 15 volumeMounts: - name: nginx-conf mountPath: /etc/nginx/conf.d/default.conf subPath: default.conf volumes: - name: nginx-conf configMap: name: nginx-conf items: - key: default.conf path: default.conf注意Compose 直接挂载本地配置文件K8s 不支持直接挂载宿主机文件不推荐需要转为 ConfigMap 存放配置。步骤 3Service 配置暴露业务访问入口apiVersion: v1 kind: Service metadata: name: web-svc namespace: default spec: type: NodePort #内网测试使用NodePort生产建议LoadBalancer或者Ingress selector: app: web #标签匹配pod流量转发给标签appweb的pod ports: - port: 80 #service内部端口 targetPort: 80 #pod容器端口 nodePort: 30080 #节点对外端口范围30000‑32767步骤 4有状态服务注意事项示例 Redis像 Redis、MySQL 这类带持久化数据的服务不要直接使用 Deployment优先使用StatefulSet。关键点PVC 持久存储一定要规划数据不能存 Pod 内部Pod 重建数据直接丢失。StatefulSet 的 Pod 拥有稳定网络身份适合数据库类组件。步骤 5部署到 K8s 集群执行命令#一次性应用所有yaml资源创建deployment、service、configmap、pvc kubectl apply -f web-deployment.yaml -f web-service.yaml -f nginx-configmap.yaml #查看deployment部署状态 kubectl get deployments #查看pod运行状态STATUS全部Running代表启动正常 kubectl get pods -o wide #查看service端口 kubectl get svc #查看pod详细事件排错使用如果pod异常看事件报错 kubectl describe pod pod‑name #查看容器业务日志 kubectl logs ‑f pod‑name步骤 6业务验证访问集群节点 IP:30080确认 nginx 页面正常打开查看日志确认没有报错模拟杀死 Pod测试集群是否自动新建 Pod验证自愈能力。#删除pod测试自愈删除之后deployment会自动重新拉起pod kubectl delete pod web‑7f9685798‑xxxx四、真实踩坑记录全部是迁移时实际遇到的问题坑 1直接使用 kompose 输出的 yaml 直接部署Pod 反复重启节点资源占满现象Pod 不断 CrashLoopBackOff节点 CPU 内存打满影响集群其他业务。排查kompose 生成配置不会自带 resources 资源限制容器可以无限制占用节点 CPU 内存。解决手动补充requests申请资源和limits最大占用资源。坑 2容器日志时间相差 8 小时时区不对现象业务日志打印的时间是 UTC 时间和实际北京时间差 8 小时。排查镜像默认 UTC 时区没有配置东八区。解决Pod 环境变量增加TZAsia/Shanghai部分基础镜像不识别环境变量时区需要挂载宿主机/etc/localtime。坑 3ImagePullBackOff 镜像拉取失败现象Pod 状态 ImagePullBackOff无法启动。** 排查场景 1内网离线环境镜像不在镜像仓库节点本地存在镜像。kompose 默认imagePullPolicy: Always每次都去远程拉取镜像。解决修改imagePullPolicy: IfNotPresent本地有镜像优先使用本地镜像。排查场景 2镜像名称写错、镜像版本不存在、私有仓库没有配置 secret 密钥。坑 4Compose 的 depends_on 迁移后服务启动顺序错乱现象web 服务启动比数据库早业务直接报错连不上数据库。排查Compose 的 depends_on 仅仅控制容器启动先后不会等待数据库就绪K8s 没有等价字段。解决在业务容器启动脚本增加等待逻辑等待数据库端口可连通之后再启动主程序不能依赖编排工具控制顺序。坑 5配置文件挂载直接写宿主机路径Pod 启动失败现象kompose 把 compose 挂载本地文件直接生成为 hostPath集群多节点时其他节点没有这个文件Pod 启动异常。排查hostPath 只适合单节点调试多节点集群严禁大量使用 hostPath。解决普通配置转为 ConfigMap密钥信息使用 Secret。坑 6没有配置探针流量发送给还没启动完成的 Pod现象业务刚启动需要初始化十几秒Pod 刚启动就接收请求大量请求报错 502。排查缺少 readinessProbe 就绪探针Pod 容器进程起来就被加入 Service 流量池但业务程序还没初始化完成。解决配置就绪探针业务真正就绪之后才接入流量。五、迁移的整体流程建议生产环境流程先在测试 K8s 集群完成整套迁移完整跑通业务所有接口验证读写、存储、重启、故障自愈。有状态组件优先做数据备份迁移前备份数据库。不要直接删除原有 Compose 业务两套环境并行运行一段时间确认新集群无问题再下线旧环境。命名空间做业务隔离不同项目放到不同 namespace方便权限、资源配额管理。存储提前规划不要把业务数据存于 Pod 内部Pod 重建数据丢失。资源配额提前评估根据业务实际负载设置 CPU 内存不要全部写很大浪费服务器资源。六、本周总结Docker Compose 迁移 K8s不是简单工具一键转换就完事。kompose 只能帮我们节省手写基础模板的时间生产环境必须人工二次优化资源限制、探针、镜像策略、配置管理、存储。优先迁移无状态 web、后端服务把整套流程摸清楚之后再处理 MySQL、Redis 这类有状态组件循序渐进不容易出现大规模故障。完成业务迁移之后业务已经跑在 K8s 集群但是我们看不到集群资源使用率、看不到业务日志下周就开始搭建 K8s 监控与日志体系。个人运维小感悟很多新人学习 K8s 会记大量参数命令一上来直接折腾数据库这种复杂有状态服务很容易心态崩掉。建议先拿简单 Nginx、测试后端服务练习完整迁移流程理解 Pod、Deployment、Service、探针、存储概念再去处理复杂业务。
返回列表