Skip to content

Använd Frostmoln Hemligheter med External Secrets Operator (ESO)

External Secrets Operator (ESO) synkroniserar hemligheter från ett externt lager till inbyggda Kubernetes-Secret-objekt. Dess generiska webhook-leverantör kan läsa från vilket HTTP-API som helst — inklusive Frostmoln Hemligheter — så du kan behålla dina hemligheter hanterade i Frostmoln och låta ESO spegla dem in i dina kluster, utan kod på ESO-sidan och utan någon egen leverantör.

Detta fungerar på vilket Kubernetes-kluster som helst med internetutgång — eget, on-prem eller ett hanterat Frostmoln-kluster — eftersom ESO når det publika API-kantskiktet (api.frostmoln.cloud) över HTTPS.

Vad detta gör

Du lagrar en hemlighet i Frostmoln en gång. Vid varje uppdateringsintervall anropar ESO Frostmolns uppslags-endpoint, läser värdet och skriver in det i ett Kubernetes-Secret som dina arbetsbelastningar använder som vanligt (miljövariabel eller monterad fil). När du roterar värdet i Frostmoln plockar ESO upp det nya värdet vid nästa uppdatering.

Förutsättningar

  • ESO installerat i klustret.
    • Frostmoln hanterad Kubernetes: ESO levereras som klustertillägget external-secrets — aktivera det i stället för att installera ett eget (den begränsade kluster-kubeconfig kan inte själv installera klusteromfattande CRD:er och webhooks).
    • Alla andra kluster: installera det ordinarie diagrammet —
      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-nyckel. Skapa en under Konto → API-nycklar i portalen (eller med fm account api-key create).
  • Ditt tenant-ID — från fm auth whoami eller portalen.

Begränsa API-nyckeln till hemligheter

När du skapar nyckeln, ge den endast scope-behörigheten secrets:read. Frostmoln tillämpar API-nyckelns scope-behörigheter på serversidan, så en nyckel utan secrets:read avvisas (403) av Secrets-tjänsten vid anropet — att begränsa nyckeln begränsar alltså på riktigt vad den kan göra, inte bara som en rekommendation. Behandla nyckeln som känslig; ESO lagrar den i ett Kubernetes-Secret.

Steg 1 — Lagra API-nyckeln som ett märkt Secret

ESO:s webhook-leverantör läser API-nyckeln från ett Kubernetes-Secret. Secret måste bära etiketten external-secrets.io/type: webhook — webhook-leverantören vägrar att läsa ett omärkt Secret.

yaml
apiVersion: v1
kind: Secret
metadata:
  name: frostmoln-api-key
  namespace: default
  labels:
    external-secrets.io/type: webhook # KRÄVS — webhook-leverantören ignorerar ett omärkt Secret
stringData:
  apikey: fmk_... # din Frostmoln-API-nyckel (scope secrets:read)

Skapa detta Secret från en lokal fil med kubectl applychecka inte in det i git. Endast SecretStore- och ExternalSecret-manifesten nedan är säkra att versionshantera.

Steg 2 — Skapa SecretStore

SecretStore pekar ESO mot Frostmolns uppslags-endpoint. Använd CRD-gruppen external-secrets.io/v1 (inte den äldre v1beta1). Ersätt <TENANT_ID> med ditt tenant-ID.

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-hemlighet-KARTA: <secrets-postnamn>.<datanyckel>.
        # {{ .apikey }} renderar hela kartan och API:et returnerar 401 — använd nyckeln .apikey.
        X-API-Key: '{{ .apikey.apikey }}'
      result:
        jsonPath: '$.secretValue'
      secrets:
        - name: apikey
          secretRef:
            name: frostmoln-api-key
            key: apikey

{{ .remoteRef.key }} i URL:en fylls i per ExternalSecret med Frostmolns hemlighetsnamn (Steg 3), så en SecretStore betjänar alla dina hemligheter.

Steg 3 — Skapa en ExternalSecret

Varje ExternalSecret mappar en Frostmoln-hemlighet till ett Kubernetes-Secret. remoteRef.key är Frostmolns hemlighetsnamn; target.name är det Kubernetes-Secret som ESO skapar och håller synkroniserat.

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 # nyckeln inuti det synkade Kubernetes-Secret
      remoteRef: { key: my-secret-name } # Frostmolns hemlighetsnamn

ESO skapar Secret my-secret-synced med en value-nyckel som håller det hämtade hemlighetsvärdet. Montera det eller referera till det från din Pod som vilket annat Secret som helst.

Uppdateringsintervall

refreshInterval styr hur ofta ESO hämtar på nytt. Ett kort intervall sprider rotationer snabbare men gör fler API-anrop; ett längre är lättare. Välj per hemlighet utifrån hur snabbt en rotation måste nå dina arbetsbelastningar — en minut eller några minuter är typiskt.

Låsa en specifik version

Frostmoln-hemligheter är versionshanterade. För att låsa en version, lägg till &version=N i SecretStore-URL:en (skapa en andra SecretStore för den låsta hemligheten):

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

Utan &version läser ESO alltid den senaste versionen.

Att ta bort en hemlighet är felsäkert

Om du kör fm secrets delete på en hemlighet som ESO synkroniserar börjar uppslaget returnera ett fel (hemligheten går in i väntande borttagning). ESO:s uppdatering misslyckas (SecretSyncedError) och behåller det senast synkade Kubernetes-Secret oförändrat — det tömmer det inte. Dina arbetsbelastningar fortsätter köra på det senast kända fungerande värdet.

Återställ för att återuppta synkronisering

Medan hemligheten är borttagen kan ESO inte uppdatera den och värdet i ditt kluster blir inaktuellt. Kör fm secrets recover <name> inom återställningsfönstret för att återställa det; ESO återupptar då synkroniseringen vid nästa intervall. Om återställningsfönstret passerar och hemligheten tas bort permanent fortsätter uppslaget att misslyckas — återskapa hemligheten för att återuppta.

Felsökning

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

  • secret does not contain needed label — API-nyckelns Secret saknar etiketten external-secrets.io/type: webhook (Steg 1).
  • 401 / obehörig — headermallen är fel. Den måste vara {{ .apikey.apikey }} (<secrets-postnamn>.<datanyckel>); {{ .apikey }} renderar hela kartan och API:et avvisar den. Kontrollera även nyckelvärdet och att nyckeln inte har gått ut.
  • could not get secret data from provider — hemlighetsnamnet eller tenant-ID:t är fel, eller så är hemligheten borttagen / under väntande borttagning. Verifiera att namnet finns: fm secrets get <name>.
  • Inget synkroniseras alls — bekräfta att ESO körs (kubectl -n external-secrets get pods) och att SecretStore använder external-secrets.io/v1, inte v1beta1.

Relaterat