
Kubernetes TLS, Demystified
This is the anniversary 10th article in this series.
🛡️ It is more than obvious a secured connection to any exposed service running in Kubernetes cluster is important.
The supposition for this article is that you wish to set up TLS (Transport Layer Security) realm for youringress resource and that you already have a functioning ingress controller established in your cluster.
The SSL replacement technology is called Transport Layer Security (TLS) today. An enhanced version of SSL is TLS.
Similar to how SSL operates, it uses encryption to safeguard the transmission of data and information. Although SSL is still commonly utilized in the industry, thetwo names are frequently used interchangeably.
Getting a certificate: what paths can be taken?
A TLS/SSL certificate is the fundamental prerequisite for ingress TLS. These certificates are available to you in the following ways.
- Path one. Self-signed certificates: Our own Certificate Authority (root CA)created and signed the TLS certificate. It is a well-known, stunt choice fortesting scenarios where you can "collaborate" on the root CA so that browsers will accept the certificate.
Path two. Get an SSL certificate: for production use cases, you mustpurchase an SSL certificate from a reputable certificate authority that operating systems and browsers trust. But you must bear in mind that a so-calledwildcard certificate suitable to protect all subdomains in a domain can cost $300+/year from major commercial issuers.
Path three. Use a Let's Encrypt certificate: Let's Encrypt is a reputable certificate authority that issuesfree TLS certificates.
A few words about Let's Encrypt
It is a non-profit organization founded byenthusiasts in the field of struggle for privacy and security in 2014.
The challenge–response protocol used to automate enrolling with the certificate authority is called Automated Certificate Management Environment (ACME). It can query either Web servers or DNS servers controlled by the domain covered by the certificate to be issued.
If you are interested in the implementation of the protocol, read whatAdrian Colyer from SpringSource writes about them.
Each SSL certificate has anexpiration date. So, before the certificate expires, you need torotate it. For instance, Let's Ecrypt certificates have athree-month expiration date (andhere they tell why).
This way, below in this article series, the author will dwell on thethird path further in detail. Why? Well, since this path is interesting for its relative self-sufficiency and [relative] independence from commercial / state-owned certificate issuers. In general, the motto of this path is: "If made something with your hands, you know how it works - you're more adapted to survival!"
Of course, Let's Encrypt approach does notalways fit needs, but for academic purposes and for startups it works.
But let's look at the situation "in manual mode" - just try to associate a certificate with a protected application. So,
Chicken or egg?
Theingress controller, not the ingress resource, is in charge of SSL. In other words, the ingress controlleraccesses the TLS certificates you provide to the ingress resource as a Kubernetessecret
and incorporates them into its configuration.
Setup TLS/SSL certificates for ingress
Let's examine the procedures for setting up TLS for ingress. We'll start by launching a test application on the cluster. This application will be used to test our TLS-secured ingress.
Establish the new namespace,trial
.
kubectl create namespace trial
Keep this ashello-app.yaml
. TheDeployment
andService
objects are present.
apiVersion:apps/v1kind:Deploymentmetadata:name:hello-appnamespace:trialspec:selector:matchLabels:app:helloreplicas:1template:metadata:labels:app:hellospec:containers:-name:helloimage:"rbalashevich/hello-app:2.0"---apiVersion:v1kind:Servicemetadata:name:hello-servicenamespace:triallabels:app:hellospec:type:ClusterIPselector:app:helloports:-port:80targetPort:8080protocol:TCP
Deploy the application with a command:
kubectl apply -f hello-app.yaml -n trial
Create a Kubernetes TLS Secret
It is necessary to make the SSL certificate a Kubernetes secret. It will subsequently be directed to thetls
block forIngress
resources.
Theserver.crt
(CA trust chain) andserver.key
(private key) SSL files are assumed to be available from a Certificate Authority, your company, or self-signed, as a last resort.
⚠️ A private key is created by you (the certificate owner) when you request your certificate with a Certificate Signing Request (CSR). Saying other words, you receive a private key when generate a CSR. You submit the CSR code to the certificate authority and keep private key in a safe place.
As for the big three public cloud providers, they have instructions for exporting certificates:AWS CM,GCP CAS,Azure KV.
It is necessary to make the SSL certificate a Kubernetes secret. It will subsequently be directed to thetls
block forIngress
resources.
And yes, keep the private key (
server.key
)!
Let's use theserver.crt
andserver.key
files to construct a Kubernetes secret oftls
type (SSL certificates). In thetrial
namespace, where thehello-app
deployment is located, we are creating the secret.
Run thekubectl
command listed below from the directory where your server is located. Supply theabsolute path to the files or the.crt
and.key
files. The namehello-app-tls
is made up.
kubectl create secret tls hello-app-tls \ --namespace trial \ --key server.key \ --cert server.crt
The comparable YAML file, where you must include the contents of the.crt
and.key
files, is provided below.
apiVersion:v1kind:Secretmetadata:name:hello-app-tlsnamespace:trialtype:kubernetes.io/tlsdata:server.crt:|<crt contents here>server.key:|<private key contents here>
A Kubernetes ingress isa set of rules that can be configured to give services externally reachable URLs. Based on this understanding, to turn on secure connection, we should addtls
block toIngress
object. So, in thetrial
namespace, we create the sample ingress TLS-capable resource:
apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:hello-app-ingressnamespace:trialspec:ingressClassName:nginxtls:-hosts:-app.hosting.cloudprovider.comsecretName:hello-app-tlsrules:-host:"app.hosting.cloudprovider.com"http:paths:-pathType:Prefixpath:"/"backend:service:name:hello-serviceport:number:80
⚠️ Replaceapp.hosting.cloudprovider.com
to your actual hostname. Thehost(s)
should be the same in both therules
andtls
blocks in theIngress
manifest. In other words, they must match.
In case of using NGINX ingress, you can add the supported annotation by the ingress controller you are using if you want astrict SSL. For instance, you can use theannotationnginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
in the Nginx ingress controller to permit SSL traffic up until the application.
The way to make sure
Let's check withcurl https://app.hosting.cloudprovider.com -kv
, is the connection to the app secure now:
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384* ALPN, server accepted to use h2* Server certificate:* subject: CN=app.hosting.cloudprovider.com* start date: Oct 6 15:35:07 2022 GMT* expire date: Oct 6 15:35:07 2023 GMT* issuer: CN=Go Daddy Secure Certificate Authority - G2, OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.",L=Scottsdale,ST=Arizona,C=US* SSL certificate verify ok.
🔒 If the certificate is valid, then the browser will not swear and there will be no frightening warnings either. Voilà, the connection to our app is secure!
Okay, we've covered the situations for the first and second paths. The next step is pathfinding the third path involving Let's Encrypt certificate.
Estne vita vere brevis?
Sed vita est cum dignitate vivendum. As the author noted above, the life of a certificate from a let's encrypt isshort. You have to pay for insolence. Accordingly, some solution is required that would automate the re-issuance of short-lived certificates, right? And such a solution exists, it iscert-manager
! It streamlines the process of getting, renewing, and using certificates by adding certificates and certificate issuers asresource types in Kubernetes clusters.
It can generate certificates from a number of supported sources, including Let's Encrypt.
Furthermore, it will check that certificates are current and valid and make an attempt torenew them for a specified periodbefore theyexpire.
Install cert-manager on Kubernetes
According to the officialcert-manager
documentation, you can install it by usingkubectl or by the providedhelm chart.
# Create a dedicated Kubernetes namespace for cert-managerkubectl create namespace cert-manager# Add official cert-manager repository to helm CLIhelm repo add jetstack https://charts.jetstack.io# Update Helm repository cache (think of apt update)helm repo update# Install cert-manager on Kubernetes## cert-manager relies on several Custom Resource Definitions (CRDs)helm install certmgr jetstack/cert-manager \ --set installCRDs=true \ --version v1.9.1 \ --namespace cert-manager
TheIssuer
is responsible for issuing certificates. It is the signing authority and based on its configuration. The issuer knows how certificate requests are handled.
Cert-manager also creates several objects using different specifications such asCertificateRequest
.
ACertificate
resource is a readable representation of a certificate request. Certificate resources are linked to anIssuer
who is responsible for requesting and renewing the certificate.
To determineif a certificateneeds to be re-issued,cert-manager
looks at the thespec
ofCertificate
resource and latestCertificateRequests
as well as the data inSecret
containing the certificate.
Let's Encrypt: staging or production server?
AnIssuer
is a custom resource (CRD) which tellscert-manager
how to sign aCertificate
. Followingthis howto (section 7) theIssuer
will be configured to connect to the Let's Encrypt staging server, which allows us to test everything without using up your Let's Encryptcertificate quota for the domain name.
After debugging, you can safely issue a certificate by using LE's production server.
A video describingcert-manager
YAML syntax and recommended by the author of this article is📽️ Anton Putra's good one.
Conclusion
SSL certificate acquisition was made simple by Let's Encrypt's reputation as a reliable certificate authority. Together withcert-manager
tool, ops can quickly and easily assure correct transport encryption and interoperability with already-existing parts like NGINX Ingress. In addition to the example mentioned above,cert-manager
can help with trickier situations like those involving wildcard SSL certificates.
If you're interested in using letsencrypt outside of a kubernetes cluster, take a look atCaddy, a 43k ⭐ open source web server, and also at Certbot, a 29k ⭐ ACME client which is open source, too.
Ever tried usingwireshark
to monitor web traffic? FollowAaron Phillips from Comparitech to learn how.
Safe connections to you!
Top comments(1)

- Email
- LocationAmsterdam
- WorkMaster Instructor at Mulesoft
- Joined
Hi thanks for the guide, seems that with the latest version of kubernetes the commandkubectl create -n trial
now works with the following syntax instead:kubectl create namespace trial
For further actions, you may consider blocking this person and/orreporting abuse