When deploying to Kubernetes, there can be scenarios where you would want to use your own TLS certificates for ingress rather than Let's Encrypt or another external provider.
In this tutorial, I will show you how to set up your own certificates.
Step 1 - Civo Kubernetes cluster creation
You can create the cluster from the UI or from the Civo CLI. For this tutorial, let's create using the CLI.
$ civo k3s create
The cluster green-stone (14e7bb11-b41f-4e4b-a177-dd97670a0183) has been created
Above will create a 3 node cluster named green-stone
. The name has been generated randomly as we did not provide a name. Once the cluster is up and running in a few minutes, we can proceed.
We will need to get the Kubeconfig for the cluster and save to our desired location. If you do not specify a path, it will save it to the default location of ~/.kube/config
.
$ civo k3s config green-stone --save --local-path /Users/saiyampathak/civo/test/tls-demo.config
Access your cluster with:
KUBECONFIG=/Users/saiyampathak/civo/test/tls-demo.config kubectl get node
Let's make sure that kubectl
knows to use our cluster's configuration file:
$ export KUBECONFIG=/Users/saiyampathak/civo/test/tls-demo.config
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
NAME STATUS ROLES AGE VERSION
k3s-green-stone-4e4d-cc89a2-node-pool-860c Ready <none> 47h v1.20.2+k3s1
k3s-green-stone-4e4d-cc89a2-node-pool-e1ea Ready <none> 47h v1.20.2+k3s1
k3s-green-stone-4e4d-cc89a2-node-pool-caf8 Ready <none> 47h v1.20.2+k3s1
Step 2 - Create certificates
For this tutorial, create a self-signed certificate with OpenSSL. In a real-world scenario, you should request a signed certificate from a certificate authority.
Make sure your computer has OpenSSL installed, and run the following, making sure to replace the 14e7bb11-b41f-4e4b-a177-dd97670a0183.k8s.civo.com
string in your command with the DNS A record of your cluster. You can get this record by running civo k8s show your-cluster-name
and viewing the A record section.
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -out civo-ingress-tls.crt -keyout civo-ingress-tls.key -subj "/CN=14e7bb11-b41f-4e4b-a177-dd97670a0183.k8s.civo.com/O=civo-ingress-tls"
Generating a 2048 bit RSA private key
..........................................................................+++
....................................................................................................................................................+++
writing new private key to 'civo-ingress-tls.key'
-----
$ ls
civo-ingress-tls.crt civo-ingress-tls.key
Step3 - Create Kubernetes secret
Create a Kubernetes TLS secret in order to use the key generated in the previous step. This secret will be used later in the ingress.
$ kubectl create secret tls civo-ingress-tls --key civo-ingress-tls.key --cert civo-ingress-tls.crt
secret/civo-ingress-tls created
Step 4 - Create deployment, service and ingress
Let's create the deployment. For this demo we will be using a sample "hello world" application image:
$ kubectl create deployment demo --image=gcr.io/google-samples/hello-app:1.0
deployment.apps/demo created
Expose the deployment as a service:
$ kubectl expose deployment demo --port=8080
service/demo exposed
Now, we need to create the ingress with TLS. Civo Kubernetes ships with Traefik as the default ingress controller so you can directly create the ingress. Save the following yaml file as ingress.yaml
in your current directory, making sure to edit where noted:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
spec:
tls:
- hosts:
- 14e7bb11-b41f-4e4b-a177-dd97670a0183.k8s.civo.com # Replace with your cluster DNS name
secretName: civo-ingress-tls
rules:
- host: 14e7bb11-b41f-4e4b-a177-dd97670a0183.k8s.civo.com # Replace with your cluster DNS name
http:
paths:
- backend:
service:
name: demo
port:
number: 8080
path: /demo
pathType: Prefix
Then apply this ingress to your cluster to allow us to access the application:
$ kubectl apply -f ingress.yaml
ingress.networking.k8s.io/demo-ingress created
Verify the ingress is correctly set up with kubectl get ing
:
kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
demo-ingress <none> demo.14e7bb11-b41f-4e4b-a177-dd97670a0183.k8s.civo.com 212.2.240.135 80, 443 6h56m
Step 5 - Check everything works
You already get a DNS with your Civo Kubernetes cluster so you can test using the curl
command, replacing domain string below with your cluster's A record:
curl -v -k https://14e7bb11-b41f-4e4b-a177-dd97670a0183.k8s.civo.com/demo
There will be a complete verbose output but you can see that in the server certificate section, the issuer and the secret will be mentioned.
Server certificate:
* subject: CN=14e7bb11-b41f-4e4b-a177-dd97670a0183.k8s.civo.com; O=civo-ingress-tls
* start date: Jan 4 18:44:06 2022 GMT
* expire date: Jan 4 18:44:06 2023 GMT
* issuer: CN=14e7bb11-b41f-4e4b-a177-dd97670a0183.k8s.civo.com; O=civo-ingress-tls
* SSL certificate verify result: self signed certificate (18), continuing anyway.
And the request will be served completely, in the end of the output of the curl
request you can see the output.
Hello, world!
Version: 1.0.0
Hostname: demo-6cfc75f989-bzlsm
Wrapping up
This is how you can use self signed certificates for ingress.
Let us know on Twitter @Civocloud and @SaiyamPathak if you try your own certificate out on Civo Kubernetes or face any issues.