【问题标题】:GKE Kubernetes Ingress not routing traffic to microservicesGKE Kubernetes Ingress 未将流量路由到微服务
【发布时间】:2021-12-03 21:48:34
【问题描述】:

我对 Kubernetes 还很陌生,并试图将我认为非常常见的用例部署到我们使用 Terraform 创建的 GKE 集群上,微服务都托管在一个集群上,但我终生无法获得路由为正确的服务提供流量。我正在尝试创建的设置如下:

  • 每个微服务的部署和服务(canvas-servicevideo-service
  • 集群上的单一入口(GCE 类),托管在静态 IP 上,根据路径将流量路由到每个服务

当前配置如下:

canvas-service.yaml

# Deployment (Service Manager)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: canvas-service-deployment
  labels:
    name: canvas-service
spec:
  replicas: 2
  selector:
    matchLabels:
      app: canvas-service
  template:
    metadata:
      labels:
        app: canvas-service
    spec:
      restartPolicy: Always
      containers:
      - name: canvas-service
        image: gcr.io/emile-learning-dev/canvas-service-image:latest
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
        ports:
          - name: root
            containerPort: 8080
        resources:
          requests:
            memory: "4096Mi"
            cpu: "1000m"
          limits:
            memory: "8192Mi"
            cpu: "2000m"
---
# Service
apiVersion: v1
kind: Service
metadata:
  name: canvas-service
spec:
  type: NodePort
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: canvas-service

video-service.yaml

# Deployment (Service Manager)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: video-service-deployment
  labels:
    name: video-service
spec:
  replicas: 2
  selector:
    matchLabels:
      app: video-service
  template:
    metadata:
      labels:
        app: video-service
    spec:
      restartPolicy: Always
      containers:
      - name: video-service
        image: gcr.io/emile-learning-dev/video-service-image:latest
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
        ports:
          - name: root
            containerPort: 8080
        resources:
          requests:
            memory: "4096Mi"
            cpu: "1000m"
          limits:
            memory: "8192Mi"
            cpu: "2000m"
---
# Service
apiVersion: v1
kind: Service
metadata:
  name: video-service
spec:
  type: NodePort
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: video-service

services-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: services-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "services-ip"
spec:
  defaultBackend:
    service:
      name: canvas-service
      port:
        number: 80
  rules:
  - http:
      paths:
      - path: /canvas/*
        pathType: ImplementationSpecific
        backend:
          service:
            name: canvas-service
            port:
              number: 80
      - path: /video/*
        pathType: ImplementationSpecific
        backend:
          service:
            name: video-service
            port:
              number: 80

kubectl describe ingress services-ingress 的输出如下所示:

Name:             services-ingress
Namespace:        default
Address:          34.107.136.153
Default backend:  canvas-service:80 (10.244.2.17:8080,10.244.5.15:8080)
Rules:
  Host        Path  Backends
  ----        ----  --------
  *
              /canvas/*   canvas-service:80 (10.244.2.17:8080,10.244.5.15:8080)
              /video/*    video-service:80 (10.244.1.15:8080,10.244.8.51:8080)
Annotations:  ingress.kubernetes.io/backends: {"k8s-be-30551--8ba41a687ec15071":"HEALTHY","k8s-be-32145--8ba41a687ec15071":"HEALTHY"}
              ingress.kubernetes.io/forwarding-rule: k8s2-fr-xlhz0sas-default-services-ingress-hqyvwyy1
              ingress.kubernetes.io/target-proxy: k8s2-tp-xlhz0sas-default-services-ingress-hqyvwyy1
              ingress.kubernetes.io/url-map: k8s2-um-xlhz0sas-default-services-ingress-hqyvwyy1
              kubernetes.io/ingress.global-static-ip-name: services-ip
Events:
  Type    Reason     Age                  From                     Message
  ----    ------     ----                 ----                     -------
  Normal  Sync       9m36s                loadbalancer-controller  UrlMap "k8s2-um-xlhz0sas-default-services-ingress-hqyvwyy1" created
  Normal  Sync       9m34s                loadbalancer-controller  TargetProxy "k8s2-tp-xlhz0sas-default-services-ingress-hqyvwyy1" created
  Normal  Sync       9m26s                loadbalancer-controller  ForwardingRule "k8s2-fr-xlhz0sas-default-services-ingress-hqyvwyy1" created
  Normal  IPChanged  9m26s                loadbalancer-controller  IP is now 34.107.136.153
  Normal  Sync       6m56s (x5 over 11m)  loadbalancer-controller  Scheduled for sync

对于测试,我在/health 为每项服务都有一个健康检查路线。我遇到的是,当我点击{public_ip}/health(使用默认后端)时,我得到了预期的响应。但是当我点击{public_ip}/canvas/health{public_ip}/video/health 时,我会得到404 Not Found

我知道这与整个服务路由结构位于/canvas/video 路由这一事实有关,但我认为/* 应该解决这个问题。我想基本上使每个服务的根路由存在于相应的子路径/canvas/video 上。很想听听你们对我做错了什么导致流量无法正确路由的任何想法。

如果 GCP 默认 Ingress 资源存在问题,或者这不在其功能范围内,我完全愿意使用 nginx Ingress。但是,我根本无法获得nginx Ingress 来公开 IP,因此我认为 GCP Ingress 可能是让该集群正常工作的更短路径。如果我对此有误,也请告诉我。

【问题讨论】:

    标签: docker kubernetes microservices google-kubernetes-engine kubernetes-ingress


    【解决方案1】:

    这是由于Ingress 中定义的路径。将路径类型更改为 /video/canvas 即可。

    要了解这背后的原因,您需要阅读有关pathpathType 的nginx 入口控制器文档。您还可以根据此处的文档在路径中使用正则表达式模式https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/

    提示:如有疑问,您可以随时前往 nginx 入口控制器 pod,查看 nginx.conf 文件中有关 nginx 确定的 location 的信息。

    【讨论】:

    • 就是这样,这不是 nginx 入口控制器。这是本机 GCP 入口,我尝试了几天调整 nginx 入口,但没有成功。你知道任何可行的例子吗?
    猜你喜欢
    • 2020-08-12
    • 2020-03-13
    • 1970-01-01
    • 1970-01-01
    • 2019-02-03
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 2023-01-02
    相关资源
    最近更新 更多