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 a 2i2c federation member on Hetzner #3169

Merged
merged 25 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ff2a59b
Add a 2i2c federation member on Hetzner
yuvipanda Jan 17, 2025
2a6581b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 17, 2025
bc9ef71
Credit 2i2c
yuvipanda Jan 17, 2025
d6ee272
Add 2i2c to redirector
yuvipanda Jan 17, 2025
4438b89
Setup a local docker registry for faster pushes / pulls
yuvipanda Jan 18, 2025
595601e
Fix network policy labels
yuvipanda Jan 18, 2025
c30441a
Add missing registry config
yuvipanda Jan 18, 2025
64e478f
Add note about local path provisioner
yuvipanda Jan 18, 2025
8fb4f33
Add note about docker registry config
yuvipanda Jan 18, 2025
b97f254
Add registry secrets
yuvipanda Jan 18, 2025
05ec4a4
Add encrypted ssh key for machine access
yuvipanda Jan 18, 2025
ce94809
Use hetzner object storage as backend for registry
yuvipanda Jan 19, 2025
5deee2e
Run two replicas of the registry
yuvipanda Jan 19, 2025
29b881a
Move storage config to right place
yuvipanda Jan 19, 2025
7832301
Add to wisdom
yuvipanda Jan 19, 2025
27a057a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 19, 2025
8490ecd
Add simple docs on k3s
yuvipanda Jan 19, 2025
dab0eb6
Add shared secret for registry load balancing
yuvipanda Jan 19, 2025
0f979e4
Actually add the 2i2c hetzner kubeconfig file
yuvipanda Jan 19, 2025
42a4edb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 19, 2025
51a756b
Add note about DNS
yuvipanda Jan 19, 2025
7122515
Switch to newer bigger Hetzner machine
yuvipanda Jan 21, 2025
42764ea
Bump up nginx memory limit
yuvipanda Jan 21, 2025
0212202
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 21, 2025
c4402bc
add hetzner-2i2c to deployment workflow
minrk Jan 21, 2025
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
128 changes: 128 additions & 0 deletions config/hetzner-2i2c.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
projectName: hetzner-2i2c

registry:
enabled: true
storage:
filesystem:
storageClassName: "local-path"
ingress:
hosts:
- registry.2i2c.mybinder.org

cryptnono:
detectors:
monero:
enabled: false

binderhub:
config:
BinderHub:
hub_url: https://hub.2i2c.mybinder.org
badge_base_url: https://mybinder.org
sticky_builds: true
image_prefix: registry.2i2c.mybinder.org/i-
# image_prefix: quay.io/mybinder-hetzner-2i2c/image-
# build_docker_host: /var/run/dind/docker.sock
# TODO: we should have CPU requests, too
# use this to limit the number of builds per node
# complicated: dind memory request + KubernetesBuildExecutor.memory_request * builds_per_node ~= node memory
KubernetesBuildExecutor:
memory_request: "2G"
docker_host: /var/run/dind/docker.sock

LaunchQuota:
total_quota: 300

# DockerRegistry:
# token_url: "https://2lmrrh8f.gra7.container-registry.ovh.net/service/token?service=harbor-registry"

replicas: 1

extraVolumes:
- name: secrets
secret:
secretName: events-archiver-secrets
extraVolumeMounts:
- name: secrets
mountPath: /secrets
readOnly: true
extraEnv:
GOOGLE_APPLICATION_CREDENTIALS: /secrets/service-account.json

dind: {}

ingress:
hosts:
- 2i2c.mybinder.org

jupyterhub:
# proxy:
# chp:
# resources:
# requests:
# cpu: "1"
# limits:
# cpu: "1"
ingress:
hosts:
- hub.2i2c.mybinder.org
tls:
- secretName: kubelego-tls-hub
hosts:
- hub.2i2c.mybinder.org

imageCleaner:
# Use 40GB as upper limit, size is given in bytes
imageGCThresholdHigh: 40e9
imageGCThresholdLow: 30e9
imageGCThresholdType: "absolute"

grafana:
ingress:
hosts:
- grafana.2i2c.mybinder.org
tls:
- hosts:
- grafana.2i2c.mybinder.org
secretName: kubelego-tls-grafana
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: prometheus
orgId: 1
type: prometheus
url: https://prometheus.2i2c.mybinder.org
access: direct
isDefault: true
editable: false
# persistence:
# storageClassName: csi-cinder-high-speed

prometheus:
server:
persistentVolume:
size: 50Gi
retention: 30d
ingress:
hosts:
- prometheus.2i2c.mybinder.org
tls:
- hosts:
- prometheus.2i2c.mybinder.org
secretName: kubelego-tls-prometheus

ingress-nginx:
controller:
replicas: 1
scope:
enabled: true
service:
loadBalancerIP: 138.199.149.127

static:
ingress:
hosts:
- static.2i2c.mybinder.org
tls:
secretName: kubelego-tls-static
10 changes: 8 additions & 2 deletions config/prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,16 @@ federationRedirect:
weight: 0
health: https://gke.mybinder.org/health
versions: https://gke.mybinder.org/versions
gesis:
hetzner-2i2c:
prime: true
url: https://notebooks.gesis.org/binder
url: https://2i2c.mybinder.org
weight: 60
health: https://2i2c.mybinder.org/health
versions: https://2i2c.mybinder.org/versions
gesis:
prime: false
url: https://notebooks.gesis.org/binder
weight: 40
health: https://notebooks.gesis.org/binder/health
versions: https://notebooks.gesis.org/binder/versions
ovh2:
Expand Down
29 changes: 12 additions & 17 deletions deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
"prod": "us-central1",
}

# Projects using raw KUBECONFIG files
KUBECONFIG_CLUSTERS = {"ovh2", "hetzner-2i2c"}

# Mapping of config name to cluster name for AWS EKS deployments
AWS_DEPLOYMENTS = {"curvenote": "binderhub"}

Expand Down Expand Up @@ -100,17 +103,15 @@ def setup_auth_azure(cluster, dry_run=False):
print(stdout)


def setup_auth_ovh(release, cluster, dry_run=False):
def setup_auth_kubeconfig(release, cluster, dry_run=False):
"""
Set up authentication with 'ovh' K8S from the ovh-kubeconfig.yml
Setup authentication with a pure kubeconfig file
"""
print(f"Setup the OVH authentication for namespace {release}")
print(f"Setup authentication for namespace {release} with kubeconfig")

ovh_kubeconfig = os.path.join(ABSOLUTE_HERE, "secrets", f"{release}-kubeconfig.yml")
os.environ["KUBECONFIG"] = ovh_kubeconfig
print(f"Current KUBECONFIG='{ovh_kubeconfig}'")
stdout = check_output(["kubectl", "config", "use-context", cluster], dry_run)
print(stdout)
kubeconfig = os.path.join(ABSOLUTE_HERE, "secrets", f"{release}-kubeconfig.yml")
os.environ["KUBECONFIG"] = kubeconfig
print(f"Current KUBECONFIG='{kubeconfig}'")


def setup_auth_gcloud(release, cluster=None, dry_run=False):
Expand Down Expand Up @@ -436,13 +437,7 @@ def main():
argparser.add_argument(
"release",
help="Release to deploy",
choices=[
"staging",
"prod",
"ovh",
"ovh2",
"curvenote",
],
choices=["staging", "prod", "ovh", "ovh2", "curvenote", "hetzner-2i2c"],
)
argparser.add_argument(
"--name",
Expand Down Expand Up @@ -511,8 +506,8 @@ def main():
# script is running on CI, proceed with auth and helm setup

if args.stage in ("all", "auth"):
if cluster.startswith("ovh"):
setup_auth_ovh(args.release, cluster, args.dry_run)
if cluster in KUBECONFIG_CLUSTERS:
setup_auth_kubeconfig(args.release, cluster, args.dry_run)
patch_coredns(args.dry_run, args.diff)
elif cluster in AZURE_RGs:
setup_auth_azure(cluster, args.dry_run)
Expand Down
4 changes: 2 additions & 2 deletions mybinder/templates/netpol.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ spec:
to:
- podSelector:
matchLabels:
app: nginx-ingress
component: controller
app.kubernetes.io/component: controller
app.kubernetes.io/name: ingress-nginx

{{- end }}
13 changes: 13 additions & 0 deletions mybinder/templates/registry/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if .Values.registry.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: registry-config
labels:
app: registry
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
data:
config.yml: |
{{ .Values.registry.config | toJson }}
{{- end }}
56 changes: 56 additions & 0 deletions mybinder/templates/registry/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{{- if .Values.registry.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: registry
labels:
app: registry
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: registry
spec:
replicas: {{ .Values.registry.replicas }}
selector:
matchLabels:
app: registry
release: {{ .Release.Name }}
component: registry
template:
metadata:
annotations:
checksum/registry-config: {{ include (print $.Template.BasePath "/registry/configmap.yaml") . | sha256sum }}
labels:
app: registry
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: registry
spec:
automountServiceAccountToken: false
nodeSelector: {{ toJson .Values.registry.nodeSelector }}
volumes:
- name: registry-config
configMap:
name: registry-config
- name: registry-secret
secret:
secretName: registry-secret
- name: registry-storage
persistentVolumeClaim:
claimName: registry
containers:
- name: registry
image: registry:2.8.3
Copy link
Member

Choose a reason for hiding this comment

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

In a future PR we should add this to the watch-dependencies workflow

strategy:
fail-fast: false
matrix:
include:
- name: repo2docker
registry: quay.io
repository: jupyterhub/repo2docker

volumeMounts:
- name: registry-config
mountPath: /etc/distribution/config.yml
subPath: config.yml
- name: registry-storage
mountPath: /var/lib/registry
- name: registry-secret
mountPath: /etc/distribution/auth.htpasswd
subPath: auth.htpasswd
{{- with .Values.registry.resources }}
resources:
{{- . | toYaml | nindent 10 }}
{{- end }}
{{- end }}
35 changes: 35 additions & 0 deletions mybinder/templates/registry/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{{- if .Values.registry.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: registry
labels:
app: registry
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
kubernetes.io/tls-acme: "true"
# things be big yo
nginx.ingress.kubernetes.io/proxy-body-size: 4096m
spec:
ingressClassName: nginx
rules:
{{- range $host := .Values.registry.ingress.hosts }}
- host: {{ $host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: registry
port:
number: 5000
{{- end }}
tls:
- secretName: tls-registry
hosts:
{{- range $host := .Values.registry.ingress.hosts }}
- {{ $host }}
{{- end }}
{{- end }}
17 changes: 17 additions & 0 deletions mybinder/templates/registry/pvc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{- if .Values.registry.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: registry
labels:
app: registry
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
storageClassName: {{ .Values.registry.storage.filesystem.storageClassName }}
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.registry.storage.filesystem.size }}
{{- end }}
13 changes: 13 additions & 0 deletions mybinder/templates/registry/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if .Values.registry.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: registry-secret
labels:
app: registry
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
type: Opaque
data:
auth.htpasswd: {{ htpasswd .Values.registry.auth.username .Values.registry.auth.password | b64enc }}
{{- end }}
20 changes: 20 additions & 0 deletions mybinder/templates/registry/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{{- if .Values.registry.enabled }}
apiVersion: v1
kind: Service
metadata:
name: registry
labels:
app: registry
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
type: {{ .Values.registry.service.type }}
selector:
app: registry
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
ports:
- name: registry
protocol: TCP
port: 5000
{{- end }}
Loading