Skip to content

Kubernetes agent: read-only

One read-only collector, installed with Helm, reads nodes, pods, deployments and events, never Secrets, and sends a snapshot out every 60 seconds. It changes nothing and comes out with two commands.

How do I install it?

  1. Register the cluster

    On the connect page, choose Kubernetes and register the cluster. Its token is shown once.

  2. Run the install command

    The connect page fills in your address and cluster id. The last line asks for the token without showing it and stores it in a Secret.

    Shell (Helm and kubectl)
    helm upgrade --install marshal oci://ghcr.io/marshalcloud/charts/marshal \
      --namespace marshal --create-namespace \
      --set marshal.url=<your MarshalCloud API address> \
      --set marshal.clusterId=<your cluster id> \
      --set marshal.existingSecret=marshal-cluster-token
    kubectl -n marshal delete secret marshal-cluster-token --ignore-not-found >/dev/null; printf 'Cluster token: '; stty -echo; read -r MARSHAL_TOKEN; stty echo; echo; printf '%s' "$MARSHAL_TOKEN" | kubectl -n marshal create secret generic marshal-cluster-token --from-file=MARSHAL_CLUSTER_TOKEN=/dev/stdin; unset MARSHAL_TOKEN; kubectl -n marshal rollout restart deployment/marshal-controller

How you know it worked. The cluster shows last seen a moment ago on the connect page, usually within a minute. If helm cannot find the chart, use the connect page's kubectl tab.

Signed in? Open this guide with your own valuesNot signed in: sign in, then open Settings, Setup guides.

What do I need first?

  • Kubernetes clusters are on Growth and Scaled.
  • kubectl pointed at the cluster, with rights to create a namespace, a ClusterRole and a ClusterRoleBinding.
  • Helm 3. The chart comes from oci://ghcr.io/marshalcloud/charts/marshal and the image from ghcr.io/marshalcloud/marshal-controller, so the cluster (or your laptop, for the chart) needs to reach ghcr.io.
  • Outbound HTTPS (443) from the cluster to MarshalCloud's API address only. Behind a proxy, set proxy.url (and proxy.noProxy) in the chart values; a proxy that inspects TLS goes in proxy.caBundle.
  • An admin role in MarshalCloud to register the cluster. If Helm is not an option, the connect page also offers an older kubectl agent.

What access does it grant?

What it installs

  • A namespace, marshal (Helm creates it).
  • One Deployment, marshal-controller, from the image ghcr.io/marshalcloud/marshal-controller. It runs as a non-root user with a read-only filesystem and every capability dropped.
  • A read-only ClusterRole and its binding, plus a Role inside the marshal namespace for its own leader lease.
  • A Secret, marshal-cluster-token, that holds the cluster token. The install command reads the token from your terminal, so it is never on a command line, in shell history or in Helm's records.

What it can do

  • Read nodes, pods, deployments, replica sets and events, and the kubelet's usage figures.
  • List resource quotas, disruption budgets, cron jobs, certificate requests and cert-manager certificates, to report on them.
  • Write one thing: its own leader lease in the marshal namespace.
  • Get nodes/proxy, which is how it reaches the kubelet. It calls only /stats/summary and /metrics/cadvisor, but Kubernetes cannot scope this grant by path, so it also reaches the kubelet's other reads, container logs included. It never calls those.

What it never does

  • Read Secrets: the collector's role has no rule for them.
  • Change, restart or delete anything in the cluster.
  • Accept connections from outside: it only sends out, and has no Service.

How do I check or remove it?

  1. Check it is running

    Is the collector running, and what did it last say?

    Shell
    kubectl -n marshal get pods -l app.kubernetes.io/name=marshal-controller
    kubectl -n marshal logs deploy/marshal-controller --tail=50
  2. Remove the collector

    Remove the collector and the read-only permissions Helm installed, then the namespace and the leader lease the collector wrote inside it.

    Shell
    helm uninstall marshal --namespace marshal
    kubectl delete namespace marshal
  3. Disconnect the cluster

    In MarshalCloud, open Settings, Accounts and press Disconnect on the cluster (owners only). This removes the cluster and its map, and its token stops working.