K8s入口用于基于路径的多种服务路由

问题描述

我正在使用nginx入口进行多种服务的基于路径的路由。

我的服务输出

NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)                      

ingress-nginx-controller             LoadBalancer   X.X.X.33    X.X.X.112   80:30853/TCP,443:31386/TCP   
ingress-nginx-controller-admission   ClusterIP      X.X.X.139   <none>           443/TCP                      

test1                         ClusterIP      X.X.X.197   <none>           9080/TCP                     
test2                         ClusterIP      X.X.X.30    <none>           9995/TCP                     

我的ingress.yaml文件

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-resource
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/"
spec:
  rules:
  - http:
      paths:
      - path: /test2
        backend:
          serviceName: test2
          servicePort: 9995
      - path: /test1
        backend:
          serviceName: test1
          servicePort: 9080

和kubectl入口输出

NAME               HOSTS   ADDRESS   PORTS   AGE
ingress-resource   *                 80      45m

当我尝试从外部群集访问服务时- 我收到404

-> http:// X.X.X.112/test1 return 404
-> http:// X.X.X.112/test2 return 404 

Where  X.X.X.112 is external ip of ingress-nginx-controller

->当我创建端口8080上运行的服务的入口时,它似乎运行良好。 什么问题?

解决方法

我发现了问题。我不见了

annotations:
 kubernetes.io/ingress.class: nginx

现在我还有其他问题。 当我使用

spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: test2
          servicePort: 9995

我的http:// X.X.X.112 /正常工作,它指向serviceName-test2 同样,它适用于其他服务。

但是当我使用

  spec:
  rules:
  - http:
      paths:
      - path: /test2
        backend:
          serviceName: test2
          servicePort: 9995
      - path: /test1
        backend:
          serviceName: test1
          servicePort: 9080

这样做的时候我得到了405方法不允许

 -> http:// X.X.X.112/test1 return 405
-> http:// X.X.X.112/test2 return 405

我讨厌再添加一些注释。

nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: PUT,GET,POST,OPTIONS,DELETE,PATCH
nginx.ingress.kubernetes.io/enable-cors: "true"

我想念其他东西吗?

,

我已经在GKE上尝试了您的示例(更改了部署,因为您没有提供使用过的示例)。

正如我在评论中提到的,要在Nginx Ingress上强制GKE,您必须使用注释:

annotations: 
  kubernetes.io/ingress.class: nginx

否则,GKE将使用不支持rewrite注释的默认gce入口。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test1
spec:
  replicas: 1
  selector:
    matchLabels:
      key: test1
  template:
    metadata:
      labels:
        key: test1
    spec:
      containers:
      - name: hello1
        image: gcr.io/google-samples/hello-app:1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: test1
spec:
  selector:
    key: test1
  ports:
    - port: 80
      targetPort: 8080
---
apiVersion: apps/v1
kind:  Deployment
metadata:
  name: test2
  labels:
    app: mycha-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test2
  template:
    metadata:
      labels:
        app: test2
    spec:
      containers:
        - name: nginx2
          image: nginx
          ports:
          - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: test2
  labels:
    app: test2
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: test2
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /test1
        backend:
          serviceName: test1
          servicePort: 80
      - path: /test2
        backend:
          serviceName: test2
          servicePort: 80
      
$ kubectl get svc -A
NAMESPACE       NAME                                 TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                      AGE
default         kubernetes                           ClusterIP      10.0.0.1      <none>          443/TCP                      7h59m
default         test1                                ClusterIP      10.0.14.220   <none>          80/TCP                       9m18s
default         test2                                ClusterIP      10.0.0.243    <none>          80/TCP                       9m16s
ingress-nginx   ingress-nginx-controller             LoadBalancer   10.0.7.75     35.228.2XX.XX   80:32643/TCP,443:32733/TCP   18m

$ curl 35.228.2XX.XX/test1
Hello,world!
Version: 1.0.0
Hostname: test1-5844dc9688-n95tj
$ curl 35.228.2XX.XX/test2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
...

如果此示例不适用于您的群集,则需要创建Firewall rules来允许流量。

如果此示例将起作用,则表明您的Deployment/Service中的配置不匹配。

  • servicedeployment之间可能selector配置错误(第一个是key: test1,第二个部署是app: test2)。
  • 应用程序正在containerPort中设置的其他端口上侦听。如果仅在服务中设置port,则将在containerPort中设置相同的值。在test1部署中,它无法像hello-app:1.0那样仅在port 8080上监听。

你好豆荚

# 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

Nginx容器

# netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro    

如果仍有问题,请发表评论。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...