Skip to content

Bruk Frostmoln Hemmeligheter med External Secrets Operator (ESO)

External Secrets Operator (ESO) synkroniserer hemmeligheter fra et eksternt lager til native Kubernetes-Secret-objekter. Den generiske webhook-leverandøren kan lese fra hvilket som helst HTTP-API — inkludert Frostmoln Hemmeligheter — slik at du kan holde hemmelighetene dine administrert i Frostmoln og la ESO speile dem inn i klyngene dine, uten kode på ESO-siden og uten en egen leverandør.

Dette fungerer på hvilken som helst Kubernetes-klynge med internettutgang — egen, on-prem eller en administrert Frostmoln-klynge — fordi ESO når den offentlige API-kanten (api.frostmoln.cloud) over HTTPS.

Hva dette gjør

Du lagrer en hemmelighet i Frostmoln én gang. Ved hvert oppdateringsintervall kaller ESO Frostmolns oppslags-endepunkt, leser verdien og skriver den inn i et Kubernetes-Secret som arbeidslastene dine bruker som vanlig (miljøvariabel eller montert fil). Når du roterer verdien i Frostmoln, plukker ESO opp den nye verdien ved neste oppdatering.

Forutsetninger

  • ESO installert i klyngen.
    • Frostmoln administrert Kubernetes: ESO leveres som klyngetillegget external-secrets — aktiver det i stedet for å installere ditt eget (den begrensede klynge-kubeconfig kan ikke selv installere klyngeomfattende CRD-er og webhooks).
    • Alle andre klynger: installer standarddiagrammet —
      bash
      helm repo add external-secrets https://charts.external-secrets.io
      helm install external-secrets external-secrets/external-secrets \
        -n external-secrets --create-namespace --set installCRDs=true
  • En Frostmoln-API-nøkkel. Opprett en under Konto → API-nøkler i portalen (eller med fm account api-key create).
  • Tenant-ID-en din — fra fm auth whoami eller portalen.

Begrens API-nøkkelen til hemmeligheter

Når du oppretter nøkkelen, gi den kun scope-tilgangen secrets:read. Frostmoln håndhever API-nøkkelens scope-tilganger på serversiden, så en nøkkel uten secrets:read avvises (403) av Secrets-tjenesten ved forespørselen — å begrense nøkkelen begrenser altså på ekte hva den kan gjøre, ikke bare som en anbefaling. Behandle nøkkelen som sensitiv; ESO lagrer den i et Kubernetes-Secret.

Trinn 1 — Lagre API-nøkkelen som et merket Secret

ESOs webhook-leverandør leser API-nøkkelen fra et Kubernetes-Secret. Secret må bære etiketten external-secrets.io/type: webhook — webhook-leverandøren nekter å lese et umerket Secret.

yaml
apiVersion: v1
kind: Secret
metadata:
  name: frostmoln-api-key
  namespace: default
  labels:
    external-secrets.io/type: webhook # PÅKREVD — webhook-leverandøren ignorerer et umerket Secret
stringData:
  apikey: fmk_... # din Frostmoln-API-nøkkel (scope secrets:read)

Opprett dette Secret fra en lokal fil med kubectl applyikke sjekk det inn i git. Bare SecretStore- og ExternalSecret-manifestene nedenfor er trygge å ha i versjonskontroll.

Trinn 2 — Opprett SecretStore

SecretStore peker ESO mot Frostmolns oppslags-endepunkt. Bruk CRD-gruppen external-secrets.io/v1 (ikke den eldre v1beta1). Erstatt <TENANT_ID> med tenant-ID-en din.

yaml
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
  name: frostmoln
  namespace: default
spec:
  provider:
    webhook:
      url: 'https://api.frostmoln.cloud/api/v1/tenants/<TENANT_ID>/secrets/lookup?name={{ .remoteRef.key }}'
      headers:
        # per-hemmelighet-KART: <secrets-oppføringsnavn>.<datanøkkel>.
        # {{ .apikey }} rendrer hele kartet og API-et returnerer 401 — bruk nøkkelen .apikey.
        X-API-Key: '{{ .apikey.apikey }}'
      result:
        jsonPath: '$.secretValue'
      secrets:
        - name: apikey
          secretRef:
            name: frostmoln-api-key
            key: apikey

{{ .remoteRef.key }} i URL-en fylles inn per ExternalSecret med Frostmolns hemmelighetsnavn (Trinn 3), så én SecretStore betjener alle hemmelighetene dine.

Trinn 3 — Opprett en ExternalSecret

Hver ExternalSecret kobler én Frostmoln-hemmelighet til ett Kubernetes-Secret. remoteRef.key er Frostmolns hemmelighetsnavn; target.name er Kubernetes-Secret-et som ESO oppretter og holder synkronisert.

yaml
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: my-secret
  namespace: default
spec:
  refreshInterval: 1m
  secretStoreRef: { name: frostmoln, kind: SecretStore }
  target: { name: my-secret-synced }
  data:
    - secretKey: value # nøkkelen inne i det synkroniserte Kubernetes-Secret
      remoteRef: { key: my-secret-name } # Frostmolns hemmelighetsnavn

ESO oppretter my-secret-synced-Secret med en value-nøkkel som holder den hentede hemmelighetsverdien. Monter det eller referer til det fra Pod-en din som et hvilket som helst annet Secret.

Oppdateringsintervall

refreshInterval styrer hvor ofte ESO henter på nytt. Et kort intervall sprer rotasjoner raskere, men gjør flere API-kall; et lengre er lettere. Velg per hemmelighet ut fra hvor raskt en rotasjon må nå arbeidslastene dine — ett minutt eller noen minutter er typisk.

Lås en bestemt versjon

Frostmoln-hemmeligheter er versjonert. For å låse en versjon, legg til &version=N i SecretStore-URL-en (opprett et andre SecretStore for den låste hemmeligheten):

yaml
url: 'https://api.frostmoln.cloud/api/v1/tenants/<TENANT_ID>/secrets/lookup?name={{ .remoteRef.key }}&version=2'

Uten &version leser ESO alltid den nyeste versjonen.

Å slette en hemmelighet er feilsikkert

Hvis du kjører fm secrets delete på en hemmelighet som ESO synkroniserer, begynner oppslaget å returnere en feil (hemmeligheten går inn i ventende sletting). ESOs oppdatering mislykkes (SecretSyncedError) og beholder det sist synkroniserte Kubernetes-Secret uendret — det tømmer det ikke. Arbeidslastene dine fortsetter å kjøre på den sist kjente fungerende verdien.

Gjenopprett for å gjenoppta synkronisering

Mens hemmeligheten er slettet, kan ESO ikke oppdatere den, og verdien i klyngen din blir foreldet. Kjør fm secrets recover <name> innenfor gjenopprettingsvinduet for å gjenopprette den; ESO gjenopptar da synkroniseringen ved neste intervall. Hvis gjenopprettingsvinduet passerer og hemmeligheten fjernes permanent, fortsetter oppslaget å mislykkes — opprett hemmeligheten på nytt for å gjenoppta.

Feilsøking

Sjekk ExternalSecret-statusen med kubectl describe externalsecret <name>.

  • secret does not contain needed label — API-nøkkelens Secret mangler etiketten external-secrets.io/type: webhook (Trinn 1).
  • 401 / uautorisert — header-malen er feil. Den må være {{ .apikey.apikey }} (<secrets-oppføringsnavn>.<datanøkkel>); {{ .apikey }} rendrer hele kartet og API-et avviser den. Sjekk også nøkkelverdien og at nøkkelen ikke har utløpt.
  • could not get secret data from provider — hemmelighetsnavnet eller tenant-ID-en er feil, eller hemmeligheten er slettet / venter på sletting. Bekreft at navnet finnes: fm secrets get <name>.
  • Ingenting synkroniseres i det hele tatt — bekreft at ESO kjører (kubectl -n external-secrets get pods) og at SecretStore bruker external-secrets.io/v1, ikke v1beta1.

Relatert