Skip to content

Commit

Permalink
Updates for uplink docs
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
  • Loading branch information
alexellis committed Jan 22, 2025
1 parent 122dfb2 commit e0a5bc1
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 60 deletions.
Binary file added docs/images/uplink/ingress-per-data-plane.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/uplink/no-external-ingress.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/uplink/wildcard-ingress.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Connect to tunnels
# Connect the tunnel client

The tunnel plugin for the inlets-pro CLI can be used to get connection instructions for a tunnel.

Expand Down
68 changes: 48 additions & 20 deletions docs/uplink/create-tunnels.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
# Create a tunnel for a customer
# Create a tunnel

## Use separate namespaces for your tunnels
## Create a namespace for the tunnel

The `inlets` namespace contains the control plane for inlets uplink, so you'll need to create at least one additional namespace for your customer tunnels.
The `inlets` namespace contains the control plane for inlets uplink and should not be used to host tunnels.

1. Create a namespace per customer (recommended)
So you'll need to create at least one additional namespace for your tunnels.

=== "One namespace per tenant"

This approach avoids conflicts on names, and gives better isolation between tenants.

After creating the tunnel, you'll also need to label it `inlets.dev/uplink=1`

```bash
kubectl create namespace acmeco
kubectl label --overwrite namespace acmeco "inlets.dev/uplink"=1
export NS="tenant1"
kubectl create namespace $NS
kubectl label --overwrite namespace $NS "inlets.dev/uplink"=1
```

Then, create a copy of the license secret in the new namespace:

```bash
export NS="n1"
export NS="tenant1"
export LICENSE=$(kubectl get secret -n inlets inlets-uplink-license -o jsonpath='{.data.license}' | base64 -d)

kubectl create secret generic \
Expand All @@ -27,27 +30,44 @@ The `inlets` namespace contains the control plane for inlets uplink, so you'll n
--from-literal license=$LICENSE
```

2. A single namespace for all customer tunnels (not recommended)
=== "One namespace for all tunnels"

For development purposes, you could create a single namespace for all your tenants.

For development purposes, you could create a single namespace for all your customers.
After creating the tunnel, you'll also need to label it `inlets.dev/uplink=1`\

```bash
kubectl create namespace tunnels
export NS="tunnels"
kubectl create namespace $NS
kubectl label --overwrite namespace $NS "inlets.dev/uplink"=1
```

Finally, if you're using Istio, then you need to label each additional namespace to enable sidecar injection:
Then, create a copy of the license secret in the new namespace:

```bash
export NS="tunnels"
export LICENSE=$(kubectl get secret -n inlets inlets-uplink-license -o jsonpath='{.data.license}' | base64 -d)

kubectl create secret generic \
-n $NS \
inlets-uplink-license \
--from-literal license=$LICENSE
```

If you're using Istio, then you need to label each additional namespace to enable sidecar injection:

```bash
kubectl label namespace inlets \
export NS="tunnels"

kubectl label namespace $NS \
istio-injection=enabled --overwrite
```

## Create a Tunnel with an auto-generated token

`Tunnel` describes an inlets-uplink tunnel server. The specification describes a set of ports to use for TCP tunnels.
The `Tunnel` Custom Resource describes an inlets-uplink tunnel server. You can specify a reference to a pre-existing Kubernetes secret for the token, or have one generated for you.

For example the following Tunnel configuration sets up a http tunnel on port `8000` by default and adds port `8080` for use with TCP tunnels. The `licenceRef` needs to reference a secret containing an inlets-uplink license.
The below configures a tunnel for a customer called `acmeco` in the `tunnels` namespace. Port 8080 is exposed as a TCP tunnel, and the `licenceRef` needs to reference a secret containing an inlets-uplink license.

```yaml
apiVersion: uplink.inlets.dev/v1alpha1
Expand All @@ -71,13 +91,19 @@ inlets-pro tunnel create acmeco \
--port 8080
```

Once created, you can check the status of the tunnel, and you will see a secret was generated for the token.

```bash
kubectl get -n tunnels tunnel/acmeco
```

## Create a Tunnel with a pre-defined token

If you delete a Tunnel with an auto-generated token, and re-create it later, the token will change. So we recommend that you pre-define your tokens. This style works well for GitOps and automated deployments with Helm.

Make sure the secret is in the same namespace as the Tunnel Custom Resource.

You can use `openssl` to generate a secure token:
You can use `openssl` to generate a strong token:

```bash
openssl rand -base64 32 |tr -d '\n' > token.txt
Expand Down Expand Up @@ -105,14 +131,16 @@ spec:
licenseRef:
name: inlets-uplink-license
namespace: tunnels
tokenRef:
name: acmeco-token
namespace: tunnels
+ tokenRef:
+ name: acmeco-token
+ namespace: tunnels
tcpPorts:
- 8080
```
Clients can now connect to the tunnel using the custom token.
The `tokenRef` section is used to reference the secret containing the token.

Clients can now connect to the tunnel using the pre-defined token.

### Node selection and annotations for tunnels

Expand All @@ -135,7 +163,7 @@ spec:
tcpPorts:
- 8080
podAnnotations:
cutomer: acmeco
customer: acmeco
nodeSelector:
region: east
```
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Ingress for tunnels
# How to Expose Tunnels on the Internet

!!! info

Expand All @@ -8,8 +8,14 @@

Each inlets uplink tunnel is provisioned with a ClusterIP service that you can access internally within the cluster. The same service can be used to expose the tunnel to the public Internet using an Ingress resource. This approach is recommended for new users for dozens of tunnels.

[![Each tunnel's data-plane is exposed via a separate Ingress and Certificate](/images/uplink/ingress-per-data-plane.png)](/images/uplink/ingress-per-data-plane.png)
> Each tunnel's data-plane is exposed via a separate Ingress and Certificate
Alternatively, the data-router component can be used along with a wild-card DNS record and TLS certificate to expose many tunnels with a single Ingress record or Istio Gateway. This approach requires additional setup because the DNS01 challenge requires a special cert-manager Issuer with a secret for the DNS provider's API. It is recommended for users with many tunnels, but is more complex to setup.

[![A single certificate and Ingress record can be used for multiple tunnels](/images/uplink/wildcard-ingress.png)](/images/uplink/wildcard-ingressplane.png)
> A single certificate and Ingress record can be used for multiple tunnels
## Quick start

The instructions assume that you want to expose two HTTP tunnels. We will configure ingress for the first tunnel, called `grafana`, on the domain `grafana.example.com`. The second tunnel, called `openfaas`, will use the domain `openfaas.example.com`.
Expand Down Expand Up @@ -287,6 +293,8 @@ After applying these resources you should be able to access the data plane for b
As an alternative to creating individual sets of Ingress records, DNS A/CNAME entries and TLS certificates for each tunnel, you can use the `data-router` to route traffic to the correct tunnel based on the hostname. This approach uses a wildcard DNS entry and a single TLS certificate for all tunnels.
To enable the data-router, you will need to modify the values.yaml file you created during the [initial installation](/uplink/installation/) of the Inlets Uplink Helm chart.
The following example is adapted from the cert-manager documentation to use DigitalOcean's DNS servers, however you can find [instructions for issuers](https://cert-manager.io/docs/configuration/acme/dns01/) such as AWS Route53, Cloudflare, Google Cloud DNS, and AzureDNS being listed.
DNS01 challenges require a secret to be created containing the credentials for the DNS provider. The secret is referenced by the issuer resource.
Expand Down Expand Up @@ -356,7 +364,7 @@ helm upgrade --install inlets-uplink \
--values ./values.yaml
```
Create a tunnel with an Ingress Domain specified in the `.Spec` field:
You can now create a new tunnel or modify an existing one and specify the hostname you want to use under the `ingressDomains` field. This field is an array and can take more than one hostname, depending on how many services you want to expose via the tunnel.
```bash
export TUNNEL_NS="tunnels"
Expand Down
28 changes: 15 additions & 13 deletions docs/uplink/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,32 @@

!!! info "What's the difference between Inlets Pro and Inlets Uplink?"

Inlets Pro is a stand-alone binary that can be use to expose local HTTPs and TCP services on a remote machine or network.
Inlets Pro is a stand-alone binary that can be use to expose local HTTPs and TCP services on a remote machine or network. This is the easiest option for individuals and small teams.

Inlets Uplink is a complete management solution for tunnels for SaaS companies and service providers. It's designed for scale, multi-tenancy and easy management.
Inlets Uplink is a complete management solution for tunnels for SaaS companies, infrastructure teams, and service providers. It's designed for scale, multi-tenancy and automation.

Inlets Uplink is our answer to the question: "How do you access customer services from within your own product?"
Inlets Uplink answers two primary questions:

You may consider building your own agent, using a AWS SQS queue, or a VPN.
1. "How do you access customer services from within your own product?"
2. "How to we provide tunnels as a managed service?"

The first two options involve considerable work both up front and in the long run. VPNs require firewall changes, specific network conditions, and lengthy paperwork.
In the first case, of accessing private customer services, you have have already considered building your own agent, using a queue, or a VPN.

Inlets Uplink uses a TLS encrypted websocket to make an outbound connection, and can also work over corporate HTTP proxies.
The first two options involve considerable work both up front and in the long run. VPNs require firewall changes, specific network conditions, additional paperwork, and can have prohibitive costs associated with them.

Here are some of the other differences between Inlets Pro and Inlets Uplink:
The Inlets Uplink runs inside a private network to connect to a public server endpoint using an outbound HTTP connection. Once established, the TLS-encrypted connection is upgraded to a websocket for bi-directional communication. This means it works over NAT, firewalls, and HTTP proxies.

* The management solution is built-in, self-hosted and runs on your Kubernetes cluster
Here are some of the other differences between stand-alone Inlets Pro and Inlets Uplink:

* The management solution is built-in, self-hosted and runs on your own Kubernetes cluster
* You can create a tunnel almost instantly via CLI, REST API or the "Tunnel" Custom Resource
* The license is installed on the server, instead of each client needing it
* TCP ports can be remapped to avoid conflicts
* The license is installed on the server, instead of being attached to the client, to make it easier to give out a connection command to customers and team members
* When exposing TCP ports, they can be remapped to avoid conflicts or needing privileged ports
* A single tunnel can expose HTTP and TCP at the same time
* All tunnels can be monitored centrally for reliability and usage
* By default all tunnels are private and only available for access by your own applications

With Uplink, you deploy tunnel servers for a customers to your Kubernetes cluster, and our operator takes care of everything else.
* Tunnels can also be managed through Helm, ArgoCD or Flux for a GitOps workflow

You can read more about why we created inlets uplink [in the product announcement](https://inlets.dev/blog/2022/11/16/service-provider-uplinks.html).

Reach out to us if you have questions: [Contact the inlets team](https://inlets.dev/contact)
Reach out to us if you have questions or would like to see a demo: [Contact the inlets team](https://inlets.dev/contact)
32 changes: 12 additions & 20 deletions docs/uplink/become-a-provider.md → docs/uplink/installation.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Become an inlets uplink provider
# Install Inlets Uplink

inlets uplink makes it easy for Service Providers and SaaS companies to deliver their product and services to customer networks.
Inlets Uplink requires a Kubernetes cluster, and an inlets uplink subscription.

To become a provider, you'll need a Kubernetes cluster, an inlets uplink subscription and to install the inlets-uplink-provider Helm chart.
The installation is performed through a Helm chart (inlets-uplink-provider)) which is published as an OCI artifact in a container registry.

- [Read the Inlets Uplink announcement](https://inlets.dev/blog/2022/11/16/service-provider-uplinks.html)
The default installation keeps tunneled services private, with only the control-plane exposed to the public Internet. To expose the data-plane for one or more tunnels, after you've completed the installation, see the page [Expose tunnels](/uplink/expose-tunnels/).

## Before you start

Before you start, you'll need the following:

* A Kubernetes cluster with LoadBalancer capabilities (i.e. public cloud).
* A Kubernetes cluster where you can create a LoadBalancer i.e. a managed Kubernetes service like AWS EKS, Azure AKS, Google GKE, etc.
* A domain name clients can use to connect to the tunnel control plane.
* An inlets uplink license (an inlets-pro license cannot be used)
* Optional: [arkade](https://github.com/alexellis/arkade) - a tool for installing popular Kubernetes tools
Expand All @@ -21,25 +21,23 @@ Before you start, you'll need the following:
curl -sSLf https://get.arkade.dev/ | sudo sh
```

Inlets uplink has its own independent subscription from inlets-pro.

Sign-up here: [inlets uplink plans](https://subscribe.openfaas.com/).
You can obtain a subscription for inlets uplink here: [inlets uplink plans](https://inlets.dev/pricing).

## Create a Kubernetes cluster

We recommend creating a Kubernetes cluster with a minimum of three nodes. Each node should have a minimum of 2GB of RAM and 2 CPU cores.

## Install cert-manager

Install [cert-manager](https://cert-manager.io/docs/), which is used to manage TLS certificates for inlets-uplink.
Install [cert-manager](https://cert-manager.io/docs/), which is used to manage TLS certificates for inlets-uplink for the control-plane and the REST API.

You can use Helm, or arkade:

```bash
arkade install cert-manager
```

## Create a namespace for the inlets-uplink-provider and install your license
## Create a namespace for the chart and add the license secret

Make sure to create the target namespace for you installation first.

Expand Down Expand Up @@ -72,21 +70,15 @@ kubectl create secret generic \
--from-file license=$HOME/.inlets/LICENSE_UPLINK
```
## Setup up ingress for customer tunnels
Tunnels on your customers' network will connect to your own inlets-uplink-provider.
## Setup up Ingress for the control-plane
There are two options for deploying the inlets-uplink-provider.
Tunnel clients will connect to the client-router component which needs to be exposed via Ingress.
Use Option A if you're not sure, if your team already uses Istio or prefers Istio, use Option B.
You can use Kubernetes Ingress or Istio. We recommend using Ingress (Option A), unless your team or organisation is already using Istio (Option B).
### A) Install with Kubernetes Ingress
We recommend ingress-nginx, and have finely tuned the configuration to work well for the underlying websocket for inlets. That said, you can change the IngressController if you wish.
!!! note "Chart configuration changes - Sept 2024"
The configuration for a built-in issuer, and some ingress configuration has now moved up one level from the clientRouter, dataRouter, clientApi etc, to the top level of values.yaml. This is a breaking change and you will need to update your values.yaml file before upgrading the chart.
We recommend [ingress-nginx](https://github.com/kubernetes/ingress-nginx) for Ingress, and have finely tuned the configuration to work well for the underlying websocket for inlets. If your organisation uses a different Ingress Controller, you can alter the `class` fields in the chart.
Install ingress-nginx using arkade or Helm:
Expand Down
2 changes: 1 addition & 1 deletion docs/uplink/manage-tunnels.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Manage customer tunnels
# Manage tunnels

You can use `kubectl` or the tunnel plugin for the `inlets-pro` CLI to manage tunnels.

Expand Down
69 changes: 69 additions & 0 deletions docs/uplink/private-tunnels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
## Access tunnels privately

By default, only the control-plane is made public, and the data-plane is kept private.

This suits two use-cases:

* A SaaS or Service Provider who needs to give customers a way to tunnel a private endpoint or service to their control plane
* An infrastructure team managing their own applications or services across multiple environments

Once the [tunnel client is connected](/uplink/connect-tunnel-client/), the data-plane of the tunnel can be access from within the Inlets Uplink control-plane cluster.

You can deploy your applications to the management Kubernetes Cluster, then access them via the tunnel's ClusterIP just like they were running directly within your cluster.

The traffic will go to the ClusterIP, which points at the tunnel server's data-plane ports, which then causes a connection to be dialed back to the client.

[![Uplink with no external ingress or exposed tunnels](/images/uplink/no-external-ingress.png)](/images/uplink/no-external-ingress.png)
> Uplink with no external ingress or exposed tunnels
If you need external ingress for one or more tunnels, then you should see the [expose tunnels](/uplink/expose-tunnels/) page.

### Access a TCP service via ClusterIP

If you have forwarded a TCP service, then you can access it via the ClusterIP of the service.

Let's say that you port-forwarded SSH and remapped port 22 to 2222 to avoid needing to use any additional privileged for the tunnel server Pod:

```bash
kubectl run -t -i --rm tcp-access --image=ubuntu --restart=Never -- sh
```

Then from within the pod, you can access the service via the ClusterIP:

```bash
# apt update
# apt install -qy openssh-client

# ssh -p 2222 user@tunnel1.customer1
```

The address is made up of the tunnel name plus the namespace you used for the customer.

### Access a HTTP service via ClusterIP

If you have forwarded an HTTP service, then you can access it via the ClusterIP of the service, using port 8000.

If you have forwarded multiple HTTP endpoints, use the HTTP "Host" header to access one or the other.

```bash
kubectl run -t -i --rm http-access --image=ubuntu --restart=Never -- sh
```

Then from within the pod, you can access the service via the ClusterIP:

```bash
# apt update
# apt install -qy curl

# curl -i http://tunnel1.customer1:8000
```

To access a specific domain, use the HTTP "Host" header:

```bash
# apt update
# apt install -qy curl

# curl -H "Host: www.example.com" -i http://tunnel1.customer1:8000
```

7 changes: 4 additions & 3 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,13 @@ nav:
- Manage private clusters with ArgoCD (ext): https://inlets.dev/blog/2022/08/10/managing-tunnel-servers-with-argocd.html
- Inlets Uplink:
- Overview: uplink/index.md
- Become a provider: uplink/become-a-provider.md
- Installation: uplink/installation.md
- Create a tunnel: uplink/create-tunnels.md
- Manage tunnels: uplink/manage-tunnels.md
- Connect to tunnels: uplink/connect-to-tunnels.md
- Connect the tunnel client: uplink/connect-tunnel-client.md
- Monitor tunnels: uplink/monitoring-tunnels.md
- Ingress for tunnels: uplink/ingress-for-tunnels.md
- Access tunnels privately: uplink/private-tunnels.md
- Expose tunnels publicly: uplink/public-tunnels.md
- REST API: uplink/rest-api.md
- Reference:
- Overview: reference/index.md
Expand Down

0 comments on commit e0a5bc1

Please sign in to comment.