Docker 为什么入口总是只向特定服务节点端口返回502错误?

Docker 为什么入口总是只向特定服务节点端口返回502错误?,docker,kubernetes,google-kubernetes-engine,kubernetes-ingress,gke-networking,Docker,Kubernetes,Google Kubernetes Engine,Kubernetes Ingress,Gke Networking,我有一个alpine docker映像,可以在apache服务器(PHP7.4)上运行我的原始PHP网站EXPOSE 80 我想使用入口控制器在Kubernetes(GKE)上运行映像。 我正在使用gcloud命令将图像推送到google容器注册表。 部署和服务都没有错误,并成功创建为节点端口。 我部署的入口来自google教程() 现在在我的入口中有: 34.68.78.46.xip.io/ 34.68.78.46.xip.io/你好 34.68.78.46.xip.io/jb(/|$)(*

我有一个alpine docker映像,可以在apache服务器(PHP7.4)上运行我的原始PHP网站
EXPOSE 80

我想使用入口控制器在Kubernetes(GKE)上运行映像。
我正在使用gcloud命令将图像推送到google容器注册表。
部署和服务都没有错误,并成功创建为节点端口。
我部署的入口来自google教程() 现在在我的入口中有:

  • 34.68.78.46.xip.io/
  • 34.68.78.46.xip.io/你好
  • 34.68.78.46.xip.io/jb(/|$)(*)
/hello与本教程的配置相同,工作正常。
/jb的配置与我在下面提到的相同,总是返回502错误。
GCP控制台中的入口详细信息不显示任何警告或错误

我已检查:


以下是部署文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jomlahbazar-deployment
spec:
  selector:
    matchLabels:
      greeting: jomlah
      department: bazar
  replicas: 1
  template:
    metadata:
      labels:
        greeting: jomlah
        department: bazar
    spec:
      containers:
      - name: jomlah
        image: "us.gcr.io/third-nature-273904/jb-img-1-0:v1"
        ports:
        - containerPort: 80
        env:
        - name: "PORT"
          value: "80"
以下是服务文件:

apiVersion: v1
kind: Service
metadata:
  name: jomlahbazar-service
spec:
  type: NodePort
  selector:
    greeting: jomlah
    department: bazar
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
在入口文件中:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-resource
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/add-base-url : "true"
spec:
  rules:
  - host: 34.68.78.46.xip.io
    http:
      paths:
      - path: /
        backend:
          serviceName: jomlahbazar-service
          servicePort: 80
      - path: /hello
        backend:
          serviceName: hello-app
          servicePort: 8080
      - path: /jb(/|$)(.*)
        backend:
          serviceName: jomlahbazar-service
          servicePort: 80     
以下是入口说明:

Name:             ingress-resource
Namespace:        default
Address:          34.68.78.46
Default backend:  default-http-backend:80 (10.20.1.6:8080)
Rules:
  Host                Path  Backends
  ----                ----  --------
  34.68.78.46.xip.io
                      /              jomlahbazar-service:80 (<none>)
                      /hello         hello-app:8080 (10.20.2.61:8080)
                      /jb(/|$)(.*)   jomlahbazar-service:80 (<none>)
Annotations:
  kubernetes.io/ingress.class:                       nginx
  nginx.ingress.kubernetes.io/add-base-url:          true
  nginx.ingress.kubernetes.io/rewrite-target:        /$2
  nginx.ingress.kubernetes.io/ssl-redirect:          false
  nginx.ingress.kubernetes.io/use-regex:             true
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx","nginx.ingress.kubernetes.io/add-base-url":"true","nginx.ingress.kubernetes.io/rewrite-target":"/$2","nginx.ingress.kubernetes.io/ssl-redirect":"false","nginx.ingress.kubernetes.io/use-regex":"true"},"name":"ingress-resource","namespace":"default"},"spec":{"rules":[{"host":"34.68.78.46.xip.io","http":{"paths":[{"backend":{"serviceName":"jomlahbazar-service","servicePort":80},"path":"/"},{"backend":{"serviceName":"hello-app","servicePort":8080},"path":"/hello"},{"backend":{"serviceName":"jomlahbazar-service","servicePort":80},"path":"/jb(/|$)(.*)"}]}}]}}

Events:
  Type    Reason          Age                 From                      Message
  ----    ------          ----                ----                      -------
  Normal  AddedOrUpdated  36m (x6 over 132m)  nginx-ingress-controller  Configuration for default/ingress-resource was added or updated

我已经在我的GKE集群上运行了一些测试。我已经使用两个hello world应用程序v1和v2复制了您的行为

情景1 HW 1

SVC HW1

spec:
  type: NodePort
  selector:
    key: app
  ports:
    - port: 80
      targetPort: 8080
HW 2

SVC HW2

spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: hello2
入口

spec:
  rules:
  -  http:
      paths:
      - path: /hello2
        backend:
          serviceName: h2
          servicePort: 80
      - path: /hello
        backend:
          serviceName: fs
          servicePort: 80
产出:

$ curl 34.117.70.75/hello
Hello, world!
Version: 1.0.0
Hostname: fd-c6d79cdf8-7rmmd

$ curl 34.117.70.75/hello2

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>502 Server Error</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Server Error</h1>
<h2>The server encountered a temporary error and could not complete your request.<p>Please try again in 30 seconds.</h2>
<h2></h2>
</body></html>
在您的服务中,您设置了
containerPort:8080
,因此服务期望流量流向正确的端口
8080
。由于pod仅在
80
上监听,并且流量出现故障
8080
您将收到
502
错误

情景2 将值从“80”更改为“8080”后,应用新配置

$ curl 34.117.70.75/hello
Hello, world!
Version: 1.0.0
Hostname: fd-c6d79cdf8-7rmmd

$ curl 34.117.70.75/hello2
Hello, world!
Version: 2.0.0
Hostname: h2-deploy-5f5ccfbf9f-fjhrb
Netstat:

$ kubectl exec -ti f2-deploy-5f5ccfbf9f-fjhrb -- bin/sh
/ # netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :::8080                 :::*                    LISTEN      1/hello-app
解决方案 解决方案1

您应该将应用程序部署更改为:

        env:
        - name: "PORT"
          value: "8080"
并应用新配置

$ curl 34.117.70.75/hello
Hello, world!
Version: 1.0.0
Hostname: fd-c6d79cdf8-7rmmd

$ curl 34.117.70.75/hello2
Hello, world!
Version: 2.0.0
Hostname: h2-deploy-5f5ccfbf9f-fjhrb
解决方案2 使用
containerPort

    spec:
      containers:
      - name: jb
        image: "us.gcr.io/third-nature-273904/jb-img-1-0:v3"
        ports:
        - containerPort: 8080
注意

请注意,如果您创建了自己的映像并在
Dockerfile
中使用了
EXPOSE
,则应将部署配置为使用此特定端口


如果仍然存在问题,请告诉我。

您的部署中存在配置错误。您应该使用
env.name.value:“8080”
,而不是
env.name.value:“8080”
。我会尽快详细说明答案。这肯定是一个错误是的。我更改了它,但仍然得到了502错误。我应该删除部署和服务,然后用不同的名称重新创建,还是配置它们就可以了?因为我仍然可以看到相同的后端服务。我修复了您注意到的问题并再次编辑了问题信息,502错误仍然显示。好的,您的意思是在docker文件中它应该是EXPOSE 8080,对吗?您是否也可以共享
netstat-plnt
您的
jb
pod的输出?我已经开始了一个新的配置。我会尽快通知你。非常感谢。因此,如果映像在端口80上公开,那么您应该:在部署中设置端口值:80,服务
targetPort:80
和服务
port
应该与应用程序中的入口
servicePort
相同,
暴露
端口的值应与
服务
中的
目标端口
部署
中的
容器端口
相同。如果在部署中仅使用
端口
,kubernetes将为
部署容器端口
分配与
端口
相同的值。请查看更好的
containerPort
targetPort
说明。
$ kubectl exec -ti f2-deploy-5f5ccfbf9f-fjhrb -- bin/sh
/ # netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :::8080                 :::*                    LISTEN      1/hello-app
        env:
        - name: "PORT"
          value: "8080"
    spec:
      containers:
      - name: jb
        image: "us.gcr.io/third-nature-273904/jb-img-1-0:v3"
        ports:
        - containerPort: 8080