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

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:

    1. 给KeyDb的Deployment添加ReadinessProbe和LivenessProbe,检测6379端口:
      livenessProbe:
        tcpSocket:
          port: 6379
        initialDelaySeconds: 5
        periodSeconds: 10
      readinessProbe:
        tcpSocket:
          port: 6379
        initialDelaySeconds: 5
        periodSeconds: 10
      
    2. 给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端口暴露配置:检查KeyDb的Deployment中容器端口是否为6379,Service类型使用ClusterIP即可(无需NodePort,除非需要外部访问)。

内容的提问来源于stack exchange,提问作者Yermolenko Dmytro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 13:10:19