Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kubernetes Ingress path should be configurable #26747

Closed
ThoSap opened this issue Jul 15, 2022 · 14 comments · Fixed by #28813
Closed

Kubernetes Ingress path should be configurable #26747

ThoSap opened this issue Jul 15, 2022 · 14 comments · Fixed by #28813
Labels
area/kubernetes kind/bug Something isn't working
Milestone

Comments

@ThoSap
Copy link

ThoSap commented Jul 15, 2022

Describe the bug

Currently, the quarkus-kubernetes extension (2.10.2.Final) does not honor the value of Quarkus property quarkus.http.root-path, so the Kubernetes ingress path is always the root /.

Expected behavior

The Kubernetes ingress path should equal property quarkus.http.root-path.

application.properties

quarkus.http.root-path=/newroot

kubernetes.yml

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    app.quarkus.io/build-timestamp: 2022-07-14 - 15:06:39 +0000
  labels:
    app.kubernetes.io/name: quarkus-app
    app.kubernetes.io/version: 1.0.0
  name: quarkus-app
  namespace: my-namespace
spec:
  rules:
    - host: myhost.example.com
      http:
        paths:
          - backend:
              service:
                name: quarkus-app
                port:
                  name: http
            path: /newroot
            pathType: Prefix

Actual behavior

application.properties

quarkus.http.root-path=/newroot

kubernetes.yml

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    app.quarkus.io/build-timestamp: 2022-07-14 - 15:06:39 +0000
  labels:
    app.kubernetes.io/name: quarkus-app
    app.kubernetes.io/version: 1.0.0
  name: quarkus-app
  namespace: my-namespace
spec:
  rules:
    - host: myhost.example.com
      http:
        paths:
          - backend:
              service:
                name: quarkus-app
                port:
                  name: http
            path: /
            pathType: Prefix

How to Reproduce?

https://code.quarkus.io/?j=17&e=kubernetes&e=resteasy-reactive&e=resteasy-reactive-jackson&extension-search=origin:platform%20resteasy

application.properties

quarkus.http.root-path=/newroot

Output of uname -a or ver

Linux myhost 4.18.0-372.13.1.0.1.el8_6.x86_64 #1 SMP Fri Jul 1 15:06:54 PDT 2022 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)

GraalVM version (if different from Java)

OpenJDK 64-Bit Server VM GraalVM CE 22.1.0 (build 17.0.3+7-jvmci-22.1-b06, mixed mode, sharing)

Quarkus version or git rev

2.10.2.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 7.4.2

Additional information

No response

@ThoSap ThoSap added the kind/bug Something isn't working label Jul 15, 2022
@quarkus-bot
Copy link

quarkus-bot bot commented Jul 15, 2022

/cc @geoand, @iocanel

@geoand
Copy link
Contributor

geoand commented Jul 15, 2022

Sounds reasonable, WDYT @iocanel ?

@ThoSap
Copy link
Author

ThoSap commented Jul 15, 2022

Hmmm, maybe it is not as easy as I thought.
What about the case when somebody sets the properties like this:
https://quarkus.io/blog/path-resolution-in-quarkus/#move-the-non-application-root-path-q

quarkus.http.root-path=/newroot/v1
quarkus.http.non-application-root-path=/newroot

Then for example /newroot/swagger-ui/ would not work.

WDYT @geoand ?

@geoand
Copy link
Contributor

geoand commented Jul 15, 2022

Interesting point

@ThoSap
Copy link
Author

ThoSap commented Jul 15, 2022

Maybe the best solution would be to let the user set the HTTP ingress path with a new optional ingress property quarkus.kubernetes.ingress.path?

My use case is the following.
I have, for example, the domain api.prod.example.com and different Quarkus microservices are served using different K8s ingress paths:
https://api.prod.example.com/api/fights
https://api.prod.example.com/api/heroes
https://api.prod.example.com/api/villains

Without such property the generated Kubernetes YAML/JSON need to be post-processed (for example with sed) to replace K8s ingress path defintion:
spec.rules[*].http.paths[*].path=/
with
spec.rules[*].http.paths[*].path=/api/fights

@geoand
Copy link
Contributor

geoand commented Jul 15, 2022

Let's see what @iocanel thinks

@Sgitario
Copy link
Contributor

Maybe the best solution would be to let the user set the HTTP ingress path with a new optional ingress property quarkus.kubernetes.ingress.path?

My use case is the following. I have, for example, the domain api.prod.example.com and different Quarkus microservices are served using different K8s ingress paths: https://api.prod.example.com/api/fights https://api.prod.example.com/api/heroes https://api.prod.example.com/api/villains

Without such property the generated Kubernetes YAML/JSON need to be post-processed (for example with sed) to replace K8s ingress path defintion: spec.rules[*].http.paths[*].path=/ with spec.rules[*].http.paths[*].path=/api/fights

You can already set the ingress host property:


This change was added in 788b5be.

Let me know if this works for you and if we can close the issue now.

@ThoSap
Copy link
Author

ThoSap commented Sep 12, 2022

Ahh cool, thanks! So the issue regarding secured ingress was fixed in Quarkus 2.12.0.CR1, nice 😏

The PR/commit you mentioned fixes another workaround I made with a post-process step using sed for a secured ingress, but does not fix this issue regarding the path explained here:
#26747 (comment)

@Sgitario
Copy link
Contributor

Oh I see. Yes, I think we should let users configure the rules HTTP paths of the Ingress resources. I think this would need to be addressed on the Dekorate side first though. Wdyt @iocanel ?

@geoand
Copy link
Contributor

geoand commented Oct 18, 2022

@Sgitario @iocanel is this still an issue?

@Sgitario
Copy link
Contributor

@Sgitario @iocanel is this still an issue?

Yes, the only workaround is to provide a custom Ingress resource in src/main/kubernetes/kubernetes.yml with this definition.
I've reported this issue in Dekorate to be fixed there first: dekorateio/dekorate#1083

@Sgitario
Copy link
Contributor

Quarkus main has been updated using the latest version of Dekorate which includes dekorateio/dekorate#1083. So, I will be working on enabling this configuration in Quarkus asap.

@ThoSap ThoSap changed the title Kubernetes Ingress should use quarkus.http.root-path Kubernetes Ingress path should be configurable Oct 25, 2022
Sgitario added a commit to Sgitario/quarkus that referenced this issue Oct 25, 2022
These changes also ensures that not duplicated ingress rules are generated.

#### Adding Ingress rules

To customize the default `host` and `path` properties of the generated Ingress resources, you need to apply the following configuration:

```
quarkus.kubernetes.ingress.expose=true
# To change the Ingress host. By default, it's empty.
quarkus.kubernetes.ingress.host=prod.svc.url
# To change the Ingress path of the generated Ingress rule. By default, it's "/".
quarkus.kubernetes.ports.http.path=/prod
```

This would generate the following Ingress resource:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app.kubernetes.io/name: kubernetes-with-ingress
    app.kubernetes.io/version: 0.1-SNAPSHOT
  name: kubernetes-with-ingress
spec:
  rules:
    - host: prod.svc.url
      http:
        paths:
          - backend:
              service:
                name: kubernetes-with-ingress
                port:
                  name: http
            path: /prod
            pathType: Prefix
```

Additionally, you can also add new Ingress rules by adding the following configuration:

```
# Example to add a new rule
quarkus.kubernetes.ingress.rules.1.host=dev.svc.url
quarkus.kubernetes.ingress.rules.1.path=/dev
quarkus.kubernetes.ingress.rules.1.path-type=ImplementationSpecific
# by default, path type is Prefix

# Exmple to add a new rule that use another service binding
quarkus.kubernetes.ingress.rules.2.host=alt.svc.url
quarkus.kubernetes.ingress.rules.2.path=/ea
quarkus.kubernetes.ingress.rules.2.service-name=updated-service
quarkus.kubernetes.ingress.rules.2.service-port-name=tcpurl
```

This would generate the following Ingress resource:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app.kubernetes.io/name: kubernetes-with-ingress
    app.kubernetes.io/version: 0.1-SNAPSHOT
  name: kubernetes-with-ingress
spec:
  rules:
    - host: prod.svc.url
      http:
        paths:
          - backend:
              service:
                name: kubernetes-with-ingress
                port:
                  name: http
            path: /prod
            pathType: Prefix
    - host: dev.svc.url
      http:
        paths:
          - backend:
              service:
                name: kubernetes-with-ingress
                port:
                  name: http
            path: /dev
            pathType: ImplementationSpecific
    - host: alt.svc.url
      http:
        paths:
          - backend:
              service:
                name: updated-service
                port:
                  name: tcpurl
            path: /ea
            pathType: Prefix
```

Fix quarkusio#28812
Fix quarkusio#26747
@quarkus-bot quarkus-bot bot added this to the 2.15 - main milestone Oct 26, 2022
@ThoSap
Copy link
Author

ThoSap commented Oct 26, 2022

Is this going to be merged in Quarkus 2.14.0.Final?

@geoand
Copy link
Contributor

geoand commented Oct 26, 2022

That's the plan

tmihalac pushed a commit to tmihalac/quarkus that referenced this issue Oct 27, 2022
These changes also ensures that not duplicated ingress rules are generated.

#### Adding Ingress rules

To customize the default `host` and `path` properties of the generated Ingress resources, you need to apply the following configuration:

```
quarkus.kubernetes.ingress.expose=true
# To change the Ingress host. By default, it's empty.
quarkus.kubernetes.ingress.host=prod.svc.url
# To change the Ingress path of the generated Ingress rule. By default, it's "/".
quarkus.kubernetes.ports.http.path=/prod
```

This would generate the following Ingress resource:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app.kubernetes.io/name: kubernetes-with-ingress
    app.kubernetes.io/version: 0.1-SNAPSHOT
  name: kubernetes-with-ingress
spec:
  rules:
    - host: prod.svc.url
      http:
        paths:
          - backend:
              service:
                name: kubernetes-with-ingress
                port:
                  name: http
            path: /prod
            pathType: Prefix
```

Additionally, you can also add new Ingress rules by adding the following configuration:

```
# Example to add a new rule
quarkus.kubernetes.ingress.rules.1.host=dev.svc.url
quarkus.kubernetes.ingress.rules.1.path=/dev
quarkus.kubernetes.ingress.rules.1.path-type=ImplementationSpecific
# by default, path type is Prefix

# Exmple to add a new rule that use another service binding
quarkus.kubernetes.ingress.rules.2.host=alt.svc.url
quarkus.kubernetes.ingress.rules.2.path=/ea
quarkus.kubernetes.ingress.rules.2.service-name=updated-service
quarkus.kubernetes.ingress.rules.2.service-port-name=tcpurl
```

This would generate the following Ingress resource:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app.kubernetes.io/name: kubernetes-with-ingress
    app.kubernetes.io/version: 0.1-SNAPSHOT
  name: kubernetes-with-ingress
spec:
  rules:
    - host: prod.svc.url
      http:
        paths:
          - backend:
              service:
                name: kubernetes-with-ingress
                port:
                  name: http
            path: /prod
            pathType: Prefix
    - host: dev.svc.url
      http:
        paths:
          - backend:
              service:
                name: kubernetes-with-ingress
                port:
                  name: http
            path: /dev
            pathType: ImplementationSpecific
    - host: alt.svc.url
      http:
        paths:
          - backend:
              service:
                name: updated-service
                port:
                  name: tcpurl
            path: /ea
            pathType: Prefix
```

Fix quarkusio#28812
Fix quarkusio#26747
@gsmet gsmet modified the milestones: 2.15 - main, 2.14.0.Final Oct 28, 2022
gsmet pushed a commit to gsmet/quarkus that referenced this issue Oct 28, 2022
These changes also ensures that not duplicated ingress rules are generated.

#### Adding Ingress rules

To customize the default `host` and `path` properties of the generated Ingress resources, you need to apply the following configuration:

```
quarkus.kubernetes.ingress.expose=true
# To change the Ingress host. By default, it's empty.
quarkus.kubernetes.ingress.host=prod.svc.url
# To change the Ingress path of the generated Ingress rule. By default, it's "/".
quarkus.kubernetes.ports.http.path=/prod
```

This would generate the following Ingress resource:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app.kubernetes.io/name: kubernetes-with-ingress
    app.kubernetes.io/version: 0.1-SNAPSHOT
  name: kubernetes-with-ingress
spec:
  rules:
    - host: prod.svc.url
      http:
        paths:
          - backend:
              service:
                name: kubernetes-with-ingress
                port:
                  name: http
            path: /prod
            pathType: Prefix
```

Additionally, you can also add new Ingress rules by adding the following configuration:

```
# Example to add a new rule
quarkus.kubernetes.ingress.rules.1.host=dev.svc.url
quarkus.kubernetes.ingress.rules.1.path=/dev
quarkus.kubernetes.ingress.rules.1.path-type=ImplementationSpecific
# by default, path type is Prefix

# Exmple to add a new rule that use another service binding
quarkus.kubernetes.ingress.rules.2.host=alt.svc.url
quarkus.kubernetes.ingress.rules.2.path=/ea
quarkus.kubernetes.ingress.rules.2.service-name=updated-service
quarkus.kubernetes.ingress.rules.2.service-port-name=tcpurl
```

This would generate the following Ingress resource:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app.kubernetes.io/name: kubernetes-with-ingress
    app.kubernetes.io/version: 0.1-SNAPSHOT
  name: kubernetes-with-ingress
spec:
  rules:
    - host: prod.svc.url
      http:
        paths:
          - backend:
              service:
                name: kubernetes-with-ingress
                port:
                  name: http
            path: /prod
            pathType: Prefix
    - host: dev.svc.url
      http:
        paths:
          - backend:
              service:
                name: kubernetes-with-ingress
                port:
                  name: http
            path: /dev
            pathType: ImplementationSpecific
    - host: alt.svc.url
      http:
        paths:
          - backend:
              service:
                name: updated-service
                port:
                  name: tcpurl
            path: /ea
            pathType: Prefix
```

Fix quarkusio#28812
Fix quarkusio#26747

(cherry picked from commit 8cce3d5)
@gsmet gsmet modified the milestones: 2.14.0.Final, 2.13.4.Final Oct 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/kubernetes kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants