GKE - 使用 Ingress 和内部负载平衡公开服务
GKE - expose service with Ingress and Internal Load Balancing
我在内部 GKE 集群上有 REST API Web 服务,我想通过内部 HTTP 负载平衡公开它。
我们称此服务为“蓝色”服务:
我想在以下映射中公开它:
http://api.xxx.yyy.internal/blue/isalive -> http://blue-service/isalive
http://api.xxx.yyy.internal/blue/v1/get -> http://blue-service/v1/get
http://api.xxx.yyy.internal/blue/v1/create -> http://blue-service/v1/create
http://api.xxx.yyy.internal/ -> http://blue-service/ (expose Swagger)
我省略了部署 yaml,因为它与讨论的相关性较低。
但是我的服务 yaml 看起来像这样:
apiVersion: v1
kind: Service
metadata:
name: blue-service
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
selector:
app: blue-service
我的 Ingress 配置如下:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: blue-ingress
annotations:
kubernetes.io/ingress.class: "gce-internal"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: api.xxx.yyy.internal
http:
paths:
- path: /blue/*
backend:
serviceName: blue-service
servicePort: 80
但是,我收到所有请求的 404。 /blue/v1/get
、/blue/v1/create
和 /blue/isalive
returns 404.
在我的“蓝色”应用程序中,我记录了所有未找到的请求,我可以清楚地看到我的 URI 没有被重写,到达应用程序的请求是 /blue/v1/get
、/blue/v1/create
和 /blue/isalive
.
我在 Ingress 配置中缺少什么?我该如何修复这些重写?
我解决了这个问题并把它写在这里以备忘,希望有人会觉得它有用。
第一个问题是我有混合注释类型。 GKE 入口控制器之一,第二个用于 Nginx 服务器控制器。目前 GKE ingress controller 不支持 URL 重写功能,所以我需要使用 nginx ingress controller。
所以我需要安装基于 Nginx 的入口控制器。它可以使用 Helm chart 或部署 yaml 轻松完成。但是,默认情况下,此控制器将使用外部负载均衡器公开入口,这不是我想要的。所以我们需要修改这个控制器的部署图表或 YAML 文件。
我没有使用 Helm,所以我使用 wget 命令下载了 yaml 本身。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/cloud/deploy.yaml
在编辑器中打开它,在命名空间 ingress-nginx
中找到服务名称 ingress-nginx-controller
的定义。添加以下注释。
cloud.google.com/load-balancer-type: "Internal"
之后我可以 运行 kubectl apply -f deploy.yaml
命令为我创建 Ingress 控制器。配置它需要几分钟时间。
此外,我需要打开防火墙规则,这将允许主节点访问端口 8443/tcp
上的工作节点。
最后一项是入口 yaml 本身,它应该如下所示:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "nginx"
name: blue-ingress
namespace: default
spec:
rules:
- host: api.xxx.yyy.internal
http:
paths:
- backend:
serviceName: blue-service
servicePort: 80
path: /blue(/|$)(.*)
我在内部 GKE 集群上有 REST API Web 服务,我想通过内部 HTTP 负载平衡公开它。
我们称此服务为“蓝色”服务: 我想在以下映射中公开它:
http://api.xxx.yyy.internal/blue/isalive -> http://blue-service/isalive
http://api.xxx.yyy.internal/blue/v1/get -> http://blue-service/v1/get
http://api.xxx.yyy.internal/blue/v1/create -> http://blue-service/v1/create
http://api.xxx.yyy.internal/ -> http://blue-service/ (expose Swagger)
我省略了部署 yaml,因为它与讨论的相关性较低。
但是我的服务 yaml 看起来像这样:
apiVersion: v1
kind: Service
metadata:
name: blue-service
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
selector:
app: blue-service
我的 Ingress 配置如下:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: blue-ingress
annotations:
kubernetes.io/ingress.class: "gce-internal"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: api.xxx.yyy.internal
http:
paths:
- path: /blue/*
backend:
serviceName: blue-service
servicePort: 80
但是,我收到所有请求的 404。 /blue/v1/get
、/blue/v1/create
和 /blue/isalive
returns 404.
在我的“蓝色”应用程序中,我记录了所有未找到的请求,我可以清楚地看到我的 URI 没有被重写,到达应用程序的请求是 /blue/v1/get
、/blue/v1/create
和 /blue/isalive
.
我在 Ingress 配置中缺少什么?我该如何修复这些重写?
我解决了这个问题并把它写在这里以备忘,希望有人会觉得它有用。
第一个问题是我有混合注释类型。 GKE 入口控制器之一,第二个用于 Nginx 服务器控制器。目前 GKE ingress controller 不支持 URL 重写功能,所以我需要使用 nginx ingress controller。
所以我需要安装基于 Nginx 的入口控制器。它可以使用 Helm chart 或部署 yaml 轻松完成。但是,默认情况下,此控制器将使用外部负载均衡器公开入口,这不是我想要的。所以我们需要修改这个控制器的部署图表或 YAML 文件。 我没有使用 Helm,所以我使用 wget 命令下载了 yaml 本身。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/cloud/deploy.yaml
在编辑器中打开它,在命名空间 ingress-nginx
中找到服务名称 ingress-nginx-controller
的定义。添加以下注释。
cloud.google.com/load-balancer-type: "Internal"
之后我可以 运行 kubectl apply -f deploy.yaml
命令为我创建 Ingress 控制器。配置它需要几分钟时间。
此外,我需要打开防火墙规则,这将允许主节点访问端口
8443/tcp
上的工作节点。最后一项是入口 yaml 本身,它应该如下所示:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: / kubernetes.io/ingress.class: "nginx" name: blue-ingress namespace: default spec: rules: - host: api.xxx.yyy.internal http: paths: - backend: serviceName: blue-service servicePort: 80 path: /blue(/|$)(.*)