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

EKS集群gRPC Server启用TLS后拒绝连接问题求助

gRPC TLS 配置故障排查与解决方案

问题背景

使用cert-manager生成的tls.crt、tls.key和ca.crt搭建带客户端认证的gRPC TLS服务器,结合Istio网格部署。仅当SERVER_TLS_ENABLED=false时调用正常,开启TLS后遇到多类错误,包括Istio SDS相关报错、连接终止、证书信任问题,同时健康探针在TLS开启时失败。

错误场景回顾

  • 场景1:开启TLS+配置Istio DestinationRule/PeerAuthentication,grpcurl调用报错:
    ❯ grpcurl -proto ../grpc-server/proto/greeter.proto -d '{ "name": "Chase" }' grpc-server.dev-cluster.xxx.xxxx.xx.com:31111 example.Greeter/SayHello
    ERROR:
      Code: Unavailable
      Message: upstream connect error or disconnect/reset before headers. retried and the latest reset reason: remote connection failure, transport failure reason: TLS error: Secret is not supplied by SDS
    
  • 场景2:开启TLS但删除Istio规则,带客户端证书调用报错:
    ❯ grpcurl -proto ../grpc-server/proto/greeter.proto -d '{ "name": "Chase" }' -cert="tls.crt" -key="tls.key" grpc-server.dev-cluster.xxx.xxxx.xx.com:31111 example.Greeter/SayHello
    ERROR:
      Code: Unavailable
      Message: upstream connect error or disconnect/reset before headers. reset reason: connection termination
    
  • 场景3:额外指定CA证书后出现信任错误:
    ❯ grpcurl -proto ../grpc-server/proto/greeter.proto -d '{ "name": "Chase" }' -cacert="ca.crt" -cert="tls.crt" -key="tls.key" grpc-server.dev-cluster.xxx.xxxx.xx.com:31111 example.Greeter/SayHello
    Failed to dial target host "grpc-server.dev-cluster.xxx.xxxxx.xx.com:31111": tls: failed to verify certificate: x509: certificate signed by unknown authority
    
  • 场景4:关闭TLS时调用正常,健康探针也正常。

排查与解决步骤

1. 解决Istio SDS证书供应问题(场景1)

当Istio PeerAuthentication开启严格TLS模式时,sidecar会期望通过SDS(Secret Discovery Service)获取证书,而非直接挂载Kubernetes Secret:

  • 替换cert-manager颁发者为IstioIssuer/ClusterIstioIssuer,普通ClusterIssuer/Issuer无法被Istio SDS识别。
  • 同步DestinationRule的TLS配置与PeerAuthentication模式:
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: grpc-server
    spec:
      host: grpc-server.dev-cluster.svc.cluster.local
      trafficPolicy:
        tls:
          mode: STRICT
          credentialName: grpc-server-tls # 对应cert-manager生成的Secret名称
    
  • 验证sidecar证书加载状态:
    kubectl exec -it <pod-name> -c istio-proxy -- curl http://localhost:15000/certs
    
    确认grpc-server-tls对应的证书状态为READY。

2. 修复gRPC服务端TLS配置(场景2、3)

证书SAN匹配检查

验证服务端证书的**Subject Alternative Name(SAN)**是否包含外部访问域名:

openssl x509 -in tls.crt -text -noout | grep -A 1 "Subject Alternative Name"

若缺失目标域名,更新cert-manager的Certificate资源:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: grpc-server-tls
spec:
  dnsNames:
    - grpc-server.dev-cluster.svc.cluster.local
    - grpc-server.dev-cluster.xxx.xxxx.xx.com # 添加外部访问域名
  issuerRef:
    name: your-istio-issuer
    kind: ClusterIstioIssuer

证书信任链修复(场景3)

验证CA证书是否能正确验证服务端证书:

openssl verify -CAfile ca.crt tls.crt

若验证失败,确保cert-manager生成的Secret包含完整证书链,同时在Certificate资源中指定正确的证书用途:

spec:
  usages:
    - server auth
    - client auth

服务端TLS代码校验

确保服务端正确加载证书并启用客户端认证:

// 加载服务端证书
serverCert, err := tls.LoadX509KeyPair("tls.crt", "tls.key")
if err != nil {
    log.Fatalf("Failed to load server cert: %v", err)
}
// 加载CA证书用于验证客户端
caCert, err := os.ReadFile("ca.crt")
if err != nil {
    log.Fatalf("Failed to read CA cert: %v", err)
}
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(caCert) {
    log.Fatalf("Failed to add CA cert to pool")
}
// 配置TLS
creds := credentials.NewTLS(&tls.Config{
    Certificates: []tls.Certificate{serverCert},
    ClientCAs:    certPool,
    ClientAuth:   tls.RequireAndVerifyClientCert,
})
// 启动gRPC服务器
server := grpc.NewServer(grpc.Creds(creds))

3. 修复健康探针问题

开启TLS后,grpc_health_probe需指定TLS参数:

livenessProbe:
  exec:
    command:
      - grpc_health_probe
      - -addr=:50051
      - -tls
      - -tls-cert=/mnt/certs/tls.crt
      - -tls-key=/mnt/certs/tls.key
      - -tls-ca-cert=/mnt/certs/ca.crt
  initialDelaySeconds: 5
periodSeconds: 10

确保命令中证书路径与容器内挂载路径一致。

4. 端到端流量路径验证

  • 检查Istio Gateway配置(通过Ingress访问时):
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: grpc-gateway
    spec:
      selector:
        istio: ingressgateway
      servers:
      - port:
          number: 31111
          name: grpc-tls
          protocol: GRPC
        tls:
          mode: SIMPLE
          credentialName: grpc-server-tls
        hosts:
        - grpc-server.dev-cluster.xxx.xxxx.xx.com
    
  • 直接测试Pod IP访问:若绕过Istio后调用正常,说明问题出在Istio配置;若仍失败,排查服务端TLS本身的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 05:26:20