-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Add support for fetching k8s Ingress TLS data from secrets #2439
Changes from 6 commits
3892fb7
228362c
765fba4
1f96b88
bf648b8
4c0ba9e
18c5f9e
cc0b448
1c60f29
b0a7899
741163e
c13b21a
bce97e9
383b9e8
74616a4
e082818
3ecf770
d0a5c2f
4d156ec
d00111a
6ab8f21
1d2e121
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -330,6 +330,45 @@ echo "$(minikube ip) traefik-ui.minikube" | sudo tee -a /etc/hosts | |
|
||
We should now be able to visit [traefik-ui.minikube](http://traefik-ui.minikube) in the browser and view the Træfik Web UI. | ||
|
||
### Add a TLS Certificate to the Ingress | ||
|
||
!!! note | ||
For this example to work you need a tls entrypoint. You don't have to provide a tls certificate at this point. For more details see [here](/configuration/entrypoints/). | ||
|
||
To setup a https protected ingress, you can leverage the tls feature of the ingress resource. | ||
|
||
```yaml | ||
apiVersion: extensions/v1beta1 | ||
kind: Ingress | ||
metadata: | ||
name: traefik-web-ui | ||
namespace: kube-system | ||
annotations: | ||
kubernetes.io/ingress.class: traefik | ||
spec: | ||
rules: | ||
- host: traefik-ui.minikube | ||
http: | ||
paths: | ||
- backend: | ||
serviceName: traefik-web-ui | ||
servicePort: 80 | ||
tls: | ||
- hosts: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I don't see us parsing the hosts list in our code explicitly. Am I missing something? |
||
- traefik-ui.minikube | ||
secretName: traefik-ui-tls-cert | ||
``` | ||
|
||
In addition to the modified ingress you need to provide the tls certificate via a kubernetes secret in the same namespace as the ingress. The following two commands will generate a new certificate and create a secret containing the key and cert files. | ||
|
||
```shell | ||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=traefik-ui.minikube" | ||
kubectl -n kube-system create secret tls traefik-ui-tls-cert --key=/tmp/tls.key --cert=/tmp/tls.crt | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd drop the |
||
``` | ||
|
||
!!! note | ||
The secret must have two entries named `tls.key`and `tls.crt`. See the [kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) for more details. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Excellent extension to the guide 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had no idea how to do something like this but I'm glad it is OK |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please add a note to explain that the certificates contained into the K8s secrets will be added to all the TLS entryPoints linked to the services which use them (if the label There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would the following ok with you? The TLS certificates will be added to all entrypoints defined by the ingress annotation Did you mean with 'note' the note formatting or just an addition to the documentation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes the sentence LGTM 👍 |
||
## Basic Authentication | ||
|
||
It's possible to add additional authentication annotations in the Ingress rule. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ import ( | |
"github.com/containous/traefik/log" | ||
"github.com/containous/traefik/provider" | ||
"github.com/containous/traefik/safe" | ||
"github.com/containous/traefik/tls" | ||
"github.com/containous/traefik/types" | ||
"k8s.io/client-go/pkg/api/v1" | ||
"k8s.io/client-go/pkg/apis/extensions/v1beta1" | ||
|
@@ -140,8 +141,9 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error) | |
ingresses := k8sClient.GetIngresses() | ||
|
||
templateObjects := types.Configuration{ | ||
Backends: map[string]*types.Backend{}, | ||
Frontends: map[string]*types.Frontend{}, | ||
Backends: map[string]*types.Backend{}, | ||
Frontends: map[string]*types.Frontend{}, | ||
TLSConfiguration: []*tls.Configuration{}, | ||
} | ||
for _, i := range ingresses { | ||
ingressClass := i.Annotations[annotationKubernetesIngressClass] | ||
|
@@ -308,6 +310,56 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error) | |
} | ||
} | ||
} | ||
|
||
for _, t := range i.Spec.TLS { | ||
tlsSecret, exists, err := k8sClient.GetSecret(i.Namespace, t.SecretName) | ||
if err != nil { | ||
log.Errorf("Unable to retrieve secret %s/%s: %s", i.Namespace, t.SecretName, err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use Failed instead of Unable to be consistent with the existing wording. |
||
continue | ||
} | ||
if !exists { | ||
log.Warnf("Unable to find secret %s/%s", i.Namespace, t.SecretName) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. find here and retrieve above are very similar. Can we say something like Secret %s/%s does not exist? |
||
continue | ||
} | ||
|
||
tlsCrtData, tlsCrtExists := tlsSecret.Data["tls.crt"] | ||
tlsKeyData, tlsKeyExists := tlsSecret.Data["tls.key"] | ||
if !tlsCrtExists || !tlsKeyExists { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we split this up into two dedicated errors? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should there also be a specific error for both entries missing to speed up the errorhandling? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never mind |
||
if !tlsCrtExists { | ||
log.Warnf("Secret %s/%s doesn't have an entry named 'tls.crt'", i.Namespace, t.SecretName) | ||
} | ||
if !tlsKeyExists { | ||
log.Warnf("Secret %s/%s doesn't have an entry named 'tls.key'", i.Namespace, t.SecretName) | ||
} | ||
continue | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. None of the four error cases above seem to have test coverage. Can we improve here? |
||
|
||
var hosts []string | ||
if len(t.Hosts) > 0 { | ||
hosts = t.Hosts | ||
} else { | ||
// If no hosts are provided the hosts property should default ot the wildcard host. To ensure that the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: |
||
// tls config only matches rules in this ingress, add all the used hosts to simulate a wildcard like | ||
// behavior. | ||
hosts = []string{} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If If |
||
|
||
for _, r := range i.Spec.Rules { | ||
if r.Host != "" { | ||
hosts = append(hosts, r.Host) | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My code coverage indicator tells me that the |
||
|
||
tlsConfig := &tls.Configuration{ | ||
EntryPoints: hosts, | ||
Certificate: &tls.Certificate{ | ||
CertFile: tls.FileOrContent(tlsCrtData), | ||
KeyFile: tls.FileOrContent(tlsKeyData), | ||
}, | ||
} | ||
|
||
templateObjects.TLSConfiguration = append(templateObjects.TLSConfiguration, tlsConfig) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we put the TLS logic into a dedicated function? |
||
} | ||
return &templateObjects, nil | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please uppercase
tls
toTLS
here and in every other comment (also the ones in the code).