feat(ql3): expose worker observations in console

This commit is contained in:
whyour
2026-08-20 14:02:01 +08:00
parent af5d5bfc0b
commit 344680d64a
25 changed files with 840 additions and 49 deletions
+36 -1
View File
@@ -12,6 +12,12 @@ by default. Supplying a separate Run management mTLS config and short-lived
User assertion adds only status, blocked-list and inspect reads to the same
loopback process; rearm, stop and retry remain absent.
Worker observation is a third, independent authority and is also disabled by
default. Supplying its generic Worker management mTLS config and short-lived
User assertion adds only a fixed 16-item list and point inspect to the same
loopback process. Credential mutation, drain, revoke, background polling and
automatic pagination remain absent.
Use `ql3-cluster-admin` from the same independently verified Admin release as
the Cluster deployment. D-328 also supports the image-carried
`docker-loopback.sh`: it uses an explicit container-only listener but publishes
@@ -111,6 +117,14 @@ credential. Supplying only one of config/assertion is rejected before a
listener or Cluster request is created. The assertion is reread for every
explicit click so it can be rotated or removed while the Console is running.
To enable Worker observation, copy
`worker-management-client-config.example.json` to
`worker-management-client.json`, install its separate CA, client certificate
and private key, and issue a short-lived strong User assertion with only
`worker.manage` into `worker-management-assertion.jwt`. Its endpoint must be
the D-374 canonical `/api/v3/workers/management`; the Console cannot accept the
legacy credential-management path or a credential mutation command file.
Create an independent 256-bit browser session key without placing its value in
argv or an environment variable:
@@ -125,6 +139,10 @@ If optional Run management reads are enabled, apply the same owner-private,
canonical, non-symlink `0600` rule to `run-management-client.json`,
`run-management-ca.pem`, `run-management-client.crt`,
`run-management-client.key` and `run-management-assertion.jwt`.
Apply the same rule to `worker-management-client.json`,
`worker-management-ca.pem`, `worker-management-client.crt`,
`worker-management-client.key` and `worker-management-assertion.jwt` when
Worker observation is enabled.
Every file must be a current-owner, non-symlink, canonical regular file. The
session file contains exactly 43 base64url characters and no newline. It is a
@@ -151,7 +169,14 @@ intended:
--run-management-assertion /absolute/private/ql3-copilot-console/run-management-assertion.jwt
```
It validates all three private authorities and performs one unauthenticated
Worker observation uses its own pair:
```sh
--worker-management-config /absolute/private/ql3-copilot-console/worker-management-client.json \
--worker-management-assertion /absolute/private/ql3-copilot-console/worker-management-assertion.jwt
```
It validates every configured private authority and performs one unauthenticated
TLS 1.3 `GET /readyz`. It does not open the Console listener or reveal paths,
endpoint, credential, Project or Cluster identity.
@@ -191,6 +216,12 @@ offers a user-clicked blocked-list step; each returned Run offers a user-clicked
inspect step. Pagination is also click-only. There is no polling, automatic
page traversal, bulk inspection or mutation route.
Explicit Worker management authority adds `worker_list|worker_inspect`. The
list is fixed at 16 items and exposes a next cursor only as a new user-clicked
read; each listed Worker can be inspected only by another explicit click. The
projection contains bounded lifecycle, compatibility, architecture, protocol
and capacity facts, but no credential, raw capability, label or Secret.
## Export a redacted evidence bundle
After at least one successful read, **Export redacted bundle** creates one
@@ -243,6 +274,10 @@ The image launcher keeps Run management disabled unless
`run-management-client.json` and `run-management-assertion.jwt` from the same
read-only private mount; all certificate paths in the config must point into
that mount. `disabled` is the only default and unknown values fail closed.
Worker observation follows the independent
`QL3_COPILOT_CONSOLE_WORKER_MANAGEMENT=enabled` switch and reads only its
Worker config/assertion pair. Enabling one management authority does not enable
the other.
| Resource class | Memory | CPU | PIDs | Console reads |
| --- | ---: | ---: | ---: | ---: |
@@ -25,6 +25,7 @@ network=${QL3_COPILOT_CONSOLE_NETWORK-}
port=${QL3_COPILOT_CONSOLE_PORT-}
resource_class=${QL3_COPILOT_CONSOLE_RESOURCE_CLASS-compact}
run_management=${QL3_COPILOT_CONSOLE_RUN_MANAGEMENT-disabled}
worker_management=${QL3_COPILOT_CONSOLE_WORKER_MANAGEMENT-disabled}
printf '%s' "$image" | grep -Eq '^[A-Za-z0-9][A-Za-z0-9._/-]{0,191}@sha256:[0-9a-f]{64}$' || fail
printf '%s' "$network" | grep -Eq '^[A-Za-z0-9][A-Za-z0-9_.-]{0,62}$' || fail
@@ -62,6 +63,10 @@ case "$run_management" in
disabled|enabled) ;;
*) fail ;;
esac
case "$worker_management" in
disabled|enabled) ;;
*) fail ;;
esac
set -- docker run --rm --pull never --init --read-only \
--network "$network" \
@@ -92,6 +97,12 @@ if [ "$run_management" = enabled ]; then
--run-management-assertion /var/run/secrets/qinglong3/copilot-console/run-management-assertion.jwt
fi
if [ "$worker_management" = enabled ]; then
set -- "$@" \
--worker-management-config /var/run/secrets/qinglong3/copilot-console/worker-management-client.json \
--worker-management-assertion /var/run/secrets/qinglong3/copilot-console/worker-management-assertion.jwt
fi
if [ "$mode" = check ]; then
set -- "$@" --check
fi
@@ -4,5 +4,6 @@
"QL3_COPILOT_CONSOLE_NETWORK": "qinglong3-copilot-console-egress",
"QL3_COPILOT_CONSOLE_PORT": "5701",
"QL3_COPILOT_CONSOLE_RESOURCE_CLASS": "compact",
"QL3_COPILOT_CONSOLE_RUN_MANAGEMENT": "disabled"
"QL3_COPILOT_CONSOLE_RUN_MANAGEMENT": "disabled",
"QL3_COPILOT_CONSOLE_WORKER_MANAGEMENT": "disabled"
}
@@ -0,0 +1,9 @@
{
"schemaVersion": 1,
"endpoint": "https://replace-cluster-api.example.com:8448/api/v3/workers/management",
"servername": "replace-cluster-api.example.com",
"caFile": "/absolute/private/ql3-copilot-console/worker-management-ca.pem",
"clientCertificateFile": "/absolute/private/ql3-copilot-console/worker-management-client.crt",
"clientPrivateKeyFile": "/absolute/private/ql3-copilot-console/worker-management-client.key",
"requestTimeoutMs": 5000
}
@@ -87,6 +87,8 @@ COPY --chmod=0444 deploy/console/ql3-cluster-copilot/client-config.example.json
share/ql3-copilot-console/client-config.example.json
COPY --chmod=0444 deploy/console/ql3-cluster-copilot/run-management-client-config.example.json \
share/ql3-copilot-console/run-management-client-config.example.json
COPY --chmod=0444 deploy/console/ql3-cluster-copilot/worker-management-client-config.example.json \
share/ql3-copilot-console/worker-management-client-config.example.json
COPY --chmod=0444 deploy/console/ql3-cluster-copilot/host-environment.example.json \
share/ql3-copilot-console/host-environment.example.json