无法通过 nginx-ingress-controller 访问 Kubernetes ClusterIP 服务
Unable to access Kubernetes ClusterIP services via nginx-ingress-controller
我是一名 Kubernetes 业余爱好者,试图在 GKE 上使用 NGINX 入口控制器。我正在按照 this google 云文档为我的服务设置 NGINX Ingress,但是,我在访问 NGINX 位置时遇到了问题。
什么有效?
- 使用 Helm 部署 Ingress-Controller(启用 RBAC)
- ClusterIP 服务部署
什么不起作用?
- 使用唯一路径(扇出路由)公开多个 ClusterIP 服务的入口资源
K8S 服务
[msekar@ebs kube-base]$ kubectl get services -n payment-gateway-7682352
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-controller LoadBalancer 10.35.241.255 35.188.161.171 80:31918/TCP,443:31360/TCP 6h
nginx-ingress-default-backend ClusterIP 10.35.251.5 <none> 80/TCP 6h
payment-gateway-dev ClusterIP 10.35.254.167 <none> 5000/TCP 6h
payment-gateway-qa ClusterIP 10.35.253.94 <none> 5000/TCP 6h
K8S 入口
[msekar@ebs kube-base]$ kubectl get ing -n payment-gateway-7682352
NAME HOSTS ADDRESS PORTS AGE
pgw-nginx-ingress * 104.198.78.169 80 6h
[msekar@ebs kube-base]$ kubectl describe ing pgw-nginx-ingress -n payment-gateway-7682352
Name: pgw-nginx-ingress
Namespace: payment-gateway-7682352
Address: 104.198.78.169
Default backend: default-http-backend:80 (10.32.1.4:8080)
Rules:
Host Path Backends
---- ---- --------
*
/dev/ payment-gateway-dev:5000 (<none>)
/qa/ payment-gateway-qa:5000 (<none>)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx","nginx.ingress.kubernetes.io/ssl-redirect":"false"},"name":"pgw-nginx-ingress","namespace":"payment-gateway-7682352"},"spec":{"rules":[{"http":{"paths":[{"backend":{"serviceName":"payment-gateway-dev","servicePort":5000},"path":"/dev/"},{"backend":{"serviceName":"payment-gateway-qa","servicePort":5000},"path":"/qa/"}]}}]}}
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: false
Events: <none>
注释中最后应用的配置(入口描述输出)显示了入口资源清单。但是,我将其粘贴在下面以供参考
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: pgw-nginx-ingress
namespace: payment-gateway-7682352
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- backend:
serviceName: payment-gateway-dev
servicePort: 5000
path: /dev/
- backend:
serviceName: payment-gateway-qa
servicePort: 5000
path: /qa/
附加信息
我尝试访问的服务是使用上下文的 springboot 服务,因此根位置不是有效的端点。
相应地定义了容器的就绪和活跃度探测。
例如,"payment-gateway-dev" 服务正在使用上下文 /pgw/v1 上下文,因此只能通过上下文访问部署。要访问应用程序的 swagger 规范,您可以使用 URL
http://<>/pgw/v1/swagger-ui.html
我的部署行为
ingress-controller-LB-ip = 35.188.161.171
- 访问入口控制器负载平衡器“http://35.188.161.171”将我带到默认的 404 后端
- 正在访问入口控制器负载均衡器运行状况“http://35.188.161.171/healthz”returns 200 HTTP 响应符合预期
- 尝试使用下面的 URLs 访问服务 returns“404:找不到页面”错误
任何关于我可能做错的建议或见解将不胜感激。
+1 这个问得很好的问题。
你的设置对我来说似乎是正确的。在您的解释中,我发现您的服务需要 http://<>/pgw/v1/swagger-ui.html
作为上下文。但是,在您的设置中,如果您的路由是 /qa/
.
,则提交给服务的路径将是 http://<>/qa/pgw/v1/swagger-ui.html
要删除前缀,您需要做的是向您的入口添加 rewrite
规则:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: pgw-nginx-ingress
namespace: payment-gateway-7682352
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- backend:
serviceName: payment-gateway-dev
servicePort: 5000
path: /dev/(.+)
- backend:
serviceName: payment-gateway-qa
servicePort: 5000
path: /qa/(.+)
在此之后,您的服务应该会收到正确的上下文。
参考:
另一种方法是使用基于主机的路由。您可以简单地为 Ingress 静态 IP (pgw-dev.foo.com, pgw-qa.foo.com) 创建几个 CNAME DNS 条目,并将您的路径:属性替换为主机:属性。不需要 URL 重写。
在我看来,使用基于主机的方法的最佳理由是对人类来说清晰度和灵活性。我在很多不同的地方工作过。几乎所有这些都使用主机名以这种方式区分环境。味道不错,馅料少。
例如,如果您将 DEV 和 QA 拆分到单独的集群中,则没有人必须更改他们的配置(并且您的 K8s 模板将是可重用的)。只需更新 DNS。如果你想启动一个新的暂存或性能测试环境,那么你现有的测试工具应该很容易适应新环境:只需更改配置中的主机名。
随着时间的推移,我认为您会发现主机名是一种比路径前缀更自然的区分环境的方式。
我是一名 Kubernetes 业余爱好者,试图在 GKE 上使用 NGINX 入口控制器。我正在按照 this google 云文档为我的服务设置 NGINX Ingress,但是,我在访问 NGINX 位置时遇到了问题。
什么有效?
- 使用 Helm 部署 Ingress-Controller(启用 RBAC)
- ClusterIP 服务部署
什么不起作用?
- 使用唯一路径(扇出路由)公开多个 ClusterIP 服务的入口资源
K8S 服务
[msekar@ebs kube-base]$ kubectl get services -n payment-gateway-7682352
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-controller LoadBalancer 10.35.241.255 35.188.161.171 80:31918/TCP,443:31360/TCP 6h
nginx-ingress-default-backend ClusterIP 10.35.251.5 <none> 80/TCP 6h
payment-gateway-dev ClusterIP 10.35.254.167 <none> 5000/TCP 6h
payment-gateway-qa ClusterIP 10.35.253.94 <none> 5000/TCP 6h
K8S 入口
[msekar@ebs kube-base]$ kubectl get ing -n payment-gateway-7682352
NAME HOSTS ADDRESS PORTS AGE
pgw-nginx-ingress * 104.198.78.169 80 6h
[msekar@ebs kube-base]$ kubectl describe ing pgw-nginx-ingress -n payment-gateway-7682352
Name: pgw-nginx-ingress
Namespace: payment-gateway-7682352
Address: 104.198.78.169
Default backend: default-http-backend:80 (10.32.1.4:8080)
Rules:
Host Path Backends
---- ---- --------
*
/dev/ payment-gateway-dev:5000 (<none>)
/qa/ payment-gateway-qa:5000 (<none>)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx","nginx.ingress.kubernetes.io/ssl-redirect":"false"},"name":"pgw-nginx-ingress","namespace":"payment-gateway-7682352"},"spec":{"rules":[{"http":{"paths":[{"backend":{"serviceName":"payment-gateway-dev","servicePort":5000},"path":"/dev/"},{"backend":{"serviceName":"payment-gateway-qa","servicePort":5000},"path":"/qa/"}]}}]}}
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: false
Events: <none>
注释中最后应用的配置(入口描述输出)显示了入口资源清单。但是,我将其粘贴在下面以供参考
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: pgw-nginx-ingress
namespace: payment-gateway-7682352
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- backend:
serviceName: payment-gateway-dev
servicePort: 5000
path: /dev/
- backend:
serviceName: payment-gateway-qa
servicePort: 5000
path: /qa/
附加信息
我尝试访问的服务是使用上下文的 springboot 服务,因此根位置不是有效的端点。
相应地定义了容器的就绪和活跃度探测。
例如,"payment-gateway-dev" 服务正在使用上下文 /pgw/v1 上下文,因此只能通过上下文访问部署。要访问应用程序的 swagger 规范,您可以使用 URL
http://<>/pgw/v1/swagger-ui.html
我的部署行为
ingress-controller-LB-ip = 35.188.161.171
- 访问入口控制器负载平衡器“http://35.188.161.171”将我带到默认的 404 后端
- 正在访问入口控制器负载均衡器运行状况“http://35.188.161.171/healthz”returns 200 HTTP 响应符合预期
- 尝试使用下面的 URLs 访问服务 returns“404:找不到页面”错误
任何关于我可能做错的建议或见解将不胜感激。
+1 这个问得很好的问题。
你的设置对我来说似乎是正确的。在您的解释中,我发现您的服务需要 http://<>/pgw/v1/swagger-ui.html
作为上下文。但是,在您的设置中,如果您的路由是 /qa/
.
http://<>/qa/pgw/v1/swagger-ui.html
要删除前缀,您需要做的是向您的入口添加 rewrite
规则:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: pgw-nginx-ingress
namespace: payment-gateway-7682352
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- backend:
serviceName: payment-gateway-dev
servicePort: 5000
path: /dev/(.+)
- backend:
serviceName: payment-gateway-qa
servicePort: 5000
path: /qa/(.+)
在此之后,您的服务应该会收到正确的上下文。
参考:
另一种方法是使用基于主机的路由。您可以简单地为 Ingress 静态 IP (pgw-dev.foo.com, pgw-qa.foo.com) 创建几个 CNAME DNS 条目,并将您的路径:属性替换为主机:属性。不需要 URL 重写。
在我看来,使用基于主机的方法的最佳理由是对人类来说清晰度和灵活性。我在很多不同的地方工作过。几乎所有这些都使用主机名以这种方式区分环境。味道不错,馅料少。
例如,如果您将 DEV 和 QA 拆分到单独的集群中,则没有人必须更改他们的配置(并且您的 K8s 模板将是可重用的)。只需更新 DNS。如果你想启动一个新的暂存或性能测试环境,那么你现有的测试工具应该很容易适应新环境:只需更改配置中的主机名。
随着时间的推移,我认为您会发现主机名是一种比路径前缀更自然的区分环境的方式。