【发布时间】:2019-10-10 04:32:28
【问题描述】:
我想使用 HTTP/2 和双向 TLS 在 GKE 上部署 gRPC + HTTP 服务器。我的部署具有自定义路径的就绪探针和活性探针。我通过 Ingress 公开 gRPC 和 HTTP 服务器。
部署的探针和暴露的端口:
livenessProbe:
failureThreshold: 3
httpGet:
path: /_ah/health
port: 8443
scheme: HTTPS
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /_ah/health
port: 8443
scheme: HTTPS
name: grpc-gke
ports:
- containerPort: 8443
protocol: TCP
- containerPort: 50052
protocol: TCP
NodePort 服务:
apiVersion: v1
kind: Service
metadata:
name: grpc-gke-nodeport
labels:
app: grpc-gke
annotations:
cloud.google.com/app-protocols: '{"grpc":"HTTP2","http":"HTTP2"}'
service.alpha.kubernetes.io/app-protocols: '{"grpc":"HTTP2", "http": "HTTP2"}'
spec:
type: NodePort
ports:
- name: grpc
port: 50052
protocol: TCP
targetPort: 50052
- name: http
port: 443
protocol: TCP
targetPort: 8443
selector:
app: grpc-gke
入口:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: grpc-gke-ingress
annotations:
kubernetes.io/ingress.allow-http: "false"
#kubernetes.io/ingress.global-static-ip-name: "grpc-gke-ip"
labels:
app: grpc-gke
spec:
rules:
- http:
paths:
- path: /_ah/*
backend:
serviceName: grpc-gke-nodeport
servicePort: 443
backend:
serviceName: grpc-gke-nodeport
servicePort: 50052
在创建 liveness 和 readiness 探针之前,pod 确实存在,并且处于“绿色”状态。我在我的服务器上看到/_ah/live 和/_ah/ready 都被kube-probe 调用并且服务器以200 响应响应的常规日志。
我在负载平衡器 (LB) 上使用 Google 托管的 TLS 证书。我的 HTTP 服务器创建了一个自签名证书——灵感来自 this blog。
我在开始查看探测日志后创建 Ingress。之后,它会创建一个具有两个后端的 LB,一个用于 HTTP,一个用于 gRPC。 HTTP 后端的运行状况检查正常,并且可以从 Internet 访问 HTTP 服务器。 gRPC 后端的健康检查失败,因此 LB 没有路由 gRPC 协议,我收到了502 错误响应。
这是 GKE 主控 1.12.7-gke.10。我还尝试了新的 1.13 和旧的 1.11 大师。集群启用了 HTTP 负载平衡并启用了 VPC-native。有防火墙规则允许从 LB 访问我的 pod(我什至尝试允许来自所有 IP 地址的所有端口)。延迟探测也无济于事。
有趣的是,我部署了几乎相同的设置,只是服务器的 Docker 映像不同,几个月前它运行没有任何问题。我什至可以部署服务器的新 Docker 映像,一切都很棒。我找不到这两者之间的任何区别。
还有一个问题,Ingress 卡在“Creating Ingress”状态好几天了。它永远不会结束,也永远不会看到 LB。 Ingress 的 LB 从来没有前端,我总是必须手动添加一个带有静态 IP 和 Google 管理的 TLS 证书的 HTTP/2 前端。这应该只发生在没有“HTTP 负载平衡”的情况下创建的集群上,但在我的情况下,每次我的所有“启用了 HTTP 负载平衡”的集群都会发生这种情况。工作部署已经处于这种状态数月了。
任何想法为什么 gRPC 后端的健康检查可能会失败,即使我看到了 kube-probe 调用就绪和活跃端点的日志?
编辑:
describe svc grpc-gke-nodeport
Name: grpc-gke-nodeport
Namespace: default
Labels: app=grpc-gke
Annotations: cloud.google.com/app-protocols: {"grpc":"HTTP2","http":"HTTP2"}
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"cloud.google.com/app-protocols":"{\"grpc\":\"HTTP2\",\"http\":\"HTTP2\"}",...
service.alpha.kubernetes.io/app-protocols: {"grpc":"HTTP2", "http": "HTTP2"}
Selector: app=grpc-gke
Type: NodePort
IP: 10.4.8.188
Port: grpc 50052/TCP
TargetPort: 50052/TCP
NodePort: grpc 32148/TCP
Endpoints: 10.0.0.25:50052
Port: http 443/TCP
TargetPort: 8443/TCP
NodePort: http 30863/TCP
Endpoints: 10.0.0.25:8443
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
gRPC 后端的运行状况检查是 HTTP/2 GET,使用路径 / 在端口 32148 上。它的描述是“默认 kubernetes L7 负载平衡健康检查”。其中 HTTP 的后端健康检查的描述是“Kubernetes L7 健康检查生成与就绪探测设置。”。因此,gRPC 后端的运行状况检查不是从就绪探针创建的。
编辑运行状况检查以指向端口 30863 并更改准备就绪探测的路径可解决此问题。
【问题讨论】:
-
我很好奇这是否可能是 LB 健康检查的限制。修改 gRPC HC 以匹配 HTTP 应该可以正常工作,因为我们知道该路径正在响应。我看看能不能找到什么
-
我还注意到您的就绪和活跃度探测都检查端口 8443,而不是 gRPC。
-
@PatrickW 我需要两个探测器来检查端口 8443,因为我不知道在 gRPC 服务器正在侦听的端口上返回 HTTP/2 响应。我基本上有一个 HTTP 服务器在与 gRPC 服务器相同的二进制文件中侦听 8443,它会根据需要响应不同的运行状况检查。但是 gRPC 后端的 LB HC 忽略了就绪探测设置。
-
好的,这就是问题所在,HC 不适用于 gRCP 端口。这就是对端口 32148 使用 LB HC 失败的原因。在上面的配置中,只有端口 30863 会产生一个健康的后端。 HTTP/2 仍处于测试阶段,正在努力让 gRPC 充分发挥作用。
-
@PatrickW 我认为应该将 LB HC 设置为就绪探测器的设置。我正在使用创建 LB 的 Ingress。 ...有趣的是,我们已经部署了类似的设置(几个月前,但每周更新)并且“坏”的 LB HC 工作正常。它设置为
/和 gRPC 后端的 NodePort 端口。奇怪的测试版:)
标签: kubernetes google-kubernetes-engine grpc kubernetes-ingress kubernetes-health-check