
The Traefik Kubernetes Ingress provider is an open-source Kubernetes Ingress controller. It integrates with cert-manager to provide a TLS certificate to expose the internal Services of your Kubernetes cluster securely.
In this article, you will install the Traefik Ingress controller on your Kubernetes cluster along with cert-manager to expose your applications securely using a TLS certificate. You will also create a sample application, create an internal Service for it, create an Ingress resource to expose that Service, and issue a TLS certificate using cert-manager.
Prerequisites
Before you begin, make sure you:
- Have access to a Kubernetes cluster.
- Install Kubect on your local machine.
- Install the Helm client on your local machine.
- Have access to a domain name. This guide uses
example.com
. Replace all occurrences with your actual domain.
Install and Configure Traefik
Create a namespace
traefik-namespace
for the Traefik Ingress controller resources.console$ kubectl create namespace traefik-namespace
Add the Traefik Helm repository.
console$ helm repo add traefik https://helm.traefik.io/traefik
Update your Helm chart repositories.
console$ helm repo update
Using Helm, install the Traefik Ingress controller.
console$ helm install --namespace=traefik-namespace traefik traefik/traefik
The above command installs the Traefik Ingress controller in the
traefik-namespace
you created earlier.Check the Traefik Ingress controller Service's external IP Address.
console$ kubectl get services -n traefik-namespace
Your output should look like the one below:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE traefik LoadBalancer 10.108.209.185 <pending> 80:30046/TCP,443:30279/TCP 78s
The
EXTERNAL-IP
value of thetraefik
Service is not allocated yet. Depending on your cloud provider, it may take some time for thetraefik
Service to get its external IP address. After some time, the output changes to:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE traefik LoadBalancer 10.107.61.70 192.0.2.10 80:30351/TCP,443:32047/TCP 9m34s
Visit your Domain DNS registrar. For example, Vultr DNS.
Set up a domain A record pointing to the Traefik LoadBalancer external IP Address.
Install cert-manager
cert-manager is a Kubernetes custom resource that can issue TLS certificates from different Certificate Authorities, such as Let's Encrypt, HashiCorp Vault, Venafi, and many more. It also ensures that the certificates are valid and up to date by actively attempting to renew them before they expire. In this section, you will install cert-manager on your Kubernetes cluster.
Install the latest cert-manager version on your cluster.
console$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yaml
The above command installs version
v1.17.2
of cert-manager. To find the latest cert-manager version, visit the cert-manager GitHub repository.Verify that all cert-manager components are installed and running.
console$ kubectl get pods --namespace cert-manager
You should see resources with
cert-manager
in their names in the output.
Create a ClusterIssuer
ClusterIssuer is a cluster-scoped custom resource that comes with cert-manager. It issues TLS certificates for Ingress resources. In this section, you will create a ClusterIssuer resource to issue Let's Encrypt certificates.
Create a new file named
cluster-issuer.yaml
.console$ nano cluster-issuer.yaml
Add the following contents to the file.
yamlapiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: email: hello@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod-key solvers: - http01: ingress: class: traefik
Noteexample.com
domain, specify a valid email address. Otherwise, the ClusterIssuer resource would not work.Below is what the above configuration declarations represent:
acme
: Specifies the ACME configuration for the CA, which is Let's Encrypt in this case.email
: Your email address to associate with a Let's Encrypt account.server
: The ACME server URL.privateKeySecretRef
: Specifies the Secret that holds the Let's Encrypt account private key.solvers
: Sets the method for solving the ACME challenge.http01
: Sets HTTP-01 as the challenge solver to verify domain ownership.ingress
: Sets the ingress class to solve the challenge.
Save and close the file.
Apply the manifest file.
console$ kubectl apply -f cluster-issuer.yaml
Check the ClusterIssuer.
console$ kubectl get clusterissuer
Output:
NAME READY AGE letsencrypt-prod True 2m44s
Notice the
True
value of theREADY
field. It indicates that the ClusterIssuer resource is ready to issue certificates.
Deploy a Sample Application
In this section, you will deploy a sample application based on the Nginx web server to test your Traefik configuration and the cert-manager certificate issuance process.
Create a new namespace,
example-app-namespace
, to store the resources of the sample application.console$ kubectl create namespace example-app-namespace
Create a new Deployment file named
example-app-deployment.yaml
.console$ nano example-app-deployment.yaml
Add the following contents to the file.
yamlapiVersion: apps/v1 kind: Deployment metadata: namespace: example-app-namespace name: example-app-deployment spec: replicas: 3 selector: matchLabels: app: example-app template: metadata: labels: app: example-app spec: containers: - name: web-app image: nginx ports: - containerPort: 80
This manifest file creates a Deployment
example-app-deployment
that uses the Nginx web-server image and creates three replicas.Below is what the Deployment configurations represent:
replicas
: The number of replicas (pods) of the Deployment.selector
: The labels used for selecting the pods controlled by the Deployment.template
: Specifies the template for creating the pods.metadata
: Specifies the labels for the pods.spec
: Specification for the pods.containers
: Specifies the containers within the pods.name
: Specifies the container name.image
: Container image of the pods.ports
: Ports opened in the container.
Save and close the file.
Apply the Deployment manifest.
console$ kubectl apply -f example-app-deployment.yaml
The above command creates the Deployment
example-app-deployment
in the namespaceexample-app-namespace
.Verify that the example application pods are running.
console$ kubectl get pods -n example-app-namespace
You should see three pods with names starting with
example-app-deployment-
listed in the output.
Create an Ingress Resource
In this section, you will create a Service for your Deployment and then create an Ingress resource to expose that Service externally using a TLS certificate.
Create a new Service manifest file named
example-app-service.yaml
.console$ nano example-app-service.yaml
Add the following contents to the file.
yamlapiVersion: v1 kind: Service metadata: namespace: example-app-namespace name: example-app-service spec: selector: app: example-app ports: - protocol: TCP port: 80 targetPort: 80
This creates a Service
example-app-service
that exposes the pods of your Deploymentexample-app-deployment
.Below is what the Service manifest represent:
spec
: Describes the Service's specification.selector
: Specifies a set of labels used to select the pods to which the Service should route traffic.app
: Specifies a label namedapp
with the valueexample-app
.ports
: Defines the ports exposed by the Service.protocol
: Specifies the protocol to use for the ports.port
: The port number the Service should listen on.targetPort
: Specifies the port number to which traffic should be forwarded within the pods.
Save and close the file.
Apply the Service manifest file.
console$ kubectl apply -f example-app-service.yaml
Verify that the Service is created.
console$ kubectl get services -n example-app-namespace
Output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-app-service ClusterIP 10.97.221.68 <none> 80/TCP 81s
Create a new Ingress manifest file
example-app-ingress.yaml
.console$ nano example-app-ingress.yaml
Add the following contents to the file. Replace
example.com
with your actual domain.yamlapiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-app-ingress namespace: example-app-namespace annotations: traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.tls: "true" cert-manager.io/cluster-issuer: letsencrypt-prod spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: example-app-service port: number: 80 tls: - secretName: web-app-cert hosts: - example.com
This manifest file creates an Ingress resource to expose your Service
example-app-service
for the domain nameexample.com
.Below is what the Ingress declarations represent.
annotations
: Specifies the annotations for the Ingress, including Traefik-specific and cert-manager-specific annotations.traefik.ingress.kubernetes.io/router.entrypoints: websecure
: Configures the Traefik ingress controller to route incoming traffic to thewebsecure
entrypoint. It specifies the entrypoint to use for handling HTTPS traffic.traefik.ingress.kubernetes.io/router.tls: "true"
: Specifies that the router should handle HTTPS traffic. It enables TLS termination and ensures secure communication between clients and the application.cert-manager.io/cluster-issuer: letsencrypt-prod
: Specifies the cert-manager cluster issuer to use for obtaining SSL/TLS certificates. It associates the Ingress resource with theletsencrypt-prod
cluster issuer you created earlier.spec
: Specifies the specification for the Ingress.rules
: Specifies the rules for routing the traffic.host
: Specifies a domain/host to match the rule.http
: Specifies the HTTP routing for the host.paths
: Specifies the paths to match within the host.path
: Specifies the path to match.backend
: Specifies the backend Service to route the traffic to.service
: Specifies the name of the to which to forward the traffic.port
: Specifies the port number of the Service to use.tls
: Specifies the TLS configuration for the Ingress resource.secretName
: Specifies the name of the Secret resource that stores the TLS certificate and private key. cert-manager creates this Secret resource. It need not be present before creating the Ingress.hosts
: Specifies the hostnames associated with the TLS certificate.
Save and close the file.
Apply the ingress configuration.
console$ kubectl apply -f example-app-ingress.yaml
Verify that the Ingress resource is created.
console$ kubectl get ingress -n example-app-namespace
Output:
NAME CLASS HOSTS ADDRESS PORTS AGE web-app-ingress traefik example.com 80, 443 9s
The
ADDRESS
filed is empty right now. A few seconds later, its value populates. The value should be the external IP address of thetraefik
Service.Verify that a Let's Encrypt SSL certificate is registered for your domain.
console$ kubectl get certificates -n example-app-namespace
Output:
NAME READY SECRET AGE web-app-cert True web-app-cert 41s
If the READY column returns
True
, your SSL certificate is successfully issued and ready to use. It may take some time for the Certificate resource to become ready.Verify that the certificate auto-renews on expiry.
console$ kubectl describe -n example-app-namespace certificate web-app-cert
The about command prints information about the certificate. Find the
Renewal Time
setting, and make sure its value is a date as below:... Renewal Time: 2023-09-17T15:23:45Z ...
In a web browser like Chrome, visit your domain name to access your application securely.
https://example.com
The default Nginx welcome page displays in your browser.
Troubleshooting
To manage Traefik and your cluster resources, below are troubleshooting tips for fixing common problems.
Unable to get Let's Encrypt Certificate: If your certificate column returns False, verify that your domain is correctly pointed to your Traefik LoadBalancer external IP Address. Additionally, to investigate further causes, view the cert-manager logs using the command below.
console$ kubectl logs deployment/cert-manager -n cert-manager --tail=15 -f
Check Traefik logs: If you're experiencing issues with Traefik, check the logs for any error messages or warnings using the following command.
console$ kubectl logs -n <namespace> <traefik-pod>
Verify DNS configuration: Verify that your domain name is correctly pointed to the External IP address of your Traefik load balancer. Wrong DNS configurations prevent Traefik from handling incoming requests correctly.
Verify ingress configuration: If Traefik does not route external traffic correctly, check your Ingress resource configuration and verify that the necessary annotations for Traefik and cert-manager are included in your YAML file.
console$ kubectl get ingress
Inspect Traefik resources: Occasionally, inspect the status of Traefik resources such as pods, Services, and ingresses to ensure they are running correctly.
console$ kubectl get pods -n traefik-namespace
Conclusion
In this article, you installed the Traefik Ingress Controller. You created a web application and securely exposed it using Traefik, cert-manager, and Let's Encrypt. For more information and configuration options, visit the following resources:
No comments yet.