Brug Frostmoln Hemmeligheder med External Secrets Operator (ESO)
External Secrets Operator (ESO) synkroniserer hemmeligheder fra et eksternt lager ind i indbyggede Kubernetes-Secret-objekter. Dens generiske webhook-udbyder kan læse fra et hvilket som helst HTTP-API — inklusive Frostmoln Hemmeligheder — så du kan beholde dine hemmeligheder administreret i Frostmoln og lade ESO spejle dem ind i dine klynger, uden kode på ESO-siden og uden en egen udbyder.
Det virker på Frostmoln Administreret Kubernetes, hvor platformen installerer ESO for dig som en klyngetilføjelse, og på enhver anden Kubernetes-klynge med udgående internetadgang, som du selv kører — din egen eller on-prem — fordi ESO når det offentlige API-kantlag (api.frostmoln.cloud) over HTTPS.
Hvad dette gør
Du gemmer en hemmelighed i Frostmoln én gang. Ved hvert opdateringsinterval kalder ESO Frostmolns opslags-endpoint, læser værdien og skriver den ind i en Kubernetes-Secret, som dine arbejdslaster bruger som sædvanligt (miljøvariabel eller monteret fil). Når du roterer værdien i Frostmoln, tager ESO den nye værdi med ved næste opdatering.
Forudsætninger
- ESO installeret i klyngen.
- Frostmoln Administreret Kubernetes: vælg klyngetilføjelsen External Secrets Operator (
external-secrets), når du opretter klyngen, eller føj den til en klynge, der kører. Installer ikke chartet selv. Se På Frostmoln Administreret Kubernetes. - Enhver anden klynge: installer standard-chartet —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
- Frostmoln Administreret Kubernetes: vælg klyngetilføjelsen External Secrets Operator (
- En Frostmoln-API-nøgle. Opret en under Konto → API-nøgler i portalen (eller med
fm account api-key create --name eso --scopes secrets:read). På Frostmoln Administreret Kubernetes skal du i stedet bruge Arbejdslastidentitet. - Dit tenant-ID — fra
fm auth whoamieller portalen.
Begræns API-nøglen til hemmeligheder
Når du opretter nøglen, så giv den kun adgangen secrets:read. Frostmoln håndhæver API-nøglers adgange på serversiden, så en nøgle uden secrets:read afvises (403) af Secrets-tjenesten på anmodningstidspunktet — at begrænse nøglen indskrænker altså reelt, hvad den kan gøre, ikke bare som en konvention. Behandl nøglen som følsom; ESO gemmer den i en Kubernetes-Secret.
På Frostmoln Administreret Kubernetes
Platformen installerer ESO for dig i navnerummet external-secrets. Når den kører, autentificerer du den med Arbejdslastidentitet — uden API-nøgle — eller med en API-nøgle som i trin 1–3 nedenfor.
Føj den til, når du opretter klyngen, eller senere
- Når du opretter en klynge — vælg External Secrets Operator i portalens oprettelsesformular, angiv
--addons external-secretstilfm kubernetes cluster create, eller medtagexternal-secretsiaddonspåfrostmoln_kubernetes_cluster. Klyngen rapporteres først som kører; ESO anvendes nogle minutter senere, når arbejdsknuderne har tilsluttet sig, og tilføjelsen vises som Anvendes indtil da. - Til en klynge, der kører —
- Portalen — klyngens fane Tilføjelser.
- fm CLI —bash
fm kubernetes cluster add-addons <cluster-id> --addons external-secrets - Terraform — føj
external-secretstiladdons, og kør apply igen; opdateringen føjer tilføjelsen til den kørende klynge uden at erstatte den.
Når du først angiver addons i Terraform, skal nøglen blive stående der: en tilføjelse, der er føjet til fra portalen eller med fm, og som din addons ikke indeholder, fjernes ved næste apply.
At føje den til en klynge, der kører, træder ikke i kraft med det samme: tilføjelsen starter sin egen synkronisering, og ESO når klyngen typisk inden for få minutter; kan den synkronisering ikke startes, sker det først ved platformens næste synkronisering, op til en time. På en klynge, hvis kontrolplan er ældre end tilføjelsen, bliver tilføjelsen accepteret, men ESO installeres aldrig; opret en ny klynge for at bruge den.
Dine noder har brug for udgående HTTPS til ghcr.io
ESO's controller-image, ghcr.io/external-secrets/external-secrets, hentes over klyngens egen udgående HTTPS, når podden starter. Det er ikke forudindlæst på dine noder. Hvis du filtrerer udgående trafik på værtsnavn, så tillad bådeghcr.io og pkg-containers.githubusercontent.com, fordi ghcr.io omdirigerer hentningen af images dertil. ESO har desuden brug for udgående HTTPS til api.frostmoln.cloud for at læse dine hemmeligheder. Platformen kontrollerer ingen af delene; se Opret en klynge.
Autentificer med Arbejdslastidentitet (anbefalet)
Med Arbejdslastidentitet læser ESO et kortlivet token, som platformen holder i en Secret for dig, så der er ingen API-nøgle at oprette, gemme eller rotere. Du har brug for:
- Begge tilføjelser på klyngen: External Secrets Operator og Workload Identity.
- En binding med
secrets:readtil en ServiceAccount i det navnerum, hvorSecretStoreligger:bashfm kubernetes workload-identity binding create \ --cluster <cluster-id> --namespace default --service-account eso \ --scope secrets:read - Den ServiceAccount, annoteret, så tokenet holdes i en Secret ved navn
frostmoln-token:yamlapiVersion: v1 kind: ServiceAccount metadata: name: eso namespace: default annotations: frostmoln.cloud/workload-identity-secret: frostmoln-token
Secret'en bærer allerede etiketten external-secrets.io/type: webhook, så spring Trin 1 over. I Trin 2 bruger du i stedet denne SecretStore — samme URL, med tokenet som bearer-header:
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:
Authorization: 'Bearer {{ .auth.token }}'
result:
jsonPath: '$.secretValue'
secrets:
- name: auth
secretRef:
name: frostmoln-token
key: tokenTrin 3 er uændret. Sådan holdes Secret'en, og hvornår den fjernes: Legitimationsoplysning i en Secret.
Forskelle fra en ESO, du selv har installeret
Du kan ikke se ESO's pods eller logs.
external-secretser et beskyttet platformsnavnerum: din kubeconfig kan hverken læse eller skrive noget i det, såkubectl -n external-secrets get podsogkubectl logsdér afvises. Læs i stedet status og hændelser for dine egne objekter medkubectl -n <namespace> describe externalsecret <name>ogkubectl -n <namespace> describe secretstore <name>.Kun navnerumsbundne ressourcer.
SecretStoreogExternalSecreter tilgængelige.ClusterSecretStore,ClusterExternalSecretogPushSecreter ikke aktiveret.ESO kan læse alle Secrets i klyngen. Ligesom standard-ESO har tilføjelsens controller læseadgang til Secrets i hele klyngen, også i dine navnerum. Platformen begrænser, hvad den må skrive, ikke hvad den må læse.
Servicekonto-tokens afvises bevidst. ESO må ikke skrive Secrets i platformens navnerum. I alle navnerum må den ikke oprette eller opdatere en Secret af typen
kubernetes.io/service-account-tokeneller en, der bærer annotationenkubernetes.io/service-account.name, og den må ikke anmode om tokens til platformens servicekonti. EnExternalSecret, hvis mål ville blive sådan en Secret — viatarget.templateeller medcreationPolicy: Mergeind i en eksisterende — synkroniseres ikke, og fejlen ikubectl describe externalsecretindeholder:textthe external-secrets add-on may not create or update a service-account token SecretFjern din egen ESO først, i denne rækkefølge:
- Mens din egen ESO stadig kører, slet eller frigør hver
ExternalSecretsom beskrevet i Fjern tilføjelsen. - Afinstaller din ESO.
- Slet dens CRD'er.
Hold rækkefølgen. At slette en CRD sletter alle
ExternalSecretaf den type og medcreationPolicy: Ownerogså deres Secrets; uden en controller til at fjerne deres finalizers bliver CRD'en hængende iTerminating, og tilføjelsen kan ikke installere sine egne. CRD'er, du lader blive liggende, overtages, som de er, inklusive felter, du har tilføjet.- Mens din egen ESO stadig kører, slet eller frigør hver
Fjern tilføjelsen
Når tilføjelsen fjernes, bliver navnerummet external-secrets også liggende. Det forbliver reserveret til platformen, så din kubeconfig stadig ikke kan bruge det, og tilføjer du tilføjelsen igen, genbruges det.
Håndter hver ExternalSecret, FØR du fjerner tilføjelsen
ESO sætter en oprydnings-finalizer på hver ExternalSecret. Når tilføjelsen fjernes, slettes ESO-controlleren og dens webhooks, men CRD'erne bliver liggende, og uden controlleren er der intet, der fjerner den finalizer. En ExternalSecret, der stadig er i klyngen, kan så ikke slettes, og det kan et navnerum, der indeholder en, heller ikke.
List
ExternalSecret-objekterne i hvert navnerum. En liste på tværs af alle navnerum afvises, så kør den én gang pr. navnerum:bashkubectl -n <namespace> get externalsecretsFor hver
ExternalSecret, hvis Secret du vil beholde, skal du gøre alt dette i rækkefølge. Vent ikke på, at ESO opgiver ejerskabet ved en synkronisering: det sker kun ved en vellykket synkronisering, og en mislykket hentning, et tomt resultat medRetaineller visse opdateringsindstillinger springer det over.<target>er den Secret, der er angivet ispec.target.name, ellerExternalSecret'ens eget navn, hvis feltet ikke er sat.- Sæt
creationPolicy: Orphanførst; medOwnertilføjer ESO ejerreferencen igen ved næste synkronisering:bashkubectl -n <namespace> patch externalsecret <name> \ --type=merge -p '{"spec":{"target":{"creationPolicy":"Orphan"}}}' - Kontroller, om Secret'en stadig har en ejerreference:bash
kubectl -n <namespace> get secret <target> -o jsonpath='{.metadata.ownerReferences}' - Kun hvis det udskrev noget, så fjern den, og kør derefter trin 2.2 igen, indtil intet udskrives. Et
422(Unprocessable Entity) fra patchen er ikke en fejl: Secret'en har ingen ejerreference at fjerne og er allerede sikker.bashkubectl -n <namespace> patch secret <target> \ --type=json -p '[{"op":"remove","path":"/metadata/ownerReferences"}]' - Slet
ExternalSecret'en; Secret'en bevares:bashkubectl -n <namespace> delete externalsecret <name>
- Sæt
For hver
ExternalSecret, hvis Secret du ikke har brug for, så sletExternalSecret'en, mens ESO stadig kører. Med standardværdiencreationPolicy: Ownerslettes dens synkroniserede Secret med den, og alt, der stadig bruger den Secret, holder op med at virke: pods, der henviser til den, fejler, næste gang de starter, og er det en pull secret til images, kan nye noder ikke længere hente imaget.Først derefter fjerner du tilføjelsen — fra fanen Tilføjelser, med
fm kubernetes cluster remove-addons <cluster-id> --addons external-secretseller ved at fjerne nøglen fraaddonsi Terraform.
Hvis du allerede har fjernet tilføjelsen
Fjerner du finalizeren, kan den synkroniserede Secret blive slettet
Med standardværdien creationPolicy: Owner ejes den synkroniserede Secret af sin ExternalSecret. Når finalizeren er væk, og ExternalSecret er slettet, sletter Kubernetes' garbage collection også Secret'en — også med deletionPolicy: Retain.
For hver resterende ExternalSecret:
- Hvis selve navnerummet er ved at blive slettet, kan du ikke beholde Secret'en: alle Secrets i det slettes også, uanset deres ejerreferencer. Genskab den et andet sted ud fra Frostmoln Hemmeligheder. Ellers skal du, for at beholde dens Secret, først kontrollere, om der er en ejerreference, og i så fald fjerne den (trin 2.2 og 2.3 ovenfor).
- Fjern finalizeren:bash
kubectl -n <namespace> patch externalsecret <name> \ --type=merge -p '{"metadata":{"finalizers":null}}' - Hvis
ExternalSecret'en ikke allerede er ved at blive slettet, så slet den.
På Frostmoln-klynger er det kun ExternalSecret, der har denne finalizer, fordi PushSecret og ClusterExternalSecret ikke er aktiveret.
Trin 1 — Gem API-nøglen som en mærket Secret
API-nøgle: andre klynger end Frostmoln Administreret Kubernetes
Trin 1 og 2 bruger en API-nøgle. På Frostmoln Administreret Kubernetes skal du i stedet bruge Arbejdslastidentitet.
ESO's webhook-udbyder læser API-nøglen fra en Kubernetes-Secret. Secret'en skal bære etiketten external-secrets.io/type: webhook — webhook-udbyderen nægter at læse en umærket Secret.
Gem nøglen i en lokal fil, der kun indeholder nøglen, uden afsluttende linjeskift. Opret Secret'en ud fra filen, mærk den, og slet derefter filen:
kubectl -n default create secret generic frostmoln-api-key --from-file=apikey=./apikey
# PÅKRÆVET — webhook-udbyderen ignorerer en umærket Secret
kubectl -n default label secret frostmoln-api-key external-secrets.io/type=webhook
rm ./apikeyBrug kubectl create, ikke kubectl apply med et manifest: apply gemmer hele manifestet, inklusive nøglen, i klartekst i Secret'ens annotation kubectl.kubernetes.io/last-applied-configuration. Tjek ikke nøglen ind i git. Kun SecretStore- og ExternalSecret-manifesterne nedenfor er sikre at gemme i versionsstyring.
Hold nøglen i sit eget navnerum
En SecretStore læser API-nøglens Secret fra sit eget navnerum, så nøglen, lageret og de ExternalSecret-objekter, der bruger det, deler navnerum. Nøglen kan læse alle hemmeligheder i din tenant, og det kan alle, der kan læse Secrets i det navnerum, også. Brug et dedikeret navnerum til dem, og hold dets RBAC stramt. Eksemplerne på denne side bruger default.
Trin 2 — Opret SecretStore
SecretStore peger ESO mod Frostmolns opslags-endpoint. Brug CRD-gruppen external-secrets.io/v1 (ikke den ældre v1beta1). Erstat <TENANT_ID> med dit tenant-ID.
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:
# KORT pr. hemmelighed: <secrets-entry-name>.<data-key>.
# {{ .apikey }} gengiver hele kortet, og API'et returnerer 401 — brug nøglen .apikey.
X-API-Key: '{{ .apikey.apikey }}'
result:
jsonPath: '$.secretValue'
secrets:
- name: apikey
secretRef:
name: frostmoln-api-key
key: apikey{{ .remoteRef.key }} i URL'en udfyldes pr. ExternalSecret med Frostmolns hemmelighedsnavn (Trin 3), så én SecretStore betjener alle dine hemmeligheder.
Trin 3 — Opret en ExternalSecret
Hver ExternalSecret knytter én Frostmoln-hemmelighed til én Kubernetes-Secret. remoteRef.key er Frostmolns hemmelighedsnavn; target.name er den Kubernetes-Secret, ESO opretter og holder synkroniseret.
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øglen inde i den synkroniserede Kubernetes-Secret
remoteRef: { key: my-secret-name } # Frostmolns hemmelighedsnavnESO opretter Secret'en my-secret-synced med en value-nøgle, der indeholder den hentede hemmelighedsværdi. Monter den, eller referer til den fra din Pod som enhver anden Secret.
Opdateringsinterval
refreshInterval styrer, hvor ofte ESO henter på ny. Et kort interval udbreder rotationer hurtigere, men giver flere API-kald; et længere er lettere. Vælg pr. hemmelighed ud fra, hvor hurtigt en rotation skal nå dine arbejdslaster — et minut eller nogle få minutter er typisk.
Fastlås en bestemt version
Frostmoln-hemmeligheder er versionerede. Vil du fastlåse en version, så tilføj &version=N til SecretStore-URL'en (opret en ekstra SecretStore til den fastlåste hemmelighed):
url: 'https://api.frostmoln.cloud/api/v1/tenants/<TENANT_ID>/secrets/lookup?name={{ .remoteRef.key }}&version=2'Uden &version læser ESO altid den nyeste version.
Det er fejlsikkert at slette en hemmelighed
Kører du fm secrets delete på en hemmelighed, som ESO synkroniserer, begynder opslaget at returnere en fejl (hemmeligheden går i afventende sletning). ESO's opdatering mislykkes (SecretSyncedError), og den lader det senest synkroniserede Kubernetes-Secret stå uændret — den tømmer det ikke. Dine arbejdslaster kører videre på den senest kendte fungerende værdi.
Gendan for at genoptage synkroniseringen
Mens hemmeligheden er slettet, kan ESO ikke opdatere den, og værdien i din klynge bliver forældet. Kør fm secrets recover <name> inden for gendannelsesvinduet for at gendanne den; ESO genoptager derefter synkroniseringen ved næste interval. Går gendannelsesvinduet, og hemmeligheden fjernes permanent, bliver opslaget ved med at mislykkes — opret hemmeligheden på ny for at genoptage.
Fejlfinding
Kontroller ExternalSecret-statussen med kubectl describe externalsecret <name>.
secret does not contain needed label— API-nøglensSecretmangler etikettenexternal-secrets.io/type: webhook(Trin 1).401/ uautoriseret — headerskabelonen er forkert. Den skal være{{ .apikey.apikey }}(<secrets-entry-name>.<data-key>);{{ .apikey }}gengiver hele kortet, og API'et afviser den. Kontroller også nøgleværdien, og at nøglen ikke er udløbet.- Arbejdslastidentitet: Secret'en
frostmoln-tokendukker ikke op — kontroller, at tilføjelsen Workload Identity er på klyngen, at ServiceAccount'en bærer annotationen og har en binding, og at der ikke fandtes en Secret med det navn i forvejen: tilføjelsen overskriver aldrig en Secret, den ikke selv har oprettet. could not get secret data from provider— hemmelighedsnavnet eller tenant-ID'et er forkert, eller hemmeligheden er slettet / afventer sletning. Bekræft, at navnet kan slås op:fm secrets get <name>.- Intet synkroniseres overhovedet — kontroller, at
SecretStorebrugerexternal-secrets.io/v1, ikkev1beta1. På en klynge, du selv kører, så bekræft, at ESO kører (kubectl -n external-secrets get pods). På Frostmoln Administreret Kubernetes kan du ikke liste de pods: bekræft, at tilføjelsen er på klyngen (fm kubernetes cluster addons <cluster-id>eller fanen Tilføjelser), at den blev tilføjet for mere end nogle få minutter siden (hvis platformen meldte, at den ikke kunne starte synkroniseringen, så regn med længere tid: typisk højst en time, mere under platformsvedligeholdelse), og at dine noder kan någhcr.ioogpkg-containers.githubusercontent.com.