From 2db9085ec75e2b93703b9b608a76a0b99aa7680a Mon Sep 17 00:00:00 2001 From: YuviPanda Date: Wed, 6 Dec 2023 13:30:15 -0800 Subject: [PATCH 1/2] Fix binder-staging so launches succeed Just porting over changes we had in our basehub chart that were missing, to deal with some breaking changes in kubespawner Ref https://github.com/2i2c-org/infrastructure/issues/3508 --- helm-charts/binderhub/values.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/helm-charts/binderhub/values.yaml b/helm-charts/binderhub/values.yaml index 887044dbe4..50d43833a8 100644 --- a/helm-charts/binderhub/values.yaml +++ b/helm-charts/binderhub/values.yaml @@ -99,17 +99,15 @@ binderhub: # # DASK_GATEWAY__CLUSTER__OPTIONS__IMAGE makes the default worker image # match the singleuser image. - DASK_GATEWAY__CLUSTER__OPTIONS__IMAGE: "{JUPYTER_IMAGE_SPEC}" + DASK_GATEWAY__CLUSTER__OPTIONS__IMAGE: "{{JUPYTER_IMAGE_SPEC}}" # DASK_GATEWAY__CLUSTER__OPTIONS__ENVIRONMENT makes some environment # variables be copied over to the worker nodes from the user nodes. - DASK_GATEWAY__CLUSTER__OPTIONS__ENVIRONMENT: - '{"SCRATCH_BUCKET": "$(SCRATCH_BUCKET)", - "PANGEO_SCRATCH": "$(PANGEO_SCRATCH)"}' + DASK_GATEWAY__CLUSTER__OPTIONS__ENVIRONMENT: '{{"SCRATCH_BUCKET": "$(SCRATCH_BUCKET)", "PANGEO_SCRATCH": "$(PANGEO_SCRATCH)"}}' # DASK_DISTRIBUTED__DASHBOARD__LINK makes the suggested link to the # dashboard account for the /user/ prefix in the path. Note # that this still misbehave if you have a named server but now its at # least functional for non-named servers. - DASK_DISTRIBUTED__DASHBOARD__LINK: "/user/{JUPYTERHUB_USER}/proxy/{port}/status" + DASK_DISTRIBUTED__DASHBOARD__LINK: "/user/{{JUPYTERHUB_USER}}/proxy/{{port}}/status" extraFiles: jupyter_notebook_config.json: mountPath: /usr/local/etc/jupyter/jupyter_notebook_config.json From 97c26f74a84c971445e15a69f7530e137e39682f Mon Sep 17 00:00:00 2001 From: YuviPanda Date: Wed, 6 Dec 2023 15:58:04 -0800 Subject: [PATCH 2/2] Setup agu-binder for AGU 2023 - Puts it on its own nodepool, with ssd disk for much faster spinup time. - CILogon authentication for now, with just 2i2c accounts allow_listed. We will open this up soon. - Automatically redirects you to login as soon as you hit the URL. This is a bit jarring, so perhaps we shall figure a better landing page there. - A new repo has templates that customize the binderhub template, at https://github.com/2i2c-org/agu-binder-custom-templates. Currently there are no customizations, but this will change. - No resource differences right now, but will probably be given more resources than usual. Ref https://github.com/2i2c-org/infrastructure/issues/3508 --- config/clusters/2i2c/agu-binder.values.yaml | 102 ++++++++++++++++++ config/clusters/2i2c/cluster.yaml | 7 ++ .../2i2c/enc-agu-binder.secret.values.yaml | 24 +++++ helm-charts/binderhub/values.yaml | 2 + terraform/gcp/cluster.tf | 13 +-- terraform/gcp/projects/pilot-hubs.tfvars | 21 +++- terraform/gcp/variables.tf | 10 ++ 7 files changed, 167 insertions(+), 12 deletions(-) create mode 100644 config/clusters/2i2c/agu-binder.values.yaml create mode 100644 config/clusters/2i2c/enc-agu-binder.secret.values.yaml diff --git a/config/clusters/2i2c/agu-binder.values.yaml b/config/clusters/2i2c/agu-binder.values.yaml new file mode 100644 index 0000000000..99fa3a3e5b --- /dev/null +++ b/config/clusters/2i2c/agu-binder.values.yaml @@ -0,0 +1,102 @@ +binderhub: + dind: + # This has to be separate for each binderhub we run on the same cluster + hostSocketDir: /var/run/agu-binder/dind + hostLibDir: /var/lib/agu-binder/dind + ingress: + hosts: + - agu-binder.2i2c.cloud + tls: + - secretName: https-auto-tls + hosts: + - agu-binder.2i2c.cloud + registry: + url: https://us-central1-docker.pkg.dev + config: + DockerRegistry: + token_url: https://us-central1-docker.pkg.dev/v2/token?service= + BinderHub: + # The URL set as jupyterhub.ingress.hosts[0] in this config + auth_enabled: true + hub_url: https://hub.agu-binder.2i2c.cloud + image_prefix: us-central1-docker.pkg.dev/two-eye-two-see/agu-binder-registry/ + template_path: /etc/binderhub/custom/templates + extra_static_path: /etc/binderhub/custom/static + extra_static_url_prefix: /extra_static/ + about_message: | +

agu-binder.2i2c.cloud is operated by the 2i2c team for AGU 2023.

+ initContainers: + - name: git-clone-templates + image: alpine/git + args: + - clone + - --single-branch + - --branch=master + - --depth=1 + - -- + - https://github.com/2i2c-org/agu-binder-custom-templates + - /etc/binderhub/custom + securityContext: + runAsUser: 0 + volumeMounts: + - name: custom-templates + mountPath: /etc/binderhub/custom + extraVolumes: + - name: custom-templates + emptyDir: {} + extraVolumeMounts: + - name: custom-templates + mountPath: /etc/binderhub/custom + + jupyterhub: + ingress: + enabled: true + hosts: + - hub.agu-binder.2i2c.cloud + tls: + - secretName: https-auto-tls-hub-binder + hosts: + - hub.agu-binder.2i2c.cloud + hub: + redirectToServer: false + services: + binder: + oauth_client_id: service-binderhub + oauth_no_confirm: true + oauth_redirect_uri: "https://agu-binder.2i2c.cloud/oauth_callback" + loadRoles: + user: + scopes: + - self + - "access:services" + config: + BinderSpawner: + auth_enabled: true + JupyterHub: + authenticator_class: cilogon + CILogonOAuthenticator: + oauth_callback_url: "https://hub.agu-binder.2i2c.cloud/hub/oauth_callback" + allowed_idps: + http://google.com/accounts/o8/id: + username_derivation: + username_claim: "email" + Authenticator: + admin_users: + - choldgraf@2i2c.org + - colliand@2i2c.org + - damianavila@2i2c.org + - erik@2i2c.org + - georgianaelena@2i2c.org + - jmunroe@2i2c.org + - sgibson@2i2c.org + - yuvipanda@2i2c.org + singleuser: + nodeSelector: + 2i2c.org/community: agu-binder + extraTolerations: + - key: "2i2c.org/community" + operator: "Equal" + value: "agu-binder" + effect: "NoSchedule" + # to make notebook servers aware of hub + cmd: jupyterhub-singleuser diff --git a/config/clusters/2i2c/cluster.yaml b/config/clusters/2i2c/cluster.yaml index 4151b30592..3565e3864c 100644 --- a/config/clusters/2i2c/cluster.yaml +++ b/config/clusters/2i2c/cluster.yaml @@ -40,6 +40,13 @@ hubs: helm_chart_values_files: - binder-staging.values.yaml - enc-binder-staging.secret.values.yaml + - name: agu-binder + display_name: "2i2c AGU Demo Binder" + domain: agu-binder.2i2c.cloud + helm_chart: binderhub + helm_chart_values_files: + - agu-binder.values.yaml + - enc-agu-binder.secret.values.yaml - name: imagebuilding-demo display_name: "2i2c image building demo" domain: imagebuilding-demo.2i2c.cloud diff --git a/config/clusters/2i2c/enc-agu-binder.secret.values.yaml b/config/clusters/2i2c/enc-agu-binder.secret.values.yaml new file mode 100644 index 0000000000..023edea190 --- /dev/null +++ b/config/clusters/2i2c/enc-agu-binder.secret.values.yaml @@ -0,0 +1,24 @@ +binderhub: + registry: + username: ENC[AES256_GCM,data:J8Do9728Flzx,iv:xc9O7QLsxCj1ihu+Sax2wNEBgT4rxt3gYhVhRkeVcgg=,tag:pG/ISFKpRJWGKFA49Qd11g==,type:str] + password: ENC[AES256_GCM,data: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,iv:rLpuwMEoJryf3Xh+MksFRhr3ekbCXyOm7kTsVFYuhUI=,tag:Qz/6pJh6WOPzbbz6yQ/CjA==,type:str] + jupyterhub: + hub: + config: + CILogonOAuthenticator: + client_id: ENC[AES256_GCM,data:IB5AfR1TPYSoAbIPR2Uunb/nlqxZRHyR8NwhHDiJiYTMtKDrmPTB/7aEbvZVxK4DQq+E,iv:oODyyF9jfZwQF/4v1wNNsXFDK9cAWUYlhNw/EESWeDA=,tag:kuh1jICGg6TOPK9wVkYWtw==,type:str] + client_secret: ENC[AES256_GCM,data:grQBxNNENGKMe7Jm/bhrQFKgCmWUsvA16Kg0cDHHF7eVIaaMYNclNIsoZkEcTay/EVZfvjPgstG+t2j85kmAmVSz/PHQRFG5pOB5Lud9GWY28/ANCg4=,iv:duVks5blb7Yu1nvZk0eowndbNXNN87NKQMEEn89rOL0=,tag:5eL3ZWAMaj5535nfrX6MQA==,type:str] +sops: + kms: [] + gcp_kms: + - resource_id: projects/two-eye-two-see/locations/global/keyRings/sops-keys/cryptoKeys/similar-hubs + created_at: "2023-12-06T23:25:45Z" + enc: CiUA4OM7eKXCQVwUHjh2yd/0/ogofhfHGPqvEvLmN24jAnxJFywOEkgAjTWv+niyZUOfBHbu09dctaM4bVQNHckAweQtdeuew5OY3Ienk1ivzRb7o37En5OvirSQn/4Xk/GsZ+R+ZzjKFM/2d1aTbKo= + azure_kv: [] + hc_vault: [] + age: [] + lastmodified: "2023-12-06T23:34:23Z" + mac: ENC[AES256_GCM,data:hGrhZGDCvpmACopyQsEBLt6gH/fzYwKIMcEL0DrJW9nBk1n1YBOD4TRRP6vnUwiTLbmGzIRPmjn5JeXmMgmogr/436JHifoexWmBTE+8iXoIRHHfBATjW1L/ivFk740Bp7bI1ZEkLbsKscssUiczM6GI5B7kbtNRf0BVxSHhkDU=,iv:axEVH1i9qb2YzDiuSw0V1+/p0b9W6uLvKF7tm8grZ0U=,tag:6bHKRcsI9bN2AuGeLeZR1g==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3 diff --git a/helm-charts/binderhub/values.yaml b/helm-charts/binderhub/values.yaml index 50d43833a8..13114acfde 100644 --- a/helm-charts/binderhub/values.yaml +++ b/helm-charts/binderhub/values.yaml @@ -174,6 +174,8 @@ binderhub: app.kubernetes.io/component: traefik hub: config: + Authenticator: + auto_login: true JupyterHub: # Allow unauthenticated prometheus requests # Otherwise our prometheus server can't get hub metrics diff --git a/terraform/gcp/cluster.tf b/terraform/gcp/cluster.tf index e30fa73b13..f4238f00bc 100644 --- a/terraform/gcp/cluster.tf +++ b/terraform/gcp/cluster.tf @@ -283,12 +283,7 @@ resource "google_container_node_pool" "notebook" { node_config { - - # Balanced disks are much faster than standard disks, and much cheaper - # than SSD disks. It contributes heavily to how fast new nodes spin up, - # as images being pulled takes up a lot of new node spin up time. - # Faster disks provide faster image pulls! - disk_type = "pd-balanced" + disk_type = each.value.disk_type dynamic "guest_accelerator" { for_each = each.value.gpu.enabled ? [1] : [] @@ -388,11 +383,7 @@ resource "google_container_node_pool" "dask_worker" { preemptible = each.value.preemptible - # Balanced disks are much faster than standard disks, and much cheaper - # than SSD disks. It contributes heavily to how fast new nodes spin up, - # as images being pulled takes up a lot of new node spin up time. - # Faster disks provide faster image pulls! - disk_type = "pd-balanced" + disk_type = each.value.disk_type workload_metadata_config { # Config Connector requires workload identity to be enabled (via GKE_METADATA_SERVER). diff --git a/terraform/gcp/projects/pilot-hubs.tfvars b/terraform/gcp/projects/pilot-hubs.tfvars index 6081b6a570..37994fa40f 100644 --- a/terraform/gcp/projects/pilot-hubs.tfvars +++ b/terraform/gcp/projects/pilot-hubs.tfvars @@ -102,7 +102,25 @@ notebook_nodes = { resource_labels : { "community" : "temple" }, - } + }, + "agu-binder" : { + min : 0, + max : 100, + machine_type : "n2-highmem-8", + node_version : "1.26.4-gke.1400", + disk_type : "pd-ssd", + labels : { + "2i2c.org/community" : "agu-binder" + }, + taints : [{ + key : "2i2c.org/community", + value : "agu-binder", + effect : "NO_SCHEDULE" + }], + resource_labels : { + "community" : "agu-binder" + }, + }, } # Setup a single node pool for dask workers. @@ -152,4 +170,5 @@ hub_cloud_permissions = { container_repos = [ "pilot-hubs", "binder-staging", + "agu-binder" ] diff --git a/terraform/gcp/variables.tf b/terraform/gcp/variables.tf index 0acd6963f3..8d89320b5b 100644 --- a/terraform/gcp/variables.tf +++ b/terraform/gcp/variables.tf @@ -89,6 +89,11 @@ variable "notebook_nodes" { value : string, effect : string })), []) + # Balanced disks are much faster than standard disks, and much cheaper + # than SSD disks. It contributes heavily to how fast new nodes spin up, + # as images being pulled takes up a lot of new node spin up time. + # Faster disks provide faster image pulls! + disk_type : optional(string, "pd-balanced"), gpu : optional( object({ enabled : optional(bool, false), @@ -120,6 +125,11 @@ variable "dask_nodes" { value : string, effect : string })), []) + # Balanced disks are much faster than standard disks, and much cheaper + # than SSD disks. It contributes heavily to how fast new nodes spin up, + # as images being pulled takes up a lot of new node spin up time. + # Faster disks provide faster image pulls! + disk_type : optional(string, "pd-balanced"), gpu : optional( object({ enabled : optional(bool, false),