Skip to content

FIx issues with components startup #1

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

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM eu.gcr.io/gitpod-core-dev/build/installer:main.3237 AS installer
FROM eu.gcr.io/gitpod-core-dev/build/installer:main.3413 AS installer

FROM rancher/k3s:v1.21.12-k3s1

Expand All @@ -8,6 +8,8 @@ RUN chmod +x /bin/mkcert
ADD https://github.com/krallin/tini/releases/download/v0.19.0/tini-static /tini
RUN chmod +x /tini

ADD https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml /var/lib/rancher/k3s/server/manifests/cert-manager.yaml

ADD https://github.com/mikefarah/yq/releases/download/v4.25.1/yq_linux_amd64 /bin/yq
RUN chmod +x /bin/yq

Expand Down
34 changes: 23 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
# Gitpod in a Docker container with k3s
# Gitpod Preview Installation

**This is merely a starting point**
This repo helps users to try out and preview self-hosted Gitpod **locally** without all the things
needed for a production instance. The aim is to provide an installation mechanism as minimal and
simple as possible.

Things that are working:
- latest installer is integrated
- PVCs are provisioned using `local-path`
- All containers go out of pending (some don't work because of the `buildin-registry-certs` issue)
## Installation

Things that are missing:
- generating self-signed certs in the entrypoint.sh
- all the DNS setup, e.g. patching CoreDNS in the entrypoint
```bash
sudo docker run --privileged --name gitpod --rm -it -v /tmp/gitpod:/var/gitpod 5000-gitpodio-previewinstall-ox4ypumem4w.ws-us46.gitpod.io/gitpod-k3s:latest
```

Things that are not working:
- the `builtin-registry-certs` secret seems to be missing
Once the above command starts running and the pods are ready (can be checked by running `docker exec gitpod kubectl get pods`),
The URL to access your gitpod instance can be retrieved by running

```
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' gitpod | sed -r 's/[.]+/-/g' | sed 's/$/.nip.io/g'
```

[nip.io](https://nip.io/) is just wildcard DNS for local addresses, So all off this is local, and cannot be accessed over the internet.

As the `self-hosted` instance is self-signed, The root certificate to upload into your browser trust store to access the URL is available at
`/tmp/gitpod/gitpod-ca.crt`.

## Known Issues

- Prebuilds don't work as they require webhooks support over the internet.
246 changes: 84 additions & 162 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,204 +1,126 @@
#!/bin/sh

set -eux -o pipefile

if [ -z "$DOMAIN" ]; then
>&2 echo "Error: Environment variable DOMAIN is missing."
exit 1;
set -ex -o pipefail

# check for minimum requirements
REQUIRED_MEM_KB=$((6 * 1024 * 1024))
total_mem_kb=$(cat /proc/meminfo | awk '/MemTotal:/ {print $2}')
if [ $total_mem_kb -lt $((REQUIRED_MEM_KB)) ]; then
echo "Preview installation of Gitpod requires a system with at least 6GB of memory"
exit 1
fi

REQUIRED_CORES=4
total_cores=$(nproc)
if [ $total_cores -lt $((REQUIRED_CORES)) ]; then
echo "Preview installation of Gitpod requires a system with at least 4 CPU Cores"
exit 1
fi

# Get container's IP address
if [ -z "${DOMAIN}" ]; then
NODE_IP=$(hostname -i)
DOMAIN_STRING=${NODE_IP//[.]/-}
DOMAIN="${DOMAIN_STRING}.nip.io"
fi

FN_CACERT="/certs/ca.pem"
FN_SSLCERT="/certs/ssl.crt"
FN_SSLKEY="/certs/ssl.key"
FN_CAKEY="/certs/ca.key"
FN_CSREXT="/certs/cert.ext"

if [ ! -f "$FN_CACERT" ] && [ ! -f "$FN_SSLCERT" ] && [ ! -f "$FN_SSLKEY" ]; then
[ ! -d /certs ] && mkdir -p /certs

/bin/mkcert \
-cert-file "$FN_SSLCERT" \
-key-file "$FN_SSLKEY" \
"*.ws.${DOMAIN}" "*.${DOMAIN}" "${DOMAIN}" "ws-manager" "wsdaemon"
CAROOT="/certs" /bin/mkcert -install
mv /certs/rootCA.pem "$FN_CACERT"
echo "Gitpod Domain: $DOMAIN"

if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
echo "[$(date -Iseconds)] [CgroupV2 Fix] Evacuating Root Cgroup ..."
# move the processes from the root group to the /init group,
# otherwise writing subtree_control fails with EBUSY.
mkdir -p /sys/fs/cgroup/init
busybox xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || :
# enable controllers
sed -e 's/ / +/g' -e 's/^/+/' <"/sys/fs/cgroup/cgroup.controllers" >"/sys/fs/cgroup/cgroup.subtree_control"
echo "[$(date -Iseconds)] [CgroupV2 Fix] Done"
fi

mkdir -p /var/lib/rancher/k3s/server/manifests/gitpod
mount --make-shared /sys/fs/cgroup
mount --make-shared /proc
mount --make-shared /var/gitpod/workspaces
Copy link
Author

@Pothulapati Pothulapati Jun 7, 2022

Choose a reason for hiding this comment

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

This was done intentionally, as I wanted to output the root cert into /var/gitpod/gitpod-ca.crt and workspaces folder felt specific to workspaces (updated README around this) WDYT @csweichel ?


CACERT=$(base64 -w0 < "$FN_CACERT")
SSLCERT=$(base64 -w0 < "$FN_SSLCERT")
SSLKEY=$(base64 -w0 < "$FN_SSLKEY")
mkcert -install
# install in local store
cat $HOME/.local/share/mkcert/rootCA.pem >> /etc/ssl/certs/ca-certificates.crt
# also send root cert into a volume
cat $HOME/.local/share/mkcert/rootCA.pem > /var/gitpod/gitpod-ca.crt

cat << EOF > /var/lib/rancher/k3s/server/manifests/gitpod/customCA-cert.yaml
---
cat << EOF > /var/lib/rancher/k3s/server/manifests/ca-pair.yaml
apiVersion: v1
kind: Secret
metadata:
name: ca-cert
labels:
app: gitpod
name: ca-key-pair
data:
ca.crt: $CACERT
ca.crt: $(cat $HOME/.local/share/mkcert/rootCA.pem | base64 -w0)
tls.crt: $(cat $HOME/.local/share/mkcert/rootCA.pem | base64 -w0)
tls.key: $(cat $HOME/.local/share/mkcert/rootCA-key.pem | base64 -w0)
EOF

cat << EOF > /var/lib/rancher/k3s/server/manifests/gitpod/https-cert.yaml
---
apiVersion: v1
kind: Secret
cat << EOF > /var/lib/rancher/k3s/server/manifests/issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: https-cert
labels:
app: gitpod
data:
tls.crt: $SSLCERT
tls.key: $SSLKEY
name: ca-issuer
spec:
ca:
secretName: ca-key-pair
EOF

cat << EOF > /var/lib/rancher/k3s/server/manifests/gitpod/registry-cert.yaml
---
apiVersion: v1
kind: Secret
echo "creating Gitpod SSL secret..."
cat << EOF > /var/lib/rancher/k3s/server/manifests/https-cert.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: builtin-registry-certs
labels:
app: gitpod
data:
ca.crt: $CACERT
tls.crt: $SSLCERT
tls.key: $SSLKEY
EOF

cat << EOF > /var/lib/rancher/k3s/server/manifests/gitpod/manager-cert.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: ws-manager-client-tls
labels:
app: gitpod
data:
ca.crt: $CACERT
tls.crt: $SSLCERT
tls.key: $SSLKEY
EOF

cat << EOF > /var/lib/rancher/k3s/server/manifests/gitpod/ws-manager-cert.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: ws-manager-tls
labels:
app: gitpod
data:
ca.crt: $CACERT
tls.crt: $SSLCERT
tls.key: $SSLKEY
name: https-cert
spec:
secretName: https-certificates
issuerRef:
name: ca-issuer
kind: Issuer
dnsNames:
- "$DOMAIN"
- "*.$DOMAIN"
- "*.ws.$DOMAIN"
EOF

cat << EOF > /var/lib/rancher/k3s/server/manifests/gitpod/ws-daemon-cert.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: ws-daemon-tls
labels:
app: gitpod
data:
ca.crt: $CACERT
tls.crt: $SSLCERT
tls.key: $SSLKEY
EOF
mkdir -p /var/lib/rancher/k3s/server/manifests/gitpod

/gitpod-installer init > config.yaml
yq e -i '.domain = "'"$DOMAIN"'"' config.yaml
yq e -i ".certificate.name = \"https-cert\"" config.yaml
yq e -i ".certificate.name = \"https-certificates\"" config.yaml
yq e -i ".certificate.kind = \"secret\"" config.yaml
yq e -i ".customCACert.name = \"ca-cert\"" config.yaml
yq e -i ".customCACert.name = \"ca-key-pair\"" config.yaml
yq e -i ".customCACert.kind = \"secret\"" config.yaml
yq e -i ".observability.logLevel = \"debug\"" config.yaml
yq e -i '.workspace.runtime.containerdSocket = "/run/k3s/containerd/containerd.sock"' config.yaml
yq e -i '.workspace.runtime.containerdRuntimeDir = "/var/lib/rancher/k3s/agent/containerd/io.containerd.runtime.v2.task/k8s.io/"' config.yaml
yq e -i '.experimental.webapp.server.workspaceDefaults.workspaceImage = "docker.io/gitpod/workspace-base:latest"' config.yaml

echo "extracting images to download ahead..."
/gitpod-installer render --config config.yaml | grep 'image:' | sed 's/ *//g' | sed 's/image://g' | sed 's/\"//g' | sed 's/^-//g' | sort | uniq > /gitpod-images.txt
echo "downloading images..."
cat /gitpod-images.txt | while read image
do
ctr images pull $image &>/dev/null &
done

ctr images pull "docker.io/gitpod/workspace-base:latest" &>/dev/null &

/gitpod-installer render --config config.yaml --output-split-files /var/lib/rancher/k3s/server/manifests/gitpod
for f in /var/lib/rancher/k3s/server/manifests/gitpod/*.yaml; do (cat "$f"; echo) >> /var/lib/rancher/k3s/server/gitpod.debug; done
rm /var/lib/rancher/k3s/server/manifests/gitpod/*NetworkPolicy*
for f in /var/lib/rancher/k3s/server/manifests/gitpod/*PersistentVolumeClaim*.yaml; do yq e -i '.spec.storageClassName="local-path"' "$f"; done
yq eval-all -i '. as $item ireduce ({}; . *+ $item)' /var/lib/rancher/k3s/server/manifests/gitpod/*_StatefulSet_messagebus.yaml /app/manifests/messagebus.yaml
for f in /var/lib/rancher/k3s/server/manifests/gitpod/*StatefulSet*.yaml; do yq e -i '.spec.volumeClaimTemplates[0].spec.storageClassName="local-path"' "$f"; done

for f in /var/lib/rancher/k3s/server/manifests/gitpod/*.yaml; do (cat "$f"; echo) >> /var/lib/rancher/k3s/server/manifests/gitpod.yaml; done
rm -rf /var/lib/rancher/k3s/server/manifests/gitpod

# gitpod-helm-installer.yaml needs access to kubernetes by the public host IP.
kubeconfig_replacip() {
while [ ! -f /etc/rancher/k3s/k3s.yaml ]; do sleep 1; done
HOSTIP=$(hostname -i)
sed "s+127.0.0.1+$HOSTIP+g" /etc/rancher/k3s/k3s.yaml > /etc/rancher/k3s/k3s_.yaml
}
kubeconfig_replacip &

installation_completed_hook() {
echo "Waiting for pods to be ready ..."
kubectl wait --for=condition=ready pod -l app=gitpod --timeout 30s

echo "Removing network policies ..."
kubectl delete networkpolicies.networking.k8s.io --all

echo "Removing installer manifest ..."
rm -f /var/lib/rancher/k3s/server/manifests/gitpod.yaml
}
installation_completed_hook &

# add HTTPS certs secret
if [ -f /certs/chain.pem ] && [ -f /certs/dhparams.pem ] && [ -f /certs/fullchain.pem ] && [ -f /certs/privkey.pem ]; then
CHAIN=$(base64 --wrap=0 < /certs/chain.pem)
DHPARAMS=$(base64 --wrap=0 < /certs/dhparams.pem)
FULLCHAIN=$(base64 --wrap=0 < /certs/fullchain.pem)
PRIVKEY=$(base64 --wrap=0 < /certs/privkey.pem)
cat << EOF > /var/lib/rancher/k3s/server/manifests/proxy-config-certificates.yaml
apiVersion: v1
kind: Secret
metadata:
name: proxy-config-certificates
labels:
app: gitpod
data:
chain.pem: $CHAIN
dhparams.pem: $DHPARAMS
fullchain.pem: $FULLCHAIN
privkey.pem: $PRIVKEY
EOF
fi

# removing init container from ws-daemon (systemd and Ubuntu)
yq eval-all -i 'del(.spec.template.spec.initContainers[0])' /var/lib/rancher/k3s/server/manifests/gitpod/*_DaemonSet_ws-daemon.yaml

# patch DNS config
# if [ -n "$DOMAIN" ] && [ -n "$DNSSERVER" ]; then
# patchdns() {
# echo "Waiting for CoreDNS to patch config ..."
# while [ -z "$(kubectl get pods -n kube-system | grep coredns | grep Running)" ]; do sleep 10; done

# DOMAIN=$1
# DNSSERVER=$2

# if [ -z "$(kubectl get configmap -n kube-system coredns -o json | grep $DOMAIN)" ]; then
# echo "Patching CoreDNS config ..."

# kubectl get configmap -n kube-system coredns -o json | \
# sed -e "s+.:53+$DOMAIN {\\\\n forward . $DNSSERVER\\\\n}\\\\n.:53+g" | \
# kubectl apply -f -
# echo "CoreDNS config patched."
# else
# echo "CoreDNS has been patched already."
# fi
# }
# patchdns "$DOMAIN" "$DNSSERVER" &
# fi

for f in /var/lib/rancher/k3s/server/manifests/gitpod/*.yaml; do (cat "$f"; echo) >> /var/lib/rancher/k3s/server/manifests/gitpod.yaml; done
rm -rf /var/lib/rancher/k3s/server/manifests/gitpod

# start k3s
/bin/k3s server --disable traefik \
--node-label gitpod.io/workload_meta=true \
--node-label gitpod.io/workload_ide=true \
Expand Down