(setup-k8s-beamline)= # Create a Kubernetes Beamline :::{warning} **DLS users:** beamlines and accelerators are set up through the internal developer guide at , not these public cluster steps. Follow along on your own test cluster only. ::: So far the tutorials have deployed IOCs to the local podman instance on your workstation with `docker compose`. This tutorial creates a **services repository** that deploys into a Kubernetes cluster instead, using Helm. By the end you will have: - a services repo, `t02-services`, generated from [`services-template-helm`](https://github.com/epics-containers/services-template-helm); - the shared beamline services `t02-epics-pvcs` and `t02-epics-opis` running in your cluster; - the `ec` CLI configured to deploy and manage services in your namespace. The worked example uses the domain **`t02`** (beamline **`bl02t`**) and the namespace **`t02-beamline`** created in {any}`setup-kubernetes`. Substitute your own names throughout. :::{note} A Helm/Kubernetes services repo has the same shape as the `docker compose` one from {any}`create-beamline`: a `services/` folder with one deployable unit per subfolder. The difference is that each unit is a **Helm chart** (a `Chart.yaml` plus a `values.yaml`) rather than a `compose.yaml`, and `services/values.yaml` holds the defaults shared by every chart. ::: ## Prerequisites - A Kubernetes cluster with a namespace for your beamline. {any}`setup-kubernetes` sets up a single-node k3s cluster plus the `t02-beamline` namespace and context. - A workstation with `ec`, `copier`, `git` and `kubectl` (see {any}`setup_workstation`). ## Scaffold the services repo Generate the repo from the template with `copier` (the flow mirrors {any}`create-beamline`): ```bash copier copy https://github.com/epics-containers/services-template-helm t02-services ``` Answer the prompts as follows for a local k3s cluster: | Prompt | Worked-example answer | |---|---| | `domain` | `t02` | | `description` | *(accept default — `t02 IOC Instances and Services`)* | | `location` | `bl02t` | | `cluster_name` | `local` *(any lower-case name for your cluster)* | | `cluster_namespace` | `t02-beamline` | | `git_platform` | `github.com` | | `gateway` | `No` *(k3s uses host networking — see below)* | | `athena_services` | *(leave blank)* | | `logging_url` | `Skip` | :::{note} The template defines copier **migration scripts** that run when you later bring the repo up to a newer template version with `copier update`. Those scripts require the `--trust` flag, i.e. `copier update --trust`. ::: Create the repo on GitHub () named `t02-services`, then commit and push: ```bash cd t02-services git init -b main git add . git commit -m "initial commit" git remote add origin https://github.com//t02-services git push -u origin main ``` ## Configure the ec CLI `ec` wraps `helm` and `kubectl` to deploy and manage services. Install it if you do not have it already, then source the generated `environment.sh` from inside the repo: ```bash # install ec if needed (see the workstation setup) uv tool install edge-containers-cli # from inside the t02-services directory: source ./environment.sh ``` `environment.sh` configures `ec` for this repo by exporting: ```bash export EC_CLI_BACKEND=K8S # deploy with Helm/kubectl export EC_TARGET=t02-beamline # your namespace export EC_SERVICES_REPO=https://github.com//t02-services export EC_LOG_URL= # central log server (blank) ``` It also checks that `ec` is installed and enables shell completion. For the full command and environment-variable reference see {any}`edge-containers-cli`. ## Deploy the shared services Every beamline namespace needs two shared services, both generated by the template: - **`t02-epics-pvcs`** — persistent volumes where IOCs store autosave files, generated GUIs and other data. - **`t02-epics-opis`** — an nginx server that serves those GUI files. `ec` deploys a service at a **git tag** of the repo, so tag the current state first: ```bash git tag 2026.7.1 git push origin 2026.7.1 ``` Then deploy each service at that tag (`-v` prints the underlying helm/kubectl commands): ```bash ec -v deploy t02-epics-pvcs 2026.7.1 ec -v deploy t02-epics-opis 2026.7.1 ``` :::{note} On a local k3s cluster the template sets `hostNetwork: true` (in `services/values.yaml`), so Channel Access reaches your workstation directly and no gateway is needed. Clusters that forbid host networking — including DLS personal namespaces — instead run a Channel Access gateway; answer **Yes** to the `gateway` prompt to have the template generate one. ::: ## Check the deployment List what is running in your namespace: ```bash ec ps ``` ```text name label version ready deployed t02-epics-pvcs service 2026.7.1 True 2026-07-01T09:10:00Z t02-epics-opis service 2026.7.1 True 2026-07-01T09:11:00Z ``` Run `ec --help` to explore the other commands (`ec logs`, `ec exec`, `ec monitor`, `ec stop`/`start`/`delete`). :::{note} When something will not start, inspect the underlying resources with `kubectl describe pod `, or browse them in the Kubernetes dashboard (see {any}`k8s-dashboard` for the local-cluster install). ::: ## Next steps - {any}`add_k8s_ioc` — add your own IOC instance to this beamline. - {any}`deploy-argocd` — drive a services repo through ArgoCD (GitOps continuous deployment) instead of deploying by hand. - {any}`helm` — the pure-Helm reference for what `ec deploy` runs under the hood.