You landed here because you want to configure certificates so you can access your services in your Kubernetes cluster securely. Well, you've come to the right place. Configuring certificates in Kubernetes can be challenging, but today we're going to break it all down end to end to get your cluster trusted certificates.
We're going to use the ever popular reverse proxy traffic as our Kubernetes ingress so we can route web-f facing or internal traffic to our Kubernetes cluster. Using traffic, we can easily create HTTPS endpoints to route our traffic securely. Which certificates are we going to use?
We're going to use certificates that are provisioned absolutely free from Let's Encrypt, the open-source, secure, and automated way to provide TLS certificates, but we won't store those certificates in traffic. No, no, no, not this time. We want a highly available traffic instance.
And in order to do that, we can't store them in Kubernetes storage. So, that's where Manager comes in. Cert Manager is an open-source cloudnative certificate management system for Kubernetes.
It can obtain certificates from a variety of issuers, both public and private, and ensure that the certificates are up to date. And if they're not, it will automatically renew them before the expiration date. We'll use a DNS provider like Cloudflare, but domain verification can be done with many different providers.
And we're going to make this highly available. All of it from traffic toert manager to even a workload secured with our newly obtained certificates. I've spent the last few weeks creating this tutorial to make it as easy and as repeatable as possible.
So by the end of this video, you'll have a highly available way to secure your services in Kubernetes. Also, I've included all of my resources you need on my documentation site. But before we jump in, a huge thanks to our sponsor the tree for making today's video possible.
How many times have you applied a Kubernetes configuration only to realize later that it was misconfigured, not configured according to best practices, or just plain wrong? These types of misconfigurations can create engineering churn and possibly even downtime. That's where Dree can help.
Dre is an open source tool that prevents Kubernetes misconfigurations from ever reaching your Kubernetes cluster. It does this by scanning objects against a centrally managed policy. This policy comes with Kubernetes best practices builtin, but it's flexible enough so that teams can customize this policy according to your organization's needs.
And the tree isn't just a simple YAML enter. Along with YAML validation, it does schema validation as well as checking against your configured policy. The tree also comes with a fancy dashboard that is backed by great documentation to help you fix errors fast.
It installs in seconds and can be run from a CLI from coupube control in your CI and CD pipeline and even as a Kubernetes admission hook that can intercept and test Kubernetes manifest even in this last mile. To sum it all up, Dree can help prevent Kubernetes misconfigurations from happening in the first place. So help empower your engineers by installing Dre today.
So what do we need to get started? First, we'll need a Kubernetes cluster. I've created a simple way to get a highly available K3S cluster using Anible that comes with everything you need to get started, but any Kubernetes cluster will do.
Next, we'll want to be sure we have a few tools installed. We're going to use Helm, which is a package manager for Kubernetes. This will help us install packages into our Kubernetes cluster.
So, first we'll want to run a coupe control get nodes to make sure we can communicate with our Kubernetes cluster. Then, we'll want to run a Helm version to make sure that Helm is installed and working. Now, it's also important to mention that you should have met installed.
Metalb is a load balancer that allows you to communicate with your Kubernetes cluster from the outside. And if you ran my K3S anal playbook, it installs it for you. So, first we want to install traffic.
Remember that's our Kubernetes ingress that allows us to communicate with our services inside of our cluster. So, first we'll create a namespace for traffic. And then after that, you'll want to make sure that you can see your namespace in the list and we can.
Then we'll want to add traffic to our repositories on our local machine. Then we'll want to update our local repositories with helm repo update. Then we're going to install traffic, but we're going to provide some values as you can see from that argument-values equals value.
yaml. And this is the values. yaml that we're going to use.
So I've stripped most of this down to the basics. So let's talk about what some of these flags mean. So first we're setting up some global arguments that will pass to the binary traffic when it starts.
So, we're saying send anonymous usage equals false and check new versions equals false. Now, this is totally optional. If you want to send anonymous usage to traffic, you're absolutely welcome to.
And the same with checking for new versions, I turn it off. Next are some additional arguments. And this argument right here is really just to skip verification of untrusteds.
This is basically telling traffic to, hey, if you see an insecure or a self-signed certificate in between, allow it to pass through. And I'm allowing this because some of my services behind traffic will have a self-signed certificate. So, this is kind of a way around that.
Next, I'm setting the log level to debug. Really, this should be info once you get it working, but it's really nice to keep it in debug mode while you're actually setting this up in case you run into some problems. But technically, this should be at info.
Next are some flags for our deployments. So enabled, obviously true. We want to enable a traffic deployment.
Replicas is set to one. We can set it to three. I said we were going to make this HA, so we might as well go three.
Annotations, pod annotations, additional containers, and init containers. Those are all empty, but I'm leaving them there just in case I need them in the future. I don't have to go and look up to see what each of these values are.
I'll see the keys and fill it in. And for ports, these are ports to expose from traffic. So I'm saying traffic should expose the web port but then redirect to web secure port which is TLS enabled true.
So this is saying that all traffic coming into traffic should be redirected to the TLS endpoint. So that means if someone tries to make a request over HTTP it's going to redirect automatically to HTTPS. And we're doing this here at this level for all of traffic.
Next is actually disabling the dashboard on the ingress route. This one's a little bit confusing, but if you use ingress route, which is also a little bit confusing, you have the option to enable the dashboard here through an ingress route. So, two things.
First of all, I do use an ingress route. It's a little more advanced than just an ingress. So, Kubernetes has an object called an ingress and traffic can be used for that ingress.
However, I like to go the ingress route because you get a little more control. It's a little more advanced and I get to write all my routes declaratively. I could write them declaratively as an ingress, but I get a few more options with ingress route.
Really up to you. I choose ingress route and I think we're touching on a few flags that are later on. So, I'll probably mention this again when we get there.
Anyways, long story short, I'm disabling the ingress route for the dashboard here because we'll configure it later on. Next, we're setting up providers. So we're telling it, hey, do we want to install the Kubernetes CRD?
So custom resource definitions. I'm saying yes. And then here's what I was just talking about, ingress class.
So our ingress class is going to be traffic external. So what does that mean? Well, as I mentioned earlier, I'm setting up an ingress route rather than a normal ingress.
Not too important, but the name of that will be traffic external. Now, you can name this anything you want. You could name it just traffic, but I like to name this according to what I'm going to expose it to.
For this, I'm calling it traffic external, and it's just a way for me to know that I'm going to expose this externally, but really it can be named anything you'd like. Next, we have the option to expose the ingress as well. And I enabled that.
And then whether or not you want to enable the Kubernetes ingress, too. And then publish service enabled true. I think this actually needs to be false.
I was testing something earlier and it needs to be false which is the default value. So this is not something we need. It's pretty advanced too.
Next is arback enabled and that's rolebased access control and we want to enable that so we can use our traffic service account to configure our ingress within our cluster and do some other things. So next is the actual service. So we want this enabled obviously and then we'll enable the type of load balancer which means that when traffic stands up it'll actually be a load balancer and we'll get an IP address from Metal LB which you'll see here in a little bit which is right here and this should be an IP address in the range of your MELB IP range.
So if you specified a range just pick one IP address in that range. If you only specified one that's going to be your one. So this is our traffic config.
Pretty small, pretty easy. So let's actually go back and install this. So we're saying helm install install namespace traffic a release name of traffic from a repo traffic traffic and the values were pointing at the values.
yamel that I just explained. So let's run that. And so this now should be installing the service.
It's actually already deployed. And if we want to check we can say coupubecontrol get service all namespaces o wide. So we're saying give me every single service in all name spaces in our Kubernetes cluster.
If we run that we can see we don't have many but we can see traffic right here which is a good sign and it is of type load balancer like we wanted and then we see our cluster IP and then we see our external IP. So that's our middle LB IP address. So this is a good sign traffic is already up and running and we have an external IP address from middle LB.
So something I like to do is create a middleware. So a middleware is really just a block of configuration that will run whenever you wanted to on some routes. And so this middleware right here, I'm actually creating a group of default headers.
Some of the services I run require some additional headers. And so these are the headers that I found that a lot of my services need. So I'm creating a middleware that we can apply to a route that you'll see later on that will apply these headers to that route.
So let's actually just create this middleware. We won't use it yet, but let's create it so we have it. So to apply that, we would say coupubecontrol apply-f for file default-headers.
So we applied that and we created it. And if we do a quick coupubecontrol get middleware, we should see we have our middleware there. Default headers.
That's a good sign. Next, we can expose the traffic dashboard to see our routes as they get created. Now, it's readon, so you can't modify anything, but it's nice to look at to troubleshoot or to see what routes you have without going through all of your manifests or even using a coupe control command.
So, in order to do that, we need to generate a basic O credential. And to create a basic O credential, we're going to need something called HT password that comes from Apache utilities. So, we need to install Apache 2 utils really quick so we can get HTT password.
And then we're going to create our basic O username and password. So the way that we do this is run ht password and then we use a username and then the password and then we pipe it to open SSL B 64. So we're going to B 64 encode this credential so we can create a secret to apply to our dashboard.
So this should output a B 64 credential and you can see that right here. So this is saying when we go to our dashboard, the username is techno and the password is password. You should probably use something a lot more secure than that.
So let's actually create a secret now to apply to Kubernetes so we can tie that secret to our dashboard. So when we sign in, we can use this credential. It'll all make sense here in a minute.
So we're going to create a Kubernetes secret. You can see right here, it's a secret. I'm going to name this secret traffic dashboard off O.
So I'm going to put it in the name space of traffic. And this needs to be in the same name space as our service. And then the data users key is our base 64 encoded secret.
And you can see that matches this right here. So let's apply this secret really quick. So we'll do a coupe control apply-f for file and secret-do.
yamel which is our file with our secret in it. We'll apply it. And so now it created it.
So now just to check we could say coupe control get secrets in the name space of traffic. And we should see our secret here. Traffic-door- off.
Now, you see Helm one in there, too. That's because Helm actually creates secrets for our config. Don't worry about that one.
The one we just created is actually right here. Okay. So, now that we have that, we can actually deploy our dashboard.
And you're probably asking, what are you talking about? Didn't we already deploy our dashboard? Kind of.
So, the dashboard is actually enabled in traffic, but we need to create that ingress to actually get to it. So, we need to be able to route traffic into that dashboard. And here's how we do it.
I mentioned I'm going to use an ingress route. You can see here the kind is actually ingress route. I'm naming this traffic- dashboard.
It's in the name space traffic. And here's our annotation right here for our ingress class. I'm calling this traffic- external.
And you'll name that whatever you named your ingress class earlier. Then we're saying the entry point is web secure. And then for our rule, we're saying match this host name right here.
So the host name I have set up on my local network is traffic. local. technotim.
live. So you'll have to have a DNS entry somewhere in your environment that points to this IP address right here that we configured for your load balancer IP. So create a DNS entry that points to this load balancer IP and then that DNS entry should be put right here.
So when a client goes to request it, it'll be sent to that load balancer IP. That load balancer IP will send it inside of your Kubernetes cluster to traffic. Traffic will look at the header for the host name that was requested and then it's going to route it to API internal traffic service.
So that might not make a ton of sense, but that's how traffic does it. They have a service called API at internal and it's of kind traffic service. And one more thing we probably need to do as you see here called middleware.
We didn't actually create this middleware and we should but this is actually traffic dashboard basic o. So we never created the middleware to apply to our ingress. So here's the middleware we need to create.
So we're saying traffic dashboard basic o in the name space of traffic and we're saying that basic o secret is this secret that we created earlier. So this is going to tie our secret to our ingress. We're applying middleware in the middle.
So first let's apply our middleware with coupube control apply-f middleware. Then it's created and then we'll apply our ingress which is coupubecontrol apply-fing. l.
So now we created our ingress. So now we should have our dashboard up and running. So if we go to that DNS name we created, traffic.
local. technotim. live, we can see we're getting a connection is not private warning.
Now this is actually a good thing at least right now. This is saying right now that hey traffic is serving out this page over HTTPS. And if we look at our certificate right now, it's saying it's from traffic.
So good sign. Later on we'll replace this with a let's encrypt certificate that is trusted but for now this is a good sign. So let's say advanced and then we'll proceed.
Then we should get a prompt here. This is another good sign. So I said it was techno and then I said it was password.
If we sign in that's bright. Let's go to dark mode. We can see our traffic dashboard.
So really cool. We have our dashboard up now. We don't have any routes or anything right now.
We do have metrics installed for Prometheus and we have traffic actually exposed and then we have web and web secure exposed what we saw earlier but we don't have any other routes. So once we create a service we'll see routes here later on but this is a good sign up until now we're doing great. So what we've done in the past with traffic was actually have traffic configured with let's encrypt to go out and fetch our certificates and then store them in local storage which is fine.
It works and it's not wrong. It's just different. But the challenge there is that you can't really run a true HA traffic.
You can only run one instance. One instance is only able to read and write to that certificate store that's on a persistent volume claim which is on disk and only one pod can access that disk at a time. This is where manager comes in.
So cert manager can actually be our issuer and it can also fetch and retrieve certificates from say let's encrypt and then it will store those certificates as secrets within kubernetes and you can have as many pods as you want that can access those secrets. So that frees us from binding to disk and it allows us to pull secrets from C manager as our certificates and then we can scale traffic as wide as we want because they can mount secrets on all of those pods. So let's get Manager installed really quick.
And let me tell you this is probably the easiest way I've ever managed certificates. I've managed certificates on Windows and Linux and Mac and it is super duper hard. Cert Manager in Kubernetes makes it super easy.
So first let's create our namespace forert manager with coupube control create namespace manager. Then we'll do the usual get namespaces to make sure we can see our namespace we just created and we can see it right there. Next what we're going to do is apply some CRDs or some custom resource definitions.
Now this is a very big topic but at a high level what custom resource definitions allow you to do is define objects in Kubernetes that Kubernetes doesn't know about natively. For instance, let's say I did a coupe control get certificate. So Kubernetes is going to say hey I don't have the resource type of certificate.
That's because natively Kubernetes doesn't know what it is. But we can apply this custom resource definition that will define resources so that you can use these commands to do these things. And it's not just me doing these commands.
It's so all of these services know how to interact with these objects. So long story short, we're going to apply this custom resource definition fromert manager. That should apply it.
And now if we do the simple, hey, get a certificate. Now look, it's not giving us an error. It's just saying, hey, no resources found in default namespace.
So it knows what I'm talking about, but we don't have any certificates there. So that's kind of CRDs in a nutshell. So next, we would run our helm installert manager jetstackert manager namespace manager and pass in a values argument of our values file and then version of the current latest version of manager.
So what does our values file look like? So our values file is really small. looks just like this.
So, I'm saying, "Hey, install CRDs false because we just installed them. I don't want Helm to install them. I'll manage them outside of there.
" And it's a lot easier if you just apply them ahead of time than to let the Helm package manager install them. So, and then we can specify our replica account. But remember, I said I wanted HA.
So, we need at least two. We can go three. Then, we need to set some extra arguments.
Now, these are really important. This tripped me up for a while. So these extra arguments are saying, "Hey, for the DNS01 challenge, here are your name servers.
" And your name servers are going to be Cloudflare and it's going to be quad 9. And then we're saying recursive name servers only. So why do we need this?
I'm not going to explain why we need that until I explain the next couple because it'll all make sense. Next, we're saying these pods, we have a DNS policy of none. We're not going to use DNS from the host machine.
And so the pods aren't going to inherit DNS from the host machine. And then we're passing in so we're hard coding a DNS configuration to these pods of 1111 and 9999 again cloudflare and quad 9. So now why are we doing this?
Well so when we need to get certificates we're going to do a DNS01 challenge which means we're actually going to verify that we own a domain. And so let's encrypt is going to create a text record in Cloudflare in our case that we can read and verify that we own this domain. And that all works great.
The problem is if you use your own local DNS here and you have DNS say for this DNS name we're going to validate it will actually return back the IP address of the name on your local network which is not a good thing because then it doesn't know how to read that text record in the cloud in global DNS. So the way to get around this is to always just hardcode your name servers onert manager for the pod and to override any DNS that these pods are going to use. And this will ensure that it's always going to look at public DNS rather than your internal DNS.
And this one especially tripped me up for a while this week. It was the pod DNS config that I didn't know I needed until I needed it. So anyways, all this is doing is telling the pods, hey, you know what?
You're not going to use local DNS. You're going to go straight to Cloudflare and you're going to go straight to Cloud9 for DNS, which is fine because that's the only responsibility of these pods really as far as DNS is concerned outside of the cluster is to validate DNS for us. So I think we can install this now.
So let's install this. And so now it's going out to our cluster and it's going to install cert manager. This one might take a minute or two depending on your resources in your cluster.
And then we can run coupube control get pods namespace of manager to see all of our pods that are running. So this looks good. We have our threeert manager pods.
Then we have our CA injector pod. And then we have our C manager web hook pod running. And they're all running.
No restarts. Up for 61 seconds. This is fantastic.
So now that cert manager is running, we need to set up our issuer. So as I mentioned before, we want to get certificates from let's encrypt. So we want a new issuer and our cluster issuer is going to be let's encrypt and our cluster issuer config looks like this.
So we have a cluster issuer of let's encrypt staging. Now let's talk about this really quick. So with Let's Encrypt, you have a staging endpoint which you can get certificates from that aren't globally trusted but do allow you to test their API.
And then they have the production endpoints which is globally trusted but has some rate limiting applied to it. I highly recommend you get this working 100% repeatable in staging before going to production. As I mentioned before, they rate limit production, and if you exceed the failure rate that they have set, you'll lock yourself out for up to a week.
So, I'd highly recommend getting this all working in staging before going to production. You've been warned. So, we're going to set our server to the staging endpoint, and this is going to be your email address for Cloudflare.
Now, we haven't created this secret yet, but we will create it. And this is going to be pointing to your Cloudflare token. Then, we're saying our solver.
So, how are we going to solve or what challenge type are we going to use? We're going to use the DNS01 challenge like I mentioned earlier of Cloudflare. And then we're setting our email address to our Cloudflare email.
And then we're setting an API token secret ref to our Cloudflare token secret, which we'll create at the key name Cloudflare token. And then we're using a selector to say it's on this zone in Cloudflare. So, that was a lot.
That was a lot. Hopefully that makes sense. What it boils down to is we're just configuring a solver of DNS01 type challenge.
We're going to pass this issuer some credentials or a token from Cloudflare. We're saying it's from this zone technim. live and we're going to reference a bunch of secrets that we're about to create.
So we don't want to create this yet. We actually want to create our secrets. So our secret is what we just talked about.
So this secret is a cloudflare token secret in the namespace of cert manager and then some string data of cloudflare-token and then our token. This is a token you will get from cloudflare in your dashboard and that token should have read and write access to the domain or DNS that we're referencing here so that it can create that text record and then delete that text record. So get your token, paste it here.
So we can apply this secret token and create it. Then we can create our issuer for let's encrypt staging and we just created it. And now we can create a certificate.
So remember when we did a coupe control get resource earlier of type certificate. This is actually what we're creating. So this is really awesome.
We can define our certificates in YAML and have manager go out and fetch them and then we can apply them to traffic later on. So we're going to create this certificate. I'm just calling this local-technotim-live.
It can be whatever you want it to be named. You could name it your domain if you want. Then I'm putting it in the namespace of default.
You might be asking why I'm putting it in the namespace of default. Well, I found that this certificate needs to live in the same namespace of the service you're going to use where your ingress lives. So I'm going to deploy a service in the namespace of default.
So I'm setting this to default. That'll save you some pain later on. And then I'm referencing this secret name.
So the secret is going to be named local-technotim-live-staging-tls. That's the secret name within kubernetes that we'll use to put in our ingress later on. And then we're saying the issuer ref is let's encrypt staging what we just created.
The kind is cluster issuer. And then the common name and DNS names. So I'm going to create a wildcard certificate.
And this is totally up to you. You can create a wild card certificate or you can create one certificate for your services. I'm going to create a wild card because it's a little bit easier and it's pretty cool.
But I'm creating one for the subdomain local of technotim. live. So this domain does not exist publicly.
Only technim. live exists publicly. I'm creating an internal certificate that I can use on all of my services.
And I'm adding the subdomain. local so no one can resolve it anywhere. And so that if I use it internally, it doesn't match the external name.
Super geeky, I know, but you can change this to anything you want. It could be example. technotim.
live. And then you would do the same thing down here for this DNS name and get rid of that. And that would create one certificate on the subdomain of technotim.
live. And if you didn't want a subdomain, you could do a top level domain like this and just have one certificate. Or you can create a wild card at that level, too.
You have so many options. But what I'm going to do is exactly what I showed before, which I'm creating a wildcard certificate for my subdomain. Totally up to you.
So now we can create the certificate by applying this YAML. And it's being created. So how do we know it's being created?
Well, let's tail the logs. So I'm going to say coupe control logs in the name space ofert manager-f for follow. And I want to follow one of these pods.
I don't know which pod it's going to be. Not that pod. Not that pod.
It is that pod. So right here I can see that manager is trying to propagate that DNS name right now. So what this is doing right now is creating a text record in Cloudflare that has a secret or a key that it's looking for.
It's going to verify that key and then it's going to issue a certificate to me. So this could take some time. Sometimes it takes, I don't know, three, four, five minutes, but it can vary.
So, you'll just have to wait until this is done. And you'll know it's done because it'll stop queuing and looking for this. And it'll stop throwing an error.
It's not really an error. I mean, it is an error because it can't find this DNS record, but nothing is wrong. It's normal.
And another thing we can do is coupube control get challenges. So, we can do this, too. And we could tail this if we want.
Uh, but we could see right here that we have two challenges that went out. One for local and then one for the wild card. the one for local already passed and the one for the wild card is still pending.
So we can do this over and over and over or we can just wait and then eventually if you say get challenges and you don't see any challenges that most likely means that you have a certificate. So now that we generate that certificate we actually want to apply this now to a service. So let's create a really quick and easy service of engine X and apply that certificate to it.
So I created this really quick and easy enginex deployment. It's just an enginex deployments replica of one. Let's just change that to three for fun.
And then some typical settings. Then we'll create a service for this. And then we'll create an ingress.
And so this ingress is just a typical ingress. We'll name the ingress. We'll put it in the default name space.
And here we're going to specify our ingress class is traffic external. We're saying the entry point is web secure and I'm going to set a couple of rule matching for routing. So I'm saying hey either www.
engineext. local. technotim.
live or engineext. local. technotim.
live. We're going to route to port 80 on that enginex container. We're going to use our middleware which we talked about earlier of default headers.
And here's where the magic is right here. We're actually going to uncomment that. So this is how easy it is to apply certificates to these routes.
We're saying hey on spec use a TLS key and the secret name of local-technotim-live-staging-tls and the secret if you remember if we go into certificates and we look right here it should match this secret name right here and it does. So this means that this route is going to apply this secret which is a certificate for TLS. So let's just apply this whole thing.
So a quick shortcut we can say coupubctl apply-f and this whole folder of engine x. Now it deployed our deployment deployed our ingress route and deployed our service. So now let's check to see if we have a let's encrypt staging on this service.
Oh, and also remember for the service, if you're doing the same thing, you'll want to make sure you have a DNS entry pointing to this right here. So, this route needs to be somewhere on your network, which then routes to metal lb, which then goes to traffic, which then gets routed to this container. So, once we go to engineext.
local. technotim. live, we're getting the same security warning.
But if we look right here and we look at our certificate. Aha, we're actually using our wildcard certificate. And look where it's from.
It's from staging. So this means it's using our Let's Encrypt staging certificate and serving this out through that, which is a good sign. Now I know that this isn't trusted, but it does mean that traffic is serving out this traffic using a certificate from SER Manager, which is awesome.
So, how do we go to production? Pretty easy. So, in order to go to production, we just need to create a couple more things.
First, we need to create a new issuer. So, we need to create a let's encrypt production issuer. Now, this looks exactly like the staging issuer except for a few differences.
One, we're just going to call it let's encrypt- production. That's so we know it's the production issuer. Then, we're going to actually point at let's encrypt production endpoint.
You notice there's no staging in there. Now, you're going to use the same email and even the same secrets, too. That's because you're using the same secrets for your provider.
You don't have a lower environment of Cloudflare. We use Cloudflare production for both of these. So, those don't change, but we'll just want to make sure that our name is actually specified as let's encrypt production for this issuer.
So, we know how to refer to it in our certificates. So our solvers don't change and even our tokens don't change and our DNS doesn't change either. So pretty simple here.
Then we need to actually create a production certificate. So this looks exactly the same too with the exception that I actually took out the staging in the name. So this is called local technotim live and local technim-live-tls.
And everything else except for this right here which I almost missed looks the same. So the issuer reference is let's encrypt- production. So first let's apply our let's encrypt production issuer.
So we can create that. So we're creating our issuer now for production that points to let's encrypt production. Then we want to apply the production version of our certificate which is the local-technotim.
live. yaml. So now we just created our production certificate.
Now it should be creating that text record, verifying that text record and then creating a certificate for us. So let's get our challenges. And we can see we have one that's pending.
And we can see that the certificate was approved. And now it's verifying DNS. So it's actually checking for that record over and over and over.
And now we can see our challenge is valid. Our next one is pending. It's doing the same thing, looking for that text record again.
And eventually we should see that there aren't any challenges left. So this is a good sign. So this means we should have our certificate now.
And if we do a coupe control get certificates, we can see our certificate is there and it's ready is true. So this is a good sign so far. So the last thing we need to do is actually update our ingress to now use this new certificate secret.
Let's do that. So, if we go back to EngineX, we should see that our secret name was local technoim-live-staging. TLS.
Now, let's replace this with the production version, which is right here, which as you can see, I leave production off. Usually, I use a naked version of it without staging uh or a lower environment if it is production. So, let's replace this and let's apply this.
So let's do a coupube control apply-f ingress. We applied it. Let's just do a coupe ctl describe ingress.
Describe our one ingress. We can see here here's our engineext one and we can see our TLS secret name is our naked one without staging on it. Now remember I said your certificates could be cached.
So, at this point, I would probably use a new browser, one you haven't used yet to visit this because you don't want to see the cached ones from staging and try to figure out what's going on. So, new private window in Firefox going to httpsenx. local.
technotim. live. And yes, this worked first try.
Woohoo. You can see our engineext welcome page. And if we look at our certificate more information view certificate we can see the issuer is right right wait for it wait for it wait for it wait for it let's encrypt right here so let's encrypt let's encrypt they're the issuer and it is trusted I didn't need to do anything because it's publicly trusted so this is really awesome so we've accomplished a ton here from a basic Kubernetes cluster we installed called traffic and got our ingress controller configured and working.
Then we set up our traffic dashboard and got that working. Then we set up manager and set up let's encrypt along with our DNS to issue certificates that we can use on our ingresses as you can see here. And we set that up for staging and production.
So we know it works. Congratulations, you now have certificates for your Kubernetes cluster. So I hope you learned something today.
And remember, if you found anything in this video helpful, don't forget to like and subscribe. Thanks for watching at Oh. Whoa.
That's like a mirror. You can actually see my camera pointing down at it. But look at that.
Oh my gosh. Uh, I think you can see that presented to Techno Tim for passing 100,000 subscriber. This is actually super nice.
This is way nicer than I thought it was going to be. Like I thought I didn't think there was going to be any like depth here and I didn't think it was going to be a mirror. So this is like and it's it's like heavy.
It's like it's like really metal I think. But man, this is uh yeah, this is because of all of you.