Docker环境下K6无法挂载本地模块的问题求助
我来帮你理清这个问题的根源,以及对应的解决方案:
问题根源
k6的运行环境不是基于Node.js的——它使用独立的Go嵌入V8引擎来执行测试脚本,完全不兼容Node.js的核心模块和npm生态中的Node专属包(比如request-promise、aws-sdk这类依赖Node API的包)。
当你在k6脚本里导入request-promise时,k6会错误地将它当作一个HTTP URL去请求(因为它不识别Node的require/import模块规则),这就导致了DNS解析超时的错误:
ERRO[0024] GoError: Get https://request-promise?_k6=1 : dial tcp: lookup request-promise on 127.0.0.11:53: read udp 127.0.0.1:55571->127.0.0.11:53: i/o timeout
即使你挂载了本地的node_modules目录也没用,因为k6根本不遵循Node的模块加载机制。
解决方案
1. 用k6原生http模块替代request-promise
k6内置了功能完整的http模块,足以处理HTTP请求,完全不需要依赖Node的request-promise。举个POST请求的例子:
import http from 'k6/http'; import { check } from 'k6'; export default function () { const url = 'https://your-target-api.com'; const payload = JSON.stringify({ key: 'value' }); const params = { headers: { 'Content-Type': 'application/json', // 如果需要认证头,这里直接添加 }, }; const res = http.post(url, payload, params); check(res, { 'status is 200': (r) => r.status === 200, }); }
2. 用k6官方AWS扩展处理认证生成JWT
如果你需要对接AWS生成JWT Token,不要使用Node版的aws-sdk,而是用k6官方提供的AWS扩展(k6/x/aws),它是专门为k6环境设计的,兼容k6的运行时。
步骤:
- 使用包含AWS扩展的k6镜像:比如
grafana/k6:latest已经包含了常用扩展,或者你可以自行构建带扩展的镜像。 - 在脚本中导入并使用AWS扩展来生成认证Token,比如对接AWS Cognito生成JWT的示例:
import { AWSConfig, CognitoIdentityProvider } from 'k6/x/aws/cognitoidentityserviceprovider'; const awsConfig = new AWSConfig({ region: 'us-east-1', accessKeyId: 'YOUR_AWS_ACCESS_KEY', secretAccessKey: 'YOUR_AWS_SECRET_KEY', }); const cognito = new CognitoIdentityProvider(awsConfig); export default function () { // 调用Cognito API生成JWT const authParams = { AuthFlow: 'USER_PASSWORD_AUTH', ClientId: 'YOUR_COGNITO_CLIENT_ID', AuthParameters: { USERNAME: 'test-user', PASSWORD: 'test-password', }, }; const response = cognito.initiateAuth(authParams); const jwtToken = response.AuthenticationResult.IdToken; // 之后就可以用这个Token在HTTP请求中做认证 const res = http.get('https://your-protected-api.com', { headers: { Authorization: `Bearer ${jwtToken}` }, }); }
3. 关于本地模块的正确用法
如果你的测试脚本需要自定义的纯JavaScript模块(无Node.js依赖),可以挂载本地目录,但要确保模块是ES模块格式,并且不依赖Node的API。k6支持用import导入这类纯JS模块。
总结
- 不要在k6脚本中使用Node.js专属的npm包,改用k6原生模块或官方扩展
- 对接AWS认证时,使用
k6/x/aws扩展而非Node版aws-sdk - 挂载
node_modules对k6来说没有意义,因为它不识别Node的模块系统
内容的提问来源于stack exchange,提问作者user860511

