如何配置入口以在不创建新负载均衡器的情况下将服务部署到子域

How to configure ingress to deploy services to subdomains without creating a new loadbalancer

我是 Kubernetes 的新手,在 mydomain.com 上通过 GKE 部署了一个应用程序,现在想添加另一个应该在 api.mydomain.com 上可用的服务,而不添加新的昂贵的负载均衡器。 api.mydomain 的新入口文件应该是什么样的?我阅读了文档,但不知道如何执行此操作。

这是我 运行 在 mydomain.com 上的第一个服务:

kind: Service
apiVersion: v1
metadata:
  name: app-service
spec:
  selector:
    app: app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "ip"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    acme.cert-manager.io/http01-edit-in-place: "true"
    kubernetes.io/tls-acme: "true"
spec:
  rules:
  - host: mydomain.com
    http:
      paths:
      - backend:
          serviceName: app-service
          servicePort: 80
  tls:
  - hosts:
    - mydomain.com
    secretName: my-certs

我尝试对子域 api.mydomain.com 使用相同的配置,但这不起作用。

kind: Service
apiVersion: v1
metadata:
  name: api-service
spec:
  selector:
    app: api
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "ip"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    acme.cert-manager.io/http01-edit-in-place: "true"
    kubernetes.io/tls-acme: "true"
spec:
  rules:
  - host: api.mydomain.com
    http:
      paths:
      - backend:
          serviceName: api-service
          servicePort: 80
  tls:
  - hosts:
    - api.mydomain.com
    secretName: my-certs-api

也许我以错误的方式解决了这个问题,我是 GKE 的新手,有什么建议吗?

您通常会使用与默认 ingress-gce 不同的 Ingress Controller。 ingress-nginx 非常常见且易于上手,但有很多选项,因此我建议您研究它们并选择最适合您的用例的选项。

尝试"nginx"ingress.class。配置应如下所示(我已删除其中的 tls 部分)。

Nginx Ingress controller 非常简单实用。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: double-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
#    nginx.ingress.kubernetes.io/rewrite-target: /  ### you can use it to route different paths to different services under the same host
spec:
  rules:
  - host: mydomain.com
    http:
      paths:
      - path: /
#      - path: /doc/common(/|$)(.*)    ### if you are using rewrite
        backend:
          serviceName: app-service
          servicePort: 80

  - host: api.mydomain.com
    http:
      paths:
      - path: /
        backend:
          serviceName: api-service
          servicePort: 80
  tls:
  - hosts:
    - api.mydomain.com
    secretName: my-certs-api

希望对您有所帮助!

据我了解,您正在尝试为两个不同的域创建一个具有一个 public IP 地址的 HTTP 负载平衡器。

使用标准 GKE 入口控制器 GCE L7 至少对于 HTTP 协议是可行的(参见下面的示例)。

另请查找 documentation page 关于将多个 SSL 证书与 GCE L7 入口一起使用的信息。

示例:
(mydomain.com替换为example.com,because...答案正文不能包含。)

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: app-service
          servicePort: 80
  - host: api.example.com
    http:
      paths:
      - backend:
          serviceName: api-service
          servicePort: 80

将此 yaml 应用于 GKE 集群会创建一个具有以下主机和路径规则的 HTTP 负载均衡器:

http://example.com:80/* -> app-service:80 (if app-service health-check passed)
http://example.com:80/* -> default-backend:80 (return 404) (if app-service heath-check fails and default-backend health-check passed)
http://api.example.com:80/* -> api-service:80 (if app-service health-check passed)
http://api.example.com:80/* -> default-backend:80 (return 404) (if api-service heath-check fails and default-backend health-check passed)
http://lb.ip.address:80 -> default-backend:80 (return 404) (if  default-backend health-check passed)

HTTP LB returns 502 if all backends' health-checks are failed.