【发布时间】:2021-07-09 22:45:46
【问题描述】:
我正在尝试为 GKE 集群配置 nginx 入口并在配置的子域上定义路径。似乎即使我能够成功 ping 主机,并且域绑定正确完成,但每当我尝试访问配置的路径时,我都会收到 404。
我的目标是能够为我的入口控制器配置一个静态 IP,并在不同路径上公开多个服务。
您可以在下面找到我的部署文件 - 我要补充的另一件事是,我正在使用 Terraform 自动配置和部署 GCP 和 Kubernetes 资源。
成功配置 GKE 集群后,我首先从 here 部署官方 nginx-ingress 控制器 - 在我的 Terraform 脚本下方,该脚本使用我在 GCP 上配置的自定义静态 IP 配置和部署控制器。
resource "helm_release" "nginx" {
name = "nginx"
chart = "nginx-stable/nginx-ingress"
timeout = 900
set {
name = "controller.stats.enabled"
value = true
}
set {
name = "controller.service.type"
value = "LoadBalancer"
}
set {
name = "controller.service.loadBalancerIP"
value = "<MY_STATIC_IP_ADDRESS>"
}
}
在我也通过 Terraform 部署的入口配置下方:
resource "kubernetes_ingress" "ingress" {
wait_for_load_balancer = true
metadata {
name = "app-ingress"
annotations = {
"kubernetes.io/ingress.class": "nginx"
"nginx.ingress.kubernetes.io/rewrite-target": "/"
"kubernetes.io/ingress.global-static-ip-name": <MY_STATIC_IP_ADDRESS>
}
}
spec {
rule {
host = custom.my_domain.com
http {
path {
backend {
service_name = "app-service"
service_port = 5000
}
path = "/app"
}
}
}
}
}
以及从 GCP 获取的最终入口配置:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: static-ip-name
nginx.ingress.kubernetes.io/rewrite-target: /
creationTimestamp: "2021-04-14T20:28:41Z"
generation: 7
name: app-ingress
namespace: default
resourceVersion: HIDDEN
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/app-ingress
uid: HIDDEN
spec:
rules:
- host: custom.my_domain.com
http:
paths:
- backend:
serviceName: app-service
servicePort: 5000
path: /app
status:
loadBalancer:
ingress:
- ip: <MY_STATIC_IP_ADDRESS>
kubectl describe ingress app-ingress 命令的输出:
Name: app-ingress
Namespace: default
Address: <MY_STATIC_IP_ADDRESS>
Default backend: default-http-backend:80 (192.168.10.8:8080)
Rules:
Host Path Backends
---- ---- --------
custom.my_domain.com
/app app-service:5000 (192.168.10.11:5000)
Annotations: kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: static-ip-name
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal AddedOrUpdated 16m (x6 over 32m) nginx-ingress-controller Configuration for default/app-ingress was added or updated
我使用以下配置文件部署了我试图公开的应用程序:
pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: default
service.yaml
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
type: NodePort
ports:
- port: 5000
targetPort: 5000
protocol: TCP
name: http
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 1
template:
spec:
restartPolicy: Always
volumes:
- name: app-pvc
persistentVolumeClaim:
claimName: app-pvc
containers:
- name: app-container
image: "eu.gcr.io/<PROJECT_ID>/<IMAGE_NAME>:VERSION_TAG"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
livenessProbe:
tcpSocket:
port: 5000
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 5000
initialDelaySeconds: 15
periodSeconds: 20
volumeMounts:
- mountPath: "/data"
name: app-pvc
一切都成功部署,因为我可以通过运行以下命令通过配置的服务直接连接到本地应用程序:
kubectl port-forward service/app-service 5000:5000
这使我可以在浏览器中访问应用程序,一切都按预期工作。
为了确保我配置的 <MY_STATIC_IP_ADDRESS> 正确绑定到 custom.my_domain.com,我尝试 ping 主机并得到正确的响应:
ping custom.my_domain.com
Pinging custom.my_domain.com [<MY_STATIC_IP_ADDRESS>] with 32 bytes of data:
Reply from <MY_STATIC_IP_ADDRESS>: bytes=32 time=36ms TTL=113
Reply from <MY_STATIC_IP_ADDRESS>: bytes=32 time=37ms TTL=113
Reply from <MY_STATIC_IP_ADDRESS>: bytes=32 time=36ms TTL=113
Reply from <MY_STATIC_IP_ADDRESS>: bytes=32 time=45ms TTL=113
Ping statistics for <MY_STATIC_IP_ADDRESS>:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 36ms, Maximum = 45ms, Average = 38ms
即使一切似乎都按预期工作,每当我尝试在浏览器中导航到 custom.my_domain.com/app 时,我都会在浏览器中不断收到以下响应,即使在等待超过 30m 以确保入口配置已在 GCP 上正确注册:
这是显示在我的 nginx-controller pod 日志中的条目:
<HIDDEN_LOCAL_IP> - - [14/Apr/2021:21:18:10 +0000] "GET /app/ HTTP/1.1" 404 232 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0" "-"
更新 #1
看来,如果我更新我的入口以直接在 / 路径上公开目标服务,它会按预期工作。下面是更新的配置。不过,如果我尝试设置任何其他路径,它似乎不起作用。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: static-ip-name
nginx.ingress.kubernetes.io/rewrite-target: /
creationTimestamp: "2021-04-14T20:28:41Z"
generation: 7
name: app-ingress
namespace: default
resourceVersion: HIDDEN
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/app-ingress
uid: HIDDEN
spec:
rules:
- host: custom.my_domain.com
http:
paths:
- backend:
serviceName: app-service
servicePort: 5000
path: /
status:
loadBalancer:
ingress:
- ip: <MY_STATIC_IP_ADDRESS>
更新 #2
在查看了 @jccampanero 在 cmets 部分分享的材料后,我能够得到一个工作配置。
我没有使用官方 nginx 网站上引用的nginx-stable,而是使用了here,并相应地更新了我的 Terraform 脚本,以使用与我完全相同的配置。
之后,我必须按照文档here 更新我的入口 - 在更新的配置下方:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: static-ip-name
nginx.ingress.kubernetes.io/rewrite-target: /$2
creationTimestamp: "2021-04-14T20:28:41Z"
generation: 7
name: app-ingress
namespace: default
resourceVersion: HIDDEN
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/app-ingress
uid: HIDDEN
spec:
rules:
- host: custom.my_domain.com
http:
paths:
- backend:
serviceName: app-service
servicePort: 5000
path: /app(/|$)(.*)
status:
loadBalancer:
ingress:
- ip: <MY_STATIC_IP_ADDRESS>
【问题讨论】:
-
我认为问题可能与
nginx.ingress.kubernetes.io/rewrite-target注释有关。没有那个注释一切正常吗?可能不是,但正如您在docs 中看到的那样,从 Nginx 入口控制器的 0.22.0 版本开始,由于使用了捕获组,注释的行为发生了变化,这可能与您的问题有关。 -
我最初尝试在没有该注释的情况下部署它,但行为完全相同。我已经浏览了您共享的文档,但找不到合适的解决方案。即使这不是我正在寻找的解决方案,我也在尝试的是为每个入口配置公开一个服务并使用多个静态 IP 地址,一个用于我公开的每个服务。这可能会导致将它们暴露在单个子域上。尽管如此,如前所述,这只是一个实验,看看我是否可以让入口在我的子域上工作。
-
@jccampanero 我刚刚尝试使用
nginx.ingress.kubernetes.io/app-root注释重新部署整个堆栈,我得到了完全相同的行为。 -
抱歉回复晚了,非常感谢您的反馈。很抱歉@vladzam,是的,
nginx.ingress.kubernetes.io/app-root注释可能对您的情况无效。我的意思是问题可能与nginx.ingress.kubernetes.io/rewrite-target注释的定义有关,您提供的是'/',但可能需要提供/$1之类的内容。我将尝试在我的本地环境中部署新版本的控制器并查看。无论如何,现在似乎有几个版本的 Nginx 入口控制器和其中一些(续) -
在某些情况下不要正确处理重写目标注释:请考虑阅读此相关SO question,以及linked GitHub issue,以及这两个12。除了提到的注释之外,我认为您的设置看起来不错:话虽如此,但我不想让您感到困惑,(续)
标签: nginx kubernetes networking google-cloud-platform nginx-ingress