apache / apisix-ingress-controller

APISIX Ingress Controller for Kubernetes
https://apisix.apache.org/
Apache License 2.0
996 stars 340 forks source link

bug: Can't define multiple k8s ingress definitions with pathType: Prefix pointing to single service when using combined mode #2276

Open boscard opened 1 month ago

boscard commented 1 month ago

Current Behavior

Defining two ingress definitions pointing to single service with pathType prefix and different paths will cause

error   adapter/etcd.go:141     failed to create object, ignore it{error 26 0  rpc error: code = InvalidArgument desc = etcdserver: duplicate key given in txn request} {revision 11 2939  <nil>} {key 15 0 /apisix/upstreams/5ce57b8e <nil>}

Where in traditional mode everything works perfectly fine.

Expected Behavior

In combine mode there should also be possible to define multiple ingress definitions pointing to single service, where path is different for ingress definitions.

Error Logs

2024-08-05T22:18:01+08:00       info    adapter/etcd.go:147     created object{revision 11 2938  <nil>} {key 15 0 /apisix/upstreams/5ce57b8e <nil>}
2024-08-05T22:18:01+08:00       info    adapter/etcd.go:147     created object{revision 11 2939  <nil>} {key 15 0 /apisix/routes/bcb4f1ad <nil>}
2024-08-05T22:18:01+08:00       error   adapter/etcd.go:141     failed to create object, ignore it{error 26 0  rpc error: code = InvalidArgument desc = etcdserver: duplicate key given in txn request} {revision 11 2939  <nil>} {key 15 0 /apisix/upstreams/5ce57b8e <nil>}
2024-08-05T22:18:01+08:00       info    adapter/etcd.go:147     created object{revision 11 2940  <nil>} {key 15 0 /apisix/routes/59ac5ae4 <nil>}

Steps to Reproduce

  1. Install APISIX Ingress controller in combined mode
  2. Deploy httpbin for example using this specs:
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: httpbin-deployment
    namespace: default
    spec:
    replicas: 1
    selector:
    matchLabels:
      app: httpbin-deployment
    template:
    metadata:
      labels:
        app: httpbin-deployment
    spec:
      containers:
        - name: httpbin-deployment
          image: kennethreitz/httpbin:latest
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          resources: {}
          livenessProbe:
            tcpSocket:
              port: 80
            initialDelaySeconds: 2
            timeoutSeconds: 2
            periodSeconds: 5
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            tcpSocket:
              port: 80
            initialDelaySeconds: 2
            timeoutSeconds: 2
            periodSeconds: 5
            successThreshold: 1
            failureThreshold: 3
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: httpbin
    namespace: default
    spec:
    selector:
    app: httpbin-deployment
    ports:
    - name: http
    port: 80
    protocol: TCP
    targetPort: 80
    type: ClusterIP
  3. Deploy 2 Ingress definitions
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: api1
    namespace: default
    spec:
    ingressClassName: apisix
    rules:
    - http:
        paths:
          - backend:
              service:
                name: httpbin
                port:
                  number: 80
            path: /api1/api1
            pathType: Prefix
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: api2
    namespace: default
    spec:
    ingressClassName: apisix
    rules:
    - http:
        paths:
          - backend:
              service:
                name: httpbin
                port:
                  number: 80
            path: /api2/api2
            pathType: Prefix

Environment

rknightion commented 1 month ago

We're also seeing this although we seem to get it even when not using ingress but rather simple httproute CRs

With this:

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: route-test
  namespace: fek-test
spec:
  http:
    - backends:
        - resolveGranularity: service
          serviceName: data-capture
          servicePort: 8080
          weight: 100
      match:
        hosts:
          - test.test.XXX.XXX.XXX
        paths:
          - /api/data-capture/forms/*
          - /api/data-capture/profiles
          - /api/data-capture/v1/fan/*
      name: route-data-capture-public
      plugins:
        - config:
            headers:
              X-Tenant-Id: XXX
            regex_uri:
              - ^/api/data-capture(.*)$
              - $1
          enable: true
          name: proxy-rewrite

We get

2024-08-15T03:05:00+08:00   error   adapter/etcd.go:141 failed to create object, ignore it{error 26 0  rpc error: code = InvalidArgument desc = etcdserver: duplicate key given in txn request} {revision 11 93  <nil>} {key 15 0 /apisix/routes/3b8426dd <nil>}

Making me think it happens whenever multiple paths talk to the same backend. This doesn't happen with the etcd version of apisix + ingress controller

rknightion commented 1 month ago

This looks similar to https://github.com/apache/apisix-ingress-controller/issues/2071 in a way.

@boscard have you used etcdctl to see whats showing in the ingress controller etcd-adapter for your troublesome route?

boscard commented 3 weeks ago

@rknightion no, I was not trying with etcdctl. If you can point me to some docs/readme how can I do it I will try.