blob: d98a6057df5d57aaa1d8e49f209d6788ed0ecce3 [file] [view]
# Upgrade
How to run `helm upgrade` on this chart, and the breaking changes chart 5.0.0 brings — the booster
UI removal, the OAP 11 dashboard-template changes, and the new `ui.config` default.
## Run the upgrade
```shell
helm upgrade skywalking oci://docker.io/apache/skywalking-helm \
--version 5.0.0 -n skywalking \
--set oap.image.tag=11.0.0 \
--set oap.storageType=banyandb \
--set ui.image.tag=horizon-1.0.0 \
--set elasticsearch.enabled=false \
--set banyandb.enabled=true \
--set banyandb.image.tag=0.11.0 \
--wait --wait-for-jobs
```
Three values have no defaults and must be present on **every** upgrade, not just the first install:
| value | example |
|---|---|
| `oap.image.tag` | `11.0.0` |
| `oap.storageType` | `elasticsearch`, `postgresql`, `banyandb` |
| `ui.image.tag` | `horizon-1.0.0` (only when `ui.enabled` is true) |
`helm upgrade` does not remember `--set` flags from the previous release, so either repeat them,
pass a values file with `-f`, or add `--reuse-values`. `--wait-for-jobs` alongside `--wait` makes
Helm report an init-Job failure directly instead of leaving you to guess why OAP never went Ready.
## Chart 5.0.0 is a version set
OAP and BanyanDB are hard-coupled and must move together — that pair is the most common upgrade
failure. Horizon releases independently of OAP (1.0.0 covers both OAP 10.4.0 and 11.x), so its tag
is pinned separately, but it must be a `horizon-*` tag: the chart no longer supports booster UI.
| component | value | version |
|---|---|---|
| chart | `--version` | `5.0.0` |
| OAP | `oap.image.tag` | `11.0.0` |
| Horizon UI | `ui.image.tag` | `horizon-1.0.0` |
| BanyanDB | `banyandb.image.tag` | `0.11.0` |
OAP ships the BanyanDB server API versions it accepts in
`SW_STORAGE_BANYANDB_COMPATIBLE_SERVER_API_VERSIONS`. OAP 11.0.0 accepts API `0.11`, which maps to
BanyanDB release `0.11.x`. The check is an exact string match with no lenient fallback, so OAP 11
against BanyanDB 0.10.x refuses to start with `Incompatible BanyanDB server API version`. The
mapping is published at
[BanyanDB API versions](https://skywalking.apache.org/docs/skywalking-banyandb/latest/installation/versions/);
see also [BanyanDB](../storage/banyandb.md).
The bump from `4.9.0` to `5.0.0` is a major one because the UI image line, several `values.yaml`
keys and the init Job's identity all changed incompatibly. The rest of this page is that list.
## Breaking: booster UI is gone
OAP 11 deleted `apm-webapp` — the Armeria reverse proxy behind the `skywalking/ui` image — along
with the `skywalking-ui` git submodule and the `docker.ui` Maven target. The last booster image
published to `apache/skywalking-ui` is `10.4.0`; there is no `11.x` tag and there will not be one.
Only `horizon-*` tags are published going forward.
What to change when coming from a release that ran booster UI:
| | before (4.9.0) | after (5.0.0) |
|---|---|---|
| image tag | `ui.image.tag=<oap-version>` | `ui.image.tag=horizon-1.0.0` |
| container port | `8080` | `8081` (`ui.service.internalPort`; Service still fronts `80`) |
| OAP admin port | no `oap.ports.admin` key at all | `oap.ports.admin: 17128`, required |
| login | none — booster was unauthenticated | must be configured — no fallback |
| `/graphql` on the UI | proxied to OAP | **not proxied**; call OAP directly |
| UI env | `ui.env` (map); chart set `SW_OAP_ADDRESS` / `SW_ZIPKIN_ADDRESS` | `ui.extraEnv` (list) and `ui.envFromSecret`; OAP URLs come from the `horizon.yaml` ConfigMap |
| Zipkin port keys | `oap.ports.zipkinreceiver` / `zipkinquery` | `oap.ports.zipkin-receiver` / `zipkin-query` |
`ui.env` no longer exists — a values file that still sets it renders nothing and the BFF gets no
extra environment. The Zipkin keys were renamed too: `oap-deployment.yaml` reads them as
`zipkin-receiver` / `zipkin-query`, so a carried-over `zipkinquery` still opens a container port but
no longer sets `SW_QUERY_ZIPKIN` / `SW_QUERY_ZIPKIN_REST_PORT`, and the UI's `oap.zipkinUrl` is not
derived.
**Configure logins before you cut over.** Horizon has no built-in `admin/admin`, and the BFF does
**not** fail closed: with no users it boots, logs an error, serves the login page, and answers
`/api/auth/health` with 200 — which is the chart's own readiness probe. The pod goes Ready and
nobody can sign in. See [Set Up Logins](../ui/logins.md).
**Expose the OAP admin port.** OAP 11 serves `/status/*` and `/debugging/*` on the admin REST port
only, and Horizon's BFF reads inspect, DSL debugging, runtime rules and (in the default
`templates.mode: live`) the dashboard template store from it. `oap.ports.admin` defaults to `17128`;
set it to `null` on any OAP 10.x release — the admin server is an OAP 11 addition.
**Retarget `swctl` and any other GraphQL caller.** The BFF does not pass `/graphql` through to OAP,
so anything that used to query the UI must address the OAP Service:
```shell
# before
swctl --base-url=http://skywalking-skywalking-helm-ui/graphql service ls
# after — OAP directly, on oap.ports.rest
swctl --display yaml \
--base-url=http://skywalking-skywalking-helm-oap:12800/graphql \
service ls
```
Point it at the OAP Service on `12800`; copy the form from
there if you need the in-cluster hostname pattern.
### Upgrading the UI first
Horizon 1.0.0 runs against OAP 10.4.0 as well as OAP 11.x, so you can split the move in two: swap
the UI while still on OAP 10, then upgrade OAP. On OAP 10 add one setting, because OAP 10 does not
serve the `/ui-management` REST API Horizon reads templates from:
```shell
--set ui.config.templates.mode=readonly
```
That renders the templates bundled in the image and makes the configuration surface display-only.
Dashboards, traces, logs, topology, alarms and profiling all work. Remove it once OAP is on 11. The
mode is read at boot, so it needs a BFF restart — the UI Deployment's `checksum/config` annotation
rolls the pod for you whenever the ConfigMap changes.
## Breaking: OAP 11 removed the UI template seeds
These OAP-side surfaces went with the bundled UI. If your values still set them, they are read by
nothing — delete them:
| removed | where it used to live |
|---|---|
| `ui-initialized-templates` | a key under `oap.config`, seeding on-disk dashboard JSON |
| `SW_ENABLE_UPDATE_UI_TEMPLATE` | an env var under `oap.env` |
| sidebar menu storage | OAP storage |
| `UIConfigurationManagement` GraphQL queries and mutations | OAP query API |
The on-disk dashboard seed files were deleted along with `UITemplateInitializer`. Horizon ships its
own dashboard library and manages templates over the admin REST port instead — that is what
`oap.ports.admin` and `ui.config.templates.mode` are for.
## Breaking: `ui.config` is empty by default
The interim Horizon work on `main` mounted a ConfigMap of literal values over `/app/horizon.yaml`.
As of 5.0.0 `ui.config` defaults to `{}` and the ConfigMap carries only the fields the chart has to
compute:
| field | derived from |
|---|---|
| `oap.queryUrl` | the in-cluster OAP Service and `oap.ports.rest` |
| `oap.adminUrl` | the in-cluster OAP Service and `oap.ports.admin` |
| `oap.zipkinUrl` | the OAP Service and `oap.ports.zipkin-query`, only when that port is set |
| `server.publicUrl` | the first `ui.ingress.hosts` entry, only when `ui.ingress.enabled` and `ui.ingress.hosts` are both set (`https` when `ui.ingress.tls` is non-empty) |
| `server.port` | `ui.service.internalPort`, so the BFF binds the port the container exposes |
The four URLs are written as `${VAR:default}` **tokens**, not literals, so the in-cluster value is
only the default and the matching `HORIZON_*` variable still wins. `server.port` is the deliberate
exception — the chart writes it as a plain number, because the container port and both probes are
derived from `ui.service.internalPort` and the BFF has to bind that same port.
This matters because Horizon expands `${...}` over the raw *text* of the config file before parsing
it. A field written as a literal makes its `HORIZON_*` environment variable silently inert, and a
field the file omits falls back to a schema default that consults the environment for only a
fraction of the image's variables. A config file full of literals therefore does not merely
duplicate defaults — it disables most of the image's configuration surface.
**If you are carrying a full `ui.config` block forward** — from the pre-release `main` values, not
from 4.x, which had no `ui.config` at all — drop every field that only restates what the image
already sets (`server.host`, `oap.timeoutMs`, `auth.backend`, `rbac.enabled`, `session.*` and
`templates.mode` all did), and move the rest to `ui.extraEnv` or `ui.envFromSecret`:
| config field | how to set it now |
|---|---|
| `templates.mode` | `HORIZON_TEMPLATES_MODE` — works as a bare env var |
| `session.cookieSecure` | keep in `ui.config`, optionally as `${HORIZON_SESSION_COOKIE_SECURE:false}` |
| `server.trustProxy` | keep in `ui.config`, optionally as `${HORIZON_TRUST_PROXY:false}` |
| `auth.local.users` | keep in `ui.config` as `${HORIZON_AUTH_LOCAL_USERS:[]}` + `ui.envFromSecret` |
| `oap.auth` | keep in `ui.config` as `${HORIZON_OAP_AUTH:null}` + `ui.envFromSecret` |
Only the first row works from a bare environment variable. The other four have literal schema
defaults, so their `HORIZON_*` variables are reachable **only** through a `${...}` token in the
mounted file — set the variable without the token and nothing happens, with no error. See
[Configure Horizon](../ui/configure.md).
`ui.config` is still there for pinning a field regardless of the environment, and `${VAR}` tokens
you write in it do expand — that is how the Secret pattern works. See
[Configure Horizon](../ui/configure.md).
## The init Job re-runs on every upgrade that changes a value
The storage schema is created by a one-shot `*-oap-init-*` Job that runs OAP with `-Dmode=init`; the
main Deployment runs `-Dmode=no-init` and blocks until the schema exists. The Job name carries a
`sha256` of the chart values, so any `helm upgrade` that changes a value produces a new Job name and
re-runs init automatically, with Helm pruning the previous one. An upgrade that changes nothing
reuses the existing Job.
Before 5.0.0 this Job was a `post-install,post-upgrade,post-rollback` Helm hook with a fixed name —
the OAP Service name plus `-init`, e.g. `skywalking-skywalking-helm-oap-init`. Helm does not own
hook resources, so an upgrade from 4.9.0 leaves that completed Job behind in the namespace. It is
inert; delete it by hand.
To force a rerun without changing a value, delete the Job and upgrade again:
```shell
kubectl delete job -n skywalking -l release=skywalking
helm upgrade skywalking oci://docker.io/apache/skywalking-helm \
--version 5.0.0 -n skywalking --reuse-values
```
More detail in [The OAP Init Job](../operate/oap-init-job.md).
## Rolling back
`helm rollback` restores the previous release's manifests, so image tags and configuration revert.
It does **not** revert anything the init Job wrote to storage — the chart has no downgrade path for
the storage schema. Before an OAP major upgrade, make sure the storage backend is one you can
restore independently.
If the UI comes back Ready but unusable after an upgrade, start at
[UI and Login Problems](../troubleshooting/ui-and-login.md); if OAP or the init Job fails, see
[Install and Startup Failures](../troubleshooting/install-and-startup.md).