Skip to content

Commit 91e2f5b

Browse files
author
Simon Emms
committed
[installer]: create readme
1 parent a36fd97 commit 91e2f5b

File tree

2 files changed

+383
-0
lines changed

2 files changed

+383
-0
lines changed

installer/README.md

Lines changed: 374 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,374 @@
1+
<p align="center">
2+
<a href="https://www.gitpod.io">
3+
<img src="https://github.com/raw/gitpod-io/gitpod/master/components/dashboard/src/icons/gitpod.svg" height="60">
4+
<h3 align="center">Gitpod</h3>
5+
</a>
6+
<p align="center">Always ready-to-code.</p>
7+
</p>
8+
9+
# Installer
10+
11+
The best way to get started with Gitpod
12+
13+
[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-908a85?logo=gitpod)](https://gitpod.io/from-referrer/)
14+
15+
# Requirements
16+
17+
- A machine running Linux/MacOS and Docker
18+
- Windows is not currently supported, but will be in future
19+
- [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) installed
20+
- A [Kubernetes cluster configured](https://www.gitpod.io/docs/self-hosted/latest/installation)
21+
22+
Or, [open a Gitpod workspace](https://gitpod.io/from-referer/)
23+
24+
The process to install Gitpod is:
25+
1. generate a base config
26+
2. amend the config for your own use-case
27+
3. validate
28+
4. render the Kubernetes YAML
29+
5. `kubectl apply`
30+
31+
# Quickstart
32+
33+
## Create a gitpod-installer script
34+
35+
> This script is available in [/scripts/gitpod-installer.sh](../scripts/gitpod-installer.sh)
36+
37+
```shell
38+
#!/bin/bash
39+
40+
VERSION="${VERSION:-main.1844}" # Build ID taken from https://werft.gitpod-dev.com/
41+
42+
docker run -it --rm \
43+
-v $PWD:/gitpod \
44+
-v $HOME/.kube:/root/.kube \
45+
eu.gcr.io/gitpod-core-dev/build/installer:${VERSION} \
46+
$@
47+
```
48+
49+
Save this in your `$PATH` as `gitpod-installer` and make executable
50+
51+
## Generate the base config
52+
53+
```shell
54+
gitpod-installer init > gitpod.config.yaml
55+
```
56+
57+
## Customise your config
58+
59+
There are many things you can change in your config, which can be found in
60+
the [Config Guide](#config).
61+
62+
For the purposes of a quickstart, just change the `domain` to one of your
63+
own.
64+
65+
## Validate
66+
67+
```shell
68+
# Checks the validity of the configuration YAML
69+
gitpod-installer validate config --config /gitpod/gitpod.config.yaml
70+
```
71+
72+
Any errors here must be fixed before deploying. See [Config](#config) for
73+
more details.
74+
75+
```shell
76+
# Checks that your cluster is ready to install Gitpod
77+
gitpod-installer validate cluster --kubeconfig /root/.kube/config --config /gitpod/gitpod.config.yaml
78+
```
79+
80+
Any errors here must be fixed before deploying. See [Cluster Dependencies](#cluster-dependencies)
81+
for more details.
82+
83+
## Render the YAML
84+
85+
```shell
86+
gitpod-installer render --config /gitpod/gitpod.config.yaml > gitpod.yaml
87+
```
88+
89+
## Deploy
90+
91+
```shell
92+
kubectl apply -f gitpod.yaml
93+
```
94+
95+
After a few minutes, your Gitpod installation will be available on the
96+
specified `domain`.
97+
98+
## Uninstallation
99+
100+
The Installer generates a ConfigMap with the metadata of every Kubernetes
101+
object generated by the Installer. This can be retrieved to remove Gitpod
102+
from your cluster.
103+
104+
```shell
105+
kubectl get configmaps gitpod-app -o jsonpath='{.data.app\.yaml}' \
106+
| kubectl delete -f - # Piping to this will delete automatically
107+
```
108+
109+
**Important**. This may leave certain objects still in your Kubernetes
110+
cluster. This will include `Secrets` generated from internal `Certificates`
111+
and `PersistentVolumeClaims`. These will need to be manually deleted.
112+
113+
---
114+
115+
# What is installed
116+
117+
- All Gitpod components
118+
- Container registry*
119+
- MySQL database*
120+
- Jaeger operator*
121+
- RabbitMQ
122+
- Minio object storage*
123+
124+
\* By default, these dependencies are installed if the `inCluster` setting
125+
is `true`. External dependencies can be used in their place
126+
127+
# Config
128+
129+
> Not every parameter is discussed in this table, just ones that are likely
130+
> to need changing. The full config structure is available in [config.go](/installer/pkg/config/v1/config.go).
131+
132+
| Property | Required | Description | Notes |
133+
| --- | --- | --- | --- |
134+
| `domain` | Y | The domain to deploy to | This will need to be changed on every deployment |
135+
| `kind` | Y | Installation type to run - for most users, this will be `Full` | Can be `Full`, `Meta` or `Workspace` |
136+
| `metadata.region` | Y | Location for your `objectStorage` provider | If using Minio, set to `local` |
137+
| `workspace.runtime.containerdRuntimeDir` | Y | The location of containerd on host machine | Common values are: <ul><li>`/run/containerd/io.containerd.runtime.v2.task/k8s.io` (K3s)</li><li>`/var/lib/containerd/io.containerd.runtime.v2.task/k8s.io` (AWS/Azure/GCP)</li><li>`/run/containerd/io.containerd.runtime.v1.linux/k8s.io`</li><li>`/run/containerd/io.containerd.runtime.v1.linux/moby`</li></ul> |
138+
| `workspace.runtime.containerdSocket` | Y | The location of containerd socket on the host machine |
139+
| `workspace.runtime.fsShiftMethod` | Y | File system | Can be either `fuse` (fuse-overlayfs) or `shiftfs`. This depending upon your host OS/distribution. If unsure, use `fuse`. |
140+
141+
## Auth Providers
142+
143+
> This may move to a secret in future [#6867](https://github.com/gitpod-io/gitpod/issues/6867)
144+
145+
Gitpod must be connected to a Git provider. This can be done via the
146+
dashboard on first load, or by providing `authProviders` configuration.
147+
148+
```yaml
149+
authProviders:
150+
- id: Public-GitHub
151+
host: github.com
152+
type: GitHub
153+
oauth:
154+
clientId: xxx
155+
clientSecret: xxx
156+
callBackUrl: https://$DOMAIN/auth/github.com/callback
157+
settingsUrl: xxx
158+
```
159+
160+
## In-cluster vs External Dependencies
161+
162+
Gitpod requires certain services for it to function correctly. The Installer
163+
provides all of these in-cluster, but they can be configured to use services
164+
external to the cluster.
165+
166+
To use the in-cluster dependency, set `inCluster` to be `true`.
167+
168+
## Container Registry
169+
170+
```yaml
171+
containerRegistry:
172+
inCluster: false
173+
external:
174+
url: <url of registry>
175+
certificate:
176+
kind: secret
177+
name: container-registry-token
178+
```
179+
180+
The `container-registry-token` secret must contain a `.dockerconfigjson`
181+
key - this can be created by using the `kubectl create secret docker-registry`
182+
[command](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-secret-by-providing-credentials-on-the-command-line).
183+
184+
## Database
185+
186+
Gitpod requires an instance of MySQL 5.7 for data storage.
187+
188+
The default encryption keys are `[{"name":"general","version":1,"primary":true,"material":"4uGh1q8y2DYryJwrVMHs0kWXJlqvHWWt/KJuNi04edI="}]`
189+
190+
### Google Cloud SQL Proxy
191+
192+
If using a GCP SQL instance, a [Cloud SQL Proxy](https://cloud.google.com/sql/docs/mysql/sql-proxy)
193+
connection can be used.
194+
195+
```yaml
196+
database:
197+
inCluster: false
198+
cloudSQL:
199+
instance: <PROJECT_ID>:<REGION>:<INSTANCE>
200+
serviceAccount:
201+
kind: secret
202+
name: cloudsql-token
203+
```
204+
205+
The `cloudsql-token` secret must contain the following key/value pairs:
206+
- `credentials.json` - GCP Service Account key with `roles/cloudsql.client` role
207+
- `encryptionKeys` - database encryption key. Use default value as above if unsure
208+
- `password` - database password
209+
- `username` - database username
210+
211+
### External Database
212+
213+
For all other connections, use an external database configuration.
214+
215+
```yaml
216+
database:
217+
inCluster: false
218+
external:
219+
certificate:
220+
kind: secret
221+
name: database-token
222+
```
223+
224+
The `database-token` secret must contain the following key/value pairs:
225+
- `encryptionKeys` - database encryption key. Use default value as above if unsure
226+
- `host` - IP or URL of the database
227+
- `password` - database password
228+
- `port` - database port, usually `3306`
229+
- `username` - database username
230+
231+
## Object Storage
232+
233+
Gitpod supports the following object storage providers:
234+
235+
### GCP
236+
237+
```yaml
238+
metadata:
239+
region: <gcp-region-code, eg europe-west2>
240+
objectStorage:
241+
inCluster: false
242+
cloudStorage:
243+
project: <PROJECT_ID>
244+
serviceAccount:
245+
kind: secret
246+
name: gcp-storage-token
247+
```
248+
249+
The `gcp-storage-token` secret must contain the following key/value pairs:
250+
- `service-account.json` - GCP Service Account key with `roles/storage.admin` and `roles/storage.objectAdmin` roles
251+
252+
### Azure
253+
254+
> Azure Blob Storage is not S3 compatible. This uses Minio Gateway to
255+
> provide an S3 interface
256+
257+
```yaml
258+
metadata:
259+
region: <azure-region-code, eg northeurope>
260+
objectStorage:
261+
inCluster: false
262+
azure:
263+
certificate:
264+
kind: secret
265+
name: az-storage-token
266+
```
267+
268+
The `az-storage-token` secret must contain the following key/value pairs:
269+
- `accountName` - the globally-unique storage account name
270+
- `accountKey` - access key for the storage account
271+
272+
### S3
273+
274+
> This is currently only tested with AWS. Other S3-compatible providers should
275+
> work but there may compatability issues - please raise a ticket if you have
276+
> issues with other providers
277+
278+
```yaml
279+
metadata:
280+
region: <aws-region-code, eg eu-west-2>
281+
objectStorage:
282+
inCluster: false
283+
s3:
284+
endpoint: s3.amazonaws.com
285+
credentials:
286+
kind: secret
287+
name: s3-storage-token
288+
```
289+
290+
The `s3-storage-token` secret must contain the following key/value pairs:
291+
- `username` - username that has access to S3 account
292+
- `password` - password that has access to S3 account
293+
294+
> In AWS, the username/password are an IAM user's credentials with
295+
> `AmazonS3FullAccess` policy
296+
297+
# Cluster Dependencies
298+
299+
In order for the deployment to work successfully, there are certain
300+
dependencies that need to be installed.
301+
302+
## Kernel and Runtime
303+
304+
Your Kubernetes nodes must have the Linux kernel v5.4.0 or above and
305+
have a containerd runtime.
306+
307+
## Affinity Labels
308+
309+
Your Kubernetes nodes must have the following labels applied to them:
310+
- `gitpod.io/workload_meta`
311+
- `gitpod.io/workload_ide`
312+
- `gitpod.io/workload_workspace_services`
313+
- `gitpod.io/workload_workspace_regular`
314+
- `gitpod.io/workload_workspace_headless`
315+
316+
It is recommended to have a minimum of two node pools, grouping the `meta`
317+
and `ide` nodes together and the `workspace` nodes together.
318+
319+
## TLS certificates
320+
321+
It is a requirement that a certificate secret exists, named as per
322+
`certificate.name` in your config YAML with `tls.crt` and `tls.key`
323+
in the secret data. How this certificate is generated is entirely your
324+
choice - we suggest [Cert Manager](https://cert-manager.io/) for
325+
simplicity, however any certificate authority can be used by creating a
326+
Kubernetes secret.
327+
328+
The certificate must be associated with the following domains (where
329+
`$DOMAIN` is the value in config `domain`):
330+
- `$DOMAIN`
331+
- `*.$DOMAIN`
332+
- `*.ws.$DOMAIN`
333+
334+
### Cert Manager
335+
336+
Cert Manager **MUST** be installed to your cluster. In order to secure
337+
communication between the various components, the application creates
338+
internally which are created using the Cert Manager `Certificate` and
339+
`Issuer` Custom Resource Definitions.
340+
341+
```shell
342+
helm repo add jetstack https://charts.jetstack.io
343+
helm repo update
344+
helm upgrade \
345+
--atomic \
346+
--cleanup-on-fail \
347+
--create-namespace \
348+
--install \
349+
--namespace='cert-manager' \
350+
--reset-values \
351+
--set installCRDs=true \
352+
--set 'extraArgs={--dns01-recursive-nameservers-only=true,--dns01-recursive-nameservers=8.8.8.8:53\,1.1.1.1:53}' \
353+
--wait \
354+
cert-manager \
355+
jetstack/cert-manager
356+
```
357+
358+
# FAQs
359+
360+
## Why are you writing your own Installer instead of using Helm/Kustomize/etc?
361+
362+
The Installer is a complete replacement for our Helm charts. Over time,
363+
this had grown to be too complex to effectively support and was a barrier
364+
to entry for new users - the base config was many hundreds of lines long
365+
and did not have effective validation on it. By contrast, the Installer's
366+
config is < 50 lines long and can be fully validated before running.
367+
368+
# Todo
369+
370+
PRs/comments welcome
371+
372+
- [ ] [Improve distribution of gitpod-installer binaries](https://github.com/gitpod-io/gitpod/issues/6766)
373+
- [ ] [Configure and document S3 object storage](https://github.com/gitpod-io/gitpod/issues/6772)
374+
- [ ] [Create a Gitpod workspace that can be used for installing a Gitpod instance](https://github.com/gitpod-io/gitpod/issues/6801)

scripts/gitpod-installer.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
3+
VERSION="${VERSION:-main.1844}" # Build ID taken from https://werft.gitpod-dev.com/
4+
5+
docker run -it --rm \
6+
-v $PWD:/gitpod \
7+
-v $HOME/.kube:/root/.kube \
8+
eu.gcr.io/gitpod-core-dev/build/installer:${VERSION} \
9+
$@

0 commit comments

Comments
 (0)