You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel部署Kubernetes:环境变量未生效致数据库连接失败

Laravel在Kubernetes环境中未读取Kubernetes Secrets环境变量导致数据库连接失败

错误现象

访问API端点时抛出数据库连接错误:

Illuminate\Database\QueryException: SQLSTATE[HY000] [2002] Connection refused (Connection: mysql, SQL: select count(*) as aggregate from 'users' where 'email' = jhon@gmail.com)

背景信息

  • 可通过服务器终端直接连接RDS实例,数据库及表结构均正常:
ubuntu@ip-xxxxxxxxxxx:/ecom-prod$ mysql -h ecom-db-identifier.xxxxxxxx.us-east-1.rds.amazonaws.com -u root -p
Enter password: xxxxx
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 113
Server version: 8.0.35 Source distribution

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| ecom               |
| sys                |
+--------------------+
5 rows in set (0.29 sec)

mysql> use ecom
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+------------------------+
| Tables_in_ecom         |
+------------------------+
| activity_log           |
| comments               |
| failed_jobs            |
| migrations             |
| password_reset_tokens  |
| permissions            |
| personal_access_tokens |
| policies               |
| users                  |
+------------------------+
9 rows in set (0.28 sec)
  • 容器内已确认Kubernetes Secrets的环境变量已正确加载
  • 使用php artisan tinker可正常读取数据库数据:
> App\Models\User::find(1);
= App\Models\User {#5534
    id: 1,
    name: "Test User",
    email: "test@example.com",
    #email_verified_at: "2024-03-12 15:52:14",
    #password: "y$.bHDGgvm4zY.ucub4L.avOcERJzaS72sC0GZna6cAhy2/3xI1Cr/e",
    image: null,
    #remember_token: "SnA9FiQFl8",
    created_at: "2024-03-12 15:52:14",
    updated_at: "2024-03-12 15:52:14",
  }

关键矛盾点

创建测试路由输出数据库配置时,返回的是config/database.php中的默认值,说明Laravel未读取到环境变量:

// 测试路由代码
\DB::connection(config('database.default'))->getConfig()

// 返回结果
{"driver":"mysql","host":"127.0.0.1","port":"3306","database":"forge","username":"forge","password":"","unix_socket":"","charset":"utf8mb4","collation":"utf8mb4_unicode_ci","prefix":"","prefix_indexes":true,"strict":true,"engine":null,"options":[],"name":"mysql"}

问题排查与解决方案

1. 检查Laravel配置缓存

生产环境下,若执行过php artisan config:cache,Laravel会将配置文件缓存为静态文件,后续环境变量的修改不会生效。解决方法:

  • 进入容器执行命令清除缓存:
    php artisan config:clear
    
  • 若需要缓存配置,需在环境变量加载完成后重新执行:
    php artisan config:cache
    
  • 建议在Kubernetes的容器启动命令中,先清除缓存再启动应用,或者确保缓存命令在环境变量注入后执行。

2. 确认config/database.php配置

检查数据库配置文件是否正确使用env()函数读取环境变量,例如:

'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    // 其他配置...
],

确保所有需要从环境变量获取的配置项都使用了env()函数,而非硬编码值。

3. 验证Laravel运行环境

Laravel在production环境下会自动启用配置缓存,而local环境不会。检查当前运行环境:

php artisan env

若为production,需确保配置缓存是在环境变量加载后生成的;若需要临时调试,可临时切换为local环境验证。

4. 检查Kubernetes环境变量注入

虽然容器内能看到环境变量,但需确认变量名是否与Laravel预期一致:

  • 确保Secrets注入的环境变量键名为DB_HOST、DB_PORT、DB_DATABASE、DB_USERNAME、DB_PASSWORD,与Laravel默认的环境变量名匹配,避免拼写错误(如DB_HOST写成DB_HOSTNAME)。
  • 检查Kubernetes Deployment配置中,环境变量是否正确从Secrets挂载,例如:
    env:
      - name: DB_HOST
        valueFrom:
          secretKeyRef:
            name: your-db-secret
            key: db-host
      - name: DB_PORT
        valueFrom:
          secretKeyRef:
            name: your-db-secret
            key: db-port
      # 其他变量...
    

5. 检查容器启动命令顺序

若容器启动命令中包含config:cache或optimize等优化命令,需确保这些命令在环境变量完全加载后执行。例如,在Dockerfile或Kubernetes启动命令中,不要将缓存命令作为镜像构建时的步骤,而是作为容器启动时的脚本步骤:

# 错误示例:构建镜像时执行缓存,此时环境变量未注入
RUN php artisan config:cache

# 正确示例:容器启动时执行
CMD ["sh", "-c", "php artisan config:cache && php artisan serve --host=0.0.0.0 --port=8000"]

内容的提问来源于stack exchange,提问作者Muhammad AbuBaker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:54:52