Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user guide for TLS ingress #6861

Merged
merged 5 commits into from
May 30, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions site/docs/guides/tls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# TLS Ingress with Minikube

In this guide we walk through the process of configuring a Nessie Service with secure HTTPS transport in
[Minikube](https://minikube.sigs.k8s.io/docs/).

## Setting up Minikube

1. Start Minikube cluster: `minikube start`
2. Enable NGINX Ingress controller: `minikube addons enable ingress`

## Creating Certificates

If you have your own trusted certificate you can use it to sign a new certificate for the Nessie service.

Otherwise, the rest of this section shows how can create a self-signed certificate and add it the list of trusted
certificates in the client OS.

To generate a fresh pair of a key and a (self-signed) certificate:

```shell
openssl req -new -subj "/CN=Nessie" -addext "subjectAltName = DNS:nessie.local" \
-newkey rsa:2048 -keyout nessie-key.pem -out nessie.crt -x509 -nodes
```

Note the `-nodes` option. It is used only for the sake of simplicity of this example deployment. Also, newer `openssl`
versions deprecated it in favour of `-noenc`.

Add the new certificate to the local set of CA certificates on the client host (where the Nessie clients,
such as Nessie CLI / `curl` / browser, are going to run).

The following example is for Linux:

1. `sudo cp nessie.crt /usr/local/share/ca-certificates/nessie.crt`
2. `sudo update-ca-certificates`

This should output something like "Certificate added: CN=Nessie".
adutra marked this conversation as resolved.
Show resolved Hide resolved

## Creating a k8s Secret for the Nessie Certificate

Make sure a dedicated k8s namespace exists. This example uses the `nessie-ns` name. If it does not exist run the
following command to create it:

```shell
kubectl create namespace nessie-ns
```

Create a TLS secret for Nessie:

```shell
kubectl -n nessie-ns create secret tls nessie-tls \
dimas-b marked this conversation as resolved.
Show resolved Hide resolved
adutra marked this conversation as resolved.
Show resolved Hide resolved
--cert=nessie.crt --key=nessie-key.pem
```

## Deploying Nessie with Helm

Add the Nessie repository to Helm:

```shell
helm repo add nessie-helm https://charts.projectnessie.org
```

Install the Nessie helm chart:

```shell
helm install nessie -n nessie-ns nessie-helm/nessie \
--set 'ingress.enabled=true' \
--set 'ingress.hosts[0].host=nessie.local' \
--set 'ingress.hosts[0].paths[0]=/' \
--set 'ingress.tls[0].secretName=nessie-tls' \
--set 'ingress.tls[0].hosts[0]=nessie.local'
```

The deployment process may take some time. Use the following command to check its status and get the ingress IP address.

```shell
kubectl get ingress -n nessie-ns
```

Add an entry in the local hosts file (e.g. `/etc/hosts`) mapping that IP address to `nessie.local`, for example:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this works, you could avoid fiddling with /etc/hosts by using one or both of the methods below:

  1. for curl only: use the --resolve option, e.g.
curl --resolve "nessie.local:443:$(minikube ip)" https://nessie.local/api/v2/config
  1. for all tools and browsers: use a nip.io hostname, e.g. nessie.$(minikube ip).nip.io: such a host name will resolve to whatever IP minikube ip indicates. E.g.
ping nessie.$(minikube ip).nip.io
PING nessie.192.168.49.2.nip.io (192.168.49.2): 56 data bytes
64 bytes from 192.168.49.2: icmp_seq=0 ttl=64 time=0.108 ms

Then you would use nessie.192.168.49.2.nip.io as the hostname for your certificates and ingress rules.

Copy link
Member Author

@dimas-b dimas-b May 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but the certificate must have the exact host name, which is not known until we start / configure ingress... I guess that would create a chicken and egg problem. Even if adding the TLS cert after startup works, it might be too complex for a guide... WDYT?

Also, the java client still depends on OS-level host name resolution (although I did not put and example for it).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated


```shell
192.168.49.2 nessie.local
```

Note: Some tools allow substituting host names with specific IP addresses on the command line.
(e.g. `curl --resolve "nessie.local:443:$(minikube ip)" ...`) If you intend to use only those tools, then modifying
`/etc/hosts` is not necessary. However, Nessie python CLI and java client rely on the OS to be able to resolve
`nessie.local`, so to be able to use them the simplest approach is to define `nessie.local` in `/etc/hosts`.

Use `curl` to verify that the server is accessible:

```shell
$ curl https://nessie.local/api/v2/config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I finally got this to work on macOS, so I'm approving the PR, but it required many changes:

  1. First, ingress ports are not exposed on macOS, see docker: Ingress not exposed on MacOS kubernetes/minikube#7332 for background. So mac users must run the following command after installing the ingress:
minikube tunnel

This will detect the ingress rule and open ports for it:

✅  Tunnel successfully started
📌  NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...
❗  The service/ingress nessie requires privileged ports to be exposed: [80 443]
🔑  sudo permission will be asked for it.
🏃  Starting tunnel for service nessie.
Password:
  1. Once this is done, the service is accessible, but under 127.0.0.1, not $(minikube ip). So you need to change all the commands above, e.g.
curl --resolve "nessie.local:443:127.0.0.1" https://nessie.local/api/v2/config
{
  "defaultBranch" : "main",
  "minSupportedApiVersion" : 1,
  "maxSupportedApiVersion" : 2,
  "actualApiVersion" : 2,
  "specVersion" : "2.0.0",
  "noAncestorHash" : "2e1cfa82b035c26cbbbdae632cea070514eb8b773f616aaeaf668e2f0be8f10d",
  "repositoryCreationTimestamp" : "2023-05-26T10:28:53.462334804Z",
  "oldestPossibleCommitTimestamp" : "2023-05-26T10:28:53.462334804Z"
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adutra : Could you update with Mac specifics after merging? I do not have a Mac to play with :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, will do!

{
"defaultBranch" : "main",
"minSupportedApiVersion" : 1,
"maxSupportedApiVersion" : 2,
"actualApiVersion" : 2,
"specVersion" : "2.0.0"
}
```

## Accessing Nessie UI over HTTPS

Please note that most browsers do not trust self-signed certificates, so an exception will have to be manually
granted to the "Nessie" certificate.