{"id":204,"date":"2023-02-08T11:46:46","date_gmt":"2023-02-08T11:46:46","guid":{"rendered":"https:\/\/keyshell.net\/blog\/?p=204"},"modified":"2023-02-08T11:46:46","modified_gmt":"2023-02-08T11:46:46","slug":"setting-up-letsencrypt-ssl-tls-for-a-domain-in-microk8s","status":"publish","type":"post","link":"https:\/\/keyshell.net\/blog\/2023\/02\/08\/setting-up-letsencrypt-ssl-tls-for-a-domain-in-microk8s\/","title":{"rendered":"Setting up LetsEncrypt SSL\/TLS for a domain in MicroK8s"},"content":{"rendered":"<p><strong><u>Prerequisites:<\/u><\/strong><\/p>\n<ol>\n<li>Forward ports 80 &amp; 443 to your server. Set up a domain name that point to your server.<\/li>\n<li>Ngnix Ingress Controller<\/li>\n<\/ol>\n<p><strong><u>Installing MicroK8s:<\/u><\/strong><\/p>\n<p>Here, we are using MicroK8s version 1.21 and for the letsencrypt SSL\/TLS certificate we use a cert-manager.<\/p>\n<p>To install MicroK8s,<\/p>\n<p><em>snap install microk8s &#8211;classic &#8211;channel=1.21\/stable<\/em><\/p>\n<p>Now, enable the MicroK8s add-ons \u2018dns\u2019 and \u2018ingress\u2019.<\/p>\n<p><em>sudo microk8s enable dns ingress<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><strong><u>Deployment and Service file<\/u><\/strong><\/p>\n<p>A test webserver is created using an nginx image and a service is also associated with it. We are creating them in a namespace \u2018dev\u2019.<\/p>\n<p>Create the namespace using the command,<\/p>\n<p><em>microk8s kubectl create ns dev<\/em><\/p>\n<p>Following is the deployment and service file ( webserver-depl-svc.yaml ).<\/p>\n<p>&nbsp;<\/p>\n<p><em>apiVersion: apps\/v1<\/em><\/p>\n<p><em>kind: Deployment<\/em><\/p>\n<p><em>metadata:<\/em><\/p>\n<p><em>\u00a0 name: webserver-depl<\/em><\/p>\n<p><em>spec:<\/em><\/p>\n<p><em>\u00a0 selector:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 matchLabels:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0 app: webserver-app<\/em><\/p>\n<p><em>\u00a0 template:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 metadata:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0 labels:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 app: webserver-app<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 spec:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0 containers:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8211; name: webserver-app<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 image: nginx:1.8<\/em><\/p>\n<p><em>&#8212;<\/em><\/p>\n<p><em>apiVersion: v1<\/em><\/p>\n<p><em>kind: Service<\/em><\/p>\n<p><em>metadata:<\/em><\/p>\n<p><em>\u00a0 name: webserver-svc<\/em><\/p>\n<p><em>spec:<\/em><\/p>\n<p><em>\u00a0 selector:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 app: webserver-app<\/em><\/p>\n<p><em>\u00a0 ports:<\/em><\/p>\n<p><em>\u00a0 &#8211; name: webserver-app<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 protocol: TCP<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 port: 80<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 targetPort: 80<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>Apply the file using,<\/p>\n<p><em>sudo microk8s kubectl apply -f webserver-depl-svc.yaml \u2013n dev<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><strong><u>Setting up an Nginx Ingress Controller<\/u><\/strong><\/p>\n<p>All the manifests used in this documentation are taken from the official Nginx community repo.<\/p>\n<p><em>git clone https:\/\/github.com\/Keyshelltechs\/nginx-ingress-controller.git<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>Here is the one-liner to deploy all the objects.<\/p>\n<p><em>microk8s kubectl apply -f <\/em><a href=\"https:\/\/raw.githubusercontent.com\/kubernetes\/ingress-nginx\/controller-v1.1.1\/deploy\/static\/provider\/cloud\/deploy.yaml\"><em>https:\/\/raw.githubusercontent.com\/kubernetes\/ingress-nginx\/controller-v1.1.1\/deploy\/static\/provider\/cloud\/deploy.yaml<\/em><\/a><\/p>\n<p>&nbsp;<\/p>\n<p><strong><u>Install cert-manager<\/u><\/strong><\/p>\n<p>To install, cert-manager use the following command.<\/p>\n<p><em>sudo microk8s kubectl apply -f https:\/\/github.com\/jetstack\/cert-manager\/releases\/download\/v1.3.1\/cert-manager.yaml<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>To check if the cert-manager is installed and running successfully,<\/p>\n<p><em>sudo microk8s kubectl get pods -n=cert-manager <\/em>( You should see 3 pods running ).<\/p>\n<p>&nbsp;<\/p>\n<p><strong><u>Certificate Issuer config<\/u><\/strong><\/p>\n<p>Next, we have to create a certificate issuer config. Apply the following 2 yaml files for that.<\/p>\n<p>letsencrypt-staging.yaml:<\/p>\n<p>&nbsp;<\/p>\n<p><em>apiVersion: cert-manager.io\/v1<\/em><\/p>\n<p><em>kind: ClusterIssuer<\/em><\/p>\n<p><em>metadata:<\/em><\/p>\n<p><em>\u00a0 name: letsencrypt-staging<\/em><\/p>\n<p><em>spec:<\/em><\/p>\n<p><em>\u00a0 acme:<\/em><\/p>\n<p><em>#change to your email<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 email: youremail@gmail.com<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 server: https:\/\/acme-staging-v02.api.letsencrypt.org\/directory<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 privateKeySecretRef:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0 name: letsencrypt-staging<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 solvers:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 &#8211; http01:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ingress:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 class: public<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>letsencrypt-prod.yaml:<\/p>\n<p>&nbsp;<\/p>\n<p><em>apiVersion: cert-manager.io\/v1<\/em><\/p>\n<p><em>kind: ClusterIssuer<\/em><\/p>\n<p><em>metadata:<\/em><\/p>\n<p><em>\u00a0 name: letsencrypt-prod<\/em><\/p>\n<p><em>spec:\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/em><\/p>\n<p><em>\u00a0 acme:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 server: https:\/\/acme-v02.api.letsencrypt.org\/directory<\/em><\/p>\n<p><em>#change to your email<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 email: youremail@gmail.com<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 privateKeySecretRef:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 name: letsencrypt-prod<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 solvers:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 &#8211; http01:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ingress:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 class: public<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>Apply both files,<\/p>\n<p><em>sudo microk8s kubectl apply -f letsencrypt-staging.yaml<\/em><\/p>\n<p><em>sudo microk8s kubectl apply -f letsencrypt-prod.yaml<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><strong><u>Create an ingress object<\/u><\/strong><\/p>\n<p>Create an ingress object to access our nginx welcome page using a DNS. An ingress object is nothing but a setup of routing rules. The ingress controller pod connects to the Ingress API to check for rules and it updates its nginx.conf accordingly.<\/p>\n<p>To configure the ingress object, we use the following file ( ingress-routes.yaml ).<\/p>\n<p>For the staging certificate, use the following ingress object.<\/p>\n<p>&nbsp;<\/p>\n<p><em>apiVersion: networking.k8s.io\/v1beta1<\/em><\/p>\n<p><em>kind: Ingress<\/em><\/p>\n<p><em>metadata:<\/em><\/p>\n<p><em>\u00a0 name: ingress-routes<\/em><\/p>\n<p><em>\u00a0 annotations:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 cert-manager.io\/cluster-issuer: &#8220;letsencrypt-staging&#8221;<\/em><\/p>\n<p><em>spec:<\/em><\/p>\n<p><em>\u00a0 tls:<\/em><\/p>\n<p><em>\u00a0 &#8211; hosts:<\/em><\/p>\n<p><em>#change to your domain<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 &#8211; yourdomain.com<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 secretName: tls-secret<\/em><\/p>\n<p><em>\u00a0 rules:<\/em><\/p>\n<p><em>#change to your domain<\/em><\/p>\n<p><em>\u00a0 &#8211; host: yourdomain.com<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 http:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0 paths:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8211; path: \/<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pathType: Prefix<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 backend:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 service:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 name: webserver-svc<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 port:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 number: 80<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>Apply it using,<\/p>\n<p><em>sudo microk8s kubectl apply -f ingress-routes.yaml \u2013n dev<\/em><\/p>\n<p><em>sudo microk8s kubectl get certificate\u00a0 <\/em>( Check if the state Ready=True)<\/p>\n<p>&nbsp;<\/p>\n<p>Change the same ingress-routes.yaml file with the following content for production certificate.<\/p>\n<p>&nbsp;<\/p>\n<p><em>apiVersion: networking.k8s.io\/v1<\/em><\/p>\n<p><em>kind: Ingress<\/em><\/p>\n<p><em>metadata:<\/em><\/p>\n<p><em>\u00a0 name: ingress-routes<\/em><\/p>\n<p><em>\u00a0 annotations:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 cert-manager.io\/cluster-issuer: &#8220;letsencrypt-prod&#8221;<\/em><\/p>\n<p><em>spec:<\/em><\/p>\n<p><em>\u00a0 tls:<\/em><\/p>\n<p><em>\u00a0 &#8211; hosts:<\/em><\/p>\n<p><em>#change to your domain<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 &#8211; yourdomain.com<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 secretName: tls-secret<\/em><\/p>\n<p><em>\u00a0 rules:<\/em><\/p>\n<p><em>#change to your domain<\/em><\/p>\n<p><em>\u00a0 &#8211; host: yourdomain.com<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 http:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0 paths:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8211; path: \/<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pathType: Prefix<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 backend:<\/em><\/p>\n<p><em>\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0service:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 name: webserver-svc<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 port:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 number: 80<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>Apply and check the state using,<\/p>\n<p><em>sudo microk8s kubectl apply -f ingress-routes.yaml \u2013n dev<\/em><\/p>\n<p><em>sudo microk8s kubectl get certificate<\/em><\/p>\n<p>To verify if the certificate was issued,<\/p>\n<p><em>sudo microk8s kubectl describe certificate tls-secret<\/em><\/p>\n<p><em>\u00a0<\/em><\/p>\n<p>Now, visit your domain to check if the SSL\/TLS has been enabled.<\/p>\n<p>&nbsp;<\/p>\n<p><strong><u>Any SSL certificate already purchased from an authority<\/u><\/strong><\/p>\n<p>You can use the same deployment and service file for this case. For the certificate, you have to generate a secret and pass it to the ingress object from where the ingress controller will take it.<\/p>\n<p>&nbsp;<\/p>\n<p>To create the secret, go to the directory where the certificates are saved or mention the absolute path to the files in the command,<\/p>\n<p><em>microk8s kubectl create secret tls hello-app-tls &#8211;namespace dev &#8211;key server.key &#8211;cert server.cert<\/em><\/p>\n<p>Now, you can use the following ingress-routes.yaml file and apply it.<\/p>\n<p>&nbsp;<\/p>\n<p><em>apiVersion: networking.k8s.io\/v1<\/em><\/p>\n<p><em>kind: Ingress<\/em><\/p>\n<p><em>metadata:<\/em><\/p>\n<p><em>\u00a0 name: ingress-routes<\/em><\/p>\n<p><em>\u00a0 namespace: dev<\/em><\/p>\n<p><em>spec:<\/em><\/p>\n<p><em>\u00a0 ingressClassName: nginx<\/em><\/p>\n<p><em>\u00a0 tls:<\/em><\/p>\n<p><em>\u00a0 &#8211; hosts:<\/em><\/p>\n<p><em>#change to your domain<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 &#8211; yourdomain.com<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 secretName: hello-app-tls<\/em><\/p>\n<p><em>\u00a0 rules:<\/em><\/p>\n<p><em>#change to your domain<\/em><\/p>\n<p><em>\u00a0 &#8211; host: &#8221; <\/em><em>yourdomain.com &#8220;<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0 http:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0 paths:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8211; pathType: Prefix<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 path: &#8220;\/&#8221;<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 backend:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 service:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 name: webserver-svc<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 port:<\/em><\/p>\n<p><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 number: 80<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><em>sudo microk8s kubectl apply -f ingress-routes.yaml<\/em><\/p>\n<p>If needed you can forcefully apply the deployment file using,<\/p>\n<p><em>sudo microk8s kubectl apply \u2013f\u00a0 webserver-depl-svc.yaml \u2013force<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>Access the domain in browser and check if the certificate is applied.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Prerequisites: Forward ports 80 &amp; 443 to your server. Set up a domain name that point to your server. Ngnix Ingress Controller Installing MicroK8s: Here, we are using MicroK8s version 1.21 and for the letsencrypt SSL\/TLS certificate we use a cert-manager. To install MicroK8s, snap install microk8s &#8211;classic &#8211;channel=1.21\/stable Now, enable the MicroK8s add-ons \u2018dns\u2019 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[1],"tags":[9,8,7,5,6],"class_list":["post-204","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-cert-manager","tag-ingress","tag-letsencrypt","tag-microk8s","tag-ssl-tls"],"_links":{"self":[{"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/posts\/204","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/comments?post=204"}],"version-history":[{"count":3,"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/posts\/204\/revisions"}],"predecessor-version":[{"id":207,"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/posts\/204\/revisions\/207"}],"wp:attachment":[{"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/media?parent=204"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/categories?post=204"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/keyshell.net\/blog\/wp-json\/wp\/v2\/tags?post=204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}