ExternalDNS
ExternalDNS holder postene i dine Frostmoln Administrert DNS-soner synkronisert med Kubernetes-ressursene Ingress, Service og Gateway API — fra hvilken som helst Kubernetes-klynge. Når du eksponerer en arbeidslast, opprettes, oppdateres og ryddes vertsnavnets poster opp automatisk; du redigerer aldri DNS for hånd.
Frostmoln leverer en webhook-leverandør som kjører som en sidecar i external-dns-poden og oversetter ExternalDNS' planer til kall mot Frostmolns DNS-API.
Forutsetninger
- En Frostmoln DNS-sone for domenet du vil ha poster i — se Administrert DNS for å opprette en.
- En legitimasjon for webhooken, en av:
- Workload Identity (anbefalt): ingen nøkkel å opprette eller lagre. Se Autentiser med Workload Identity.
- En tenant-API-nøkkel (
fmk_...) som eies av en bruker i den tenanten. Se Lagre en API-nøkkel.
- Utgående HTTPS fra arbeidsnodene dine til
registry.k8s.ioogregistry.sweden.frostmoln.cloud. Oppstrøms ExternalDNS-kontrollerbildet hentes fraregistry.k8s.ioog Frostmolns webhook-bilde fraregistry.sweden.frostmoln.cloudnår poden starter. Filtrerer du utgående trafikk per vertsnavn, er det ikke nok å tillateregistry.k8s.io: hentingen omdirigeres til skybaserte lagringssteder på andre domener. Uten dette blir kontrollercontaineren stående iImagePullBackOff, og plattformen kan ikke varsle deg — tilgjengeligheten hører til ditt VPC, ikke til oss.
Slik fungerer det
- Poster — webhooken lister tenantens soner og postsett og returnerer dem til ExternalDNS som endepunkter (ett postsett = ett
(navn, type)med alle verdiene). - Anvend — opprettelser og oppdateringer går gjennom DNS-API-ets idempotente upsert på samlingsnivå; slettinger løses opp via postsettets stabile ID.
- Domenefilter — som standard henter webhooken tenantens sonenavn ved oppstart og administrerer bare disse. Opprett en ny sone → start poden på nytt slik at den plukkes opp (eller angi
DOMAIN_FILTEReksplisitt). - Eierskap — bruk ExternalDNS' standard TXT-register (
--registry=txtmed--txt-owner-id=<klynge-id>) slik at en post bare endres av klyngen som opprettet den. TXT-postsett går uendret gjennom API-et.
Installer
På Frostmoln Administrert Kubernetes er ExternalDNS med Frostmoln-webhooken et klyngetillegg med ett klikk. Velg external-dns når du oppretter klyngen, eller legg det til i en klynge som allerede kjører (portalen → klyngens fane Tillegg, fm kubernetes cluster add-addons, eller settet addons i API-et/Terraform-ressursen), så installerer plattformen alt for deg — navnerommet external-dns, RBAC, ExternalDNS-kontrolleren og Frostmoln-webhook-sidecaren, med --txt-owner-id allerede satt til klyngens id og FROSTMOLN_TENANT_ID satt til klyngens tenant. Webhook-bildet leveres av plattformen og hentes fra registry.sweden.frostmoln.cloud (se forutsetningene). Du bygger eller refererer aldri til det selv.
Det eneste steget som gjenstår for deg er legitimasjonen: en Workload Identity-binding (anbefalt) eller en API-nøkkel-Secret. Inntil en av dem finnes, avslutter webhook-containeren på tilleggsversjon v0.22.0-4 med no credential og startes på nytt (CrashLoopBackOff). På tidligere versjoner venter den i CreateContainerConfigError. Opprett DNS-sonen din først (eller start external-dns-Deploymenten på nytt etter at du har opprettet den).
Tilleggsversjonene v0.22.0-1 og v0.22.0-2: flytt låsingen til v0.22.0-3
I de to versjonene spør webhooken API-et om hjemmetenanten til brukeren som opprettet nøkkelen, og administrerer den tenantens soner. Hvis nøkkelen ble opprettet i en annen tenant — klyngens, når brukeren din tilhører mer enn én — avslutter webhooken ved oppstart med 403 TENANT_ACCESS_DENIED, og poden blir stående i CrashLoopBackOff. Fra v0.22.0-3 setter plattformen webhookens tenant til klyngens egen. Begge de eldre versjonene er merket som utfasede. Flytt en eksisterende klynge med fm kubernetes cluster pin-addons <cluster-id> --version external-dns=v0.22.0-3, portalens fane Tillegg, eller addon_versions i Terraform — se Kubernetes → Tilleggsversjoner.
Legg det til ved opprettelse, eller senere
Tillegget kan velges når klyngen opprettes og legges til i en klynge som allerede kjører. Å legge det til i etterkant skjer ikke umiddelbart: tillegget starter sin egen synkronisering og installeres vanligvis i løpet av noen minutter; kan ikke den synkroniseringen startes, skjer det først ved plattformens neste synkronisering, inntil en time. Klyngens tilleggsliste viser det nye valget så snart det er akseptert — det er valget du har gjort, ikke et bevis på at objektene allerede er på klyngen.
Å fjerne det er en egen, navngitt handling. I API-et og i Terraform sender du alltid hele det ønskede settet med tillegg, ikke bare den nye nøkkelen — og et sett som rett og slett utelater external-dns, blir avvist, fordi en forespørsel bygget på et utdatert bilde av klyngen ellers ville fjernet et tillegg du aldri mente å røre. Navngi i stedet det du fjerner: knappen Fjern i portalen, fm kubernetes cluster remove-addons, eller feltet remove i forespørselen til API-et. I Terraform anvendes en fjernet nøkkel i addons nå på stedet i stedet for å erstatte klyngen.
Noen klynger som ble opprettet før denne muligheten kom, kan ikke ta imot nye tillegg i det hele tatt; API-et sier fra når du prøver, og da er eneste vei å opprette klyngen på nytt med tillegget valgt. ExternalDNS med Frostmoln-webhooken er foreløpig tilgjengelig kun på Frostmoln Administrert Kubernetes.
Administrert Kubernetes: aktiver tillegget
På Frostmoln Administrert Kubernetes er den enkleste veien klyngetillegget external-dns: velg det når klyngen opprettes, eller legg det til i en klynge som allerede kjører (portalen → klyngens fane Tillegg, fm kubernetes cluster add-addons, eller settet addons i API-et/Terraform-ressursen), så installerer plattformen alt i denne veiledningen — navnerommet external-dns, RBAC og Deploymenten, med --txt-owner-id allerede satt til klyngens id.
Det eneste manuelle steget er legitimasjonen. Se Autentiser med Workload Identity (anbefalt) eller Lagre en API-nøkkel.
Legges til i etterkant, og kan fjernes
Tillegget kan også legges til i en klynge som allerede kjører, og starter da sin egen synkronisering og installeres vanligvis i løpet av noen minutter; kan ikke den synkroniseringen startes, skjer det først ved plattformens neste synkronisering, inntil en time. Det kan fjernes på samme måte — fra fanen Tillegg i portalen, med fm kubernetes cluster remove-addons, eller ved å fjerne nøkkelen. En klynge som ble opprettet før den enkelte muligheten kom, kan ikke ta imot det, eller ikke fjerne det, og sier fra når du prøver; opprett den klyngen på nytt, eller bruk manifestet under Distribuer selv.
En fjerning lar DNS-oppføringene dine bli igjen. ExternalDNS eier oppføringene det opprettet, og å fjerne kontrolleren sletter dem ikke — ingenting vil håndtere dem etterpå. Hvis du senere sletter en lastbalanserer en slik oppføring peker på, går adressen tilbake til puljen og kan tildeles noen andre mens oppføringen din fortsatt peker dit. Å velge tillegget igjen i samme klynge gjør at det tar tilbake sine egne oppføringer og fortsetter å håndtere dem.
Med Workload Identity sletter du tilleggets binding (eller kjører terraform destroy på den) for å tilbakekalle tilgangen. Ingen nøkkel blir liggende igjen.
Med en API-nøkkel beholdes også navnerommet external-dns og frostmoln-dns-hemmeligheten din. Hemmeligheten inneholder en Frostmoln-API-nøkkel, og å slette hemmeligheten tilbakekaller ikke nøkkelen. Gjør dette i denne rekkefølgen:
Hvis noe annet bruker den samme nøkkelen, gi det først en egen nøkkel.
Tilbakekall denne nøkkelen. Bare brukeren som opprettet den, kan gjøre det: under Innstillinger → API-nøkler i portalen, eller med
fm account api-key listogfm account api-key revoke. Alle nøkler begynner medfmk_, så sammenlign nøkkelens første 12 tegn med det listede nøkkelprefikset. Les dem fra hemmeligheten:bashkubectl -n external-dns get secret frostmoln-dns -o jsonpath='{.data.api-key}' | base64 -d | cut -c1-12Slett hemmeligheten først etter det — plattformen viser aldri hele nøkkelen igjen, så les prefikset før hemmeligheten er borte.
Hvis ExternalDNS ikke er fjernet ennå, logger det autentiseringsfeil etter tilbakekallingen til det er borte; ikke legg en ny nøkkel i denne hemmeligheten for å få dem til å stoppe. For å velge tillegget igjen senere oppretter du en ny nøkkel og hemmelighet.
Bytte ut en klynge: ta over postene dens
ExternalDNS endrer bare poster der TXT-eierskapsposten angir dens egen klynge-id. En ny klynge får en ny id, så den oppdaterer ikke poster som en tidligere klynge har publisert, heller ikke under de samme navnene. Loggen viser All records are already up to date mens navnet fortsatt peker på den gamle klyngens adresse. Det skjer når du sletter en klynge og oppretter en ny, og det er også slik en blue/green-flytting mellom klynger oppfører seg.
For å overlate et navn til den nye klyngen skriver du om eieren i TXT-posten når du bytter over:
Finn den nye klyngens id med
fm kubernetes cluster list.List sonens TXT-poster med
fm dns record list <zone-id> --type TXT -o json. ExternalDNS navngir hver av dem etter posten den eier, med posttypen foran, såa-www.example.comeier A-postenwww.example.com. Verdien inneholderexternal-dns/owner=<gammel klynge-id>.Kopier verdien nøyaktig, og bytt bare id-en etter
external-dns/owner=:bashfm dns record update <zone-id> <txt-record-id> --value '<verdien med den nye klynge-id-en>'
Innen ett minutt behandler den nye klyngens ExternalDNS posten som sin egen og peker den mot den nye adressen. Kjører den gamle klyngen fortsatt, slutter den å styre navnet fra samme øyeblikk.
Skriv om alle eierskapspostene for et navn før du går videre til det neste. Det finnes én per posttype (A, AAAA, CNAME), og et navn der en eierskapspost fortsatt har den gamle id-en, styres ikke av noen av klyngene. Et jokertegn *.example.com eies av a-*.example.com. Det virker ikke for et navn i sonens apex, fordi eierskapsposten da ville havne utenfor sonen.
Ikke gjenbruk den gamle id-en i den nye klyngens --txt-owner-id i stedet. I det administrerte tillegget settes verdien av plattformen, og to kjørende klynger som deler én eier-id, sletter hverandres poster.
Autentiser med Workload Identity (anbefalt)
Fra tilleggsversjon v0.22.0-4 autentiserer webhooken med Workload Identity. Plattformen oppretter et kortlivd, soneavgrenset token for den og fornyer det omtrent hver time. Det finnes ingen API-nøkkel å opprette, lagre i en Secret, rotere eller tilbakekalle, og ingenting havner i Terraform-tilstanden din. Tilleggets tjenestekonto (external-dns i navnerommet external-dns) er allerede påmeldt, så du trenger bare å gi det tilgang.
Du trenger:
- Tillegget Workload Identity i samme klynge. Se Workload Identity → Trinn 1.
- Tillegget external-dns i versjon v0.22.0-4 eller nyere. Flytt låsingen på en eksisterende klynge med
fm kubernetes cluster pin-addons <cluster-id> --version external-dns=v0.22.0-4, portalens fane Tillegg, elleraddon_versionsi Terraform. - En binding for
external-dns/external-dnsmed en tilgangspolicy som lar den liste soner, og lese, oppdatere og slette på sonene den håndterer. Å opprette eller endre en oppføring regnes som en oppdatering av sonen som eier den, og å slette en oppføring regnes som en sletting på den sonen. Avgrens den regelen til sonens id:
resource "frostmoln_workload_identity_binding" "external_dns" {
cluster_id = frostmoln_kubernetes_cluster.prod.id
namespace = "external-dns"
service_account = "external-dns"
}
data "frostmoln_iam_policy_document" "external_dns" {
rule {
name = "list-zones"
access = "allow"
operations = ["network:dns-zones:list"]
targets = ["frn:network:*:*:dns-zones/*"]
}
rule {
name = "manage-zone"
access = "allow"
operations = ["network:dns-zones:read", "network:dns-zones:update", "network:dns-zones:delete"]
targets = ["frn:network:*:*:dns-zones/${frostmoln_dns_zone.example.id}"]
}
}
resource "frostmoln_iam_policy" "external_dns" {
name = "external-dns"
document = data.frostmoln_iam_policy_document.external_dns.json
}
resource "frostmoln_iam_policy_attachment" "external_dns" {
policy_id = frostmoln_iam_policy.external_dns.id
attachee_type = "workload_identity"
attachee_id = frostmoln_workload_identity_binding.external_dns.id
}network:dns-zones:delete tillater også å slette sonen
Oppføringer har ennå ingen egen rettighet, så rettigheten external-dns trenger for å fjerne en oppføring lar også den legitimasjonen slette hele sonen den er avgrenset til. Hold regelen avgrenset til sonene external-dns håndterer. Uten delete publiserer external-dns oppføringer, men kan aldri fjerne dem: en oppføring for en slettet Service blir liggende i DNS og peker på en adresse som kan bli gjenbrukt, og webhooken logger 403 ... does not permit network:dns-zones:delete hvert minutt.
Med fm-CLI-en oppretter du bindingen uten rettigheter og knytter til den samme policyen:
fm kubernetes workload-identity binding create \
--cluster <cluster-id> --namespace external-dns --service-account external-dns
fm iam policy create --name external-dns --document @external-dns-policy.json
fm iam policy attach <policy-id> --type workload_identity --id <binding-id>Når tillegget Workload Identity og bindingen er på plass, trenger du ikke gjøre noe mer. Legitimasjonen kobles bare inn i en pod når poden opprettes, så en pod som ble opprettet før tillegget Workload Identity kjørte, får den ikke. Det gjelder også klynger der begge tilleggene ble valgt samtidig. Fra workload-identity v0.3.0-1 starter tillegget selv en slik pod på nytt innen et par minutter, og den kommer tilbake med legitimasjonen. På en eldre versjon av workload-identity fortsetter poden å bruke API-nøkkelen eller, uten en, startes på nytt med workload identity is not injected. Flytt klyngen til den nyere versjonen:
fm kubernetes cluster pin-addons <cluster-id> --version workload-identity=v0.3.0-1Webhooken logger hvilken legitimasjon den bruker:
kubectl -n external-dns logs deploy/external-dns -c frostmoln-webhook | grep authenticating
# ... "authenticating with the workload-identity credential"Workload Identity går foran en API-nøkkel
Hver forespørsel bruker Workload Identity-tokenet når det finnes, og faller tilbake på API-nøkkelen i frostmoln-dns bare når det ikke finnes noe. Det skjer for eksempel når tillegget Workload Identity er installert, men det ikke finnes noen binding for external-dns. Dermed kan du migrere uten nedetid: legg til bindingen, sjekk logglinjen ovenfor, og tilbakekall deretter nøkkelen og slett Secreten. Hvis en binding slettes, utløper det siste tokenet innen omtrent en time. Deretter mislykkes webhookens forespørsler med 401 til en binding finnes igjen. Nøkkelen brukes ikke som reserve mens det utløpte tokenet fortsatt ligger på disk.
Lagre en API-nøkkel (reserve)
Bruk en API-nøkkel der Workload Identity ikke er tilgjengelig: i en klynge uten tillegget Workload Identity, på tilleggsversjoner før v0.22.0-4, eller når du selv distribuerer manifestet nedenfor. Legg tenant-API-nøkkelen i en Secret som webhooken kan lese:
kubectl create namespace external-dns # hopp over hvis tillegget allerede har opprettet det
kubectl create secret generic frostmoln-dns \
--namespace external-dns \
--from-literal=api-key=fmk_...Distribuer
På Administrert Kubernetes med tillegget aktivert kan du hoppe over dette avsnittet — bare Secreten ovenfor trengs.
Manifestet nedenfor kjører external-dns med Frostmoln-webhooken som en sidecar, pluss ServiceAccount og RBAC som external-dns trenger. Erstatt <klynge-id> med en verdi som er unik for denne klyngen — den stempler TXT-eierskapspostene slik at flere klynger trygt kan dele en sone. Podden deklarerer hele Pod Security-kontrakten restricted (Administrert Kubernetes håndhever den på hele klyngen; den eksplisitte runAsUser er viktig fordi external-dns-bildet oppstrøms kjører som root).
På Administrert Kubernetes er webhook-bildet forhåndslastet på nodene dine, og det ligger i et Frostmoln-internt register klyngen din ikke når — så <webhook-image> er ikke ditt valg. Den må være en referanse som allerede ligger på nodene; enhver annen verdi etterlater sidecaren i ImagePullBackOff. Hent den fra klyngen og lim den inn ordrett:
kubectl get nodes -o json \
| jq -r '.items[].status.images[]?.names[]?' \
| grep 'external-dns-frostmoln-webhook:' | sort -uMer enn én referanse betyr at nodepoolen din spenner over to nodebildegenerasjoner: bruk den som ligger på hver node, eller rull poolen på nytt så de samsvarer. Ingen utdata i det hele tatt betyr at bildet ikke er listet på en travel node — prøv én node om gangen (kubectl get node <name> -o json), eller kontakt supporten.
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
namespace: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: ['']
resources: ['services', 'endpoints', 'pods', 'nodes']
verbs: ['get', 'watch', 'list']
- apiGroups: ['discovery.k8s.io']
resources: ['endpointslices']
verbs: ['get', 'watch', 'list']
- apiGroups: ['extensions', 'networking.k8s.io']
resources: ['ingresses']
verbs: ['get', 'watch', 'list']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: external-dns
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: external-dns
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
seccompProfile:
type: RuntimeDefault
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.21.0
args:
- --source=ingress
- --source=service
- --provider=webhook
- --registry=txt
- --txt-owner-id=<cluster-id>
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
- name: frostmoln-webhook
image: <webhook-image>
imagePullPolicy: IfNotPresent
env:
- name: FROSTMOLN_API_KEY
valueFrom:
secretKeyRef:
name: frostmoln-dns
key: api-key
ports:
- containerPort: 8080
name: http
livenessProbe:
httpGet:
path: /healthz
port: http
readinessProbe:
httpGet:
path: /healthz
port: http
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]Anvend det:
kubectl apply -f external-dns.yamlWebhook-API-et lytter bare på podens loopback — det er uautentisert etter kontrakt og nekter enhver annen bindingsadresse — og FROSTMOLN_API_URL må være https. Begge håndheves ved oppstart.
Konfigurasjon
Tillegget setter fornuftige standardverdier. For å justere webhook-sidecaren, rediger external-dns-Deploymenten og sett disse miljøvariablene:
| Variabel | Standard | Beskrivelse |
|---|---|---|
FROSTMOLN_WORKLOAD_CREDENTIALS_FILE | settes av Workload Identity | Tokenfilen for Workload Identity. Injiseres av plattformen; ikke sett den selv |
FROSTMOLN_API_KEY | — | Tenant-API-nøkkel (fmk_...). Ikke nødvendig med Workload Identity |
FROSTMOLN_API_KEY_FILE | — | Les nøkkelen fra en montert fil i stedet, for å holde den ute av pod-env |
FROSTMOLN_API_URL | https://api.frostmoln.cloud/api | Basis-URL for kunde-API-et (må være https) |
FROSTMOLN_TENANT_ID | utledet fra nøkkelen | Tenanten hvis soner administreres; sett den til nøkkelens tenant når det ikke er brukerens hjemmetenant |
DOMAIN_FILTER | dine sonenavn | Overstyring av kommaseparert domenefilter |
ZONE_CACHE_TTL | 1m | Hvor lenge sonekatalogen bufres |
DRY_RUN | false | Logg endringene ExternalDNS ville gjort uten å anvende dem |
På tillegget fra v0.22.0-3 er FROSTMOLN_TENANT_ID allerede satt til klyngens tenant fra plattformens ConfigMap external-dns-cluster-identity — ikke overstyr den. Uten den faller webhooken tilbake til nøkkelens hjemmetenant.
Merknader og forbehold
- Offentlige soner avviser private mål og loopback-mål. En A/AAAA-post i en offentlig sone må peke på en rutbar adresse — en lastbalanserer eller en offentlig IP, ikke en klyngeintern IP. For interne navn, bruk en privat (
vpcId) sone. - Deleger sonen før du forventer offentlig oppslag. En sone svarer på internett først når domenet ditt er delegert til navnetjenerne dens — se Administrert DNS → Deleger domenet ditt.
- Nye soner krever en omstart av webhooken. Domenefilteret hentes én gang ved oppstart, så start external-dns-poden på nytt etter at du oppretter en sone du vil at ExternalDNS skal administrere.
- TXT-eierskap støttes innebygd — behold
--registry=txtmed en--txt-owner-idsom er unik for hver klynge, slik at flere klynger trygt kan dele en sone. En erstatningsklynge må ta over forgjengerens poster.