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

基于Nginx Ingress的gRPC TLS加密通信方案(从REST迁移)

完全可行!TLS终止在Nginx Ingress层的gRPC方案实现

你想要的方案完全可以落地,核心是借助Nginx Ingress对gRPC(基于HTTP/2)的原生支持,让Ingress承担TLS终止工作,客户端直接通过域名验证Let's Encrypt证书,无需手动嵌入证书文件。以下是具体实现步骤:

1. 修改Ingress配置

给现有Ingress添加关键注解,明确后端为gRPC服务并确保HTTP/2启用(gRPC依赖HTTP/2传输)。修改后的YAML配置如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fanout-ingress
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
    cert-manager.io/issuer: letsencrypt-prod
    # 指定后端为gRPC协议,Ingress自动处理HTTP/2转gRPC的逻辑
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
    # 显式启用HTTP/2(部分Nginx Ingress版本默认已开启,显式声明更稳妥)
    nginx.ingress.kubernetes.io/http2-push-preload: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: fancy-domain.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api
            port:
              number: 8080
  tls:
  - hosts:
    - fancy-domain.com
    secretName: letsencrypt-prod-tls

2. 调整Go后端gRPC服务

  • 确保Go gRPC服务监听在8080端口(与Ingress配置的后端端口一致)
  • 由于TLS已在Ingress层终止,后端与Ingress之间走明文gRPC,服务无需配置TLS,直接用基础gRPC Server启动即可:
package main

import (
    "net"
    "your/proto/package/path"
    "google.golang.org/grpc"
)

func main() {
    lis, err := net.Listen("tcp", ":8080")
    if err != nil {
        panic(err)
    }
    s := grpc.NewServer() // 无需传入TLS凭证
    pb.RegisterYourServiceServer(s, &yourServer{})
    if err := s.Serve(lis); err != nil {
        panic(err)
    }
}

3. Dart/Flutter客户端配置

使用官方grpc包创建客户端时,直接用默认安全通道,客户端会自动从系统信任根中验证Ingress的Let's Encrypt证书,完全不需要嵌入任何证书文件:

import 'package:grpc/grpc.dart';
import 'your_proto_file.pbgrpc.dart';

void main() async {
  // 连接到Ingress的443端口,自动启用TLS并验证证书
  final channel = ClientChannel(
    'fancy-domain.com',
    port: 443,
    options: ChannelOptions(
      credentials: ChannelCredentials.secure(),
    ),
  );

  final client = YourServiceClient(channel);

  try {
    // 调用gRPC方法,注意路径匹配:如果proto服务路径包含/api前缀,Ingress的Prefix规则会自动匹配
    final response = await client.yourGrpcMethod(YourRequest());
    print('收到响应: ${response}');
  } catch (e) {
    print('请求出错: ${e}');
  } finally {
    await channel.shutdown();
  }
}

注意事项

  • 路径匹配:如果gRPC服务的完整路径(如/com.fancy.api.v1.UserService/GetUser)需要匹配Ingress的/api前缀,可调整proto的package或service定义,或把Ingress的path改为/(无其他REST服务冲突时)
  • 移动端兼容性:Let's Encrypt根证书已被iOS、Android系统默认信任,移动端客户端无需额外配置即可正常验证证书
  • 测试验证:可用grpcurl工具快速验证连通性:
    grpcurl -d '{}' fancy-domain.com:443 com.fancy.api.v1.UserService/GetUser
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:32:25