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

如何在Kubernetes中为Node.js服务区分内部与外部API?

解决方案

方案1:基于Nginx Ingress + NetworkPolicy(无需额外依赖)

不用修改Node.js服务或启动多实例,仅通过Kubernetes原生组件就能实现需求:

  1. 统一Service配置
    只创建一个ClusterIP类型的Service,指向你的Node.js Pod(假设端口为3000),无需拆分多个Service。

  2. Ingress路径控制
    在Ingress规则中仅对外暴露/products/*路径,不配置/prices的转发规则,这样外部流量无法通过Ingress访问该私有端点。
    示例Ingress配置:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nodejs-api-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$1
    spec:
      rules:
      - host: your-domain.com
        http:
          paths:
          - path: /products/(.*)
            pathType: Prefix
            backend:
              service:
                name: nodejs-service
                port:
                  number: 3000
    
  3. NetworkPolicy限制访问
    创建NetworkPolicy,仅允许集群内指定Pod/Namespace的流量访问Node.js服务的3000端口,确保/prices只能被内部服务调用。
    示例NetworkPolicy配置:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: restrict-prices-api
    spec:
      podSelector:
        matchLabels:
          app: nodejs-api # 替换为你的Node.js Pod标签
      policyTypes:
      - Ingress
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: internal-service # 允许访问的内部服务标签
        ports:
        - protocol: TCP
          port: 3000
      - from:
        - namespaceSelector:
            matchLabels:
              name: internal-namespace # 允许访问的Namespace标签
        ports:
        - protocol: TCP
          port: 3000
    

方案2:使用Istio(服务网格进阶方案)

如果集群已部署Istio,或者需要更精细化的流量控制,Istio可以提供更灵活的访问策略:

  1. 注入Sidecar代理
    确保你的Node.js Pod已注入Istio Sidecar(可通过命名空间自动注入或手动配置)。

  2. Gateway与VirtualService配置
    通过Istio Gateway对外暴露/products/:id路径,VirtualService仅转发该路径到你的服务:

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: nodejs-api-vs
    spec:
      hosts:
      - your-domain.com
      gateways:
      - nodejs-gateway
      http:
      - match:
        - uri:
            prefix: /products/
        route:
        - destination:
            host: nodejs-service
            port:
              number: 3000
    
  3. AuthorizationPolicy控制访问
    创建Istio AuthorizationPolicy,拒绝外部流量访问/prices,仅允许集群内部服务调用:

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: prices-api-auth
    spec:
      selector:
        matchLabels:
          app: nodejs-api
      action: ALLOW
      rules:
      - to:
        - operation:
            paths: ["/prices"]
        from:
        - source:
            notRemoteIpBlocks: ["0.0.0.0/0"] # 仅允许集群内部IP访问
      - to:
        - operation:
            paths: ["/products/*"]
        from:
        - source: {} # 允许所有来源访问公开API
    

方案3:Node.js代码层控制(轻量方案)

如果不想依赖Kubernetes网络组件,可在Express代码中直接判断请求来源,限制/prices的外部访问:

const express = require('express');
const app = express();
const ipaddr = require('ipaddr.js'); // 可选,用于精确IP段匹配

// 集群内部IP段,根据你的Kubernetes配置修改
const INTERNAL_CIDRS = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'];

// 中间件:验证是否为内部请求
const validateInternalAccess = (req, res, next) => {
  const clientIp = req.headers['x-forwarded-for']?.split(',')[0].trim() || req.connection.remoteAddress;
  // 处理IPv4/IPv6格式
  const ip = ipaddr.parse(clientIp.startsWith('::ffff:') ? clientIp.slice(7) : clientIp);
  
  const isInternal = INTERNAL_CIDRS.some(cidr => {
    const [range, prefix] = cidr.split('/');
    return ip.match(ipaddr.parse(range), parseInt(prefix));
  });

  if (isInternal) {
    next();
  } else {
    res.status(403).send('Forbidden');
  }
};

// 公开API
app.get('/products/:id', (req, res) => {
  res.json({ productId: req.params.id });
});

// 内部API,应用访问控制中间件
app.get('/prices', validateInternalAccess, (req, res) => {
  res.json({ prices: 'internal data' });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

内容的提问来源于stack exchange,提问作者Saarang Tiwari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 18:34:54