DigitalOcean Kubernetes中NestJs无法连接KeyDb求助
问题:NestJs应用无法连接KeyDb容器(K8s部署环境)
我在DigitalOcean上部署了NestJs应用和KeyDb(Redis替代方案)容器,将Docker Compose配置转换为K8s配置并成功部署后,NestJs日志中出现以下连接错误:
[ioredis] Unhandled error event: Error: getaddrinfo EAI_AGAIN keydb at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26) [ioredis] Unhandled error event: Error: connect ETIMEDOUT at Socket.<anonymous> (/usr/src/app/node_modules/ioredis/built/Redis.js:170:41) at Object.onceWrapper (node:events:631:28) at Socket.emit (node:events:517:28) at Socket._onTimeout (node:net:598:8) at listOnTimeout (node:internal/timers:569:17) at process.processTimers (node:internal/timers:512:7) [ioredis] Unhandled error event: Error: getaddrinfo EAI_AGAIN keydb at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26)
相关配置文件
Dockerfile
# Start with the official Node.js 18 Alpine image FROM node:18-alpine # Set the working directory inside the container WORKDIR /usr/src/app # Copy package.json and yarn.lock files COPY package.json yarn.lock ./ # Install dependencies including 'devDependencies' for building the app RUN yarn install --frozen-lockfile # Copy the rest of the application code COPY . . # Build the application RUN yarn build # Expose the port your app will run on EXPOSE 3000 # Command to start the app CMD ["node", "dist/main"]
Docker Compose文件
version: '3.8' services: keydb: image: eqalpha/keydb ports: - "6379:6379" networks: - nestjs-keydb-net restart: always nestjs-app: image: dmytroye/node-kubernetes ports: - "80:8080" depends_on: - keydb environment: - KEYDB_HOST=keydb - KEYDB_PORT=6379 networks: - nestjs-keydb-net restart: always networks: nestjs-keydb-net: driver: bridge
Redis构造函数代码
constructor() { this.client = new Redis({ host: 'keydb', port: 6379, }); }
解决方法
检查K8s Service配置:确保KeyDb对应的Service名称为
keydb,K8s内部通过Service名称做DNS解析,而非容器名称。确认Service的spec.selector能正确匹配KeyDb的Pod标签,端口映射为6379。验证DNS解析与网络连通性:在NestJs的Pod内执行
nslookup keydb,检查是否能解析到KeyDb Service的ClusterIP。如果解析失败,确认两者在同一Namespace下,且无NetworkPolicy阻断访问。替换硬编码Host为环境变量:修改Redis构造函数,读取Docker Compose中定义的环境变量,避免硬编码:
constructor() { this.client = new Redis({ host: process.env.KEYDB_HOST || 'keydb', port: parseInt(process.env.KEYDB_PORT, 10) || 6379, }); }处理K8s中的依赖启动顺序:Docker Compose的
depends_on在K8s中不生效,需通过探针或InitContainer确保KeyDb就绪后再启动NestJs:- 给KeyDb的Deployment添加ReadinessProbe和LivenessProbe,检测6379端口:
livenessProbe: tcpSocket: port: 6379 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: tcpSocket: port: 6379 initialDelaySeconds: 5 periodSeconds: 10 - 给NestJs的Deployment添加InitContainer,等待KeyDb端口可用:
initContainers: - name: wait-for-keydb image: busybox:1.28 command: ['sh', '-c', 'until nc -z keydb 6379; do echo waiting for keydb; sleep 2; done;']
- 给KeyDb的Deployment添加ReadinessProbe和LivenessProbe,检测6379端口:
确认KeyDb端口暴露配置:检查KeyDb的Deployment中容器端口是否为6379,Service类型使用ClusterIP即可(无需NodePort,除非需要外部访问)。
内容的提问来源于stack exchange,提问作者Yermolenko Dmytro
相关产品推荐
相关产品推荐

