Skip to content

Commit fde566e

Browse files
committed
Initial version of post on airgaps
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
1 parent 753aafe commit fde566e

3 files changed

Lines changed: 395 additions & 0 deletions

File tree

Lines changed: 395 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,395 @@
1+
---
2+
title: Deploy airgapped Serverless Functions with OpenFaaS
3+
description: Learn how to install OpenFaaS into an airgap with airfaas for private serverless functions.
4+
date: 2024-04-15
5+
categories:
6+
- serverless
7+
- functions
8+
- portable
9+
- airgap
10+
dark_background: true
11+
author_staff_member: alex
12+
hide_header_image: true
13+
---
14+
15+
In this tutorial, I'll show you how to install [OpenFaaS Standard or OpenFaaS for Enterprises](https://docs.openfaas.com/openfaas-pro/introduction/) into a private, airgapped network.
16+
17+
There are no special tools required to perform an offline installation, but you will need a computer with Internet access in order to prepare for the installation. On your private network, you should have Kubernetes already installed, but if you don't, [K3s](https://k3s.io) could be a good option and has [documentation for offline installations](https://docs.k3s.io/installation/airgap).
18+
19+
If you don't have a private registry in your airgap or are unsure how to set one up, [CNCF Harbor](https://www.cncf.io/projects/harbor/) is a popular open-source choice. For testing, I used Docker's open source registry now called ["CNCF Distribution"](https://github.com/distribution/distribution), with authentication and a self-signed TLS certificate, with the CA's public key placed in the trust bundle.
20+
21+
Since the private network has no Internet access, we need to perform a subset of the tasks on a computer with access to the public Internet:
22+
23+
On the public network:
24+
25+
* Download container images
26+
* Download specific chart versions
27+
* Download any CLI tools needed
28+
29+
![The initial download](/images/2024-04-airgap/download.png)
30+
> Download the various charts, images and CLI tools required.
31+
32+
On the private network:
33+
34+
* Restore container images into a self-hosted registry
35+
* Configure any pull secrets required
36+
* Install the exported chart with Helm
37+
38+
![Restoration and installation](/images/2024-04-airgap/restore.png)
39+
> "airfaas restore" places the container images into the private registry, Helm performs an installation pointing at the new images, then the kubelet will pull those images and start the containers for OpenFaaS.
40+
41+
Now, all of the steps above can become tedious and repetitive, and there a number of existing solutions for automation. However most of the ones we looked at were opinionated, complex, and tied you into new concepts that were unnecessary. That's where airfaas comes in. A simple extension to the existing OpenFaaS CLI which makes your initial installation, and subsequent updates a walk in the park.
42+
43+
## Walk-through with airfaas
44+
45+
There are two logic parts to this walk-through, the first set of steps are run on an Internet-facing computer, to prepare what's needed for an offline installation. The second set of steps cover the offline installation itself, and deploying a sample function from the store.
46+
47+
### Download the charts you will need
48+
49+
First of all, you can download airfaas for the public network using:
50+
51+
```bash
52+
faas-cli plugin get airfaas
53+
```
54+
55+
You can then use it via `faas-cli airfaas` or create an alias `alias airfaas="faas-cli airfaas"`.
56+
57+
If your local machine is running MacOS with Apple Silicon, and the remote machine runs Linux, you can override the Operating System and Architecture to pre-download airfaas for the remote computer.
58+
59+
Now, download the Helm chart or charts that you require.
60+
61+
```bash
62+
Examples:
63+
## Download all charts from repo
64+
airfaas download chart
65+
66+
## Download a single chart
67+
airfaas download chart openfaas/cron-connector
68+
69+
## Download a specific version of a chart
70+
airfaas download chart openfaas/openfaas --version 0.9.0
71+
```
72+
73+
The charts `--url` is set to `https://openfaas.github.io/faas-netes/` as a default.
74+
75+
Here's what you get when you download all the charts in the repository (which is the default):
76+
77+
```bash
78+
$ airfaas download chart
79+
80+
Downloading: (all charts) https://openfaas.github.io/faas-netes/
81+
NAME VERSION DESCRIPTION
82+
openfaas/openfaas 14.2.34 OpenFaaS - Serverless Functions Made Simple
83+
openfaas/cron-connector 0.6.10 Trigger OpenFaaS Functions with cron schedules
84+
openfaas/federated-gateway 0.1.0 Federated Gateway for OpenFaaS service providers
85+
openfaas/kafka-connector 0.7.9 Connect OpenFaaS functions to Kafka topics
86+
openfaas/mqtt-connector 0.4.7 Connect OpenFaaS functions to MQTT topics
87+
openfaas/nats-connector 0.3.2 Trigger OpenFaaS Functions from NATS Pub/Sub
88+
openfaas/postgres-connector 0.1.1 Trigger OpenFaaS functions from PostgreSQL
89+
openfaas/pro-builder 0.4.13 Build OpenFaaS functions via a REST API
90+
openfaas/probuilder 0.2.0 Build OpenFaaS functions via a REST API
91+
openfaas/queue-worker 0.2.7 Dedicated queue-worker for OpenFaaS using JetStream
92+
openfaas/sns-connector 0.1.3 Invoke functions from an AWS SNS messages.
93+
openfaas/sqs-connector 0.2.4 Connect OpenFaaS functions to SQS topics
94+
Downloading openfaas/openfaas (14.2.34) => chart/openfaas/openfaas
95+
Downloading openfaas/cron-connector (0.6.10) => chart/openfaas/cron-connector
96+
Downloading openfaas/federated-gateway (0.1.0) => chart/openfaas/federated-gateway
97+
Downloading openfaas/kafka-connector (0.7.9) => chart/openfaas/kafka-connector
98+
Downloading openfaas/mqtt-connector (0.4.7) => chart/openfaas/mqtt-connector
99+
Downloading openfaas/nats-connector (0.3.2) => chart/openfaas/nats-connector
100+
Downloading openfaas/postgres-connector (0.1.1) => chart/openfaas/postgres-connector
101+
Downloading openfaas/pro-builder (0.4.13) => chart/openfaas/pro-builder
102+
Downloading openfaas/probuilder (0.2.0) => chart/openfaas/probuilder
103+
Downloading openfaas/queue-worker (0.2.7) => chart/openfaas/queue-worker
104+
Downloading openfaas/sns-connector (0.1.3) => chart/openfaas/sns-connector
105+
Downloading openfaas/sqs-connector (0.2.4) => chart/openfaas/sqs-connector
106+
```
107+
108+
Then you'll see the various tarballs downloaded:
109+
110+
```bash
111+
$ find chart/ | grep tgz
112+
chart/openfaas/queue-worker/queue-worker-0.2.7.tgz
113+
chart/openfaas/mqtt-connector/mqtt-connector-0.4.7.tgz
114+
chart/openfaas/nats-connector/nats-connector-0.3.2.tgz
115+
chart/openfaas/postgres-connector/postgres-connector-0.1.1.tgz
116+
chart/openfaas/probuilder/probuilder-0.2.0.tgz
117+
chart/openfaas/federated-gateway/federated-gateway-0.1.0.tgz
118+
chart/openfaas/sqs-connector/sqs-connector-0.2.4.tgz
119+
chart/openfaas/sns-connector/sns-connector-0.1.3.tgz
120+
chart/openfaas/pro-builder/pro-builder-0.4.13.tgz
121+
chart/openfaas/cron-connector/cron-connector-0.6.10.tgz
122+
chart/openfaas/kafka-connector/kafka-connector-0.7.9.tgz
123+
chart/openfaas/openfaas/openfaas-14.2.34.tgz
124+
```
125+
126+
### Download the container images
127+
128+
Next, download the images for all the charts, or a specific chart.
129+
130+
Like the previous command, a `--url` and `--version` command are available.
131+
132+
Here, we'll download just two of the charts we need:
133+
134+
```bash
135+
$ airfaas download images openfaas/openfaas
136+
$ airfaas download images openfaas/cron-connector
137+
```
138+
139+
Here's the output from the second chart, notice how it's downloaded all available images, so if you change a configuration value later on, you won't have to download and sync images again.
140+
141+
```bash
142+
$ airfaas download images openfaas/cron-connector
143+
Downloading: chart openfaas/cron-connector https://openfaas.github.io/faas-netes/
144+
Showing values for: "openfaas/cron-connector"
145+
Total images: 2
146+
NAME IMAGE
147+
image ghcr.io/openfaas/cron-connector:0.6.1
148+
pro.image ghcr.io/openfaasltd/cron-connector:0.2.5
149+
150+
Downloading: ghcr.io/openfaas/cron-connector:0.6.1
151+
Wrote images/openfaas/cron-connector/image.tar (7.4MB)
152+
153+
Downloading: ghcr.io/openfaasltd/cron-connector:0.2.5
154+
Wrote images/openfaas/cron-connector/pro.image.tar (6.205MB)
155+
```
156+
157+
### Download a sample function for testing
158+
159+
We recommend exporting one of the sample functions from the store so you can deploy something and see the setup working.
160+
161+
```bash
162+
arkade get crane
163+
164+
mkdir -p images/samples/
165+
166+
crane pull ghcr.io/openfaas/alpine:latest ./images/samples/alpine.tar
167+
```
168+
169+
### Download any supporting CLI tools
170+
171+
Lastly, you may wish to download various CLI utilities for use on the air-gapped computer on the private network, where you'll perform the installation, including a separate copy of airfaas itself.
172+
173+
Let's assume you're going to run the various tools on a Linux computer with an amd64 architecture, and want to download them to `./tools`.
174+
175+
```bash
176+
mkdir -p tools
177+
178+
export OS="linux"
179+
export ARCH="x86_64"
180+
181+
faas-cli plugin get airfaas \
182+
--path ./tools \
183+
--os $OS \
184+
--arch $ARCH
185+
186+
arkade get \
187+
--path ./tools \
188+
--os $OS \
189+
--arch $ARCH \
190+
kubectl \
191+
crane \
192+
kind \
193+
k3sup \
194+
kubectx \
195+
helm \
196+
faas-cli
197+
```
198+
199+
Now prepare a USB disk, or use `scp` or `rsync` to copy the files to the computer or jump host on the private network.
200+
201+
### Perform an installation on the private network
202+
203+
#### Restore the images into a private registry
204+
205+
We typically encounter registries with any of the below:
206+
207+
1. HTTP only, no authentication
208+
2. TLS with a self-signed certificate not in the local trust bundle
209+
3. TLS with a self-signed certificate in the local trust bundle
210+
4. TLS with authentication
211+
212+
For option one and two, when restoring images use the `--insecure-registry` flag.
213+
214+
For the third option, there is no change required.
215+
216+
For the fourth option, you should create a `~/.docker/config.json` file with valid credentials for the server
217+
218+
There is no need to install a Docker daemon to do this. You can use the `faas-cli` to generate a valid Docker credential file:
219+
220+
Create a password.txt file with the password required to log in, and then set the USERNAME variable:
221+
222+
```bash
223+
export USERNAME=openfaas
224+
export REGISTRY=probable-stargazer.local:5000
225+
226+
mkdir -p ~/.docker/
227+
228+
cat ./password.txt | faas-cli registry-login \
229+
--username $USERNAME \
230+
--server $REGISTRY \
231+
--password-stdin
232+
```
233+
234+
Restore the images into the private registry:
235+
236+
```bash
237+
export REGISTRY=probable-stargazer.local:5000
238+
airfaas restore ./images/openfaas/openfaas/images.json --prefix $REGISTRY
239+
```
240+
241+
The final output of the command will print re-mapped image names from the upstream URLs to the ones in your private registry.
242+
243+
Save that file to values-air.yaml, for instance..
244+
245+
```yaml
246+
gatewayPro:
247+
image: probable-stargazer.local:5000/openfaasltd/gateway:0.4.27
248+
autoscaler:
249+
image: probable-stargazer.local:5000/openfaasltd/autoscaler:0.3.6
250+
dashboard:
251+
image: probable-stargazer.local:5000/openfaasltd/openfaas-dashboard:0.5.11
252+
gateway:
253+
image: probable-stargazer.local:5000/openfaas/gateway:0.27.6
254+
queueWorkerPro:
255+
image: probable-stargazer.local:5000/openfaasltd/queue-worker:0.4.0
256+
```
257+
258+
#### Prepare the OpenFaaS namespaces
259+
260+
```bash
261+
kubectl create ns openfaas
262+
kubectl create ns openfaas-fn
263+
```
264+
265+
If you are using authentication for your private registry, then create a pull secret and bind it to the default service account.
266+
267+
You can skip this step if there is no authentication required for your private registry.
268+
269+
```bash
270+
export REG=probable-stargazer.local:5000
271+
export NS=openfaas
272+
273+
kubectl create namespace $NS || "echo Namespace: $NS already exists"
274+
275+
kubectl create secret docker-registry private-registry-creds \
276+
--docker-server=$REG \
277+
--from-file .dockerconfigjson=$HOME/.docker/config.json \
278+
-n $NS
279+
280+
kubectl patch serviceaccount -n $NS default -p '{"imagePullSecrets": [{"name": "private-registry-creds"}]}'
281+
```
282+
283+
Repeat the above, changing openfaas to openfaas-fn if you are intending on hosting functions within the same registry.
284+
285+
#### Create a secret for the OpenFaaS license
286+
287+
```bash
288+
kubectl create secret generic \
289+
-n openfaas \
290+
openfaas-license \
291+
--from-file license=$HOME/.openfaas/LICENSE
292+
```
293+
294+
#### Install OpenFaaS with Helm
295+
296+
First, run `ls chart/openfaas/openfaas` to see which chart versions you have available, then pick one for the installation:
297+
298+
```bash
299+
helm upgrade --install openfaas ./chart/openfaas/openfaas/openfaas-14.2.34.tgz \
300+
--namespace openfaas \
301+
--set openfaasPro=true \
302+
--set operator.create=true \
303+
--set clusterRole=true \
304+
-f ./values-air.yaml
305+
```
306+
307+
Alternatively, you can use the [values-pro.yaml file from the OpenFaaS documentation](https://docs.openfaas.com/deployment/pro/#installation), then provide values-air.yaml to set the images only:
308+
309+
```bash
310+
helm upgrade --install openfaas ./chart/openfaas/openfaas/openfaas-14.2.34.tgz \
311+
--namespace openfaas \
312+
--set openfaasPro=true \
313+
--set operator.create=true \
314+
--set clusterRole=true \
315+
-f ./values-pro.yaml \
316+
-f ./values-air.yaml
317+
```
318+
319+
As you can see, there are no special chart options required for OpenFaaS to run in an offline environment, with a private registry.
320+
321+
### Deploy and invoke a sample function
322+
323+
Port-forward and log into the gateway with the instructions from `arkade info openfaas`.
324+
325+
Now, restore the sample function to your registry:
326+
327+
```bash
328+
export REG=probable-stargazer.local:5000
329+
crane push ./images/samples/alpine.tar $REG/openfaas/alpine:latest
330+
```
331+
332+
Deploy it:
333+
334+
```bash
335+
export REG=probable-stargazer.local:5000
336+
faas-cli deploy --name env --fprocess=env --image $REG/openfaas/alpine:latest
337+
```
338+
339+
Invoke the function:
340+
341+
```bash
342+
faas-cli invoke env <<< ""
343+
Handling connection for 8080
344+
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
345+
HOSTNAME=env-6f95bcc679-qv7dp
346+
OPENFAAS_NAME=env
347+
fprocess=env
348+
KUBERNETES_SERVICE_PORT_HTTPS=443
349+
KUBERNETES_PORT=tcp://10.43.0.1:443
350+
KUBERNETES_PORT_443_TCP=tcp://10.43.0.1:443
351+
KUBERNETES_PORT_443_TCP_PROTO=tcp
352+
KUBERNETES_PORT_443_TCP_PORT=443
353+
KUBERNETES_PORT_443_TCP_ADDR=10.43.0.1
354+
KUBERNETES_SERVICE_HOST=10.43.0.1
355+
KUBERNETES_SERVICE_PORT=443
356+
```
357+
358+
### Offline function development
359+
360+
You can adapt a template from the OpenFaaS template store by downloading its Git repository, mirroring any base images and copying it across to the private registry.
361+
362+
Take the `golang-middleware` template for instance. Its [Dockerfile](https://github.com/openfaas/golang-http-template/blob/master/template/golang-middleware/Dockerfile) uses two public images:
363+
364+
```diff
365+
-FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/openfaas/of-watchdog:0.9.15 as watchdog
366+
+FROM --platform=${TARGETPLATFORM:-linux/amd64} probable-stargazer.local:5000/openfaas/of-watchdog:0.9.15 as watchdog
367+
-FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22-alpine as build
368+
+FROM --platform=${BUILDPLATFORM:-linux/amd64} probable-stargazer.local:5000/golang:1.22-alpine as build
369+
```
370+
371+
Simply mirror those images with `crane pull` and `crane push`, then add a prefix to the Dockerfile and you'll be able to build, push and deploy functions within your airgap.
372+
373+
Bear in mind that most templates use package managers like `pip`, `npm`, `gradle`, or Gomodules. These packages will need to be mirrored into a separate private package repository for completely offline development.
374+
375+
Alternatively, you could do all your function development outside of the airgap on a public network, then export individual function images as required, to be copied into the private network.
376+
377+
## Wrapping up
378+
379+
As explained in the introduction, no special tooling is required to run a commercial version of OpenFaaS in an airgap, however tooling can improve the experience. Not only can we download the images, charts, and supporting tooling very quickly, but we can perform the initial installation and subsequent updates with a few CLI commands, that have been tested together and are supported by the OpenFaaS team.
380+
381+
What's next?
382+
383+
All the tooling included in OpenFaaS Standard and OpenFaaS for Enterprises is designed to work on any Kubernetes cluster, whether online or offline - including OpenShift. Just mirror any additional connectors or components that you may need, and decide whether you're going to build functions within the airgap, or outside of it, and then to synchronise them as required.
384+
385+
Day two operations are simply a case of running:
386+
387+
```bash
388+
airfaas download chart
389+
airfaas download images
390+
```
391+
392+
Then on the private network, doing a `helm upgrade` using the instructions from above.
393+
394+
So it's over to you. [Get in touch with us](https://openfaas/pricing) if you'd like to try OpenFaaS in an airgap, or if you're already a licensed customer running in an airgap, we'd be happy to hear your feedback on how to improve airfaas for you.
395+

images/2024-04-airgap/download.png

55.4 KB
Loading

images/2024-04-airgap/restore.png

65.9 KB
Loading

0 commit comments

Comments
 (0)