Skip to content

Commit

Permalink
docs: improve dns and tls docs, giving clearer guidance and explainat…
Browse files Browse the repository at this point in the history
…ion, also contains example for enabling TLS in previews
  • Loading branch information
rawlingsj authored and jenkins-x-bot committed Nov 19, 2020
1 parent 463665c commit 1c4e637
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 13 deletions.
110 changes: 97 additions & 13 deletions content/en/v3/admin/guides/infra/tls_dns.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,27 @@ aliases:

This section will describe how to enable automated TLS and DNS for your Jenkins X installation.

To achive this we will use a couple of open source projects to help enable automated DNS for your applications.
To achieve this we will use a couple of open source projects to help enable automated DNS for your applications.

For this guide we are going to assume you own a domain called `foo.io` which is managed by Google Cloud DNS, if it is not see [configure cloud dns to manage a domain](/docs/v3/guides/infra/google_cloud_dns).

Jenkins X services will have URLs like `https://hook-jx.bar.foo.io`. The jx-requirements.yml `namespaceSubDomain:` of `-jx` refers to the Kubernetes namespace the service is running in, this helps avoid clashes of the same application running in different namespaces in the same cluster.

A common requirement for domains is to have production services accessed using a parent / [apex domain](https://docs.github.com/en/free-pro-team@latest/github/working-with-github-pages/about-custom-domains-and-github-pages#using-an-apex-domain-for-your-github-pages-site)
for example:

https://foo.com

Many organisations have extra requirements for development and test multi cluster environments to access services at

https://dev.foo.com
and
https://staging.foo.com

These use subdomains.

In this guide below there is a prerequisite that you must already have a domain which is managed by GCP, this is so that you can choose whichever of the scenarios above you need. It also means the dns management of the apex domain happens outside of a single cluster installation and can be shared by multiple installations using a subdomain.

Jenkins X services will have URLs like `https://hook-jx.dev.foo.io`. The jx-requirements.yml `namespaceSubDomain:` of `-jx` which is in the cluster git repository refers to the Kubernetes namespace the service is running in, this avoids clashes of the same application running in different namespaces in the same cluster.

To start with we are focussed on GCP but will expand to other cloud providers.

Expand All @@ -23,7 +39,7 @@ To start with we are focussed on GCP but will expand to other cloud providers.
## Prerequisites

- cluster created using Jenkins X [GCP Terraform getting started](/docs/v3/getting-started/gke/)
- own a domain, we will use [Google Domains](https://domains.google.com/registrar/) in this guide but any provider will work
- own a domain and have GCP manage it, [configure cloud dns to manage a domain](/docs/v3/guides/infra/google_cloud_dns)
- latest Jenkins X CLI, Infrastructure and Cluster git repository updates [upgrade](/docs/v3/guides/upgrade)

### Cloud Infrastructure
Expand All @@ -43,7 +59,7 @@ Most people prefer to use a subdomain for a specific installation rather than pu
To use a subdomain for this cluster add the following configuration:

```yaml
subdomain = "bar"
subdomain = "dev"
```

Now apply these changes:
Expand All @@ -53,20 +69,24 @@ git add values.auto.tfvars
git commit -m 'feat: enable DNS cloud resources'
git push
```

You may want to set two environment variables here so that Terraform does not prompt for values
```
export TF_VAR_jx_bot_username=
export TF_VAR_jx_bot_token=
```
now run
```bash
terraform plan
terraform apply
```

You can now see your managed zone in GCP [here](https://console.cloud.google.com/net-services/dns/zones)

If using a subdomain you will now see your managed zone in GCP [here](https://console.cloud.google.com/net-services/dns/zones)

### Cluster

Next we will configure the cluster requirements:

- Install [external-dns](https://github.com/kubernetes-sigs/external-dns#externaldns) - Kubernetes controller which watches for new Kubernetes Ingress resources and creates A records in Google Cloud DNS which will propogate globally across the internet
- Install [external-dns](https://github.com/kubernetes-sigs/external-dns#externaldns) - Kubernetes controller which watches for new Kubernetes Ingress resources and creates A records in Google Cloud DNS which will propagate globally across the internet
- Install [cert-manager](https://cert-manager.io/docs/) - Kubernetes controller which watches for requests to ask [Let's Encrypt](https://letsencrypt.org/) to issue a new wildcard TLS certificate for your domain and will manage this including renewals

To satisfy these requirements go to your cluster repository (contains helmfile.yaml)
Expand Down Expand Up @@ -110,7 +130,7 @@ __NOTE__ this is the top level `ingress:` section and __NOT__ in the `environmen

```bash
ingress:
domain: bar.foo.io
domain: dev.foo.io
externalDNS: false # this is unused and will be deprecated
namespaceSubDomain: -jx.
tls:
Expand All @@ -119,7 +139,9 @@ ingress:
production: false
```

When first installing set `tls.production=false` so you use the Lets Encrtpt staging serivce which allows for more API calls before rate limniting requests. They will issue a self-signed certificate so once happy everything is working change this to `tls.production=true`
When first installing set `tls.production=false` so you use the Lets Encrypt staging service which allows for more API calls before rate limiting requests. They will issue a self-signed certificate so once happy everything is working change this to `tls.production=true`.

__NOTE__ Helmfile is not able to skip insecure TLS when adding helm repositories, therefore staging certificates will not work with chartmuseum that is running in the cluster. Therefore once you have verified cert-manager can issue certificates from staging, switch to the production service.

Jenkins X uses a version stream to rollout tested versions of images, charts and default configuration. The `jx-boot` job will apply these versions to your helmfile but you can also run the step yourself to see the defaults.

Expand All @@ -128,8 +150,8 @@ jx gitops helmfile resolve
```

```bash
git add values.auto.tfvars
git commit -m 'feat: enable DNS cloud resources'
git add helmfile.yaml
git commit -m 'feat: enable DNS and TLS'
git push
```

Expand All @@ -138,6 +160,68 @@ Now tail the admin logs and wait for the job to complete
jx admin logs
```

It can take a short while for DNS to propagate so you may need to wait for 5 - 10 minutes. https://dnschecker.org/ is a useful way to check the status of DNS propagating.

You should be able to verify the TLS certificate from Lets Encrypt in your browser (beware of browser caching if you don't see any changes)

![Working TLS](/images/v3/working_tls.png)

## How to get TLS in my preview environment?

In your applications preview helm chart you can add a Kubernetes [Certificate](https://cert-manager.io/docs/concepts/certificate/) the same as in your `jx` namespace and cert-manager will create the secret needed by an Ingress rule for TLS.
In your applications preview helmfile.yaml you can add the same acme helm chart used above however because your application git repository does not have the version stream your cluster git repository above has you will need to add the default values yourself.

Add this to you applications `./preview/helmfile.yaml`

```
repositories:
- name: jx3
url: https://storage.googleapis.com/jenkinsxio/charts
releases:
- chart: jx3/acme
name: tls
namespace: '{{ requiredEnv "PREVIEW_NAMESPACE" }}'
values:
- jx-values.yaml
- issuer:
cluster: true
```

_Note_ as this will request a certificate that matches your existing domain configured above, cert-manager will reuse a cached certificate rather than issue a new one which can cause rate limitting by Lets Encrypt.

## What if I have a chartmuseum with charts running using nip.io?

It is best to comment out your Jenkins X chartmuseum repository and charts from your helmfile until your new domain and ingress is working. Then uncomment and make sure you update the chartmuseum URL to your new one.

## What if I use a subdomain with an apex domain in a different GCP project?

When using a subdomain Terraform will create a managed zone in GCP, add the recordsets to your parent / apex domain.

If the GCP managed zone for your apex domain is in a different GCP project than the project that your current installation the you will need to set in your infrastructure repository the terraform variable:

```
parent_domain_gcp_project: [your GCP project that is managing your apex domain]
```

If you do not have permission to update the recordset of the apex domain then you will need to manually update it after getting the nameservers created for your subdomain managed zone and disable the automatic way using:

```
apex_domain_integration_enabled: false
```

## How can I check if cert-manager has issued a certificate?

You can check the status of the certificate by running

```
kubectl get cert -n jx
```
```
kubectl describe cert -n jx
```
if `Ready` continues to be `false` after 10-15 mins you can check on the request using
```
kubectl get certificaterequest -n jx
```
```
kubectl describe certificaterequest -n jx
```
Binary file added static/images/v3/working_tls.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 1c4e637

Please sign in to comment.