Getting startedGuidesReferenceChangelog
Apoxy:// Docs / Getting started / Kubernetes Install

Kubernetes Install

Install the Apoxy controller into a cluster, verify the install, and debug common failure modes.

This guide walks through installing the Apoxy controller into a Kubernetes cluster. Use this path when your source of truth for Gateway API resources lives in Kubernetes.

Install the controller

apoxy k8s install fetches the onboarding manifests from the Apoxy API and applies them to your target cluster:

$terminalSH
apoxy k8s install \ --context <kube-context> \ --namespace apoxy \ --cluster-name <cluster-name> \ --mirror gateway \ --yes

Available flags

--kubeconfig
Explicit kubeconfig path.
--dry-run
Print the manifests without applying them.
--force
Force overwrite conflicting fields during apply.
--image
Override the controller image embedded in the onboarding manifests.
--yes
Skip interactive confirmation.

Your first install

Authenticate and install the controller:

$terminalSH
apoxy auth login apoxy k8s install \ --context prod-us-west-2 \ --namespace apoxy \ --cluster-name prod-us-west-2 \ --mirror gateway

During installation, the CLI resolves your kubeconfig and context, requests onboarding manifests from the Apoxy API, and applies resources into the target namespace. On subsequent runs, if you omit --cluster-name, the CLI recovers it from the namespace annotation apoxy.dev/cluster-name.

Mirror mode

The --mirror flag controls which resource types the controller mirrors to Apoxy:

ModeWhat it mirrorsWhen to use
gatewayGateway API resources (gateway.networking.k8s.io)Gateway API is your primary routing configuration.
ingressIngress resourcesYou're bridging an existing Ingress workflow into Apoxy.
allBoth Gateway API and IngressMixed environments running both resource families.

Preview with dry-run

Before applying to a cluster, preview the manifests:

$terminalSH
apoxy k8s install \ --context dev-cluster \ --namespace apoxy \ --cluster-name dev-cluster \ --mirror gateway \ --dry-run

Verify the install

After installing, confirm these basics:

  • The kubeconfig path resolves to the cluster you intended.
  • The selected context matches the target cluster.
  • The namespace is correct.
  • The Apoxy CLI is authenticated (apoxy auth login).
  • The project selection in your CLI config matches the target environment.

Common errors

failed to load kubeconfig
Bad kubeconfig path or incorrect current context.
failed to get YAML
Authentication issue or API-side onboarding problem.
Apply conflicts
Use --force only when you understand the field ownership implications.
Non-interactive runs without --yes
The CLI requires confirmation by default.

How the controller authenticates to Apoxy

The first time the controller starts in your cluster, it issues itself a per-cluster client certificate from the Apoxy control plane and uses it as its identity for every subsequent request. There is no long-lived API key in the cluster after install completes.

The flow:

  1. apoxy k8s install writes the onboarding manifests — including a one-time bootstrap secret keyed to the cluster name — into your cluster.
  2. The controller pod starts, exchanges the bootstrap material for a client certificate via the Apoxy API, and stores it in Secret apoxy/apiz-cert:
    • tls.crt — the certificate, signed by Apoxy.
    • tls.key — the matching private key (generated in the pod; never leaves the cluster).
    • ca.crt — Apoxy's root, used to verify the upstream.
  3. The controller and the aggregated API server (v1alpha.core.apoxy.dev and siblings) use this cert as a client certificate when proxying to Apoxy. The control plane authenticates each request by certificate fingerprint and authorizes against the project the cert was issued for.

The cert's subject encodes the service user kube-controller-<cluster-name>, so a cert minted for one cluster cannot impersonate another even within the same project.

Cert lifetime

Issued certificates are valid for 365 days. The controller auto-renews them when validity drops below 30 days: an hourly tick checks the live cert, and on the first tick below threshold the controller re-issues against Apoxy over mTLS with its current cert and hot-reloads the new material in place (no pod restart). See Auto-rotation for the full lifecycle and how to disable it.

You can also rotate explicitly with apoxy k8s certs rotate (see Rotating the kube-controller certificate). Manual rotation has two modes:

  • Restart mode (default) — the CLI patches the pod template to force a rolling restart; the new pod loads the new cert at startup.
  • Hot-reload mode (--no-restart) — the controller watches its projected apiz-cert Secret mount via fsnotify and atomically swaps the upstream client cert without a pod restart. Same mechanism the auto-renewer uses.

The Apoxy API publishes the cert's fingerprint and expiry; the CLI can inspect both:

$terminalSH
apoxy k8s certs list --context <kube-context>

Revocation

Revocation is project-scoped and immediate. When you revoke a fingerprint via apoxy k8s certs revoke <fp> --user-jwt <jwt>, the Apoxy ext_authz layer drops the cert from its allowed-fingerprint set within ~30 seconds, after which any request presenting that cert fails with 403. Revoke requires a user JWT (your dashboard session token), not an API key — a leaked API key sitting next to the cert in the cluster cannot revoke the cert it lives next to.

Updating the install

Re-run apoxy k8s install when you need to:

  • Change the mirror mode.
  • Switch to a custom controller image.
  • Pick up updated onboarding manifests from Apoxy.

Use --cluster-name explicitly in automation so the intended cluster identity is always clear.