我正在尝试为 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 在评论部分分享的材料后,我得到了一个可以工作的配置。
我没有使用官方 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>
答案 0 :(得分:1)
正如问题评论和问题本身所指出的,@vladzam 有很好的记录,有两个是问题的原因。
一方面,通过 Helm stable
频道提供的 nginx 入口控制器似乎是 deprecated 支持新的 ingress-nginx
控制器 - 请参阅 the Github repo 和official documentation。
另一方面,似乎是与Rewrite target
注解的定义有关的问题。根据{{3}}:
从 0.22.0 版开始,使用注释 nginx.ingress.kubernetes.io/rewrite-target
的入口定义与以前的版本不向后兼容。在 0.22.0 及更高版本中,请求 URI 中需要传递到重写路径的任何子字符串都必须在捕获组中明确定义。
因此,有必要修改入口资源的定义以考虑此更改。例如:
$ echo '
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something(/|$)(.*)
' | kubectl create -f -
问题本身提供了准确的入口资源定义。