6. Runtime view¶
6.1 Startup of a GeoServer replica (sub-project 2)¶
sequenceDiagram
participant K as Kubernetes
participant B as bootstrap-datadir.sh
participant DB as Database (geoserver schema)
participant T as Tomcat
participant GS as GeoServer (JDBCConfig, JDBCStore)
participant I as geoserver-init
K->>B: starts the container (env, Secrets, emptyDir)
B->>B: variable checks
B->>DB: SELECT to_regclass('geoserver.object'), ('geoserver.resources')
DB-->>B: present? → initdb/import=false (otherwise true)
B->>B: writes jdbcconfig/jdbcstore/status/controlflow .properties
B->>T: exec startup.sh (server.xml envsubst, admin, SKIP_DEMO_DATA)
T->>T: binds jdbc/geoserver and jdbc/meteo (pools)
T->>GS: starts the webapp
GS->>DB: loads catalog (object) and resources (resources, including security/)
GS->>I: GeoServerInitializer.initialize()
I->>GS: workspace / JNDI datastore / layer: created or verified
GS-->>K: /geoserver/index.html 200 (probes)
Hold "Alt" / "Option" to enable pan & zoom
First boot: initdb/import=true, JDBCConfig and JDBCStore create their
tables and import the initial data dir (including security/). Subsequent
boots: everything is re-read from the database; the local data dir only
contains the files regenerated by the bootstrap.
6.2 Scaling from 3 to 5 replicas (sub-project 3)¶
sequenceDiagram
participant Ops as Ops (kubectl scale / k9s)
participant K as Kubernetes
participant DNS as Headless Service DNS
participant N as New pod
participant C as Hazelcast cluster (3 members)
participant DB as Database
Ops->>K: replicas 3 → 5
K->>N: creates the pod (emptyDir, env)
K->>DNS: publishes the pod IP (publishNotReadyAddresses)
N->>DNS: resolves geoserver-hz (bootstrap, pre-check)
N->>N: regenerates cluster/*, jdbc*/*.properties
N->>DB: loads catalog and resources
N->>C: joins (5701) → size=4, then 5
N-->>K: Ready (probes) → receives traffic
Note over C: a configuration change on one node is published to the others (event)
Hold "Alt" / "Option" to enable pan & zoom
Measured: 5 pods ready in 25 s, 0 errors on in-flight requests; scale-down
5 → 2 without errors (graceful shutdown, terminationGracePeriodSeconds).
6.3 Tile request (sub-project 4)¶
sequenceDiagram
participant C as WMTS client
participant P as GeoServer pod (any of them)
participant G as GeoWebCache
participant S3 as gwc-tiles bucket
participant R as Rendering engine
C->>P: GetTile (layer, gridset, z/x/y)
P->>G: tile?
G->>S3: GET object
alt HIT
S3-->>G: tile
else MISS
G->>R: rendering (internal WMS)
R-->>G: image
G->>S3: PUT object
end
G-->>C: tile + header geowebcache-cache-result: HIT|MISS
Hold "Alt" / "Option" to enable pan & zoom
The cache is shared: a tile rendered by one pod is served as a HIT by all the others, including pods created afterwards.
6.4 Arrival of a new granule (sub-project 5)¶
sequenceDiagram
participant I as Ingestion service
participant S3 as rasters bucket
participant DB as mosaic index (PostGIS)
participant G as GeoServer (any pod)
participant C as Client
I->>I: field → canonical unit → COG
I->>S3: PUT models/…/arpege_t_isobaric85000_run_valid.tif
I->>DB: INSERT model_granule (time, elevation, reference_time, source_unit)
C->>G: GetCapabilities
G->>DB: SELECT DISTINCT time, elevation… FROM mosaic.arpege_t
G-->>C: up-to-date dimensions (new forecast validity time included)
C->>G: GetMap TIME=… ELEVATION=…
G->>DB: matching granules
G->>S3: range reads of the COG
G-->>C: image
Hold "Alt" / "Option" to enable pan & zoom
No restart and no notification: measured, the new forecast validity time is visible on all pods as soon as the row is inserted.