对于部署在ACK集群中的gRPC应用,为实现外部客户端的访问,可配置Nginx Ingress并添加 nginx.ingress.kubernetes.io/backend-protocol: "GRPC" 注解来路由gRPC流量。
核心示例
以下为Nginx Ingress安全暴露gRPC服务的核心配置。
gRPC 协议代理:通过
backend-protocol: "GRPC"注解,明确指示 Ingress 将流量作为 gRPC(基于HTTP/2)进行代理,而不是默认的HTTP。TLS 加密:为示例域名
grpc.example.com启用了 TLS,并使用Secret中存储的证书进行加密。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grpc-ingress
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "GRPC" # 关键:指明后端服务为gRPC协议
spec:
tls:
- hosts:
- grpc.example.com # 替换为gRPC服务域名
secretName: nginx-ingress-tls # 配置存储证书的Secret
rules:
- host: grpc.example.com # 替换为gRPC服务域名
#...部署gRPC示例应用
控制台
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择。
在无状态页面,单击使用YAML创建资源,然后将以下内容复制到模板区域,单击创建。
在弹窗中找到目标无状态应用,单击查看,确认Pod状态为
Running。
kubectl
将以下YAML内容保存为grpc.yaml文件。
apiVersion: apps/v1 kind: Deployment metadata: name: grpc-service spec: replicas: 1 selector: matchLabels: run: grpc-service template: metadata: labels: run: grpc-service spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/grpc-server:latest imagePullPolicy: Always name: grpc-service ports: - containerPort: 50051 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: grpc-service spec: ports: - port: 50051 protocol: TCP targetPort: 50051 selector: run: grpc-service sessionAffinity: None type: NodePort部署gRPC应用并创建服务(Service)。
kubectl apply -f grpc.yaml确认目标应用Pod状态为
Running。kubectl get pod | grep grpc-service
该服务基于以下 .proto 文件定义。服务名为 Greeter,提供了一个 SayHello 方法。
将SSL证书存储为Secret
要在 Nginx Ingress 中启用 gRPC 所依赖的 HTTP/2 协议,必须先开启 TLS 加密。可以将 SSL证书与私钥存入Secret中进行安全管理,并通过引用该Secret来完成TLS加密配置。
购买或生成SSL证书。
(可选)若已从阿里云购买证书,需下载SSL证书文件到本地。
创建Secret,存储证书及私钥。
控制台
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择。
在保密字典页面,选择
default命名空间后,单击左侧创建,在弹出面板中配置新的保密字典。配置完成后,单击确定。名称:
nginx-ingress-tls类型:TLS证书
证书:证书文件(
.crt或.pem)中的完整内容密钥:私钥文件(
.key)中的完整内容
kubectl
将以下
<PUBLIC_CERT>、<PRIVATE_KEY>替换成实际的证书文件(.crt或.pem)路径和私钥文件(.key)路径,然后执行命令将证书和私钥存储为Secret。# --key 参数指定私钥文件,--cert 参数指定证书文件 kubectl create secret tls nginx-ingress-tls --cert <PUBLIC_CERT> --key <PRIVATE_KEY>
配置Ingress暴露服务
登录容器服务管理控制台,单击目标集群名称,在集群详情页左侧导航栏选择组件管理。
在搜索框输入Nginx Ingress Controller并定位组件,然后在目标组件卡片上单击安装。
v1.2之前版本的组件已不再维护,请升级Nginx Ingress Controller组件至最新版。
配置Ingress,通过注解(
annotations)指明后端协议为gRPC,并引用上一步创建的Secret。控制台
在左侧导航栏,选择。选择
default命名空间,单击创建 Ingress。添加以下Ingress配置,单击确定。
网关类型:选择
Nginx Ingress。名称:
grpc-ingress。域名:
grpc.example.com。路径映射:路径:
/,匹配规则:前缀匹配(Prefix),服务名称:grpc-service,端口:50051。TLS配置:开启。域名:
grpc.example.com,保密字典:nginx-ingress-tls。注解:名称:
nginx.ingress.kubernetes.io/backend-protocol,值GRPC。
在路由列表页,查看新建的Ingress,获取访问端点地址。
Nginx Ingress生效过程耗时约10秒,可稍后单击刷新按钮获取端点信息。若长时间未更新端点信息,可单击路由名称,进入事件页签,进行异常问题排查。
kubectl
将以下YAML内容保存为grpc-ingress.yaml文件,然后执行
kubectl apply -f grpc-ingress.yaml命令。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grpc-ingress annotations: # 关键:指明后端服务为gRPC协议 nginx.ingress.kubernetes.io/backend-protocol: "GRPC" spec: ingressClassName: nginx # 配置TLS,引用存储证书的Secret tls: - hosts: - grpc.example.com # 替换为gRPC服务域名 secretName: nginx-ingress-tls # 上一步创建Secret指定的名称 rules: - host: grpc.example.com # 替换为gRPC服务域名 http: paths: - path: / pathType: Prefix backend: service: name: grpc-service port: number: 50051获取访问端点地址。Ingress IP分配会有延迟,若无输出结果,可等待10秒后重试。
ADDRESS=$(kubectl get ingress grpc-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo $ADDRESS
访问gRPC服务
为便于测试,以下提供本地域名映射方法。
macOS / Linux:
sudo vi /etc/hosts。Windows: 以管理员身份打开记事本,然后打开
C:\Windows\System32\drivers\etc\hosts。
将以下地址替换为实际访问端点地址,在文件末尾添加以下域名映射记录并保存。
47.102.XX.XX grpc.example.com安装grpcurl工具。调用gRPC服务接口。
grpcurl -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter/SayHello{ "message": "Hello gRPC" }
使用限制
由于gRPC基于长连接的特性,Nginx Ingress暂不支持为其配置服务权重(service-weight)路由。
常见问题
如何生成自签名证书?
执行以下命令可生成一个域名为grpc.example.com、有效期为365天的自签名证书(grpc.crt)和私钥(grpc.key)。
openssl req -x509 -newkey rsa:2048 -keyout grpc.key -out grpc.crt -days 365 -nodes \
-subj "/CN=grpc.example.com" \
-addext "subjectAltName=DNS:grpc.example.com"自签名证书缺乏权威 CA 认证,浏览器及各类客户端默认不予信任,用户访问时将触发安全警告,请勿在生产环境中使用。
SSL证书和TLS证书的区别?
SSL (Secure Sockets Layer) 为早期的加密协议,现已被更安全的TLS (Transport Layer Security) 协议取代。
在行业术语中,“SSL证书”已成为一个习惯性描述,其更准确的名称应为“TLS证书”。