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

[Kubeapps Chart] Simplify ingress configuration for cert-manager #740

Merged
merged 6 commits into from
Oct 19, 2018

Conversation

juan131
Copy link
Contributor

@juan131 juan131 commented Oct 17, 2018

What this PR does / why we need it:

This PR allows the user to configure the proper annotations when using cert-manager to handle TLS certificates in an easy way. The user just needs to setup a boolean to true to do so.

E.g.:

helm install --name kubeapps --namespace kubeapps bitnami/kubeapps \
  --set ingress.enabled=true \
  --set ingress.hosts[0].name=kubeapps.custom.domain \
  --set ingress.hosts[0].tls=true \
  --set ingress.hosts[0].tlsSecret=kubeapps-tls \
  --set ingress.hosts[0].certManager=true

This will generate the following ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubeapps
  namespace: kubeapps
  labels:
    app: kubeapps
    chart: kubeapps-0.8.0
    release: kubeapps
    heritage: Tiller
  annotations:
    kubernetes.io/tls-acme: "true"
spec:
  rules:
  - host: kubeapps.custom.domain
    http:
      paths:
      - path: /
        backend:
          serviceName: kubeapps
          servicePort: http
  tls:
  - hosts:
    - kubeapps.custom.domain 
    secretName: kubeapps-tls

See also bitnami/charts#882

Copy link
Contributor

@andresmgot andresmgot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Apart than the tag changes the rest looks good to me. Wait for @migmartri input on this since he is already configuring Kubeapps with TLS in an internal cluster.

version: 0.7.0
appVersion: DEVEL
version: 0.8.0
appVersion: v1.0.0-beta.2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this change, here it should be DEVEL

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -60,7 +90,7 @@ apprepository:
image:
registry: docker.io
repository: kubeapps/apprepository-controller
tag: latest
tag: v1.0.0-beta.2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same here, it's needed for this to be latest

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

@migmartri migmartri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @juan131, I am requesting changes until you rollback the appVersion DEVEL and image.tag changes.

A couple of comments:

helm install --name kubeapps --namespace kubeapps bitnami/kubeapps
--set ingress.enabled=true
--set ingress.hosts[0].name=kubeapps.custom.domain
--set ingress.hosts[0].tls=true
--set ingress.hosts[0].tlsSecret=kubeapps-tls
--set ingress.hosts[0].certManager=true

I am a little bit confused about the scope of the different options offered, for example:

In the example above, you referenced --set ingress.hosts[0].certManager=true which seems to reference to host[0] while the annotation is set at the ingress top level. Shouldn't then not be scoped inside the host?

Also noticed that in the description you had:

tls:
  - hosts:
    - kubeapps.juan.bkpr.run
    secretName: kubeapps-tls

I am assuming that kubeapps.juan.bkpr.run is a typo and was actually meant to be kubeapps.custom.domain?

@@ -1,38 +1,36 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "kubeapps.fullname" . -}}
{{- $ingressPath := .Values.ingress.path -}}
{{- range .Values.ingress.hosts }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this is creating an ingress per host? Why don't we want to use the multi-host capabilities of a single ingress?

Having different ingresses could mean that cert-manager instead of issuing a cert with multiple CN will potentially do different certs no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think it's better to use multi-host since it requires issuing many certificates

annotations:
# kubernetes.io/ingress.class: nginx

secrets:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can not see the reference where this is being used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just added!

TLS can be configured using the `ingress.tls` object in the same format that the Kubernetes Ingress requests. Please see [this example](https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx/examples/tls) for more information.
TLS can be configured using setting the `ingress.hosts[].tls` boolean of the corresponding hostname to true, then you can choose the TLS secret name setting `ingress.hosts[].tlsSecret`. Please see [this example](https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx/examples/tls) for more information.

If your cluster has a [cert-manager](https://github.com/jetstack/cert-manager) add-on to automate the management and issuance of TLS certificates, set `ingress.hosts[].certManager` boolean to true to enable the corresponding annotations for cert-manager. Otherwise, you can provide your own certificates using the `ingress.secrets` object.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you can add here the example you put in the description

helm install --name kubeapps --namespace kubeapps bitnami/kubeapps \
  --set ingress.enabled=true \
  --set ingress.hosts[0].name=kubeapps.custom.domain \
  --set ingress.hosts[0].tls=true \
  --set ingress.hosts[0].tlsSecret=kubeapps-tls \
  --set ingress.hosts[0].certManager=true

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@migmartri
Copy link
Contributor

Out of curiosity, could you also post what would have been the equivalent to the following command before the change?

helm install --name kubeapps --namespace kubeapps bitnami/kubeapps \
  --set ingress.enabled=true \
  --set ingress.hosts[0].name=kubeapps.custom.domain \
  --set ingress.hosts[0].tls=true \
  --set ingress.hosts[0].tlsSecret=kubeapps-tls \
  --set ingress.hosts[0].certManager=true

I am wondering if it would make sense to just add the certManager annotation helper but not the multi-host <-> multi-ingress support.

Thanks!

@juan131
Copy link
Contributor Author

juan131 commented Oct 18, 2018

In the example above, you referenced --set ingress.hosts[0].certManager=true which seems to reference to host[0] while the annotation is set at the ingress top level. Shouldn't then not be scoped inside the host?

Totally agree!! We should set it at the ingress top level.

I am assuming that kubeapps.juan.bkpr.run is a typo and was actually meant to be kubeapps.custom.domain?

Yes, it's a typo.

I am wondering if it would make sense to just add the certManager annotation helper but not the multi-host <-> multi-ingress support.

I'd rather user multi-host too, let me adapt it!

Copy link
Contributor

@migmartri migmartri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @juan131 for the changes!

Just added a couple of comments.

Also, would you mind attaching the diff of the output of helm template before and after the change when a chart is configured with 1 or 2 tls domains please?

Thanks!

release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- with .Values.ingress.annotations }}
app: {{ template "kubeapps.name" $ }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reverting back to template since it seems that here was the only place in which we used include.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you using $ instead of current scope .? It seems that in the other templates we use .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use .. I'll update it. The $ was necessary when we were using {{- range ... at the top.

app: {{ template "kubeapps.name" $ }}
chart: {{ template "kubeapps.chart" $ }}
release: {{ $.Release.Name }}
heritage: {{ $.Release.Service }}
annotations:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that this key annotations in this new case will be always added regardless of we passing .Values.ingress.annotations or .Values.ingress.certManager is that ok?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine. The result is: no annotations

kubernetes.io/tls-acme: "true"
{{- end }}
{{- range $key, $value := .Values.ingress.annotations }}
{{ $key }}: {{ $value | quote }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you prefer this approach vs dumping everything like before? {{ toYaml . | indent 4 }}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just used because it's how we use it on others charts. Anyway, it's only adding the value of quoting the value...

I think it's irrelevant to use one or the another.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just used because it's how we use it on others charts

ok, it makes sense. thanks for the explanation

We might need to move the rest of the chart to this approach in another PR since I believe that we use {{ toYaml . | indent 4 }} in other places.

{{- end }}
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this multi-yaml new line neccessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No

apiVersion: v1
kind: Secret
metadata:
name: {{ template "kubeapps.fullname" $ }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't the name going to collide if there are two secrets?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch!! I guess we can do sth like:

metadata:
  name: {{ .name }}

@juan131
Copy link
Contributor Author

juan131 commented Oct 18, 2018

Before:

$ helm template --name kubeapps --namespace kubeapps chart/kubeapps  \
--set ingress.enabled=true \
--set ingress.hosts[0]=kubeapps.custom.domain  \
--set ingress.hosts[1]=kubeapps.other.domain
...
# Source: kubeapps/templates/ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubeapps
  labels:
    app: kubeapps
    chart: kubeapps-0.7.0
    release: kubeapps
    heritage: Tiller
spec:
  rules:
    - host: "kubeapps.custom.domain"
      http:
        paths:
          - path: /
            backend:
              serviceName: kubeapps
              servicePort: http
    - host: "kubeapps.other.domain"
      http:
        paths:
          - path: /
            backend:
              serviceName: kubeapps
              servicePort: http

After:

$ helm template --name kubeapps --namespace kubeapps chart/kubeapps  \
--set ingress.enabled=true  \
--set ingress.certManager=true  \
--set ingress.hosts[0].name=kubeapps.custom.domain  \
--set ingress.hosts[0].tls=true \
--set ingress.hosts[0].tlsSecret=kubeapps-tls  \
--set ingress.hosts[1].name=kubeapps.other.domain
--set ingress.hosts[1].path=/other
...
---
# Source: kubeapps/templates/ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubeapps
  labels:
    app: kubeapps
    chart: kubeapps-0.8.0
    release: kubeapps
    heritage: Tiller
  annotations:
    kubernetes.io/tls-acme: "true"
spec:
  rules:
  - host: kubeapps.custom.domain
    http:
      paths:
      - path: /
        backend:
          serviceName: kubeapps
          servicePort: http
  - host: kubeapps.other.domain
    http:
      paths:
      - path: /other
        backend:
          serviceName: kubeapps
          servicePort: http
  tls:
  - hosts:
    - kubeapps.custom.domain
    secretName: kubeapps-tls

@juan131
Copy link
Contributor Author

juan131 commented Oct 18, 2018

@migmartri as you can check it's not easy to setup the annotations and tls before the changes. An also, you can't choose a different path per host

Copy link
Contributor

@migmartri migmartri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes @juan131! It looks good! 🎉

kubernetes.io/tls-acme: "true"
{{- end }}
{{- range $key, $value := .Values.ingress.annotations }}
{{ $key }}: {{ $value | quote }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just used because it's how we use it on others charts

ok, it makes sense. thanks for the explanation

We might need to move the rest of the chart to this approach in another PR since I believe that we use {{ toYaml . | indent 4 }} in other places.

@migmartri
Copy link
Contributor

BTW, now that I think about this. I am a little bit worried about the change on the way we define the hosts since it will mean a breaking change right? Meaning that if somebody today has an automated upgrade process that relies on having ingress enable it will fail right?

In that case, if we still decide to go ahead with the change we might need to bump the mayor version not the minor one.

what do you think @prydonius @juan131 @andresmgot ?

@juan131
Copy link
Contributor Author

juan131 commented Oct 18, 2018

I agree. It breaks backwards compatibility and, therefore, it should be considered a major change.

@juan131
Copy link
Contributor Author

juan131 commented Oct 18, 2018

PR updated bumping the major version.

Copy link
Contributor

@migmartri migmartri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@migmartri as you can check it's not easy to setup the annotations and tls before the changes. An also, you can't choose a different path per host

Wait, but in your example you are not setting TLS in the before case no?

And changing the example to do what your new code does (expect the path and annotation) would be something like:

helm template --name kubeapps --namespace kubeapps chart/kubeapps  \
--set ingress.enabled=true \
--set ingress.hosts[0]=kubeapps.custom.domain  \
--set ingress.hosts[1]=kubeapps.other.domain \
--set ingress.tls[0].secretName=kubeapps-tls \
--set ingress.tls.hosts[0]=kubeapps.custom.domain

which does not seems much more difficult that the new syntax. I agree that the new one is better though but I am not sure if it's worth breaking chart compatibility.

It might make sense to only add support to the custom certManager annotation without breaking compatibility, I am not even sure if adding support to path is even supported by out Nginx frontend?

I am removing my approval until more people chime in, probably breaking compatibility is fine since we are in beta and this change makes it consistent (I think) with our other upstreamed charts. But I'd like to hear from others.

Thanks!

Copy link
Contributor

@migmartri migmartri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my previous comment.

If we go ahead with this change we will probably need to upgrade the mayor version of the chart instead of the minor one.

@juan131
Copy link
Contributor Author

juan131 commented Oct 18, 2018

IMHO doing a major release of a chart should not be a drama.

We can add the steps you need to perform to do an upgrade if you consider it necessary but I think it's something normal since charts are improved constantly and some of these changes can break backward compatibility.

@migmartri
Copy link
Contributor

Actually @andresmgot raised a good point that in semver, for 0.x versions, minor version changes are considered breaking. So feel free to revert back to 0.9 (in your case since 0.8 has already been taken).

Thanks @juan131!

@migmartri migmartri merged commit 8cc2ba2 into vmware-tanzu:master Oct 19, 2018
@juan131 juan131 deleted the kubeapps_tls branch October 23, 2018 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants