{"id":11377,"date":"2022-02-06T16:55:04","date_gmt":"2022-02-06T15:55:04","guid":{"rendered":"https:\/\/www.origo.io\/info\/?page_id=11377"},"modified":"2022-11-28T12:02:57","modified_gmt":"2022-11-28T11:02:57","slug":"automating-dns-and-tls-in-stabile","status":"publish","type":"page","link":"https:\/\/origo.systems\/info\/stabiledocs\/guides\/automating-dns-and-tls-in-stabile\/","title":{"rendered":"Ghost Blog with Automatic DNS and TLS Certificate Provisioning in Kubernetes"},"content":{"rendered":"\n\n\n<p>The goal of this guide is to install a web application in Kubernetes running in a Origo OS environment, with automatic provisioning of a DNS domain name and automatic provisioning of a TLS certificate, provisioned by the infrastructure entirely from the Kubernetes configuration.<\/p>\n\n\n\n<p>For provisioning DNS we will use the Kubernetes project <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/kubernetes-sigs\/external-dns\" target=\"_blank\">External DNS<\/a> in conjunction with the <a href=\"https:\/\/origo.io\/cloud#DNS\">Origo DNS Services<\/a>.<br \/>External DNS monitors your Kubernetes loadbalancers and ingresses for domain name annotations, and integrates with your DNS provider to create, update and delete domain names in DNS. For this example we will of course use the the <a href=\"https:\/\/origo.io\/cloud#DNS\">Origo DNS Services<\/a>. You must either be using Origo Cloud or an on-prem Origo OS installation that is linked to Origo Registry, to access the Origo DNS Services. You may import your own domain names into Origo DNS Services, but every user also has access to the default domain &#8220;uncloud.co&#8221;, so that&#8217;s what we&#8217;ll be using for this example. External DNS comes with baked-in support for a number of cloud vendors &#8211; they call these &#8220;providers&#8221;. We have built our own <a rel=\"noreferrer noopener\" href=\"https:\/\/gitlab.origo.io\/origosys\/external-dns\/-\/tree\/stabile.io\/provider\/stabile\" target=\"_blank\">provider<\/a>, and hope to have it included in the project sometime in the future. For now, we simply use our own custom External DNS Docker image with our provider included.<\/p>\n\n\n\n<p>For provisioning TLS certificates we use the Kubernetes project <a rel=\"noreferrer noopener\" href=\"https:\/\/cert-manager.io\/\" target=\"_blank\">cert-manager<\/a> in conjunction with <a rel=\"noreferrer noopener\" href=\"https:\/\/letsencrypt.org\/\" target=\"_blank\">Let&#8217;s Encrypt<\/a>, which of course is the leading provider of free TLS certificates. Cert-manager monitors the ingresses you configure for host names, and provisions TLS certificates from Let&#8217;s Encrypt.<\/p>\n\n\n\n<p>The web application we will install and configure https access to, is the excellent <a rel=\"noreferrer noopener\" href=\"https:\/\/ghost.org\/\" target=\"_blank\">Ghost blog application<\/a>.<\/p>\n\n\n\n<p>For the rest of this guide you will be typing commands into a ssh terminal on the control plane of your Origo OS Kubernetes cluster. The procedure to install a Kubernetes cluster and ssh into the control plane server is the <a href=\"\/info\/stabiledocs\/guides\/multi-node-kubernetes\/\">same<\/a> as for the <a href=\"\/info\/stabiledocs\/guides\/longhorn\/\" data-type=\"page\" data-id=\"11232\">other guides<\/a>. You should do this before continuing this guide.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"install-ghost-to-your-kubernetes-cluster\">Install Ghost to your Kubernetes cluster<\/h2>\n\n\n\n<p>First install Ghost using  <a href=\"https:\/\/pub.origo.io\/support\/attachments\/126\/ghost4.yaml\">this yaml file.<\/a> The yaml file creates a Kubernetes deployment and a Kubernetes service.<br \/>After typing in the command below, the yaml file will be opened in your default editor. Please change &#8220;your-domain-name&#8221; to whatever domain name you want to create in the uncloud.co zone (i.e. change &#8220;your-domain-name.uncloud.co&#8221; to &#8220;something-else.uncloud.co&#8221;), and save the file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f https:\/\/pub.origo.io\/support\/attachments\/download\/126\/ghost4.yaml\nkubectl edit -f https:\/\/pub.origo.io\/support\/attachments\/download\/126\/ghost4.yaml<\/code><\/pre>\n\n\n\n<p><strong>IMPORTANT:<\/strong> Next you must assign add an internal IP address to your Kubernetes cluster using the stack UI by clicking &#8220;add internal IP address&#8221;. This internal IP address is not really used for anything, but since the Kubernetes service is of type loadbalancer, it needs an IP address in order not to be stuck waiting for one.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"install-external-dns\">Install External DNS<\/h2>\n\n\n\n<p>Install External DNS using the yaml file <a rel=\"noreferrer noopener\" href=\"https:\/\/gitlab.origo.io\/origosys\/stabile-stacks\/-\/tree\/master\/kubernetes\/files\/stabile\/tabs\/kubernetes\/manifests\" target=\"_blank\">distributed<\/a> with the Kubernetes stack.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f external-dns-stabile-test.yaml<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"install-the-nginx-ingress-controller\">Install the Nginx ingress Controller<\/h2>\n\n\n\n<p>We need an ingress controller, and use the standard <a rel=\"noreferrer noopener\" href=\"https:\/\/kubernetes.github.io\/ingress-nginx\/\" target=\"_blank\">Nginx controller<\/a> for this example.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f https:\/\/raw.githubusercontent.com\/kubernetes\/ingress-nginx\/controller-v1.1.1\/deploy\/static\/provider\/cloud\/deploy.yaml<\/code><\/pre>\n\n\n\n<p><strong>IMPORTANT:<\/strong> You must now assign another IP address to your Kubernetes cluster using the stack UI by clicking &#8220;add IP address mapping&#8221;. If your Origo OS environment supports it, you may also click &#8220;add external IP address&#8221;.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"patch-the-ingress-controller-with-the-external-ip-address-you-were-just-assigned\">Patch the ingress controller with the external IP address you were just assigned<\/h2>\n\n\n\n<p>External DNS has no idea that the IP address it is seeing is not actually an external one, wo we have to help it a little.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl patch svc ingress-nginx-controller -p '{\"spec\":{\"externalIPs\":&#91;\"xx.xx.xx.xx\"]}}' -n ingress-nginx<\/code><\/pre>\n\n\n\n<p><strong>NOTE:<\/strong> This only needs to be done, if you are using an &#8220;ipmapping&#8221; in Origo OS.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"annotate-the-ingress-controller-with-your-domain-name\">Annotate the ingress controller with your domain name<\/h2>\n\n\n\n<p>The Nginx ingress controller will typically listen on a single IP address and route incoming requests based on host names. If we annotate the ingress controller with our desired domain name, DNS registration should happen automatically. You can verify that the domain name is actually registered using the <a href=\"https:\/\/origo.io\/cloud#dns\">Origo DNS Service UI<\/a>. To annotate your new ingress, replace &#8220;your-domain-name&#8221; with your actual domain name, and type this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl -n ingress-nginx annotate service ingress-nginx-controller \"external-dns.alpha.kubernetes.io\/hostname=your-domain-name.uncloud.co\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"install-cert-manager\">Install cert-manager<\/h2>\n\n\n\n<p>Install cert-manager from the yaml file the developer has made available:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply --validate=false -f https:\/\/github.com\/jetstack\/cert-manager\/releases\/download\/v1.7.1\/cert-manager.yaml<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"configure-cert-manager-for-let-s-encrypt\">Configure cert-manager for Let&#8217;s Encrypt<\/h2>\n\n\n\n<p>Configure cert-manager by editing and applying <a rel=\"noreferrer noopener\" href=\"https:\/\/pub.origo.io\/support\/attachments\/127\/certmanager-acme.yaml\" target=\"_blank\">this <\/a><a href=\"https:\/\/pub.origo.io\/support\/attachments\/129\/certmanager-acme.yaml\">yaml<\/a><a rel=\"noreferrer noopener\" href=\"https:\/\/pub.origo.io\/support\/attachments\/127\/certmanager-acme.yaml\" target=\"_blank\"> <\/a><a href=\"https:\/\/pub.origo.io\/support\/attachments\/129\">file.<\/a> Please replace &#8220;your-email@uncloud.co&#8221; with your email address:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f https:\/\/pub.origo.io\/support\/attachments\/download\/129\/certmanager-acme.yaml\nkubectl edit -f https:\/\/pub.origo.io\/support\/attachments\/download\/129\/certmanager-acme.yaml<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"create-the-actual-ingress\">Create the actual ingress<\/h2>\n\n\n\n<p>Finally create the ingress using <a href=\"https:\/\/pub.origo.io\/support\/attachments\/130\/\/nginx-ghost-ingress.yaml\">this yaml file<\/a>. You must replace the two ocurrences of &#8220;your-domain-name.uncloud.co&#8221; with the domain name you have chosen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f https:\/\/pub.origo.io\/support\/attachments\/download\/130\/nginx-ghost-ingress.yaml\nkubectl edit -f https:\/\/pub.origo.io\/support\/attachments\/download\/130\/nginx-ghost-ingress.yaml<\/code><\/pre>\n\n\n\n<p><strong>IMPORTANT:<\/strong> After a few minutes, your Ghost blog should be up and running on the domain name you have chosen and have a valid TLS certificate. You should then head straight to https:\/\/your-domain-name.uncloud.co\/ghost and set up an account. This is because, after installing Ghost, anyone can set up an account, so you should either do this promptly, or delete the Ghost deployment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"create-more-ingresses\">Create more ingresses<\/h2>\n\n\n\n<p>Now that you have installed and configured External DNS and cert-manager, you can easily create ingresses like the one above, whenever you have a service you want external https access to. DNS registration of domain names and provisioning of TLS certificates will be done automatically.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>The goal of this guide is to install a web application in Kubernetes running in a Origo OS environment, with automatic provisioning of a DNS domain name and automatic provisioning of a TLS certificate, provisioned by the infrastructure entirely from the Kubernetes configuration. For provisioning DNS we will use the<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":7856,"menu_order":25,"comment_status":"open","ping_status":"closed","template":"page-leftsb.php","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-11377","page","type-page","status-publish","hentry"],"acf":[],"featured_image_src":null,"featured_image_src_square":null,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/origo.systems\/info\/wp-json\/wp\/v2\/pages\/11377","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/origo.systems\/info\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/origo.systems\/info\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/origo.systems\/info\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/origo.systems\/info\/wp-json\/wp\/v2\/comments?post=11377"}],"version-history":[{"count":132,"href":"https:\/\/origo.systems\/info\/wp-json\/wp\/v2\/pages\/11377\/revisions"}],"predecessor-version":[{"id":12778,"href":"https:\/\/origo.systems\/info\/wp-json\/wp\/v2\/pages\/11377\/revisions\/12778"}],"up":[{"embeddable":true,"href":"https:\/\/origo.systems\/info\/wp-json\/wp\/v2\/pages\/7856"}],"wp:attachment":[{"href":"https:\/\/origo.systems\/info\/wp-json\/wp\/v2\/media?parent=11377"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}