Last modified December 4, 2024
Obtaining TLS certificates for ingress traffic
Exposing HTTP
services using an Ingress
resource is a pretty straightforward task in Kubernetes
. However, you should always make sure that the traffic is encrypted. Relying on cert-manager
provides a simple approach to obtain declaratively TLS certificates automatically.
Our app platform provides a cert-manager-app
that users can install. By default, cert-manager
creates a ClusterIssuer
using the HTTP
challenge. It works fine for obtaining certificates in most cases. However, not creating the default issuer and instead creating a custom one solving DNS challenges is required for pure internal environments or for issuing wildcard certificates. In other words: it is not needed to disable the creation of the default issuer. However, if needed, you can disable its creation by providing the following user values:
global:
install: false
Then, it is possible to create a new ClusterIssuer
that solves DNS
challenges. The following example shows how to create a for Azure and AWS:
You need to create a user in AWS IAM with a IAM policy that allows the user to manage Route53 records like the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:GetChange",
"route53:ChangeResourceRecordSets",
"route53:GetHostedZone"
],
"Resource": "arn:aws:route53:::hostedzone/*"
},
{
"Effect": "Allow",
"Action": "route53:ListHostedZonesByName",
"Resource": "*"
}
]
}
Then create a Secret
with the AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
:
apiVersion: v1
kind: Secret
metadata:
name: route53-credentials-secret
type: Opaque
stringData:
access-key: AWS_ACCESS_KEY_ID
secret-access-key: AWS_SECRET_ACCESS_KEY
Finally, create the ClusterIssuer
:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod-dns
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: email@example.com
privateKeySecretRef:
name: letsencrypt-giantswarm
solvers:
- dns01:
route53:
region: AWS_REGION
hostedZoneID: HOSTED_ZONE_ID
accessKeyID: AWS_ACCESS_KEY_ID
secretAccessKeySecretRef:
name: route53-credentials-secret
key: secret-access-key
selector:
dnsZones:
- "{cluster-name}.installation.region.provider.gigantic.io"
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-giantswarm
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: test@customer.com
privateKeySecretRef:
name: letsencrypt-giantswarm
solvers:
- dns01:
azureDNS:
subscriptionID: subscription-id
resourceGroupName: cluster-id
hostedZoneName: cluster-id.installation.region.provider.gigantic.io
Finally, you can simply create an Ingress
resource that contains the tls
configuration like below:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test
annotations:
kubernetes.io/tls-acme: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- test.cluster.k8s.installation.region.provider.gigantic.io
secretName: test-tls
rules:
- host: test.cluster.k8s.installation.region.provider.gigantic.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-world-service
port:
number: 8080
Note: It is important to specify the correct spec.ingressClassName
(which will likely be either nginx
or nginx-internal
) and spec.tls
fields.
It is also possible to obtain wildcard certificates, which can be useful in some cases. Please note that wildcard certificates can only be obtained via a DNS
challenge such as the one set up in this example - they can not be obtained via HTTP
challenges.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard
spec:
commonName: "*.cluster.k8s.installation.region.provider.gigantic.io"
dnsNames:
- "*.cluster.k8s.installation.region.provider.gigantic.io"
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: letsencrypt-giantswarm
secretName: wildcard-tls
this certificate can then be used by setting the following spec.tls
field in an Ingress
resource:
spec:
tls:
- hosts:
- example.cluster.k8s.installation.region.provider.gigantic.io
secretName: wildcard-tls
Note: In this case, since you are using an already existing certificate, remember to remove the kubernetes.io/tls-acme: "true"
annotation from the Ingress
resource.
If you want to learn more about Ingress
connectivity, please check our tutorials.
Need help, got feedback?
We listen to your Slack support channel. You can also reach us at support@giantswarm.io. And of course, we welcome your pull requests!