【日常小问】解决 Jenkins 部署 Spring Cloud 微服务到 Docker 容器启动失败的问题
一、问题出现在使用 Jenkins 进行 CI/CD 部署 Spring Cloud 微服务项目时遇到了一个让人头疼的问题所有通过 Jenkins 构建的 Docker 容器启动后立即退出状态码为Exited (1)。查看容器日志报错信息如下*************************** APPLICATION FAILED TO START *************************** Description: Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class看起来是数据库配置没有加载到但奇怪的是同样的项目在其他人的电脑上可以正常运行唯独到了我的环境就各种报错。二、问题原因经过一番排查发现这个问题其实是三个独立的问题叠加导致的2.1 Docker 网络不通项目的各个微服务Nacos、MySQL、Redis 等部署在同一个 Linux 虚拟机的 Docker 中但它们分布在不同的 Docker 网络里容器所在网络说明Nacos、MySQL、Redistjxt手动部署时创建的网络Jenkins 构建的应用容器heima-net启动脚本中指定的网络两个网络互相隔离导致应用容器根本访问不到 Nacos 和 MySQL。2.2 Nacos 认证信息缺失项目使用了 Spring Cloud Alibaba Nacos 作为配置中心和服务注册发现中心。但bootstrap.yml中没有配置 Nacos 的地址和认证信息默认使用localhost:8848。在 Docker 容器中localhost指向的是容器自己而不是宿主机的 Nacos 服务。即使网络通了没有正确的地址和认证信息也无法连接。2.3 共享配置位置错误在修改bootstrap.yml添加 Nacos 配置时不小心把shared-configs共享配置放在了discovery服务发现下面而不是config配置中心下面。这导致应用虽然能连接 Nacos但无法加载共享的数据库配置。# ❌ 错误的结构 spring: cloud: nacos: config: server-addr: 192.168.150.101:8848 username: nacos password: nacos file-extension: yaml discovery: server-addr: 192.168.150.101:8848 username: nacos password: nacos shared-configs: # ❌ 放在 discovery 下面不会被加载 - data-id: shared-mybatis.yaml refresh: false三、解决问题3.1 解决 Docker 网络问题方法一修改 Jenkins 启动脚本推荐编辑/usr/local/src/script/startup.sh将--network heima-net改为--network tjxt# 修改前 --network heima-net ${IMAGE_NAME} \ # 修改后 --network tjxt ${IMAGE_NAME} \方法二手动连接网络如果不想修改脚本也可以手动将容器连接到正确的网络docker network connect tjxt tj-user docker network connect tjxt tj-trade docker restart tj-user tj-trade3.2 配置 Docker 镜像加速器在国内网络环境下Docker Hub 经常超时。配置镜像加速器可以显著提升拉取镜像的速度sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [ https://docker.1ms.run, https://docker.xuanyuan.me ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker3.3 添加 Nacos 认证配置在每个微服务的bootstrap.yml中添加 Nacos 的地址和认证信息。注意shared-configs必须在config下面spring: cloud: nacos: config: server-addr: 192.168.150.101:8848 username: nacos password: nacos file-extension: yaml shared-configs: # ✅ 正确位置在 config 下面 - data-id: shared-spring.yaml refresh: false - data-id: shared-redis.yaml refresh: false - data-id: shared-mybatis.yaml refresh: false - data-id: shared-logs.yaml refresh: false - data-id: shared-feign.yaml refresh: false discovery: server-addr: 192.168.150.101:8848 username: nacos password: nacos为什么需要配置两份认证Nacos 在 Spring Cloud 中承担了两个角色配置中心Config存储和管理配置文件应用启动时从这里拉取数据库、Redis 等配置服务注册发现Discovery服务启动时注册自己的地址让其他服务能找到自己两个功能是独立的请求所以需要分别配置认证信息。3.4 重新构建部署完成以上修改后将代码提交到 Gogs删除旧的 Docker 容器和镜像重新触发 Jenkins 构建# 删除旧容器和镜像 docker rm -f tj-user tj-trade docker rmi tj-user:latest tj-trade:latest四、总结这次问题的根本原因是环境差异在 IDE 中直接运行时localhost指向宿主机Nacos 认证信息可以通过其他方式注入但在 Docker 容器中网络隔离和配置缺失的问题被放大了。排查这类问题的思路是先看日志docker logs 容器名是最直接的排查手段分层排查网络 → 连接 → 认证 → 配置逐层检查对比差异和能正常运行的环境对比找出配置差异希望这篇文章能帮到遇到类似问题的朋友。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2602612.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!