Skip to content

Käytä Frostmoln Salaisuuksia External Secrets Operatorin (ESO) kanssa ​

External Secrets Operator (ESO) synkronoi salaisuudet ulkoisesta varastosta natiiveihin Kubernetes-Secret-objekteihin. Sen geneerinen webhook-tarjoaja voi lukea mistä tahansa HTTP-API:sta — mukaan lukien Frostmoln Salaisuudet — joten voit pitää salaisuutesi Frostmolnin hallinnassa ja antaa ESO:n peilata ne klustereihisi ilman ESO-puolen koodia ja ilman omaa tarjoajaa.

Tämä toimii Frostmolnin hallitussa Kubernetesissa, jossa alusta asentaa ESO:n puolestasi klusterilisäosana, sekä millä tahansa muulla itse ajamallasi Kubernetes-klusterilla, jolla on internet-lähtöliikenne — omalla tai on-prem-klusterilla — koska ESO tavoittaa julkisen API-reunan (api.frostmoln.cloud) HTTPS:n yli.

Mitä tämä tekee ​

Tallennat salaisuuden Frostmolniin kerran. Jokaisella päivitysvälillä ESO kutsuu Frostmolnin hakupäätepistettä, lukee arvon ja kirjoittaa sen Kubernetes-Secret-objektiin, jota työkuormasi käyttävät tavalliseen tapaan (ympäristömuuttuja tai liitetty tiedosto). Kun kierrätät arvon Frostmolnissa, ESO poimii uuden arvon seuraavalla päivityksellä.

Edellytykset ​

  • ESO asennettuna klusteriin.
    • Frostmolnin hallittu Kubernetes: valitse External Secrets Operator -klusterilisäosa (external-secrets) klusteria luodessasi tai lisää se käynnissä olevaan klusteriin. Älä asenna kaaviota itse. Katso Frostmolnin hallitussa Kubernetesissa.
    • Kaikki muut klusterit: asenna vakiokaavio —
      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-API-avain. Luo avain portaalissa kohdassa Tili → API-avaimet (tai komennolla fm account api-key create --name eso --scopes secrets:read). Frostmolnin hallitussa Kubernetesissa käytä sen sijaan työkuormaidentiteettiä.
  • Tenant-tunnuksesi — komennosta fm auth whoami tai portaalista.

Rajaa API-avain salaisuuksiin

Kun luot avaimen, myönnä sille vain secrets:read-oikeus. Frostmoln valvoo API-avaimen oikeuksia palvelinpuolella, joten avain ilman secrets:read-oikeutta hylätään (403) Secrets- palvelussa pyynnön yhteydessä — avaimen rajaaminen todella rajoittaa sitä, mitä sillä voi tehdä, eikä ole vain suositus. Käsittele avainta arkaluonteisena; ESO tallentaa sen Kubernetes-Secret-objektiin.

Frostmolnin hallitussa Kubernetesissa ​

Alusta asentaa ESO:n puolestasi nimiavaruuteen external-secrets. Kun se on käynnissä, todenna se työkuormaidentiteetillä — ilman API-avainta — tai API-avaimella alla olevien vaiheiden 1–3 mukaisesti.

Lisää se klusteria luodessasi tai myöhemmin ​

  • Klusteria luodessasi — valitse External Secrets Operator portaalin luontilomakkeessa, anna fm kubernetes cluster create -komennolle --addons external-secrets tai lisää external-secrets resurssin frostmoln_kubernetes_cluster addons-joukkoon. Klusteri ilmoitetaan ensin käynnissä olevaksi; ESO otetaan käyttöön muutamaa minuuttia myöhemmin, kun työsolmut ovat liittyneet, ja siihen asti lisäosan tilana näkyy Otetaan käyttöön.
  • Käynnissä olevaan klusteriin —
    • Portaali — klusterin Lisäosat-välilehti.
    • fm CLI —
      bash
      fm kubernetes cluster add-addons <cluster-id> --addons external-secrets
    • Terraform — lisää external-secrets addons-joukkoon ja aja apply uudelleen; päivitys lisää lisäosan käynnissä olevaan klusteriin paikallaan.

Kun olet kerran asettanut addons-attribuutin Terraformissa, pidä avain siellä: portaalista tai fm-komennolla lisätty lisäosa, jota addons ei listaa, poistetaan seuraavalla applyllä.

Lisäys käynnissä olevaan klusteriin ei tule voimaan heti: lisäys käynnistää oman synkronointinsa, ja ESO saapuu klusteriin tyypillisesti muutamassa minuutissa; jos synkronointia ei voida käynnistää, ESO saapuu vasta alustan seuraavassa synkronoinnissa, enintään tunnin kuluessa. Klusterissa, jonka ohjaustaso on lisäosaa vanhempi, lisäys hyväksytään, mutta ESO:ta ei koskaan asenneta; luo uusi klusteri käyttääksesi sitä.

Solmusi tarvitsevat lähtevän HTTPS-yhteyden osoitteeseen ghcr.io

ESO:n ohjainvedos ghcr.io/external-secrets/external-secrets haetaan klusterisi oman lähtevän HTTPS-yhteyden yli, kun podi käynnistyy. Sitä ei ole esiladattu solmuihisi. Jos suodatat lähtevää liikennettä isäntänimen perusteella, salli sekä ghcr.io että pkg-containers.githubusercontent.com, koska ghcr.io ohjaa vedosten lataukset sinne. ESO tarvitsee lisäksi lähtevän HTTPS-yhteyden osoitteeseen api.frostmoln.cloud lukeakseen salaisuutesi. Alusta ei tarkista kumpaakaan; katso Luo klusteri.

Todenna työkuormaidentiteetillä (suositeltu) ​

Työkuormaidentiteettiä käytettäessä ESO lukee lyhytikäisen tunnisteen, jota alusta ylläpitää puolestasi Secret-objektissa, joten API-avainta ei tarvitse luoda, tallentaa eikä kierrättää. Tarvitset:

  • Molemmat lisäosat klusteriin: External Secrets Operatorin ja Workload Identityn.
  • Sidonnan secrets:read-oikeudella palvelutilille siinä nimiavaruudessa, jossa SecretStore sijaitsee:
    bash
    fm kubernetes workload-identity binding create \
      --cluster <cluster-id> --namespace default --service-account eso \
      --scope secrets:read
  • Kyseisen palvelutilin annotaatiolla merkittynä, jotta tunniste pidetään frostmoln-token-nimisessä Secretissä:
    yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: eso
      namespace: default
      annotations:
        frostmoln.cloud/workload-identity-secret: frostmoln-token

Secretillä on jo merkintä external-secrets.io/type: webhook, joten ohita Vaihe 1. Käytä Vaiheessa 2 sen sijaan tätä SecretStore-objektia — sama URL, tunniste bearer-headerina:

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:
        Authorization: 'Bearer {{ .auth.token }}'
      result:
        jsonPath: '$.secretValue'
      secrets:
        - name: auth
          secretRef:
            name: frostmoln-token
            key: token

Vaihe 3 on ennallaan. Miten Secretiä ylläpidetään ja milloin se poistetaan: Tunnus Secret-objektissa.

Erot itse asennettuun ESO:hon ​

  • Et näe ESO:n podeja tai lokeja. external-secrets on suojattu alustan nimiavaruus: kubeconfigisi ei voi lukea eikä kirjoittaa siihen mitään, joten kubectl -n external-secrets get pods ja kubectl logs siellä hylätään. Lue sen sijaan omien objektiesi tila ja tapahtumat komennoilla kubectl -n <namespace> describe externalsecret <name> ja kubectl -n <namespace> describe secretstore <name>.

  • Vain nimiavaruuskohtaiset resurssit. SecretStore ja ExternalSecret ovat käytettävissä. ClusterSecretStore, ClusterExternalSecret ja PushSecret eivät ole käytössä.

  • ESO voi lukea klusterin kaikki Secret-objektit. Kuten tavallisella ESO:lla, lisäosan ohjaimella on lukuoikeus Secret-objekteihin koko klusterissa, myös omissa nimiavaruuksissasi. Alusta rajoittaa sitä, mitä se saa kirjoittaa, ei sitä, mitä se saa lukea.

  • Palvelutilitokenit hylätään tarkoituksella. ESO ei saa kirjoittaa Secret-objekteja alustan nimiavaruuksiin. Missään nimiavaruudessa se ei saa luoda tai päivittää kubernetes.io/service-account-token-tyyppistä Secretiä tai Secretiä, jossa on annotaatio kubernetes.io/service-account.name, eikä se saa pyytää tokeneita alustan palvelutileille. ExternalSecret, jonka kohteeksi tulisi tällainen Secret — target.template-mallin kautta tai creationPolicy: Merge -asetuksella olemassa olevaan Secretiin — ei synkronoidu, ja komennon kubectl describe externalsecret näyttämä virhe sisältää:

    text
    the external-secrets add-on may not create or update a service-account token Secret
  • Poista oma ESO-asennuksesi ensin, tässä järjestyksessä:

    1. Kun oma ESO:si on vielä käynnissä, poista tai irrota jokainen ExternalSecret kohdan Lisäosan poistaminen mukaisesti.
    2. Poista oma ESO-asennuksesi.
    3. Poista sen CRD:t.

    Noudata järjestystä. CRD:n poistaminen poistaa kaikki sen tyyppiset ExternalSecret-objektit ja creationPolicy: Owner -asetuksella myös niiden Secretit; ilman ohjainta, joka poistaisi niiden finalizerit, CRD jää tilaan Terminating, eikä lisäosa voi asentaa omiaan. Paikalleen jättämäsi CRD:t lisäosa ottaa hallintaansa sellaisinaan, myös lisäämäsi kentät.

Lisäosan poistaminen ​

Lisäosan poistaminen jättää myös external-secrets-nimiavaruuden paikalleen. Se pysyy alustan varaamana, joten kubeconfigisi ei edelleenkään voi käyttää sitä, ja kun lisäosa lisätään uudelleen, se otetaan taas käyttöön.

Käsittele jokainen ExternalSecret ENNEN lisäosan poistamista

ESO lisää siivous-finalizerin jokaiseen ExternalSecret-objektiin. Lisäosan poistaminen poistaa ESO-ohjaimen ja sen webhookit mutta jättää CRD:t paikalleen, eikä ohjaimen poistuttua mikään poista finalizeria. Klusteriin jäävää ExternalSecret-objektia ei silloin voi poistaa, eikä myöskään nimiavaruutta, joka sisältää sellaisen.

  1. Listaa ExternalSecret-objektit jokaisessa nimiavaruudessa. Kaikkien nimiavaruuksien listaus hylätään, joten aja komento kerran nimiavaruutta kohden:

    bash
    kubectl -n <namespace> get externalsecrets
  2. Jokaiselle ExternalSecret-objektille, jonka Secretin haluat säilyttää, tee kaikki nämä järjestyksessä. Älä odota, että ESO luopuu omistajuudesta synkronoinnin yhteydessä: se tapahtuu vain onnistuneessa synkronoinnissa, ja epäonnistunut haku, tyhjä tulos Retain-asetuksella tai tietyt päivitysasetukset ohittavat sen. <target> on Secret, joka on nimetty kentässä spec.target.name, tai ExternalSecret-objektin oma nimi, jos kenttää ei ole asetettu.

    1. Aseta ensin creationPolicy: Orphan; Owner-asetuksella ESO lisää omistajaviittauksen takaisin seuraavassa synkronoinnissa:
      bash
      kubectl -n <namespace> patch externalsecret <name> \
        --type=merge -p '{"spec":{"target":{"creationPolicy":"Orphan"}}}'
    2. Tarkista, onko Secretillä yhä omistajaviittaus:
      bash
      kubectl -n <namespace> get secret <target> -o jsonpath='{.metadata.ownerReferences}'
    3. Vain jos komento tulosti jotain, poista viittaus ja aja sitten vaihe 2.2 uudelleen, kunnes mitään ei tulostu. Patchin palauttama 422 (Unprocessable Entity) ei ole virhe: Secretillä ei ole poistettavaa omistajaviittausta, joten se on jo turvassa.
      bash
      kubectl -n <namespace> patch secret <target> \
        --type=json -p '[{"op":"remove","path":"/metadata/ownerReferences"}]'
    4. Poista ExternalSecret; Secret säilyy:
      bash
      kubectl -n <namespace> delete externalsecret <name>
  3. Jokaiselle ExternalSecret-objektille, jonka Secretiä et tarvitse, poista ExternalSecret, kun ESO on vielä käynnissä. Oletusarvolla creationPolicy: Owner sen synkronoitu Secret poistetaan sen mukana, ja kaikki, mikä vielä käyttää tätä Secretiä, lakkaa toimimasta: sitä käyttävät podit epäonnistuvat seuraavan käynnistyksen yhteydessä, ja jos se on vedosten pull-secret, uudet solmut eivät enää pysty hakemaan vedosta.

  4. Poista lisäosa vasta sitten — Lisäosat-välilehdeltä, komennolla fm kubernetes cluster remove-addons <cluster-id> --addons external-secrets tai poistamalla avain addons-joukosta Terraformissa.

Jos olet jo poistanut lisäosan ​

Finalizerin poistaminen voi poistaa synkronoidun Secretin

Oletusarvolla creationPolicy: Owner synkronoidun Secretin omistaa sen ExternalSecret. Kun finalizer on poissa ja ExternalSecret on poistettu, Kubernetesin roskienkeruu poistaa myös Secretin — myös asetuksella deletionPolicy: Retain.

Jokaiselle jäljellä olevalle ExternalSecret-objektille:

  1. Jos itse nimiavaruus on poistumassa, et voi säilyttää Secretiä: kaikki sen Secretit poistetaan omistajaviittauksista riippumatta. Luo Secret uudelleen muualle Frostmoln Salaisuuksista. Muussa tapauksessa, säilyttääksesi sen Secretin, tarkista ensin, onko sillä omistajaviittaus, ja poista se tarvittaessa (vaiheet 2.2 ja 2.3 yllä).
  2. Poista finalizer:
    bash
    kubectl -n <namespace> patch externalsecret <name> \
      --type=merge -p '{"metadata":{"finalizers":null}}'
  3. Jos ExternalSecret ei ole jo poistumassa, poista se.

Frostmolnin klustereissa tämä finalizer on vain ExternalSecret-objekteilla, koska PushSecret ja ClusterExternalSecret eivät ole käytössä.

Vaihe 1 — Tallenna API-avain merkittynä Secret-objektina ​

API-avain: muut kuin Frostmolnin hallitut Kubernetes-klusterit

Vaiheet 1 ja 2 käyttävät API-avainta. Frostmolnin hallitussa Kubernetesissa käytä sen sijaan työkuormaidentiteettiä.

ESO:n webhook-tarjoaja lukee API-avaimen Kubernetes-Secret-objektista. Secretin on kannettava merkintää external-secrets.io/type: webhook — webhook-tarjoaja kieltäytyy lukemasta merkitsemätöntä Secretiä.

Tallenna avain paikalliseen tiedostoon, joka sisältää vain avaimen ilman loppurivinvaihtoa. Luo Secret tiedostosta, merkitse se ja poista sitten tiedosto:

bash
kubectl -n default create secret generic frostmoln-api-key --from-file=apikey=./apikey
# PAKOLLINEN — webhook-tarjoaja ohittaa merkitsemättömän Secretin
kubectl -n default label secret frostmoln-api-key external-secrets.io/type=webhook
rm ./apikey

Käytä komentoa kubectl create, älä kubectl apply -komentoa manifestin kanssa: apply tallentaa koko manifestin avain mukaan lukien selväkielisenä Secretin annotaatioon kubectl.kubernetes.io/last-applied-configuration. Älä vie avainta gitiin. Vain alla olevat SecretStore- ja ExternalSecret-manifestit ovat turvallisia pitää versionhallinnassa.

Pidä avain omassa nimiavaruudessaan

SecretStore lukee API-avaimen Secretin omasta nimiavaruudestaan, joten avain, varasto ja sitä käyttävät ExternalSecret-objektit jakavat nimiavaruuden. Avain voi lukea jokaisen tenanttisi salaisuuden, ja niin voi myös jokainen, joka voi lukea Secret-objekteja kyseisessä nimiavaruudessa. Käytä niille omaa nimiavaruutta ja pidä sen RBAC tiukkana. Tämän sivun esimerkit käyttävät nimiavaruutta default.

Vaihe 2 — Luo SecretStore ​

SecretStore osoittaa ESO:n Frostmolnin hakupäätepisteeseen. Käytä CRD-ryhmää external-secrets.io/v1 (ei vanhempaa v1beta1). Korvaa <TENANT_ID> tenant-tunnuksellasi.

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-salaisuus-KARTTA: <secrets-merkinnan-nimi>.<data-avain>.
        # {{ .apikey }} renderoi koko kartan ja API palauttaa 401 — käytä .apikey-avainta.
        X-API-Key: '{{ .apikey.apikey }}'
      result:
        jsonPath: '$.secretValue'
      secrets:
        - name: apikey
          secretRef:
            name: frostmoln-api-key
            key: apikey

URL:n {{ .remoteRef.key }} täytetään ExternalSecret-kohtaisesti Frostmolnin salaisuuden nimellä (Vaihe 3), joten yksi SecretStore palvelee kaikkia salaisuuksiasi.

Vaihe 3 — Luo ExternalSecret ​

Jokainen ExternalSecret yhdistää yhden Frostmoln-salaisuuden yhteen Kubernetes-Secret-objektiin. remoteRef.key on Frostmolnin salaisuuden nimi; target.name on Kubernetes-Secret, jonka ESO luo ja pitää synkronoituna.

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 # avain synkronoidun Kubernetes-Secretin sisällä
      remoteRef: { key: my-secret-name } # Frostmolnin salaisuuden nimi

ESO luo my-secret-synced-Secretin, jossa on value-avain, joka pitää haetun salaisuusarvon. Liitä se tai viittaa siihen Podissasi kuten mihin tahansa muuhun Secretiin.

Päivitysväli ​

refreshInterval säätää, kuinka usein ESO hakee uudelleen. Lyhyt väli levittää kierrätykset nopeammin mutta tekee enemmän API-kutsuja; pidempi on kevyempi. Valitse salaisuuskohtaisesti sen mukaan, kuinka nopeasti kierrätyksen on tavoitettava työkuormasi — minuutti tai muutama minuutti on tyypillinen.

Kiinnitä tietty versio ​

Frostmoln-salaisuudet ovat versioituja. Kiinnitä versio lisäämällä &version=NSecretStore-URL:iin (luo toinen SecretStore kiinnitetylle salaisuudelle):

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

Ilman &version-parametria ESO lukee aina uusimman version.

Salaisuuden poistaminen on vikaturvallista ​

Jos ajat fm secrets delete salaisuudelle, jota ESO synkronoi, haku alkaa palauttaa virheen (salaisuus siirtyy odottavaan poistoon). ESO:n päivitys epäonnistuu (SecretSyncedError) ja pitää viimeksi synkronoidun Kubernetes-Secret-objektin muuttumattomana — se ei tyhjennä sitä. Työkuormasi jatkavat toimintaansa viimeisimmällä tunnetulla toimivalla arvolla.

Palauta jatkaaksesi synkronointia

Kun salaisuus on poistettu, ESO ei voi päivittää sitä ja klusterisi arvo vanhenee. Aja fm secrets recover <name> palautusikkunan sisällä palauttaaksesi sen; ESO jatkaa tällöin synkronointia seuraavalla välillä. Jos palautusikkuna umpeutuu ja salaisuus poistetaan pysyvästi, haku jatkaa epäonnistumista — luo salaisuus uudelleen jatkaaksesi.

Vianmääritys ​

Tarkista ExternalSecret-tila komennolla kubectl describe externalsecret <name>.

  • secret does not contain needed label — API-avaimen Secret-objektista puuttuu merkintä external-secrets.io/type: webhook (Vaihe 1).
  • 401 / luvaton — header-malli on väärä. Sen on oltava {{ .apikey.apikey }} (<secrets-merkinnan-nimi>.<data-avain>); {{ .apikey }} renderoi koko kartan ja API hylkää sen. Tarkista myös avaimen arvo ja että avain ei ole vanhentunut.
  • Työkuormaidentiteetti: frostmoln-token-Secret ei ilmesty — tarkista, että Workload Identity -lisäosa on klusterissa, että palvelutilillä on annotaatio ja sidonta ja ettei samannimistä Secretiä ollut olemassa ennestään: lisäosa ei koskaan korvaa Secretiä, jota se ei ole itse luonut.
  • could not get secret data from provider — salaisuuden nimi tai tenant-tunnus on väärä, tai salaisuus on poistettu / odottaa poistoa. Varmista, että nimi löytyy: fm secrets get <name>.
  • Mitään ei synkronoidu lainkaan — tarkista, että SecretStore käyttää ryhmää external-secrets.io/v1, ei v1beta1. Itse ajamassasi klusterissa vahvista, että ESO on käynnissä (kubectl -n external-secrets get pods). Frostmolnin hallitussa Kubernetesissa et voi listata näitä podeja: varmista, että lisäosa on klusterissa (fm kubernetes cluster addons <cluster-id> tai Lisäosat-välilehti), että sen lisäämisestä on kulunut yli muutama minuutti (jos alusta ilmoitti, ettei se voinut käynnistää synkronointia, varaa enemmän aikaa: yleensä enintään tunti, alustan huoltotöiden aikana pidempään) ja että solmusi tavoittavat osoitteet ghcr.io ja pkg-containers.githubusercontent.com.

Liittyvät ​