Merge branch 'master' into fix-crash-loop

* master: (78 commits)
  Update README.md with Efficient IP Provider
  feat(chart): Updated image to v0.15.0
  fix(chart): Don't use unauthenticated webhook port for health probe
  Remove unused session logic after move to aws-sdk-go-v2
  Refactor AWS provider to aws-sdk-go-v2
  Refactor AWS Cloud Map provider to aws-sdk-go-v2
  Refactor DynamoDB registry to aws-sdk-go-v2
  Update docs/release.md
  update the docs to v0.15.0
  bump kustomize version to v0.15.0
  add deprecation notice on coredns tutorial
  docs: refactor title and organisation
  review with Raffo
  chore: remove unmaintained providers
  chore(deps): bump actions/setup-python in the dev-dependencies group
  Add RouterOS provider to README.md
  feat: add annotation and label filters to Ambassador Host Source (#2633)
  chore(deps): bump GrantBirki/json-yaml-validate
  fix linter
  fix ordering
  ...
This commit is contained in:
ivan katliarchuk 2024-09-14 10:03:52 +01:00
commit ec402b057f
No known key found for this signature in database
GPG Key ID: 601CDBBBB76E47BE
153 changed files with 2807 additions and 40985 deletions

View File

@ -20,15 +20,15 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out code into the Go module directory
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Set up Go 1.x - name: Set up Go 1.x
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.22.4' go-version-file: go.mod
id: go id: go
- name: Check out code into the Go module directory
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Install CI - name: Install CI
run: | run: |
go get -v -t -d ./... go get -v -t -d ./...

View File

@ -30,7 +30,7 @@ jobs:
- name: Install go version - name: Install go version
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '^1.22.4' go-version-file: go.mod
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL

View File

@ -19,16 +19,12 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
with: with:
python-version: "3.12" python-version: "3.12"
cache: "pip" cache: "pip"
cache-dependency-path: "./docs/scripts/requirements.txt" cache-dependency-path: "./docs/scripts/requirements.txt"
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with:
go-version-file: 'go.mod'
- run: | - run: |
pip install -r docs/scripts/requirements.txt pip install -r docs/scripts/requirements.txt

View File

@ -17,7 +17,7 @@ jobs:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: json-yaml-validate - name: json-yaml-validate
uses: GrantBirki/json-yaml-validate@v3.0.0 uses: GrantBirki/json-yaml-validate@v3.2.1
with: with:
comment: "true" # enable comment mode comment: "true" # enable comment mode
yaml_exclude_regex: "(charts/external-dns/templates.*|mkdocs.yml)" yaml_exclude_regex: "(charts/external-dns/templates.*|mkdocs.yml)"

View File

@ -19,7 +19,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- name: Install Helm Docs - name: Install Helm Docs
uses: action-stars/install-tool-from-github-release@243ac555111a84756285bf7dc55df821a55d32d9 # v0.2.3 uses: action-stars/install-tool-from-github-release@ece2623611b240002e0dd73a0d685505733122f6 # v0.2.4
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
owner: norwoodj owner: norwoodj
@ -40,7 +40,7 @@ jobs:
fi fi
- name: Install Artifact Hub CLI - name: Install Artifact Hub CLI
uses: action-stars/install-tool-from-github-release@243ac555111a84756285bf7dc55df821a55d32d9 # v0.2.3 uses: action-stars/install-tool-from-github-release@ece2623611b240002e0dd73a0d685505733122f6 # v0.2.4
with: with:
github_token: ${{ github.token }} github_token: ${{ github.token }}
owner: artifacthub owner: artifacthub
@ -59,7 +59,7 @@ jobs:
version: latest version: latest
- name: Install Python - name: Install Python
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
with: with:
token: ${{ github.token }} token: ${{ github.token }}
python-version: "3.x" python-version: "3.x"

View File

@ -8,6 +8,7 @@ on:
permissions: permissions:
contents: read # to fetch code (actions/checkout) contents: read # to fetch code (actions/checkout)
checks: write
jobs: jobs:
@ -20,16 +21,16 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Set up Go 1.x
uses: actions/setup-go@v5
with:
go-version: '1.22.4'
id: go
- name: Check out code into the Go module directory - name: Check out code into the Go module directory
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Set up Go 1.x
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Lint - name: Lint
run: | uses: golangci/golangci-lint-action@v6
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.57.2 with:
make lint args: --timeout=30m
version: v1.60

70
.github/workflows/scorecards.yml vendored Normal file
View File

@ -0,0 +1,70 @@
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '25 7 * * 0'
push:
branches: [ "main" , "issue-4673"]
workflow_dispatch:
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
# Uncomment the permissions below if installing in a private repository.
# contents: read
# actions: read
steps:
- name: "Checkout code"
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecard on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional.
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories:
# - `publish_results` will always be set to `false`, regardless
# of the value entered here.
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif

View File

@ -20,15 +20,15 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out code into the Go module directory
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Set up Go 1.x - name: Set up Go 1.x
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.22.4' go-version-file: go.mod
id: go id: go
- name: Check out code into the Go module directory
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Install CI - name: Install CI
run: | run: |
go get -v -t -d ./... go get -v -t -d ./...

View File

@ -41,7 +41,7 @@ CONTROLLER_GEN=$(shell which controller-gen)
endif endif
golangci-lint: golangci-lint:
@command -v golangci-lint > /dev/null || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.57.2 @command -v golangci-lint > /dev/null || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.60.3
# Run the golangci-lint tool # Run the golangci-lint tool
.PHONY: go-lint .PHONY: go-lint

3
OWNERS
View File

@ -6,19 +6,18 @@
# https://github.com/kubernetes/k8s.io/blob/master/registry.k8s.io/images/k8s-staging-external-dns/OWNERS # https://github.com/kubernetes/k8s.io/blob/master/registry.k8s.io/images/k8s-staging-external-dns/OWNERS
approvers: approvers:
- johngmyers
- mloiseleur - mloiseleur
- raffo - raffo
- szuecs - szuecs
reviewers: reviewers:
- johngmyers
- mloiseleur - mloiseleur
- raffo - raffo
- szuecs - szuecs
emeritus_approvers: emeritus_approvers:
- hjacobs - hjacobs
- johngmyers
- linki - linki
- njuettner - njuettner
- seanmalloy - seanmalloy

View File

@ -36,13 +36,10 @@ ExternalDNS allows you to keep selected zones (via `--domain-filter`) synchroniz
* [AWS Route 53](https://aws.amazon.com/route53/) * [AWS Route 53](https://aws.amazon.com/route53/)
* [AWS Cloud Map](https://docs.aws.amazon.com/cloud-map/) * [AWS Cloud Map](https://docs.aws.amazon.com/cloud-map/)
* [AzureDNS](https://azure.microsoft.com/en-us/services/dns) * [AzureDNS](https://azure.microsoft.com/en-us/services/dns)
* [BlueCat](https://bluecatnetworks.com)
* [Civo](https://www.civo.com) * [Civo](https://www.civo.com)
* [CloudFlare](https://www.cloudflare.com/dns) * [CloudFlare](https://www.cloudflare.com/dns)
* [RcodeZero](https://www.rcodezero.at/)
* [DigitalOcean](https://www.digitalocean.com/products/networking) * [DigitalOcean](https://www.digitalocean.com/products/networking)
* [DNSimple](https://dnsimple.com/) * [DNSimple](https://dnsimple.com/)
* [Dyn](https://dyn.com/dns/)
* [OpenStack Designate](https://docs.openstack.org/designate/latest/) * [OpenStack Designate](https://docs.openstack.org/designate/latest/)
* [PowerDNS](https://www.powerdns.com/) * [PowerDNS](https://www.powerdns.com/)
* [CoreDNS](https://coredns.io/) * [CoreDNS](https://coredns.io/)
@ -52,14 +49,11 @@ ExternalDNS allows you to keep selected zones (via `--domain-filter`) synchroniz
* [RFC2136](https://tools.ietf.org/html/rfc2136) * [RFC2136](https://tools.ietf.org/html/rfc2136)
* [NS1](https://ns1.com/) * [NS1](https://ns1.com/)
* [TransIP](https://www.transip.eu/domain-name/) * [TransIP](https://www.transip.eu/domain-name/)
* [VinylDNS](https://www.vinyldns.io)
* [Vultr](https://www.vultr.com)
* [OVH](https://www.ovh.com) * [OVH](https://www.ovh.com)
* [Scaleway](https://www.scaleway.com) * [Scaleway](https://www.scaleway.com)
* [Akamai Edge DNS](https://learn.akamai.com/en-us/products/cloud_security/edge_dns.html) * [Akamai Edge DNS](https://learn.akamai.com/en-us/products/cloud_security/edge_dns.html)
* [GoDaddy](https://www.godaddy.com) * [GoDaddy](https://www.godaddy.com)
* [Gandi](https://www.gandi.net) * [Gandi](https://www.gandi.net)
* [ANS Group SafeDNS](https://portal.ans.co.uk/safedns/)
* [IBM Cloud DNS](https://www.ibm.com/cloud/dns) * [IBM Cloud DNS](https://www.ibm.com/cloud/dns)
* [TencentCloud PrivateDNS](https://cloud.tencent.com/product/privatedns) * [TencentCloud PrivateDNS](https://cloud.tencent.com/product/privatedns)
* [TencentCloud DNSPod](https://cloud.tencent.com/product/cns) * [TencentCloud DNSPod](https://cloud.tencent.com/product/cns)
@ -85,12 +79,14 @@ Known providers using webhooks:
| Adguard Home Provider | https://github.com/muhlba91/external-dns-provider-adguard | | Adguard Home Provider | https://github.com/muhlba91/external-dns-provider-adguard |
| Anexia | https://github.com/ProbstenHias/external-dns-anexia-webhook | | Anexia | https://github.com/ProbstenHias/external-dns-anexia-webhook |
| Bizfly Cloud | https://github.com/bizflycloud/external-dns-bizflycloud-webhook | | Bizfly Cloud | https://github.com/bizflycloud/external-dns-bizflycloud-webhook |
| Efficient IP | https://github.com/EfficientIP-Labs/external-dns-efficientip-webhook |
| Gcore | https://github.com/G-Core/external-dns-gcore-webhook | | Gcore | https://github.com/G-Core/external-dns-gcore-webhook |
| GleSYS | https://github.com/glesys/external-dns-glesys | | GleSYS | https://github.com/glesys/external-dns-glesys |
| Hetzner | https://github.com/mconfalonieri/external-dns-hetzner-webhook | | Hetzner | https://github.com/mconfalonieri/external-dns-hetzner-webhook |
| IONOS | https://github.com/ionos-cloud/external-dns-ionos-webhook | | IONOS | https://github.com/ionos-cloud/external-dns-ionos-webhook |
| Infoblox | https://github.com/AbsaOSS/external-dns-infoblox-webhook | | Infoblox | https://github.com/AbsaOSS/external-dns-infoblox-webhook |
| Netcup | https://github.com/mrueg/external-dns-netcup-webhook | | Netcup | https://github.com/mrueg/external-dns-netcup-webhook |
| RouterOS | https://github.com/benfiola/external-dns-routeros-provider |
| STACKIT | https://github.com/stackitcloud/external-dns-stackit-webhook | | STACKIT | https://github.com/stackitcloud/external-dns-stackit-webhook |
| Unifi | https://github.com/kashalls/external-dns-unifi-webhook | | Unifi | https://github.com/kashalls/external-dns-unifi-webhook |
@ -115,13 +111,10 @@ The following table clarifies the current status of the providers according to t
| AWS Cloud Map | Beta | | | AWS Cloud Map | Beta | |
| Akamai Edge DNS | Beta | | | Akamai Edge DNS | Beta | |
| AzureDNS | Stable | | | AzureDNS | Stable | |
| BlueCat | Alpha | @seanmalloy @vinny-sabatini |
| Civo | Alpha | @alejandrojnm | | Civo | Alpha | @alejandrojnm |
| CloudFlare | Beta | | | CloudFlare | Beta | |
| RcodeZero | Alpha | |
| DigitalOcean | Alpha | | | DigitalOcean | Alpha | |
| DNSimple | Alpha | | | DNSimple | Alpha | |
| Dyn | Alpha | |
| OpenStack Designate | Alpha | | | OpenStack Designate | Alpha | |
| PowerDNS | Alpha | | | PowerDNS | Alpha | |
| CoreDNS | Alpha | | | CoreDNS | Alpha | |
@ -131,15 +124,12 @@ The following table clarifies the current status of the providers according to t
| RFC2136 | Alpha | | | RFC2136 | Alpha | |
| NS1 | Alpha | | | NS1 | Alpha | |
| TransIP | Alpha | | | TransIP | Alpha | |
| VinylDNS | Alpha | |
| RancherDNS | Alpha | | | RancherDNS | Alpha | |
| OVH | Alpha | | | OVH | Alpha | |
| Scaleway DNS | Alpha | @Sh4d1 | | Scaleway DNS | Alpha | @Sh4d1 |
| Vultr | Alpha | |
| UltraDNS | Alpha | | | UltraDNS | Alpha | |
| GoDaddy | Alpha | | | GoDaddy | Alpha | |
| Gandi | Alpha | @packi | | Gandi | Alpha | @packi |
| SafeDNS | Alpha | @assureddt |
| IBMCloud | Alpha | @hughhuangzh | | IBMCloud | Alpha | @hughhuangzh |
| TencentCloud | Alpha | @Hyzhou | | TencentCloud | Alpha | @Hyzhou |
| Plural | Alpha | @michaeljguarino | | Plural | Alpha | @michaeljguarino |
@ -171,48 +161,40 @@ The following tutorials are provided:
* AWS * AWS
* [AWS Load Balancer Controller](docs/tutorials/aws-load-balancer-controller.md) * [AWS Load Balancer Controller](docs/tutorials/aws-load-balancer-controller.md)
* [Route53](docs/tutorials/aws.md) * [Route53](docs/tutorials/aws.md)
* [Same domain for public and private Route53 zones](docs/tutorials/public-private-route53.md) * [Same domain for public and private Route53 zones](docs/tutorials/aws-public-private-route53.md)
* [Cloud Map](docs/tutorials/aws-sd.md) * [Cloud Map](docs/tutorials/aws-sd.md)
* [Kube Ingress AWS Controller](docs/tutorials/kube-ingress-aws.md) * [Kube Ingress AWS Controller](docs/tutorials/kube-ingress-aws.md)
* [Azure DNS](docs/tutorials/azure.md) * [Azure DNS](docs/tutorials/azure.md)
* [Azure Private DNS](docs/tutorials/azure-private-dns.md) * [Azure Private DNS](docs/tutorials/azure-private-dns.md)
* [Civo](docs/tutorials/civo.md) * [Civo](docs/tutorials/civo.md)
* [Cloudflare](docs/tutorials/cloudflare.md) * [Cloudflare](docs/tutorials/cloudflare.md)
* [BlueCat](docs/tutorials/bluecat.md)
* [CoreDNS](docs/tutorials/coredns.md) * [CoreDNS](docs/tutorials/coredns.md)
* [DigitalOcean](docs/tutorials/digitalocean.md) * [DigitalOcean](docs/tutorials/digitalocean.md)
* [DNSimple](docs/tutorials/dnsimple.md) * [DNSimple](docs/tutorials/dnsimple.md)
* [Dyn](docs/tutorials/dyn.md)
* [Exoscale](docs/tutorials/exoscale.md) * [Exoscale](docs/tutorials/exoscale.md)
* [ExternalName Services](docs/tutorials/externalname.md) * [ExternalName Services](docs/tutorials/externalname.md)
* Google Kubernetes Engine * Google Kubernetes Engine
* [Using Google's Default Ingress Controller](docs/tutorials/gke.md) * [Using Google's Default Ingress Controller](docs/tutorials/gke.md)
* [Using the Nginx Ingress Controller](docs/tutorials/nginx-ingress.md) * [Using the Nginx Ingress Controller](docs/tutorials/gke-nginx.md)
* [Headless Services](docs/tutorials/hostport.md) * [Headless Services](docs/tutorials/hostport.md)
* [Istio Gateway Source](docs/tutorials/istio.md) * [Istio Gateway Source](docs/sources/istio.md)
* [Kubernetes Security Context](docs/tutorials/security-context.md)
* [Linode](docs/tutorials/linode.md) * [Linode](docs/tutorials/linode.md)
* [Nginx Ingress Controller](docs/tutorials/nginx-ingress.md)
* [NS1](docs/tutorials/ns1.md) * [NS1](docs/tutorials/ns1.md)
* [NS Record Creation with CRD Source](docs/tutorials/ns-record.md) * [NS Record Creation with CRD Source](docs/sources/ns-record.md)
* [MX Record Creation with CRD Source](docs/tutorials/mx-record.md) * [MX Record Creation with CRD Source](docs/sources/mx-record.md)
* [OpenStack Designate](docs/tutorials/designate.md) * [OpenStack Designate](docs/tutorials/designate.md)
* [Oracle Cloud Infrastructure (OCI) DNS](docs/tutorials/oracle.md) * [Oracle Cloud Infrastructure (OCI) DNS](docs/tutorials/oracle.md)
* [PowerDNS](docs/tutorials/pdns.md) * [PowerDNS](docs/tutorials/pdns.md)
* [RcodeZero](docs/tutorials/rcodezero.md)
* [RancherDNS (RDNS)](docs/tutorials/rdns.md) * [RancherDNS (RDNS)](docs/tutorials/rdns.md)
* [RFC2136](docs/tutorials/rfc2136.md) * [RFC2136](docs/tutorials/rfc2136.md)
* [TransIP](docs/tutorials/transip.md) * [TransIP](docs/tutorials/transip.md)
* [VinylDNS](docs/tutorials/vinyldns.md)
* [OVH](docs/tutorials/ovh.md) * [OVH](docs/tutorials/ovh.md)
* [Scaleway](docs/tutorials/scaleway.md) * [Scaleway](docs/tutorials/scaleway.md)
* [Vultr](docs/tutorials/vultr.md)
* [UltraDNS](docs/tutorials/ultradns.md) * [UltraDNS](docs/tutorials/ultradns.md)
* [GoDaddy](docs/tutorials/godaddy.md) * [GoDaddy](docs/tutorials/godaddy.md)
* [Gandi](docs/tutorials/gandi.md) * [Gandi](docs/tutorials/gandi.md)
* [SafeDNS](docs/tutorials/ANS_Group_SafeDNS.md)
* [IBM Cloud](docs/tutorials/ibmcloud.md) * [IBM Cloud](docs/tutorials/ibmcloud.md)
* [Nodes as source](docs/tutorials/nodes.md) * [Nodes as source](docs/sources/nodes.md)
* [TencentCloud](docs/tutorials/tencentcloud.md) * [TencentCloud](docs/tutorials/tencentcloud.md)
* [Plural](docs/tutorials/plural.md) * [Plural](docs/tutorials/plural.md)
* [Pi-hole](docs/tutorials/pihole.md) * [Pi-hole](docs/tutorials/pihole.md)
@ -304,7 +286,7 @@ show us what you can do!
The external-dns project is currently in need of maintainers for specific DNS providers. Ideally each provider The external-dns project is currently in need of maintainers for specific DNS providers. Ideally each provider
would have at least two maintainers. It would be nice if the maintainers run the provider in production, but it would have at least two maintainers. It would be nice if the maintainers run the provider in production, but it
is not strictly required. Provider listed [here](https://github.com/kubernetes-sigs/external-dns#status-of-providers) is not strictly required. Provider listed [here](https://github.com/kubernetes-sigs/external-dns#status-of-in-tree-providers)
that do not have a maintainer listed are in need of assistance. that do not have a maintainer listed are in need of assistance.
Read the [contributing guidelines](CONTRIBUTING.md) and have a look at [the contributing docs](docs/contributing/getting-started.md) to learn about building the project, the project structure, and the purpose of each package. Read the [contributing guidelines](CONTRIBUTING.md) and have a look at [the contributing docs](docs/contributing/getting-started.md) to learn about building the project, the project structure, and the purpose of each package.

View File

@ -18,6 +18,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [UNRELEASED] ## [UNRELEASED]
## [v1.15.0] - 2023-09-10
### Changed
- Updated _ExternalDNS_ OCI image version to [v0.15.0](https://github.com/kubernetes-sigs/external-dns/releases/tag/v0.15.0). ([#xxxx](https://github.com/kubernetes-sigs/external-dns/pull/xxxx)) _@stevehipwell_
### Fixed
- Fixed `provider.webhook.resources` behavior to correctly leverage resource limits. ([#4560](https://github.com/kubernetes-sigs/external-dns/pull/4560)) _@crutonjohn_
- Fixed `provider.webhook.imagePullPolicy` behavior to correctly leverage pull policy. ([#4643](https://github.com/kubernetes-sigs/external-dns/pull/4643)) _@kimsondrup_
- Fixed to add correct webhook metric port to `Service` and `ServiceMonitor`. ([#4643](https://github.com/kubernetes-sigs/external-dns/pull/4643)) _@kimsondrup_
- Fixed to no longer require the unauthenticated webhook provider port to be exposed for health probes. ([#4691](https://github.com/kubernetes-sigs/external-dns/pull/4691)) _@kimsondrup_ & _@hatrx_
## [v1.14.5] - 2023-06-10 ## [v1.14.5] - 2023-06-10
### Added ### Added
@ -187,6 +200,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
RELEASE LINKS RELEASE LINKS
--> -->
[UNRELEASED]: https://github.com/kubernetes-sigs/external-dns/tree/master/charts/external-dns [UNRELEASED]: https://github.com/kubernetes-sigs/external-dns/tree/master/charts/external-dns
[v1.15.0]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.15.0
[v1.14.5]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.14.5 [v1.14.5]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.14.5
[v1.14.4]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.14.4 [v1.14.4]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.14.4
[v1.14.3]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.14.3 [v1.14.3]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.14.3

View File

@ -2,8 +2,8 @@ apiVersion: v2
name: external-dns name: external-dns
description: ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers. description: ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.
type: application type: application
version: 1.14.5 version: 1.15.0
appVersion: 0.14.2 appVersion: 0.15.0
keywords: keywords:
- kubernetes - kubernetes
- externaldns - externaldns
@ -20,15 +20,13 @@ maintainers:
email: steve.hipwell@gmail.com email: steve.hipwell@gmail.com
annotations: annotations:
artifacthub.io/changes: | artifacthub.io/changes: |
- kind: added
description: "Added support for `extraContainers` argument."
- kind: added
description: "Added support for setting `excludeDomains` argument."
- kind: changed - kind: changed
description: "Updated _ExternalDNS_ OCI image version to [v0.14.2](https://github.com/kubernetes-sigs/external-dns/releases/tag/v0.14.2)." description: "Updated _ExternalDNS_ OCI image version to [v0.15.0](https://github.com/kubernetes-sigs/external-dns/releases/tag/v0.15.0)."
- kind: changed
description: "Updated `DNSEndpoint` CRD."
- kind: changed
description: "Changed the implementation for `revisionHistoryLimit` to be more generic."
- kind: fixed - kind: fixed
description: "Fixed the `ServiceMonitor` job name to correctly use the instance label." description: "Fixed `provider.webhook.resources` behavior to correctly leverage resource limits."
- kind: fixed
description: "Fixed `provider.webhook.imagePullPolicy` behavior to correctly leverage pull policy."
- kind: fixed
description: "Fixed to add correct webhook metric port to `Service` and `ServiceMonitor`."
- kind: fixed
description: "Fixed to no longer require the unauthenticated webhook provider port to be exposed for health probes."

View File

@ -1,6 +1,6 @@
# external-dns # external-dns
![Version: 1.14.5](https://img.shields.io/badge/Version-1.14.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.14.2](https://img.shields.io/badge/AppVersion-0.14.2-informational?style=flat-square) ![Version: 1.15.0](https://img.shields.io/badge/Version-1.15.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.15.0](https://img.shields.io/badge/AppVersion-0.15.0-informational?style=flat-square)
ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers. ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.
@ -27,7 +27,7 @@ helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
After you've installed the repo you can install the chart. After you've installed the repo you can install the chart.
```shell ```shell
helm upgrade --install external-dns external-dns/external-dns --version 1.14.5 helm upgrade --install external-dns external-dns/external-dns --version 1.15.0
``` ```
## Providers ## Providers
@ -52,7 +52,6 @@ For set up for a specific provider using the Helm chart, see the following links
- [godaddy](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/godaddy.md#using-helm) - [godaddy](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/godaddy.md#using-helm)
- [ns1](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/ns1.md#using-helm) - [ns1](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/ns1.md#using-helm)
- [plural](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/plural.md#using-helm) - [plural](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/plural.md#using-helm)
- [vultr](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/vultr.md#using-helm)
## Namespaced Scoped Installation ## Namespaced Scoped Installation
@ -134,6 +133,7 @@ If `namespaced` is set to `true`, please ensure that `sources` my only contains
| provider.webhook.readinessProbe | object | See _values.yaml_ | [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `webhook` container. | | provider.webhook.readinessProbe | object | See _values.yaml_ | [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `webhook` container. |
| provider.webhook.resources | object | `{}` | [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the `webhook` container. | | provider.webhook.resources | object | `{}` | [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the `webhook` container. |
| provider.webhook.securityContext | object | See _values.yaml_ | [Pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) for the `webhook` container. | | provider.webhook.securityContext | object | See _values.yaml_ | [Pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) for the `webhook` container. |
| provider.webhook.service.port | int | `8080` | Webhook exposed HTTP port for the service. |
| provider.webhook.serviceMonitor | object | See _values.yaml_ | Optional [Service Monitor](https://prometheus-operator.dev/docs/operator/design/#servicemonitor) configuration for the `webhook` container. | | provider.webhook.serviceMonitor | object | See _values.yaml_ | Optional [Service Monitor](https://prometheus-operator.dev/docs/operator/design/#servicemonitor) configuration for the `webhook` container. |
| rbac.additionalPermissions | list | `[]` | Additional rules to add to the `ClusterRole`. | | rbac.additionalPermissions | list | `[]` | Additional rules to add to the `ClusterRole`. |
| rbac.create | bool | `true` | If `true`, create a `ClusterRole` & `ClusterRoleBinding` with access to the Kubernetes API. | | rbac.create | bool | `true` | If `true`, create a `ClusterRole` & `ClusterRoleBinding` with access to the Kubernetes API. |

View File

@ -47,7 +47,6 @@ For set up for a specific provider using the Helm chart, see the following links
- [godaddy](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/godaddy.md#using-helm) - [godaddy](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/godaddy.md#using-helm)
- [ns1](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/ns1.md#using-helm) - [ns1](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/ns1.md#using-helm)
- [plural](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/plural.md#using-helm) - [plural](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/plural.md#using-helm)
- [vultr](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/vultr.md#using-helm)
## Namespaced Scoped Installation ## Namespaced Scoped Installation

View File

@ -147,7 +147,7 @@ spec:
{{- with .Values.provider.webhook }} {{- with .Values.provider.webhook }}
- name: webhook - name: webhook
image: {{ include "external-dns.webhookImage" . }} image: {{ include "external-dns.webhookImage" . }}
imagePullPolicy: {{ $.Values.image.pullPolicy }} imagePullPolicy: {{ .image.pullPolicy }}
{{- with .env }} {{- with .env }}
env: env:
{{- toYaml . | nindent 12 }} {{- toYaml . | nindent 12 }}
@ -158,9 +158,6 @@ spec:
{{- end }} {{- end }}
ports: ports:
- name: http-webhook - name: http-webhook
protocol: TCP
containerPort: 8888
- name: http-wh-metrics
protocol: TCP protocol: TCP
containerPort: 8080 containerPort: 8080
livenessProbe: livenessProbe:
@ -173,6 +170,10 @@ spec:
{{- toYaml . | nindent 12 }} {{- toYaml . | nindent 12 }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- with .resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .securityContext }} {{- with .securityContext }}
securityContext: securityContext:
{{- toYaml . | nindent 12 }} {{- toYaml . | nindent 12 }}

View File

@ -1,3 +1,4 @@
{{- $providerName := include "external-dns.providerName" . }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
@ -25,3 +26,11 @@ spec:
port: {{ .Values.service.port }} port: {{ .Values.service.port }}
targetPort: http targetPort: http
protocol: TCP protocol: TCP
{{- if eq $providerName "webhook" }}
{{- with .Values.provider.webhook.service }}
- name: http-webhook
port: {{ .port }}
targetPort: http-webhook
protocol: TCP
{{- end }}
{{- end }}

View File

@ -51,7 +51,7 @@ spec:
{{- end }} {{- end }}
{{- if eq $providerName "webhook" }} {{- if eq $providerName "webhook" }}
{{- with .Values.provider.webhook.serviceMonitor }} {{- with .Values.provider.webhook.serviceMonitor }}
- port: webhook-metrics - port: http-webhook
path: /metrics path: /metrics
{{- with .interval }} {{- with .interval }}
interval: {{ . }} interval: {{ . }}

View File

@ -269,6 +269,9 @@ provider:
timeoutSeconds: 5 timeoutSeconds: 5
failureThreshold: 6 failureThreshold: 6
successThreshold: 1 successThreshold: 1
service:
# -- Webhook exposed HTTP port for the service.
port: 8080
# -- Optional [Service Monitor](https://prometheus-operator.dev/docs/operator/design/#servicemonitor) configuration for the `webhook` container. # -- Optional [Service Monitor](https://prometheus-operator.dev/docs/operator/design/#servicemonitor) configuration for the `webhook` container.
# @default -- See _values.yaml_ # @default -- See _values.yaml_
serviceMonitor: serviceMonitor:

View File

@ -4,7 +4,7 @@ options:
substitution_option: ALLOW_LOOSE substitution_option: ALLOW_LOOSE
machineType: 'N1_HIGHCPU_8' machineType: 'N1_HIGHCPU_8'
steps: steps:
- name: 'docker.io/library/golang:1.22.4-bookworm' - name: 'docker.io/library/golang:1.23-bookworm'
entrypoint: make entrypoint: make
env: env:
- VERSION=$_GIT_TAG - VERSION=$_GIT_TAG

View File

@ -186,11 +186,13 @@ type Controller struct {
// The interval between individual synchronizations // The interval between individual synchronizations
Interval time.Duration Interval time.Duration
// The DomainFilter defines which DNS records to keep or exclude // The DomainFilter defines which DNS records to keep or exclude
DomainFilter endpoint.DomainFilter DomainFilter endpoint.DomainFilterInterface
// The nextRunAt used for throttling and batching reconciliation // The nextRunAt used for throttling and batching reconciliation
nextRunAt time.Time nextRunAt time.Time
// The nextRunAtMux is for atomic updating of nextRunAt // The runAtMutex is for atomic updating of nextRunAt and lastRunAt
nextRunAtMux sync.Mutex runAtMutex sync.Mutex
// The lastRunAt used for throttling and batching reconciliation
lastRunAt time.Time
// MangedRecordTypes are DNS record types that will be considered for management. // MangedRecordTypes are DNS record types that will be considered for management.
ManagedRecordTypes []string ManagedRecordTypes []string
// ExcludeRecordTypes are DNS record types that will be excluded from management. // ExcludeRecordTypes are DNS record types that will be excluded from management.
@ -203,6 +205,10 @@ type Controller struct {
func (c *Controller) RunOnce(ctx context.Context) error { func (c *Controller) RunOnce(ctx context.Context) error {
lastReconcileTimestamp.SetToCurrentTime() lastReconcileTimestamp.SetToCurrentTime()
c.runAtMutex.Lock()
c.lastRunAt = time.Now()
c.runAtMutex.Unlock()
records, err := c.Registry.Records(ctx) records, err := c.Registry.Records(ctx)
if err != nil { if err != nil {
registryErrorsTotal.Inc() registryErrorsTotal.Inc()
@ -239,7 +245,7 @@ func (c *Controller) RunOnce(ctx context.Context) error {
Policies: []plan.Policy{c.Policy}, Policies: []plan.Policy{c.Policy},
Current: records, Current: records,
Desired: endpoints, Desired: endpoints,
DomainFilter: endpoint.MatchAllDomainFilters{&c.DomainFilter, &registryFilter}, DomainFilter: endpoint.MatchAllDomainFilters{c.DomainFilter, registryFilter},
ManagedRecords: c.ManagedRecordTypes, ManagedRecords: c.ManagedRecordTypes,
ExcludeRecords: c.ExcludeRecordTypes, ExcludeRecords: c.ExcludeRecordTypes,
OwnerID: c.Registry.OwnerID(), OwnerID: c.Registry.OwnerID(),
@ -264,6 +270,24 @@ func (c *Controller) RunOnce(ctx context.Context) error {
return nil return nil
} }
func earliest(r time.Time, times ...time.Time) time.Time {
for _, t := range times {
if t.Before(r) {
r = t
}
}
return r
}
func latest(r time.Time, times ...time.Time) time.Time {
for _, t := range times {
if t.After(r) {
r = t
}
}
return r
}
// Counts the intersections of A and AAAA records in endpoint and registry. // Counts the intersections of A and AAAA records in endpoint and registry.
func countMatchingAddressRecords(endpoints []*endpoint.Endpoint, registryRecords []*endpoint.Endpoint) (int, int) { func countMatchingAddressRecords(endpoints []*endpoint.Endpoint, registryRecords []*endpoint.Endpoint) (int, int) {
recordsMap := make(map[string]map[string]struct{}) recordsMap := make(map[string]map[string]struct{})
@ -306,18 +330,20 @@ func countAddressRecords(endpoints []*endpoint.Endpoint) (int, int) {
// ScheduleRunOnce makes sure execution happens at most once per interval. // ScheduleRunOnce makes sure execution happens at most once per interval.
func (c *Controller) ScheduleRunOnce(now time.Time) { func (c *Controller) ScheduleRunOnce(now time.Time) {
c.nextRunAtMux.Lock() c.runAtMutex.Lock()
defer c.nextRunAtMux.Unlock() defer c.runAtMutex.Unlock()
// schedule only if a reconciliation is not already planned c.nextRunAt = latest(
// to happen in the following c.MinEventSyncInterval c.lastRunAt.Add(c.MinEventSyncInterval),
if !c.nextRunAt.Before(now.Add(c.MinEventSyncInterval)) { earliest(
c.nextRunAt = now.Add(c.MinEventSyncInterval) now.Add(5*time.Second),
} c.nextRunAt,
),
)
} }
func (c *Controller) ShouldRunOnce(now time.Time) bool { func (c *Controller) ShouldRunOnce(now time.Time) bool {
c.nextRunAtMux.Lock() c.runAtMutex.Lock()
defer c.nextRunAtMux.Unlock() defer c.runAtMutex.Unlock()
if now.Before(c.nextRunAt) { if now.Before(c.nextRunAt) {
return false return false
} }

View File

@ -57,7 +57,7 @@ type errorMockProvider struct {
mockProvider mockProvider
} }
func (p *filteredMockProvider) GetDomainFilter() endpoint.DomainFilter { func (p *filteredMockProvider) GetDomainFilter() endpoint.DomainFilterInterface {
return p.domainFilter return p.domainFilter
} }
@ -278,15 +278,17 @@ func valueFromMetric(metric prometheus.Gauge) uint64 {
} }
func TestShouldRunOnce(t *testing.T) { func TestShouldRunOnce(t *testing.T) {
ctrl := &Controller{Interval: 10 * time.Minute, MinEventSyncInterval: 5 * time.Second} ctrl := &Controller{Interval: 10 * time.Minute, MinEventSyncInterval: 15 * time.Second}
now := time.Now() now := time.Now()
// First run of Run loop should execute RunOnce // First run of Run loop should execute RunOnce
assert.True(t, ctrl.ShouldRunOnce(now)) assert.True(t, ctrl.ShouldRunOnce(now))
assert.Equal(t, now.Add(10*time.Minute), ctrl.nextRunAt)
// Second run should not // Second run should not
assert.False(t, ctrl.ShouldRunOnce(now)) assert.False(t, ctrl.ShouldRunOnce(now))
ctrl.lastRunAt = now
now = now.Add(10 * time.Second) now = now.Add(10 * time.Second)
// Changes happen in ingresses or services // Changes happen in ingresses or services
@ -316,12 +318,17 @@ func TestShouldRunOnce(t *testing.T) {
assert.False(t, ctrl.ShouldRunOnce(now)) assert.False(t, ctrl.ShouldRunOnce(now))
// Multiple ingresses or services changes, closer than MinInterval from each other // Multiple ingresses or services changes, closer than MinInterval from each other
ctrl.lastRunAt = now
firstChangeTime := now firstChangeTime := now
secondChangeTime := firstChangeTime.Add(time.Second) secondChangeTime := firstChangeTime.Add(time.Second)
// First change // First change
ctrl.ScheduleRunOnce(firstChangeTime) ctrl.ScheduleRunOnce(firstChangeTime)
// Second change // Second change
ctrl.ScheduleRunOnce(secondChangeTime) ctrl.ScheduleRunOnce(secondChangeTime)
// Executions should be spaced by at least MinEventSyncInterval
assert.False(t, ctrl.ShouldRunOnce(now.Add(5*time.Second)))
// Should not postpone the reconciliation further than firstChangeTime + MinInterval // Should not postpone the reconciliation further than firstChangeTime + MinInterval
now = now.Add(ctrl.MinEventSyncInterval) now = now.Add(ctrl.MinEventSyncInterval)
assert.True(t, ctrl.ShouldRunOnce(now)) assert.True(t, ctrl.ShouldRunOnce(now))

View File

@ -61,6 +61,9 @@ Otherwise, use the `IP` of each of the `Service`'s `Endpoints`'s `Addresses`.
Specifies the domain for the resource's DNS records. Specifies the domain for the resource's DNS records.
Multiple hostnames can be specified through a comma-separated list, e.g.
`svc.mydomain1.com,svc.mydomain2.com`.
## external-dns.alpha.kubernetes.io/ingress-hostname-source ## external-dns.alpha.kubernetes.io/ingress-hostname-source
Specifies where to get the domain for an `Ingress` resource. Specifies where to get the domain for an `Ingress` resource.

View File

@ -1,7 +1,7 @@
# Quick Start # Quick Start
- [Git](https://git-scm.com/downloads) - [Git](https://git-scm.com/downloads)
- [Go 1.22+](https://golang.org/dl/) - [Go 1.23+](https://golang.org/dl/)
- [Go modules](https://github.com/golang/go/wiki/Modules) - [Go modules](https://github.com/golang/go/wiki/Modules)
- [golangci-lint](https://github.com/golangci/golangci-lint) - [golangci-lint](https://github.com/golangci/golangci-lint)
- [ko](https://ko.build/) - [ko](https://ko.build/)

View File

@ -28,7 +28,7 @@ ExternalDNS can solve this for you as well.
### Which DNS providers are supported? ### Which DNS providers are supported?
Please check the [provider status table](https://github.com/kubernetes-sigs/external-dns#status-of-providers) for the list of supported providers and their status. Please check the [provider status table](https://github.com/kubernetes-sigs/external-dns#status-of-in-tree-providers) for the list of supported providers and their status.
As stated in the README, we are currently looking for stable maintainers for those providers, to ensure that bugfixes and new features will be available for all of those. As stated in the README, we are currently looking for stable maintainers for those providers, to ensure that bugfixes and new features will be available for all of those.
@ -221,7 +221,7 @@ $ docker run \
-e EXTERNAL_DNS_SOURCE=$'service\ningress' \ -e EXTERNAL_DNS_SOURCE=$'service\ningress' \
-e EXTERNAL_DNS_PROVIDER=google \ -e EXTERNAL_DNS_PROVIDER=google \
-e EXTERNAL_DNS_DOMAIN_FILTER=$'foo.com\nbar.com' \ -e EXTERNAL_DNS_DOMAIN_FILTER=$'foo.com\nbar.com' \
registry.k8s.io/external-dns/external-dns:v0.14.2 registry.k8s.io/external-dns/external-dns:v0.15.0
time="2017-08-08T14:10:26Z" level=info msg="config: &{APIServerURL: KubeConfig: Sources:[service ingress] Namespace: ... time="2017-08-08T14:10:26Z" level=info msg="config: &{APIServerURL: KubeConfig: Sources:[service ingress] Namespace: ...
``` ```

21
docs/nat64.md Normal file
View File

@ -0,0 +1,21 @@
Configure NAT64 DNS Records
=======================================
Some NAT64 configurations are entirely handled outside the Kubernetes cluster, therefore Kubernetes does not know anything about the associated IPv4 addresses. ExternalDNS should also be able to create A records for those cases.
Therefore, we can configure `nat64-networks`, which **must** be a /96 network. You can also specify multiple `nat64-networks` for more complex setups.
This creates an additional A record with a NAT64-translated IPv4 address for each AAAA record pointing to an IPv6 address within the given `nat64-networks`.
This can be configured with the following flag passed to the operator binary. You can also pass multiple `nat64-networks` by using a comma as seperator.
```sh
--nat64-networks="2001:db8:96::/96"
```
## Setup Example
We use an external NAT64 resolver and SIIT (Stateless IP/ICMP Translation). Therefore, our nodes only have IPv6 IP adresses but can reach IPv4 addresses *and* can be reached via IPv4.
Outgoing connections are a classic NAT64 setup, where all IPv6 addresses gets translated to a small pool of IPv4 addresses.
Incoming connnections are mapped on a different IPv4 pool, e.g. `198.51.100.0/24`, which can get translated one-to-one to IPv6 addresses. We dedicate a `/96` network for this, for example `2001:db8:96::/96`, so `198.51.100.0/24` can translated to `2001:db8:96::c633:6400/120`. Note: `/120` IPv6 network has exactly as many IP addresses as `/24` IPv4 network.
Therefore, the `/96` network can be configured as `nat64-networks`. This means, that `2001:0DB8:96::198.51.100.10` or `2001:db8:96::c633:640a` can be translated to `198.51.100.10`.
Any source can point a record to an IPv6 address within the given `nat64-networks`, for example `2001:db8:96::c633:640a`. This creates by default an AAAA record and - if `nat64-networks` is configured - also an A record with `198.51.100.10` as target.

76
docs/rate-limits.md Normal file
View File

@ -0,0 +1,76 @@
DNS provider API rate limits considerations
===========================================
## Introduction
By design, external-dns refreshes all the records of a zone using API calls.
This refresh may happen peridically and upon any changed object if the flag `--events` is enabled.
Depending on the size of the zone and the infrastructure deployment, this may lead to external-dns
hitting the DNS provider's rate-limits more easily.
In particular, it has been found that with 200k records in an AWS Route53 zone, each refresh triggers around
70 API calls to retrieve all the records, making it more likely to hit the AWS Route53 API rate limits.
To prevent this problem from happening, external-dns has implemented a cache to reduce the pressure on the DNS
provider APIs.
This cache is optional and systematically invalidated when DNS records have been changed in the cluster
(new or deleted domains or changed target).
## Trade-offs
The major trade-off of this setting relies in the ability to recover from a deleted record on the DNS provider side.
As the DNS records are cached in memory, external-dns will not be made aware of the missing records and will hence
take a longer time to restore the deleted or modified record on the provider side.
This option is enabled using the `--provider-cache-time=15m` command line argument, and turned off when `--provider-cache-time=0m`
## Monitoring
You can evaluate the behaviour of the cache thanks to the built-in metrics
* `external_dns_provider_cache_records_calls`
* The number of calls to the provider cache Records list.
* The label `from_cache=true` indicates that the records were retrieved from memory and the DNS provider was not reached
* The label `from_cache=false` indicates that the cache was not used and the records were retrieved from the provider
* `external_dns_provider_cache_apply_changes_calls`
* The number of calls to the provider cache ApplyChanges.
* Each ApplyChange systematically invalidates the cache and makes subsequent Records list to be retrieved from the provider without cache.
## Related options
This global option is available for all providers and can be used in pair with other global
or provider-specific options to fine-tune the behaviour of external-dns
to match the specific needs of your deployments, with the goal to reduce the number of API calls to your DNS provider.
* Google
* `--google-batch-change-interval=1s` When using the Google provider, set the interval between batch changes. ($EXTERNAL_DNS_GOOGLE_BATCH_CHANGE_INTERVAL)
* `--google-batch-change-size=1000` When using the Google provider, set the maximum number of changes that will be applied in each batch.
* AWS
* `--aws-batch-change-interval=1s` When using the AWS provider, set the interval between batch changes.
* `--aws-batch-change-size=1000` When using the AWS provider, set the maximum number of changes that will be applied in each batch.
* `--aws-batch-change-size-bytes=32000` When using the AWS provider, set the maximum byte size that will be applied in each batch.
* `--aws-batch-change-size-values=1000` When using the AWS provider, set the maximum total record values that will be applied in each batch.
* `--aws-zones-cache-duration=0s` When using the AWS provider, set the zones list cache TTL (0s to disable).
* `--[no-]aws-zone-match-parent` Expand limit possible target by sub-domains
* Cloudflare
* `--cloudflare-dns-records-per-page=100` When using the Cloudflare provider, specify how many DNS records listed per page, max possible 5,000 (default: 100)
* OVH
* `--ovh-api-rate-limit=20` When using the OVH provider, specify the API request rate limit, X operations by seconds (default: 20)
* Global
* `--registry=txt` The registry implementation to use to keep track of DNS record ownership. Other registry options such as dynamodb can help mitigate rate limits by storing the registry outside of the DNS hosted zone (default: txt, options: txt, noop, dynamodb, aws-sd)
* `--txt-cache-interval=0s` The interval between cache synchronizations in duration format (default: disabled)
* `--interval=1m0s` The interval between two consecutive synchronizations in duration format (default: 1m)
* `--min-event-sync-interval=5s` The minimum interval between two consecutive synchronizations triggered from kubernetes events in duration format (default: 5s)
* `--[no-]events` When enabled, in addition to running every interval, the reconciliation loop will get triggered when supported sources change (default: disabled)
A general recommendation is to enable `--events` and keep `--min-event-sync-interval` relatively low to have a better responsiveness when records are
created or updated inside the cluster.
This should represent an acceptable propagation time between the creation of your k8s resources and the time they become registered in your DNS server.
On a general manner, the higher the `--provider-cache-time`, the lower the impact on the rate limits, but also, the slower the recovery in case of a deletion.
The `--provider-cache-time` value should hence be set to an acceptable time to automatically recover restore deleted records.
✍️ Note that caching is done within the external-dns controller memory. You can invalidate the cache at any point in time by restarting it (for example doing a rolling update).

View File

@ -1,19 +1,11 @@
# The DynamoDB registry # The DynamoDB registry
The DynamoDB registry stores DNS record metadata in an AWS DynamoDB table. As opposed to the default TXT registry, the DynamoDB registry stores DNS record metadata in an AWS DynamoDB table instead of in TXT records in a hosted zone.
This following tutorial extends [Setting up ExternalDNS for Services on AWS](../tutorials/aws.md) to use the DynamoDB registry instead.
## The DynamoDB Table
By default, the DynamoDB registry stores data in the table named `external-dns`.
A different table may be specified using the `--dynamodb-table` flag.
A different region may be specified using the `--dynamodb-region` flag.
The table must have a partition (hash) key named `k` and string type.
The table must not have a sort (range) key.
## IAM permissions ## IAM permissions
The ExternalDNS Role must be granted the following permissions: The ExternalDNS [IAM Policy](../tutorials/aws.md#iam-policy) must additionally be granted the following permissions:
```json ```json
{ {
@ -33,10 +25,138 @@ The ExternalDNS Role must be granted the following permissions:
The region and account ID may be specified explicitly specified instead of using wildcards. The region and account ID may be specified explicitly specified instead of using wildcards.
## Create a DynamoDB Table
By default, the DynamoDB registry stores data in the table named `external-dns` and it needs to exist before configuring ExternalDNS to use the DynamoDB registry.
If the DynamoDB table has a different name, it may be specified using the `--dynamodb-table` flag.
If the DynamoDB table is in a different region, it may be specified using the `--dynamodb-region` flag.
The following command creates a DynamoDB table with the name: `external-dns`:
> The table must have a partition (HASH) key named `k` of type string (`S`) and the table must NOT have a sort (RANGE) key.
```bash
aws dynamodb create-table \
--table-name external-dns \
--attribute-definitions \
AttributeName=k,AttributeType=S \
--key-schema \
AttributeName=k,KeyType=HASH \
--provisioned-throughput \
ReadCapacityUnits=5,WriteCapacityUnits=5 \
--table-class STANDARD
```
## Set up a hosted zone
Follow [Set up a hosted zone](../tutorials/aws.md#set-up-a-hosted-zone)
## Modify ExternalDNS deployment
The ExternalDNS deployment from [Deploy ExternalDNS](../tutorials/aws.md#deploy-externaldns) needs the following modifications:
* `--registry=txt` should be changed to `--registry=dynamodb`
* Add `--dynamodb-table=external-dns` to specify the name of the DynamoDB table, its value defaults to `external-dns`
* Add `--dynamodb-region=us-east-1` to specify the region of the DynamoDB table
For example:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
labels:
app.kubernetes.io/name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: external-dns
template:
metadata:
labels:
app.kubernetes.io/name: external-dns
spec:
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.15.0
args:
- --source=service
- --source=ingress
- --domain-filter=example.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
- --provider=aws
- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
- --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
- --registry=dynamodb # previously, --registry=txt
- --dynamodb-table=external-dns # defaults to external-dns
- --dynamodb-region=us-east-1 # set to the region the DynamoDB table in
- --txt-owner-id=my-hostedzone-identifier
env:
- name: AWS_DEFAULT_REGION
value: us-east-1 # change to region where EKS is installed
# # Uncomment below if using static credentials
# - name: AWS_SHARED_CREDENTIALS_FILE
# value: /.aws/credentials
# volumeMounts:
# - name: aws-credentials
# mountPath: /.aws
# readOnly: true
# volumes:
# - name: aws-credentials
# secret:
# secretName: external-dns
```
## Validate ExternalDNS works
Create either a [Service](../tutorials/aws.md#verify-externaldns-works-service-example) or an [Ingress](../tutorials/aws.md#verify-externaldns-works-ingress-example) and
After roughly two minutes, check that the corresponding entry was created in the DynamoDB table:
```bash
aws dynamodb scan --table-name external-dns
```
This will show something like:
```
{
"Items": [
{
"k": {
"S": "nginx.example.com#A#"
},
"o": {
"S": "my-identifier"
},
"l": {
"M": {
"resource": {
"S": "service/default/nginx"
}
}
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
```
## Clean up
In addition to the clean up steps in [Setting up ExternalDNS for Services on AWS](../tutorials/aws.md#clean-up), delete the DynamoDB table that was used as a registry.
```bash
aws dynamodb delete-table \
--table-name external-dns
```
## Caching ## Caching
The DynamoDB registry can optionally cache DNS records read from the provider. This can mitigate The DynamoDB registry can optionally cache DNS records read from the provider. This can mitigate rate limits imposed by the provider.
rate limits imposed by the provider.
Caching is enabled by specifying a cache duration with the `--txt-cache-interval` flag. Caching is enabled by specifying a cache duration with the `--txt-cache-interval` flag.

View File

@ -31,7 +31,7 @@ You must be an official maintainer of the project to be able to do a release.
- Branch out from the default branch and run `scripts/kustomize-version-updater.sh` to update the image tag used in the kustomization.yaml. - Branch out from the default branch and run `scripts/kustomize-version-updater.sh` to update the image tag used in the kustomization.yaml.
- Create an issue to release the corresponding Helm chart via the chart release process (below) assigned to a chart maintainer - Create an issue to release the corresponding Helm chart via the chart release process (below) assigned to a chart maintainer
- Create a PR with the kustomize change. - Create a PR with the kustomize change.
- Create a PR to replace all versions for docker images in the tutorials. A possible script to use is `sd registry.k8s.io/external-dns/external-dns:.* registry.k8s.io/external-dns/external-dns:v0.14.2 $(fd --type file)` which uses the `fd` and `sd` utilities. - Create a PR to replace all versions for docker images in the tutorials. A possible script to use is `sd registry.k8s.io/external-dns/external-dns:v0.15.0`
- Once the PR is merged, all is done :-) - Once the PR is merged, all is done :-)
## How to release a new chart version ## How to release a new chart version

View File

@ -1,8 +1,8 @@
# Sources # About
| Source | Resources | annotation-filter | label-filter | | Source | Resources | annotation-filter | label-filter |
|---------------------------------|-------------------------------------------------------------------------------|-------------------|--------------| |---------------------------------|-------------------------------------------------------------------------------|-------------------|--------------|
| ambassador-host | Host.getambassador.io | | | | ambassador-host | Host.getambassador.io | Yes | Yes |
| connector | | | | | connector | | | |
| contour-httpproxy | HttpProxy.projectcontour.io | Yes | | | contour-httpproxy | HttpProxy.projectcontour.io | Yes | |
| cloudfoundry | | | | | cloudfoundry | | | |

View File

@ -1,4 +1,4 @@
# Configuring ExternalDNS to use the F5 Networks VirtualServer Source # F5 Networks VirtualServer Source
This tutorial describes how to configure ExternalDNS to use the F5 Networks VirtualServer Source. It is meant to supplement the other provider-specific setup tutorials. This tutorial describes how to configure ExternalDNS to use the F5 Networks VirtualServer Source. It is meant to supplement the other provider-specific setup tutorials.
The F5 Networks VirtualServer CRD is part of [this](https://github.com/F5Networks/k8s-bigip-ctlr) project. See more in-depth info regarding the VirtualServer CRD [here](https://github.com/F5Networks/k8s-bigip-ctlr/blob/master/docs/config_examples/customResource/CustomResource.md#virtualserver). The F5 Networks VirtualServer CRD is part of [this](https://github.com/F5Networks/k8s-bigip-ctlr) project. See more in-depth info regarding the VirtualServer CRD [here](https://github.com/F5Networks/k8s-bigip-ctlr/blob/master/docs/config_examples/customResource/CustomResource.md#virtualserver).

View File

@ -1,14 +1,29 @@
# Configuring ExternalDNS to use Gateway API Route Sources # Gateway API Route Sources
This describes how to configure ExternalDNS to use Gateway API Route sources. This describes how to configure ExternalDNS to use Gateway API Route sources.
It is meant to supplement the other provider-specific setup tutorials. It is meant to supplement the other provider-specific setup tutorials.
## Supported API Versions ## Supported API Versions
As the Gateway API is still in an experimental phase, ExternalDNS makes no backwards ExternalDNS currently supports a mixture of v1alpha2, v1beta1, v1 APIs.
compatibilty guarantees regarding its support. However, it currently supports a mixture of
v1alpha2, v1beta1, v1 APIs. Gateways and HTTPRoutes are supported using the v1 and v1beta1 API (which is converted to v1 when using the latest CRDs). Gateway API has two release channels: Standard and Experimental.
GRPCRoutes, TLSRoutes, TCPRoutes, and UDPRoutes are supported using the v1alpha2 API. The Experimental channel includes v1alpha2, v1beta2, and v1 APIs.
The Standard channel only includes v1beta2 and v1 APIs, not v1alpha2.
TCPRoutes, TLSRoutes, and UDPRoutes only exist in v1alpha2 and continued support for
these versions is NOT guaranteed. At some time in the future, Gateway API will graduate
these Routes to v1. ExternalDNS will likely follow that upgrade and move to the v1 API,
where they will be available in the Standard release channel. This will be a breaking
change if your Experimental CRDs are not updated to include the new v1 API.
Gateways and HTTPRoutes are available in v1alpha2, v1beta1, and v1 APIs.
However, some notable environments are behind in upgrading their CRDs to include the v1 API.
For compatibility reasons Gateways and HTTPRoutes use the v1beta1 API.
GRPCRoutes are available in v1alpha2 and v1 APIs, not v1beta2.
Therefore, GRPCRoutes use the v1 API which is available in both release channels.
Unfortunately, this means they will not be available in environments with old CRDs.
## Hostnames ## Hostnames
@ -72,7 +87,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
# Add desired Gateway API Route sources. # Add desired Gateway API Route sources.
- --source=gateway-httproute - --source=gateway-httproute

View File

@ -5,7 +5,7 @@ sources create DNS entries based on their respective `gateway.networking.k8s.io`
## Filtering the Routes considered ## Filtering the Routes considered
These sources support the `--label-filter` flag, which filters *Route resources These sources support the `--label-filter` flag, which filters \*Route resources
by a set of labels. by a set of labels.
## Domain names ## Domain names
@ -16,67 +16,103 @@ of [domain names from the *Route](#domain-names-from-route).
It then iterates over each of the `status.parents` with It then iterates over each of the `status.parents` with
a [matching Gateway](#matching-gateways) and at least one [matching listener](#matching-listeners). a [matching Gateway](#matching-gateways) and at least one [matching listener](#matching-listeners).
For each matching listener, if the For each matching listener, if the
listener has a `hostname`, it narrows the set of domain names from the *Route to the portion listener has a `hostname`, it narrows the set of domain names from the \*Route to the portion
that overlaps the `hostname`. If a matching listener does not have a `hostname`, it uses that overlaps the `hostname`. If a matching listener does not have a `hostname`, it uses
the un-narrowed set of domain names. the un-narrowed set of domain names.
### Domain names from Route ### Domain names from Route
The set of domain names from a *Route is sourced from the following places: The set of domain names from a \*Route is sourced from the following places:
* If the *Route is a GRPCRoute, HTTPRoute, or TLSRoute, adds each of the`spec.hostnames`. - If the \*Route is a GRPCRoute, HTTPRoute, or TLSRoute, adds each of the`spec.hostnames`.
* Adds the hostnames from any `external-dns.alpha.kubernetes.io/hostname` annotation on the *Route. - Adds the hostnames from any `external-dns.alpha.kubernetes.io/hostname` annotation on the \*Route.
This behavior is suppressed if the `--ignore-hostname-annotation` flag was specified. This behavior is suppressed if the `--ignore-hostname-annotation` flag was specified.
* If no endpoints were produced by the previous steps - If no endpoints were produced by the previous steps
or the `--combine-fqdn-annotation` flag was specified, then adds hostnames or the `--combine-fqdn-annotation` flag was specified, then adds hostnames
generated from any`--fqdn-template` flag. generated from any`--fqdn-template` flag.
* If no endpoints were produced by the previous steps, each - If no endpoints were produced by the previous steps, each
attached Gateway listener will use its `hostname`, if present. attached Gateway listener will use its `hostname`, if present.
### Matching Gateways ### Matching Gateways
Matching Gateways are discovered by iterating over the *Route's `status.parents`: Matching Gateways are discovered by iterating over the \*Route's `status.parents`:
* Ignores parents with a `parentRef.group` other than - Ignores parents with a `parentRef.group` other than
`gateway.networking.k8s.io` or a `parentRef.kind` other than `Gateway`. `gateway.networking.k8s.io` or a `parentRef.kind` other than `Gateway`.
* If the `--gateway-namespace` flag was specified, ignores parents with a `parentRef.namespace` other - If the `--gateway-namespace` flag was specified, ignores parents with a `parentRef.namespace` other
than the specified value. than the specified value.
* If the `--gateway-label-filter` flag was specified, ignores parents whose Gateway does not match the - If the `--gateway-label-filter` flag was specified, ignores parents whose Gateway does not match the
specified label filter. specified label filter.
* Ignores parents whose Gateway either does not exist or has not accepted the route. - Ignores parents whose Gateway either does not exist or has not accepted the route.
### Matching listeners ### Matching listeners
Iterates over all listeners for the parent's `parentRef.sectionName`: Iterates over all listeners for the parent's `parentRef.sectionName`:
* Ignores listeners whose `protocol` field does not match the kind of the *Route per the following table: - Ignores listeners whose `protocol` field does not match the kind of the \*Route per the following table:
| kind | protocols | | kind | protocols |
|------------|-------------| | --------- | ----------- |
| GRPCRoute | HTTP, HTTPS | | GRPCRoute | HTTP, HTTPS |
| HTTPRoute | HTTP, HTTPS | | HTTPRoute | HTTP, HTTPS |
| TCPRoute | TCP | | TCPRoute | TCP |
| TLSRoute | TLS | | TLSRoute | TLS |
| UDPRoute | UDP | | UDPRoute | UDP |
* If the parent's `parentRef.port` port is specified, ignores listeners without a matching `port`. - If the parent's `parentRef.port` port is specified, ignores listeners without a matching `port`.
* Ignores listeners which specify an `allowedRoutes` which does not allow the route. - Ignores listeners which specify an `allowedRoutes` which does not allow the route.
## Targets ## Targets
The targets of the DNS entries created from a *Route are sourced from the following places: The targets of the DNS entries created from a \*Route are sourced from the following places:
1. If a matching parent Gateway has an `external-dns.alpha.kubernetes.io/target` annotation, uses 1. If a matching parent Gateway has an `external-dns.alpha.kubernetes.io/target` annotation, uses
the values from that. the values from that.
2. Otherwise, iterates over that parent Gateway's `status.addresses`, 2. Otherwise, iterates over that parent Gateway's `status.addresses`,
adding each address's `value`. adding each address's `value`.
The targets from each parent Gateway matching the *Route are then combined and de-duplicated. The targets from each parent Gateway matching the \*Route are then combined and de-duplicated.
## Dualstack Routes
Gateway resources may be served from an external-loadbalancer which may support both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces.
External DNS Controller uses the `external-dns.alpha.kubernetes.io/dualstack` annotation to determine this. If this annotation is
set to `true` then ExternalDNS will create two records (one A record
and one AAAA record) for each hostname associated with the Route resource.
Example:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
annotations:
external-dns.alpha.kubernetes.io/dualstack: "true"
name: echo
spec:
hostnames:
- echoserver.example.org
rules:
- backendRefs:
- group: ""
kind: Service
name: echo
port: 1027
weight: 1
matches:
- path:
type: PathPrefix
value: /echo
```
The above HTTPRoute resource is backed by a dualstack Gateway.
ExternalDNS will create both an A `echoserver.example.org` record and
an AAAA record of the same name, that each are aliases for the same LB.

View File

@ -1,4 +1,4 @@
# Configuring ExternalDNS to use the Gloo Proxy Source # Gloo Proxy Source
This tutorial describes how to configure ExternalDNS to use the Gloo Proxy source. This tutorial describes how to configure ExternalDNS to use the Gloo Proxy source.
It is meant to supplement the other provider-specific setup tutorials. It is meant to supplement the other provider-specific setup tutorials.
@ -22,7 +22,7 @@ spec:
containers: containers:
- name: external-dns - name: external-dns
# update this to the desired external-dns version # update this to the desired external-dns version
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=gloo-proxy - --source=gloo-proxy
- --gloo-namespace=custom-gloo-system # gloo system namespace. Specify multiple times for multiple namespaces. Omit to use the default (gloo-system) - --gloo-namespace=custom-gloo-system # gloo system namespace. Specify multiple times for multiple namespaces. Omit to use the default (gloo-system)
@ -90,7 +90,7 @@ spec:
containers: containers:
- name: external-dns - name: external-dns
# update this to the desired external-dns version # update this to the desired external-dns version
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=gloo-proxy - --source=gloo-proxy
- --gloo-namespace=custom-gloo-system # gloo system namespace. Specify multiple times for multiple namespaces. Omit to use the default (gloo-system) - --gloo-namespace=custom-gloo-system # gloo system namespace. Specify multiple times for multiple namespaces. Omit to use the default (gloo-system)

View File

@ -1,4 +1,5 @@
# Configuring ExternalDNS to use the Istio Gateway and/or Istio Virtual Service Source # Istio Gateway / Virtual Service Source
This tutorial describes how to configure ExternalDNS to use the Istio Gateway source. This tutorial describes how to configure ExternalDNS to use the Istio Gateway source.
It is meant to supplement the other provider-specific setup tutorials. It is meant to supplement the other provider-specific setup tutorials.
@ -28,7 +29,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -43,6 +44,7 @@ spec:
``` ```
### Manifest (for clusters with RBAC enabled) ### Manifest (for clusters with RBAC enabled)
```yaml ```yaml
apiVersion: v1 apiVersion: v1
kind: ServiceAccount kind: ServiceAccount
@ -98,7 +100,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -150,7 +152,9 @@ $ kubectl apply -f <(istioctl kube-inject -f https://raw.githubusercontent.com/i
``` ```
#### Using a Gateway as a source #### Using a Gateway as a source
##### Create an Istio Gateway: ##### Create an Istio Gateway:
```bash ```bash
$ cat <<EOF | kubectl apply -f - $ cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3 apiVersion: networking.istio.io/v1alpha3
@ -172,6 +176,7 @@ EOF
``` ```
##### Configure routes for traffic entering via the Gateway: ##### Configure routes for traffic entering via the Gateway:
```bash ```bash
$ cat <<EOF | kubectl apply -f - $ cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3 apiVersion: networking.istio.io/v1alpha3
@ -200,6 +205,7 @@ EOF
#### Using a VirtualService as a source #### Using a VirtualService as a source
##### Create an Istio Gateway: ##### Create an Istio Gateway:
```bash ```bash
$ cat <<EOF | kubectl apply -f - $ cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3 apiVersion: networking.istio.io/v1alpha3
@ -221,6 +227,7 @@ EOF
``` ```
##### Configure routes for traffic entering via the Gateway: ##### Configure routes for traffic entering via the Gateway:
```bash ```bash
$ cat <<EOF | kubectl apply -f - $ cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3 apiVersion: networking.istio.io/v1alpha3

View File

@ -1,8 +1,10 @@
# Configuring ExternalDNS to use the Kong TCPIngress Source # Kong TCPIngress Source
This tutorial describes how to configure ExternalDNS to use the Kong TCPIngress source. This tutorial describes how to configure ExternalDNS to use the Kong TCPIngress source.
It is meant to supplement the other provider-specific setup tutorials. It is meant to supplement the other provider-specific setup tutorials.
### Manifest (for clusters without RBAC enabled) ### Manifest (for clusters without RBAC enabled)
```yaml ```yaml
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
@ -22,7 +24,7 @@ spec:
containers: containers:
- name: external-dns - name: external-dns
# update this to the desired external-dns version # update this to the desired external-dns version
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=kong-tcpingress - --source=kong-tcpingress
- --provider=aws - --provider=aws
@ -86,7 +88,7 @@ spec:
containers: containers:
- name: external-dns - name: external-dns
# update this to the desired external-dns version # update this to the desired external-dns version
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=kong-tcpingress - --source=kong-tcpingress
- --provider=aws - --provider=aws

View File

@ -1,4 +1,4 @@
# Creating MX record with CRD source # MX record with CRD source
You can create and manage MX records with the help of [CRD source](../contributing/crd-source.md) You can create and manage MX records with the help of [CRD source](../contributing/crd-source.md)
and `DNSEndpoint` CRD. Currently, this feature is only supported by `aws`, `azure`, and `google` providers. and `DNSEndpoint` CRD. Currently, this feature is only supported by `aws`, `azure`, and `google` providers.

View File

@ -1,4 +1,4 @@
# Configuring ExternalDNS to use Cluster Nodes as Source # Cluster Nodes as Source
This tutorial describes how to configure ExternalDNS to use the cluster nodes as source. This tutorial describes how to configure ExternalDNS to use the cluster nodes as source.
Using nodes (`--source=node`) as source is possible to synchronize a DNS zone with the nodes of a cluster. Using nodes (`--source=node`) as source is possible to synchronize a DNS zone with the nodes of a cluster.
@ -29,7 +29,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=node # will use nodes as source - --source=node # will use nodes as source
- --provider=aws - --provider=aws
@ -100,7 +100,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=node # will use nodes as source - --source=node # will use nodes as source
- --provider=aws - --provider=aws

View File

@ -1,4 +1,4 @@
# Creating NS record with CRD source # NS record with CRD source
You can create NS records with the help of [CRD source](../contributing/crd-source.md) You can create NS records with the help of [CRD source](../contributing/crd-source.md)
and `DNSEndpoint` CRD. and `DNSEndpoint` CRD.

View File

@ -1,4 +1,5 @@
# Configuring ExternalDNS to use the OpenShift Route Source # OpenShift Route Source
This tutorial describes how to configure ExternalDNS to use the OpenShift Route source. This tutorial describes how to configure ExternalDNS to use the OpenShift Route source.
It is meant to supplement the other provider-specific setup tutorials. It is meant to supplement the other provider-specific setup tutorials.
@ -66,7 +67,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=openshift-route - --source=openshift-route
- --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
@ -133,7 +134,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=openshift-route - --source=openshift-route
- --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones

View File

@ -1,4 +1,4 @@
# Configuring ExternalDNS to use the Traefik Proxy Source # Traefik Proxy Source
This tutorial describes how to configure ExternalDNS to use the Traefik Proxy source. This tutorial describes how to configure ExternalDNS to use the Traefik Proxy source.
It is meant to supplement the other provider-specific setup tutorials. It is meant to supplement the other provider-specific setup tutorials.
@ -24,7 +24,7 @@ spec:
containers: containers:
- name: external-dns - name: external-dns
# update this to the desired external-dns version # update this to the desired external-dns version
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=traefik-proxy - --source=traefik-proxy
- --provider=aws - --provider=aws
@ -87,7 +87,7 @@ spec:
containers: containers:
- name: external-dns - name: external-dns
# update this to the desired external-dns version # update this to the desired external-dns version
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=traefik-proxy - --source=traefik-proxy
- --provider=aws - --provider=aws
@ -96,7 +96,9 @@ spec:
``` ```
## Deploying a Traefik IngressRoute ## Deploying a Traefik IngressRoute
Create a IngressRoute file called 'traefik-ingress.yaml' with the following contents: Create a IngressRoute file called 'traefik-ingress.yaml' with the following contents:
```yaml ```yaml
apiVersion: traefik.io/v1alpha1 apiVersion: traefik.io/v1alpha1
kind: IngressRoute kind: IngressRoute

View File

@ -45,7 +45,6 @@ Providers
- [x] Linode - [x] Linode
- [x] TransIP - [x] TransIP
- [x] RFC2136 - [x] RFC2136
- [x] Vultr
- [x] UltraDNS - [x] UltraDNS
PRs welcome! PRs welcome!
@ -86,8 +85,5 @@ The Linode Provider default TTL is used when the TTL is 0. The default is 24 hou
### TransIP Provider ### TransIP Provider
The TransIP Provider minimal TTL is used when the TTL is 0. The minimal TTL is 60s. The TransIP Provider minimal TTL is used when the TTL is 0. The minimal TTL is 60s.
### Vultr Provider
The Vultr provider minimal TTL is used when the TTL is 0. The default is 1 hour.
### UltraDNS ### UltraDNS
The UltraDNS provider minimal TTL is used when the TTL is not provided. The default TTL is account level default TTL, if defined, otherwise 24 hours. The UltraDNS provider minimal TTL is used when the TTL is not provided. The default TTL is account level default TTL, if defined, otherwise 24 hours.

View File

@ -1,210 +0,0 @@
# Setting up ExternalDNS for Services on ANS Group's SafeDNS
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using SafeDNS.
Make sure to use **>=0.11.0** version of ExternalDNS for this tutorial.
## Managing DNS with SafeDNS
If you want to learn about how to use the SafeDNS service read the following tutorials:
To learn more about the use of SafeDNS in general, see the following page:
[ANS Group's SafeDNS documentation](https://docs.ukfast.co.uk/domains/safedns/index.html).
## Creating SafeDNS credentials
Generate a fresh API token for use with ExternalDNS, following the instructions
at the ANS Group developer [Getting-Started](https://developers.ukfast.io/getting-started)
page. You will need to grant read/write access to the SafeDNS API. No access to
any other ANS Group service is required.
The environment variable `SAFEDNS_TOKEN` must have a value of this token to run
ExternalDNS with SafeDNS integration.
## Deploy ExternalDNS
Connect your `kubectl` client to the cluster you want to test ExternalDNS with.
Then apply one of the following manifests file to deploy ExternalDNS.
### Manifest (for clusters without RBAC enabled)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
# You will need to check what the latest version is yourself:
# https://github.com/kubernetes-sigs/external-dns/releases
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --source=service # ingress is also possible
# (optional) limit to only example.com domains; change to match the
# zone created above.
- --domain-filter=example.com
- --provider=safedns
env:
- name: SAFEDNS_TOKEN
value: "SAFEDNSTOKENSAFEDNSTOKEN"
```
### Manifest (for clusters with RBAC enabled)
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --source=service # ingress is also possible
# (optional) limit to only example.com domains; change to match the
# zone created above.
- --domain-filter=example.com
- --provider=safedns
env:
- name: SAFEDNS_TOKEN
value: "SAFEDNSTOKENSAFEDNSTOKEN"
```
## Deploying an Nginx Service
Create a service file called 'nginx.yaml' with the following contents:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
annotations:
external-dns.alpha.kubernetes.io/hostname: my-app.example.com
spec:
selector:
app: nginx
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: 80
```
Note the annotation on the service; use a hostname that matches the domain
filter specified above.
ExternalDNS uses this annotation to determine what services should be registered
with DNS. Removing the annotation will cause ExternalDNS to remove the
corresponding DNS records.
Create the deployment and service:
```console
$ kubectl create -f nginx.yaml
```
Depending where you run your service it can take a little while for your cloud
provider to create an external IP for the service.
Once the service has an external IP assigned, ExternalDNS will notice the new
service IP address and synchronize the SafeDNS records.
## Verifying SafeDNS records
Check your [SafeDNS UI](https://my.ukfast.co.uk/safedns/index.php) and select
the appropriate domain to view the records for your SafeDNS zone.
This should show the external IP address of the service as the A record for your
domain.
Alternatively, you can perform a DNS lookup for the hostname specified:
```console
$ dig +short my-app.example.com
an.ip.addr.ess
```
## Cleanup
Now that we have verified that ExternalDNS will automatically manage SafeDNS
records, we can delete the tutorial's example:
```
$ kubectl delete service -f nginx.yaml
$ kubectl delete service -f externaldns.yaml
```

View File

@ -1,4 +1,4 @@
# Setting up External-DNS for Services on Akamai Edge DNS # Akamai Edge DNS
## Prerequisites ## Prerequisites
@ -104,7 +104,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # or ingress or both - --source=service # or ingress or both
- --provider=akamai - --provider=akamai
@ -190,7 +190,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # or ingress or both - --source=service # or ingress or both
- --provider=akamai - --provider=akamai

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on Alibaba Cloud # Alibaba Cloud
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster on Alibaba Cloud. Make sure to use **>=0.5.6** version of ExternalDNS for this tutorial This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster on Alibaba Cloud. Make sure to use **>=0.5.6** version of ExternalDNS for this tutorial
@ -113,7 +113,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -187,7 +187,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress

View File

@ -1,4 +1,4 @@
# Using ExternalDNS with aws-load-balancer-controller # AWS Load Balancer Controller
This tutorial describes how to use ExternalDNS with the [aws-load-balancer-controller][1]. This tutorial describes how to use ExternalDNS with the [aws-load-balancer-controller][1].

View File

@ -1,10 +1,10 @@
# Setting up ExternalDNS using the same domain for public and private Route53 zones # AWS Route53 with same domain for public and private zones
This tutorial describes how to setup ExternalDNS using the same domain for public and private Route53 zones and [nginx-ingress-controller](https://github.com/kubernetes/ingress-nginx). It also outlines how to use [cert-manager](https://github.com/jetstack/cert-manager) to automatically issue SSL certificates from [Let's Encrypt](https://letsencrypt.org/) for both public and private records. This tutorial describes how to setup ExternalDNS using the same domain for public and private Route53 zones and [nginx-ingress-controller](https://github.com/kubernetes/ingress-nginx). It also outlines how to use [cert-manager](https://github.com/jetstack/cert-manager) to automatically issue SSL certificates from [Let's Encrypt](https://letsencrypt.org/) for both public and private records.
## Deploy public nginx-ingress-controller ## Deploy public nginx-ingress-controller
Consult [External DNS nginx ingress docs](nginx-ingress.md) for installation guidelines. You may be interested with [GKE with nginx ingress](gke-nginx.md) for installation guidelines.
Specify `ingress-class` in nginx-ingress-controller container args: Specify `ingress-class` in nginx-ingress-controller container args:
@ -107,8 +107,6 @@ spec:
## Deploy private nginx-ingress-controller ## Deploy private nginx-ingress-controller
Consult [External DNS nginx ingress docs](nginx-ingress.md) for installation guidelines.
Make sure to specify `ingress-class` in nginx-ingress-controller container args: Make sure to specify `ingress-class` in nginx-ingress-controller container args:
```yaml ```yaml
@ -243,7 +241,7 @@ spec:
- --txt-owner-id=external-dns - --txt-owner-id=external-dns
- --ingress-class=external-ingress - --ingress-class=external-ingress
- --aws-zone-type=public - --aws-zone-type=public
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
name: external-dns-public name: external-dns-public
``` ```
@ -281,7 +279,7 @@ spec:
- --txt-owner-id=dev.k8s.nexus - --txt-owner-id=dev.k8s.nexus
- --ingress-class=internal-ingress - --ingress-class=internal-ingress
- --aws-zone-type=private - --aws-zone-type=private
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
name: external-dns-private name: external-dns-private
``` ```

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS using AWS Cloud Map API # AWS Cloud Map API
This tutorial describes how to set up ExternalDNS for usage within a Kubernetes cluster with [AWS Cloud Map API](https://docs.aws.amazon.com/cloud-map/). This tutorial describes how to set up ExternalDNS for usage within a Kubernetes cluster with [AWS Cloud Map API](https://docs.aws.amazon.com/cloud-map/).
@ -81,7 +81,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
env: env:
- name: AWS_REGION - name: AWS_REGION
value: us-east-1 # put your CloudMap NameSpace region value: us-east-1 # put your CloudMap NameSpace region
@ -148,7 +148,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
env: env:
- name: AWS_REGION - name: AWS_REGION
value: us-east-1 # put your CloudMap NameSpace region value: us-east-1 # put your CloudMap NameSpace region
@ -221,7 +221,7 @@ metadata:
name: nginx name: nginx
annotations: annotations:
external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.my-org.com external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.my-org.com
external-dns.alpha.kubernetes.io/ttl: 60 external-dns.alpha.kubernetes.io/ttl: "60"
spec: spec:
... ...
``` ```

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on AWS # AWS
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster on AWS. Make sure to use **>=0.15.0** version of ExternalDNS for this tutorial This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster on AWS. Make sure to use **>=0.15.0** version of ExternalDNS for this tutorial
@ -418,7 +418,7 @@ Finally, install the ExternalDNS chart with Helm using the configuration specifi
helm upgrade --install external-dns external-dns/external-dns --values values.yaml helm upgrade --install external-dns external-dns/external-dns --values values.yaml
``` ```
### Manifest (for clusters without RBAC enabled) ### When using clusters without RBAC enabled
Save the following below as `externaldns-no-rbac.yaml`. Save the following below as `externaldns-no-rbac.yaml`.
@ -442,7 +442,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -475,99 +475,40 @@ kubectl create --filename externaldns-no-rbac.yaml \
--namespace ${EXTERNALDNS_NS:-"default"} --namespace ${EXTERNALDNS_NS:-"default"}
``` ```
### Manifest (for clusters with RBAC enabled) ### When using clusters with RBAC enabled
Save the following below as `externaldns-with-rbac.yaml`. If you're using EKS, you can update the `values.yaml` file you created earlier to include the annotations to link the Role ARN you created before.
```yaml ```yaml
# comment out sa if it was previously created provider:
apiVersion: v1 name: aws
kind: ServiceAccount serviceAccount:
metadata: annotations:
name: external-dns eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/${EXTERNALDNS_ROLE_NAME:-"external-dns"}
labels:
app.kubernetes.io/name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
labels:
app.kubernetes.io/name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods","nodes"]
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-viewer
labels:
app.kubernetes.io/name: external-dns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default # change to desired namespace: externaldns, kube-addons
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
labels:
app.kubernetes.io/name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: external-dns
template:
metadata:
labels:
app.kubernetes.io/name: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --source=service
- --source=ingress
- --domain-filter=example.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
- --provider=aws
- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
- --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
- --registry=txt
- --txt-owner-id=external-dns
env:
- name: AWS_DEFAULT_REGION
value: us-east-1 # change to region where EKS is installed
# # Uncommend below if using static credentials
# - name: AWS_SHARED_CREDENTIALS_FILE
# value: /.aws/credentials
# volumeMounts:
# - name: aws-credentials
# mountPath: /.aws
# readOnly: true
# volumes:
# - name: aws-credentials
# secret:
# secretName: external-dns
``` ```
When ready deploy: If you need to provide credentials directly using a secret (ie. You're not using EKS), you can change the `values.yaml` file to include volume and volume mounts.
```bash ```yaml
kubectl create --filename externaldns-with-rbac.yaml \ provider:
--namespace ${EXTERNALDNS_NS:-"default"} name: aws
env:
- name: AWS_SHARED_CREDENTIALS_FILE
value: /etc/aws/credentials/my_credentials
extraVolumes:
- name: aws-credentials
secret:
secretName: external-dns # In this example, the secret will have the data stored in a key named `my_credentials`
extraVolumeMounts:
- name: aws-credentials
mountPath: /etc/aws/credentials
readOnly: true
```
When ready, update your Helm installation:
```shell
helm upgrade --install external-dns external-dns/external-dns --values values.yaml
``` ```
## Arguments ## Arguments
@ -584,7 +525,7 @@ Annotations which are specific to AWS.
### alias ### alias
`external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create an ALIAS record when the target is an ALIAS as well. To make the target an alias, the ingress needs to be configured correctly as described in [the docs](./nginx-ingress.md#with-a-separate-tcp-load-balancer). In particular, the argument `--publish-service=default/nginx-ingress-controller` has to be set on the `nginx-ingress-controller` container. If one uses the `nginx-ingress` Helm chart, this flag can be set with the `controller.publishService.enabled` configuration option. `external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create an ALIAS record when the target is an ALIAS as well. To make the target an alias, the ingress needs to be configured correctly as described in [the docs](./gke-nginx.md#with-a-separate-tcp-load-balancer). In particular, the argument `--publish-service=default/nginx-ingress-controller` has to be set on the `nginx-ingress-controller` container. If one uses the `nginx-ingress` Helm chart, this flag can be set with the `controller.publishService.enabled` configuration option.
### target-hosted-zone ### target-hosted-zone
@ -915,6 +856,10 @@ env:
key: {{ YOUR_SECRET_KEY }} key: {{ YOUR_SECRET_KEY }}
``` ```
## DynamoDB Registry
The DynamoDB Registry can be used to store dns records metadata. See the [DynamoDB Registry Tutorial](../registry/dynamodb.md) for more information.
## Clean up ## Clean up
Make sure to delete all Service objects before terminating the cluster so all load balancers get cleaned up correctly. Make sure to delete all Service objects before terminating the cluster so all load balancers get cleaned up correctly.
@ -971,8 +916,11 @@ Route53 has a [5 API requests per second per account hard quota](https://docs.aw
Running several fast polling ExternalDNS instances in a given account can easily hit that limit. Some ways to reduce the request rate include: Running several fast polling ExternalDNS instances in a given account can easily hit that limit. Some ways to reduce the request rate include:
* Reduce the polling loop's synchronization interval at the possible cost of slower change propagation (but see `--events` below to reduce the impact). * Reduce the polling loop's synchronization interval at the possible cost of slower change propagation (but see `--events` below to reduce the impact).
* `--interval=5m` (default `1m`) * `--interval=5m` (default `1m`)
* Trigger the polling loop on changes to K8s objects, rather than only at `interval`, to have responsive updates with long poll intervals * Enable a Cache to store the zone records list. It comes with a cost: slower propagation when the zone gets modified from other sources such as the AWS console, terraform, cloudformation or anything similar.
* `--provider-cache-time=15m` (default `0m`)
* Trigger the polling loop on changes to K8s objects, rather than only at `interval` and ensure a minimum of time between events, to have responsive updates with long poll intervals
* `--events` * `--events`
* `--min-event-sync-interval=5m` (default `5s`)
* Limit the [sources watched](https://github.com/kubernetes-sigs/external-dns/blob/master/pkg/apis/externaldns/types.go#L364) when the `--events` flag is specified to specific types, namespaces, labels, or annotations * Limit the [sources watched](https://github.com/kubernetes-sigs/external-dns/blob/master/pkg/apis/externaldns/types.go#L364) when the `--events` flag is specified to specific types, namespaces, labels, or annotations
* `--source=ingress --source=service` - specify multiple times for multiple sources * `--source=ingress --source=service` - specify multiple times for multiple sources
* `--namespace=my-app` * `--namespace=my-app`
@ -1003,7 +951,7 @@ A simple way to implement randomised startup is with an init container:
spec: spec:
initContainers: initContainers:
- name: init-jitter - name: init-jitter
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
command: command:
- /bin/sh - /bin/sh
- -c - -c

View File

@ -1,4 +1,4 @@
# Set up ExternalDNS for Azure Private DNS # Azure Private DNS
This tutorial describes how to set up ExternalDNS for managing records in Azure Private DNS. This tutorial describes how to set up ExternalDNS for managing records in Azure Private DNS.
@ -130,7 +130,7 @@ spec:
spec: spec:
containers: containers:
- name: externaldns - name: externaldns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -201,7 +201,7 @@ spec:
serviceAccountName: externaldns serviceAccountName: externaldns
containers: containers:
- name: externaldns - name: externaldns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -272,7 +272,7 @@ spec:
serviceAccountName: externaldns serviceAccountName: externaldns
containers: containers:
- name: externaldns - name: externaldns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -330,12 +330,12 @@ Apply the following manifest to create a service of type `LoadBalancer`. This wi
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
external-dns.alpha.kubernetes.io/hostname: server.example.com
external-dns.alpha.kubernetes.io/internal-hostname: server-clusterip.example.com
metadata: metadata:
name: nginx-svc name: nginx-svc
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
external-dns.alpha.kubernetes.io/hostname: server.example.com
external-dns.alpha.kubernetes.io/internal-hostname: server-clusterip.example.com
spec: spec:
ports: ports:
- port: 80 - port: 80

View File

@ -1,5 +1,4 @@
# Azure DNS
# Setting up ExternalDNS for Services on Azure
This tutorial describes how to setup ExternalDNS for [Azure DNS](https://azure.microsoft.com/services/dns/) with [Azure Kubernetes Service](https://docs.microsoft.com/azure/aks/). This tutorial describes how to setup ExternalDNS for [Azure DNS](https://azure.microsoft.com/services/dns/) with [Azure Kubernetes Service](https://docs.microsoft.com/azure/aks/).
@ -518,7 +517,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -586,7 +585,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -657,7 +656,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress

View File

@ -1,152 +0,0 @@
# Setting up external-dns for BlueCat
The first external-dns release with with BlueCat provider support is v0.8.0.
## Prerequisites
Install the BlueCat Gateway product and deploy the [community gateway workflows](https://github.com/bluecatlabs/gateway-workflows).
## Configuration Options
There are two ways to pass configuration options to the Bluecat Provider JSON configuration file and command line flags. Currently if a valid configuration file is used all
BlueCat provider configurations will be taken from the configuration file. If a configuraiton file is not provided or cannot be read then all BlueCat provider configurations will
be taken from the command line flags. In the future an enhancement will be made to merge configuration options from the configuration file and command line flags if both are provided.
BlueCat provider supports getting the proxy URL from the environment variables. The format is the one specified by golang's [http.ProxyFromEnvironment](https://pkg.go.dev/net/http#ProxyFromEnvironment).
### Using CLI Flags
When using CLI flags to configure the Bluecat Provider the BlueCat Gateway credentials are passed in using environment variables `BLUECAT_USERNAME` and `BLUECAT_PASSWORD`.
#### Deploy
Setup up namespace, deployment, and service account:
```
kubectl create namespace bluecat-example
kubectl create secret generic bluecat-credentials --from-literal=username=bluecatuser --from-literal=password=bluecatpassword -n bluecat-example
cat << EOF > ~/bluecat.yml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
selector:
matchLabels:
app: external-dns
strategy:
type: Recreate
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --log-level=debug
- --source=service
- --provider=bluecat
- --txt-owner-id=bluecat-example
- --bluecat-dns-configuration=Example
- --bluecat-dns-view=Internal
- --bluecat-gateway-host=https://bluecatgw.example.com
- --bluecat-root-zone=example.com
env:
- name: BLUECAT_USERNAME
valueFrom:
secretKeyRef:
name: bluecat-credentials
key: username
- name: BLUECAT_PASSWORD
valueFrom:
secretKeyRef:
name: bluecat-credentials
key: password
EOF
kubectl apply -f ~/bluecat.yml -n bluecat-example
```
### Using JSON Configuration File
The options for configuring the Bluecat Provider are available through the JSON file provided to External-DNS via the flag `--bluecat-config-file`.
| Key | Required |
| ----------------- | ------------------ |
| gatewayHost | Yes |
| gatewayUsername | No |
| gatewayPassword | No |
| dnsConfiguration | Yes |
| dnsView | Yes |
| rootZone | Yes |
| dnsServerName | No |
| dnsDeployType | No |
| skipTLSVerify | No (default false) |
#### Deploy
Setup configuration file as k8s `Secret`.
```
cat << EOF > ~/bluecat.json
{
"gatewayHost": "https://bluecatgw.example.com",
"gatewayUsername": "user",
"gatewayPassword": "pass",
"dnsConfiguration": "Example",
"dnsView": "Internal",
"rootZone": "example.com",
"skipTLSVerify": false
}
EOF
kubectl create secret generic bluecatconfig --from-file ~/bluecat.json -n bluecat-example
```
Setup up namespace, deployment, and service account:
```
kubectl create namespace bluecat-example
cat << EOF > ~/bluecat.yml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
selector:
matchLabels:
app: external-dns
strategy:
type: Recreate
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
volumes:
- name: bluecatconfig
secret:
secretName: bluecatconfig
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
volumeMounts:
- name: bluecatconfig
mountPath: "/etc/external-dns/"
readOnly: true
args:
- --log-level=debug
- --source=service
- --provider=bluecat
- --txt-owner-id=bluecat-example
- --bluecat-config-file=/etc/external-dns/bluecat.json
EOF
kubectl apply -f ~/bluecat.yml -n bluecat-example
```

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on Civo # Civo DNS
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Civo DNS Manager. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Civo DNS Manager.
@ -40,7 +40,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -104,7 +104,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on Cloudflare # Cloudflare DNS
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Cloudflare DNS. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Cloudflare DNS.
@ -57,7 +57,7 @@ Then apply one of the following manifests file to deploy ExternalDNS.
Create a values.yaml file to configure ExternalDNS to use CloudFlare as the DNS provider. This file should include the necessary environment variables: Create a values.yaml file to configure ExternalDNS to use CloudFlare as the DNS provider. This file should include the necessary environment variables:
```shell ```yaml
provider: provider:
name: cloudflare name: cloudflare
env: env:
@ -75,7 +75,7 @@ env:
Use this in your values.yaml, if you are using API Token: Use this in your values.yaml, if you are using API Token:
```shell ```yaml
provider: provider:
name: cloudflare name: cloudflare
env: env:
@ -120,22 +120,22 @@ spec:
app: external-dns app: external-dns
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
- --zone-id-filter=023e105f4ecef8ad9ca31a8372d0c353 # (optional) limit to a specific zone. - --zone-id-filter=023e105f4ecef8ad9ca31a8372d0c353 # (optional) limit to a specific zone.
- --provider=cloudflare - --provider=cloudflare
- --cloudflare-proxied # (optional) enable the proxy feature of Cloudflare (DDOS protection, CDN...) - --cloudflare-proxied # (optional) enable the proxy feature of Cloudflare (DDOS protection, CDN...)
- --cloudflare-dns-records-per-page=5000 # (optional) configure how many DNS records to fetch per request - --cloudflare-dns-records-per-page=5000 # (optional) configure how many DNS records to fetch per request
env: env:
- name: CF_API_KEY - name: CF_API_KEY
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: cloudflare-api-key name: cloudflare-api-key
key: apiKey key: apiKey
- name: CF_API_EMAIL - name: CF_API_EMAIL
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: cloudflare-api-key name: cloudflare-api-key
@ -155,15 +155,15 @@ kind: ClusterRole
metadata: metadata:
name: external-dns name: external-dns
rules: rules:
- apiGroups: [""] - apiGroups: [""]
resources: ["services","endpoints","pods"] resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"] verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"] - apiGroups: ["extensions","networking.k8s.io"]
resources: ["ingresses"] resources: ["ingresses"]
verbs: ["get","watch","list"] verbs: ["get","watch","list"]
- apiGroups: [""] - apiGroups: [""]
resources: ["nodes"] resources: ["nodes"]
verbs: ["list", "watch"] verbs: ["list", "watch"]
--- ---
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding kind: ClusterRoleBinding
@ -195,26 +195,26 @@ spec:
spec: spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
- --zone-id-filter=023e105f4ecef8ad9ca31a8372d0c353 # (optional) limit to a specific zone. - --zone-id-filter=023e105f4ecef8ad9ca31a8372d0c353 # (optional) limit to a specific zone.
- --provider=cloudflare - --provider=cloudflare
- --cloudflare-proxied # (optional) enable the proxy feature of Cloudflare (DDOS protection, CDN...) - --cloudflare-proxied # (optional) enable the proxy feature of Cloudflare (DDOS protection, CDN...)
- --cloudflare-dns-records-per-page=5000 # (optional) configure how many DNS records to fetch per request - --cloudflare-dns-records-per-page=5000 # (optional) configure how many DNS records to fetch per request
env: env:
- name: CF_API_KEY - name: CF_API_KEY
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: cloudflare-api-key name: cloudflare-api-key
key: apiKey key: apiKey
- name: CF_API_EMAIL - name: CF_API_EMAIL
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: cloudflare-api-key name: cloudflare-api-key
key: email key: email
``` ```
## Deploying an Nginx Service ## Deploying an Nginx Service
@ -270,7 +270,7 @@ will cause ExternalDNS to remove the corresponding DNS records.
Create the deployment and service: Create the deployment and service:
``` ```shell
$ kubectl create -f nginx.yaml $ kubectl create -f nginx.yaml
``` ```
@ -291,7 +291,7 @@ This should show the external IP address of the service as the A record for your
Now that we have verified that ExternalDNS will automatically manage Cloudflare DNS records, we can delete the tutorial's example: Now that we have verified that ExternalDNS will automatically manage Cloudflare DNS records, we can delete the tutorial's example:
``` ```shell
$ kubectl delete -f nginx.yaml $ kubectl delete -f nginx.yaml
$ kubectl delete -f externaldns.yaml $ kubectl delete -f externaldns.yaml
``` ```

View File

@ -1,4 +1,4 @@
# Setting up External DNS with Contour # Contour HTTPProxy
This tutorial describes how to configure External DNS to use the Contour `HTTPProxy` source. This tutorial describes how to configure External DNS to use the Contour `HTTPProxy` source.
Using the `HTTPProxy` resource with External DNS requires Contour version 1.5 or greater. Using the `HTTPProxy` resource with External DNS requires Contour version 1.5 or greater.
@ -24,7 +24,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress
@ -93,7 +93,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress

View File

@ -1,39 +1,56 @@
# Setting up ExternalDNS for CoreDNS with minikube # CoreDNS with minikube
:warning: This tutorial is out of date.
:information_source: PRs to update it are welcome !
This tutorial describes how to setup ExternalDNS for usage within a [minikube](https://github.com/kubernetes/minikube) cluster that makes use of [CoreDNS](https://github.com/coredns/coredns) and [nginx ingress controller](https://github.com/kubernetes/ingress-nginx). This tutorial describes how to setup ExternalDNS for usage within a [minikube](https://github.com/kubernetes/minikube) cluster that makes use of [CoreDNS](https://github.com/coredns/coredns) and [nginx ingress controller](https://github.com/kubernetes/ingress-nginx).
You need to: You need to:
* install CoreDNS with [etcd](https://github.com/etcd-io/etcd) enabled * install CoreDNS with [etcd](https://github.com/etcd-io/etcd) enabled
* install external-dns with coredns as a provider * install external-dns with coredns as a provider
* enable ingress controller for the minikube cluster * enable ingress controller for the minikube cluster
## Creating a cluster ## Creating a cluster
```
```shell
minikube start minikube start
``` ```
## Installing CoreDNS with etcd enabled ## Installing CoreDNS with etcd enabled
Helm chart is used to install etcd and CoreDNS. Helm chart is used to install etcd and CoreDNS.
### Initializing helm chart ### Initializing helm chart
```
```shell
helm init helm init
``` ```
### Installing etcd ### Installing etcd
[etcd operator](https://github.com/coreos/etcd-operator) is used to manage etcd clusters. [etcd operator](https://github.com/coreos/etcd-operator) is used to manage etcd clusters.
``` ```
helm install stable/etcd-operator --name my-etcd-op helm install stable/etcd-operator --name my-etcd-op
``` ```
etcd cluster is installed with example yaml from etcd operator website. etcd cluster is installed with example yaml from etcd operator website.
```
```shell
kubectl apply -f https://raw.githubusercontent.com/coreos/etcd-operator/HEAD/example/example-etcd-cluster.yaml kubectl apply -f https://raw.githubusercontent.com/coreos/etcd-operator/HEAD/example/example-etcd-cluster.yaml
``` ```
### Installing CoreDNS ### Installing CoreDNS
In order to make CoreDNS work with etcd backend, values.yaml of the chart should be changed with corresponding configurations. In order to make CoreDNS work with etcd backend, values.yaml of the chart should be changed with corresponding configurations.
``` ```
wget https://raw.githubusercontent.com/helm/charts/HEAD/stable/coredns/values.yaml wget https://raw.githubusercontent.com/helm/charts/HEAD/stable/coredns/values.yaml
``` ```
You need to edit/patch the file with below diff You need to edit/patch the file with below diff
```diff ```diff
diff --git a/values.yaml b/values.yaml diff --git a/values.yaml b/values.yaml
index 964e72b..e2fa934 100644 index 964e72b..e2fa934 100644
@ -68,23 +85,29 @@ index 964e72b..e2fa934 100644
# Complete example with all the options: # Complete example with all the options:
# - zones: # the `zones` block can be left out entirely, defaults to "." # - zones: # the `zones` block can be left out entirely, defaults to "."
``` ```
**Note**: **Note**:
* IP address of etcd's endpoint should be get from etcd client service. It should be "example-etcd-cluster-client" in this example. This IP address is used through this document for etcd endpoint configuration. * IP address of etcd's endpoint should be get from etcd client service. It should be "example-etcd-cluster-client" in this example. This IP address is used through this document for etcd endpoint configuration.
```
```shell
$ kubectl get svc example-etcd-cluster-client $ kubectl get svc example-etcd-cluster-client
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
example-etcd-cluster-client ClusterIP 10.105.68.165 <none> 2379/TCP 16m example-etcd-cluster-client ClusterIP 10.105.68.165 <none> 2379/TCP 16m
``` ```
* Parameters should configure your own domain. "example.org" is used in this example. * Parameters should configure your own domain. "example.org" is used in this example.
After configuration done in values.yaml, you can install coredns chart. After configuration done in values.yaml, you can install coredns chart.
```
```shell
helm install --name my-coredns --values values.yaml stable/coredns helm install --name my-coredns --values values.yaml stable/coredns
``` ```
## Installing ExternalDNS ## Installing ExternalDNS
### Install external ExternalDNS ### Install external ExternalDNS
ETCD_URLS is configured to etcd client service address. ETCD_URLS is configured to etcd client service address.
Optionally, you can configure ETCD_USERNAME and ETCD_PASSWORD for authenticating to etcd. It is also possible to connect to the etcd cluster via HTTPS using the following environment variables: ETCD_CA_FILE, ETCD_CERT_FILE, ETCD_KEY_FILE, ETCD_TLS_SERVER_NAME, ETCD_TLS_INSECURE. Optionally, you can configure ETCD_USERNAME and ETCD_PASSWORD for authenticating to etcd. It is also possible to connect to the etcd cluster via HTTPS using the following environment variables: ETCD_CA_FILE, ETCD_CERT_FILE, ETCD_KEY_FILE, ETCD_TLS_SERVER_NAME, ETCD_TLS_INSECURE.
@ -109,7 +132,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=ingress - --source=ingress
- --provider=coredns - --provider=coredns
@ -176,7 +199,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=ingress - --source=ingress
- --provider=coredns - --provider=coredns
@ -187,13 +210,16 @@ spec:
``` ```
## Enable the ingress controller ## Enable the ingress controller
You can use the ingress controller in minikube cluster. It needs to enable ingress addon in the cluster. You can use the ingress controller in minikube cluster. It needs to enable ingress addon in the cluster.
```
```shell
minikube addons enable ingress minikube addons enable ingress
``` ```
## Testing ingress example ## Testing ingress example
```
```shell
$ cat ingress.yaml $ cat ingress.yaml
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
@ -213,9 +239,9 @@ $ kubectl apply -f ingress.yaml
ingress.extensions "nginx" created ingress.extensions "nginx" created
``` ```
Wait a moment until DNS has the ingress IP. The DNS service IP is from CoreDNS service. It is "my-coredns-coredns" in this example. Wait a moment until DNS has the ingress IP. The DNS service IP is from CoreDNS service. It is "my-coredns-coredns" in this example.
```
```shell
$ kubectl get svc my-coredns-coredns $ kubectl get svc my-coredns-coredns
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-coredns-coredns ClusterIP 10.100.4.143 <none> 53/UDP 12m my-coredns-coredns ClusterIP 10.100.4.143 <none> 53/UDP 12m

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on OpenStack Designate # Designate DNS from OpenStack
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using OpenStack Designate DNS. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using OpenStack Designate DNS.
@ -59,7 +59,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -136,7 +136,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on DigitalOcean # DigitalOcean DNS
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using DigitalOcean DNS. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using DigitalOcean DNS.
@ -68,7 +68,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -135,7 +135,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on DNSimple # DNSimple
This tutorial describes how to setup ExternalDNS for usage with DNSimple. This tutorial describes how to setup ExternalDNS for usage with DNSimple.
@ -39,7 +39,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone you create in DNSimple. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone you create in DNSimple.
@ -108,7 +108,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone you create in DNSimple. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone you create in DNSimple.

View File

@ -1,149 +0,0 @@
# Setting up ExternalDNS for Dyn
## Creating a Dyn Configuration Secret
For ExternalDNS to access the Dyn API, create a Kubernetes secret.
To create the secret:
```
$ kubectl create secret generic external-dns \
--from-literal=EXTERNAL_DNS_DYN_CUSTOMER_NAME=${DYN_CUSTOMER_NAME} \
--from-literal=EXTERNAL_DNS_DYN_USERNAME=${DYN_USERNAME} \
--from-literal=EXTERNAL_DNS_DYN_PASSWORD=${DYN_PASSWORD}
```
The credentials are the same ones created during account registration. As best practise, you are advised to
create an API-only user that is entitled to only the zones intended to be changed by ExternalDNS
## Deploy ExternalDNS
The rest of this tutorial assumes you own `example.com` domain and your DNS provider is Dyn. Change `example.com`
with a domain/zone that you really own.
In case of the dyn provider, the flag `--zone-id-filter` is mandatory as it specifies which zones to scan for records. Without it
Create a deployment file called `externaldns.yaml` with the following contents:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --source=ingress
- --txt-prefix=_d
- --namespace=example
- --zone-id-filter=example.com
- --domain-filter=example.com
- --provider=dyn
env:
- name: EXTERNAL_DNS_DYN_CUSTOMER_NAME
valueFrom:
secretKeyRef:
name: external-dns
key: EXTERNAL_DNS_DYN_CUSTOMER_NAME
- name: EXTERNAL_DNS_DYN_USERNAME
valueFrom:
secretKeyRef:
name: external-dns
key: EXTERNAL_DNS_DYN_USERNAME
- name: EXTERNAL_DNS_DYN_PASSWORD
valueFrom:
secretKeyRef:
name: external-dns
key: EXTERNAL_DNS_DYN_PASSWORD
EOF
```
As we'll be creating an Ingress resource, you need `--txt-prefix=_d` as a CNAME cannot coexist with a TXT record. You can change the prefix to
any valid start of a FQDN.
Create the deployment for ExternalDNS:
```
$ kubectl create -f externaldns.yaml
```
## Running a locally build version
If you just want to test ExternalDNS in dry-run mode locally without doing the above deployment you can also do it.
Make sure your kubectl is configured correctly . Assuming you have the sources, build and run it like so:
```bash
make
# output skipped
./build/external-dns \
--provider=dyn \
--dyn-customer-name=${DYN_CUSTOMER_NAME} \
--dyn-username=${DYN_USERNAME} \
--dyn-password=${DYN_PASSWORD} \
--domain-filter=example.com \
--zone-id-filter=example.com \
--namespace=example \
--log-level=debug \
--txt-prefix=_ \
--dry-run=true
INFO[0000] running in dry-run mode. No changes to DNS records will be made.
INFO[0000] Connected to cluster at https://some-k8s-cluster.example.com
INFO[0001] Zones: [example.com]
# output skipped
```
Having `--dry-run=true` and `--log-level=debug` is a great way to see _exactly_ what DynamicDNS is doing or is about to do.
## Deploying an Ingress Resource
Create a file called 'test-ingress.yaml' with the following contents:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
namespace: example
spec:
rules:
- host: test-ingress.example.com
http:
paths:
- backend:
service:
name: my-awesome-service
port:
number: 8080
pathType: Prefix
```
As the DNS name `test-ingress.example.com` matches the filter, external-dns will create two records:
a CNAME for test-ingress.example.com and TXT for _dtest-ingress.example.com.
Create the Ingress:
```
$ kubectl create -f test-ingress.yaml
```
By default external-dns scans for changes every minute so give it some time to catch up with the
## Verifying Dyn DNS records
Login to the console at https://portal.dynect.net/login/ and verify records are created
## Clean up
Login to the console at https://portal.dynect.net/login/ and delete the records created. Alternatively, just delete the sample
Ingress resources and external-dns will delete the records.

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Exoscale # Exoscale
## Prerequisites ## Prerequisites
@ -40,7 +40,7 @@ spec:
# serviceAccountName: external-dns # serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=ingress # or service or both - --source=ingress # or service or both
- --provider=exoscale - --provider=exoscale

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for ExternalName Services # ExternalName Services
This tutorial describes how to setup ExternalDNS for usage in conjunction with an ExternalName service. This tutorial describes how to setup ExternalDNS for usage in conjunction with an ExternalName service.
@ -27,7 +27,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --log-level=debug - --log-level=debug
- --source=service - --source=service

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on Gandi # Gandi
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Gandi. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Gandi.
@ -41,7 +41,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -105,7 +105,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS on GKE with nginx-ingress-controller # GKE with nginx-ingress-controller
This tutorial describes how to setup ExternalDNS for usage within a GKE cluster that doesn't make use of Google's [default ingress controller](https://github.com/kubernetes/ingress-gce) but rather uses [nginx-ingress-controller](https://github.com/kubernetes/ingress-nginx) for that task. This tutorial describes how to setup ExternalDNS for usage within a GKE cluster that doesn't make use of Google's [default ingress controller](https://github.com/kubernetes/ingress-gce) but rather uses [nginx-ingress-controller](https://github.com/kubernetes/ingress-nginx) for that task.
@ -273,7 +273,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=ingress - --source=ingress
- --domain-filter=external-dns-test.gcp.zalan.do - --domain-filter=external-dns-test.gcp.zalan.do
@ -568,7 +568,7 @@ spec:
- --google-project=zalando-external-dns-test - --google-project=zalando-external-dns-test
- --registry=txt - --registry=txt
- --txt-owner-id=my-identifier - --txt-owner-id=my-identifier
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
name: external-dns name: external-dns
securityContext: securityContext:
fsGroup: 65534 fsGroup: 65534

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS on Google Kubernetes Engine # GKE with default controller
This tutorial describes how to setup ExternalDNS for usage within a [GKE](https://cloud.google.com/kubernetes-engine) ([Google Kuberentes Engine](https://cloud.google.com/kubernetes-engine)) cluster. Make sure to use **>=0.11.0** version of ExternalDNS for this tutorial This tutorial describes how to setup ExternalDNS for usage within a [GKE](https://cloud.google.com/kubernetes-engine) ([Google Kuberentes Engine](https://cloud.google.com/kubernetes-engine)) cluster. Make sure to use **>=0.11.0** version of ExternalDNS for this tutorial
@ -375,7 +375,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on GoDaddy # GoDaddy
This tutorial describes how to setup ExternalDNS for use within a This tutorial describes how to setup ExternalDNS for use within a
Kubernetes cluster using GoDaddy DNS. Kubernetes cluster using GoDaddy DNS.
@ -64,7 +64,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -135,7 +135,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Headless Services # Headless Services
This tutorial describes how to setup ExternalDNS for usage in conjunction with a Headless service. This tutorial describes how to setup ExternalDNS for usage in conjunction with a Headless service.
@ -31,7 +31,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --log-level=debug - --log-level=debug
- --source=service - --source=service
@ -96,7 +96,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --log-level=debug - --log-level=debug
- --source=service - --source=service

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on IBMCloud # IBMCloud
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using IBMCloud DNS. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using IBMCloud DNS.
@ -69,7 +69,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -142,7 +142,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,4 +1,4 @@
# kOps dns-controller compatibility mode # kOps dns-controller
kOps includes a dns-controller that is primarily used to bootstrap the cluster, but can also be used for provisioning DNS entries for Services and Ingress. kOps includes a dns-controller that is primarily used to bootstrap the cluster, but can also be used for provisioning DNS entries for Services and Ingress.

View File

@ -1,4 +1,4 @@
# Using ExternalDNS with kube-ingress-aws-controller # kube-ingress-aws-controller
This tutorial describes how to use ExternalDNS with the [kube-ingress-aws-controller][1]. This tutorial describes how to use ExternalDNS with the [kube-ingress-aws-controller][1].

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on Linode # Linode
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Linode DNS Manager. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Linode DNS Manager.
@ -41,7 +41,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -105,7 +105,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on NS1 # NS1
This tutorial describes how to setup ExternalDNS for use within a This tutorial describes how to setup ExternalDNS for use within a
Kubernetes cluster using NS1 DNS. Kubernetes cluster using NS1 DNS.
@ -92,7 +92,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -159,7 +159,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Oracle Cloud Infrastructure (OCI) # Oracle Cloud Infrastructure
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using OCI DNS. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using OCI DNS.
@ -170,7 +170,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on OVH # OVHcloud
This tutorial describes how to setup ExternalDNS for use within a This tutorial describes how to setup ExternalDNS for use within a
Kubernetes cluster using OVH DNS. Kubernetes cluster using OVH DNS.
@ -91,7 +91,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -165,7 +165,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for PowerDNS # PowerDNS
## Prerequisites ## Prerequisites
@ -42,7 +42,7 @@ spec:
# serviceAccountName: external-dns # serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # or ingress or both - --source=service # or ingress or both
- --provider=pdns - --provider=pdns

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Pi-hole # Pi-hole
This tutorial describes how to setup ExternalDNS to sync records with Pi-hole's Custom DNS. This tutorial describes how to setup ExternalDNS to sync records with Pi-hole's Custom DNS.
Pi-hole has an internal list it checks last when resolving requests. This list can contain any number of arbitrary A, AAAA or CNAME records. Pi-hole has an internal list it checks last when resolving requests. This list can contain any number of arbitrary A, AAAA or CNAME records.
@ -81,7 +81,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
# If authentication is disabled and/or you didn't create # If authentication is disabled and/or you didn't create
# a secret, you can remove this block. # a secret, you can remove this block.
envFrom: envFrom:

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on Plural # Plural
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Plural DNS. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Plural DNS.
@ -61,7 +61,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -131,7 +131,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -1,206 +0,0 @@
# Setting up ExternalDNS for Services on RcodeZero
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using [RcodeZero Anycast DNS](https://www.rcodezero.at). Make sure to use **>=0.5.0** version of ExternalDNS for this tutorial.
The following steps are required to use RcodeZero with ExternalDNS:
1. Sign up for an RcodeZero account (or use an existing account).
2. Add your zone to the RcodeZero DNS
3. Enable the RcodeZero API, and generate an API key.
4. Deploy ExternalDNS to use the RcodeZero provider.
5. Verify the setup bey deploying a test services (optional)
## Creating a RcodeZero DNS zone
Before records can be added to your domain name automatically, you need to add your domain name to the set of zones managed by RcodeZero. In order to add the zone, perform the following steps:
1. Log in to the RcodeZero Dashboard, and move to the [Add Zone](https://my.rcodezero.at/domain/create) page.
2. Select "MASTER" as domain type, and add your domain name there. Use this domain name instead of "example.com" throughout the rest of this tutorial.
Note that "SECONDARY" domains cannot be managed by ExternalDNS, because this would not allow modification of records in the zone.
## Enable the API, and create Credentials
> The RcodeZero Anycast-Network is provisioned via web interface or REST-API.
Enable the RcodeZero API to generate an API key on [RcodeZero API](https://my.rcodezero.at/enableapi). The API key will be added to the environment variable 'RC0_API_KEY' via one of the Manifest templates (as described below).
## Deploy ExternalDNS
Connect your `kubectl` client to the cluster you want to test ExternalDNS with. Choose a Manifest from below, depending on whether or not you have RBAC enabled. Before applying it, modify the Manifest as follows:
- Replace "example.com" with the domain name you added to RcodeZero.
- Replace YOUR_RCODEZERO_API_KEY with the API key created above.
- Replace YOUR_ENCRYPTION_KEY_STRING with a string to encrypt the TXT records
### Manifest (for clusters without RBAC enabled)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
- --provider=rcodezero
- --rc0-enc-txt # (optional) encrypt TXT records; encryption key has to be provided with RC0_ENC_KEY env var.
env:
- name: RC0_API_KEY
value: "YOUR_RCODEZERO_API_KEY"
- name: RC0_ENC_VAR
value: "YOUR_ENCRYPTION_KEY_STRING"
```
### Manifest (for clusters with RBAC enabled)
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
- --provider=rcodezero
- --rc0-enc-txt # (optional) encrypt TXT records; encryption key has to be provided with RC0_ENC_KEY env var.
env:
- name: RC0_API_KEY
value: "YOUR_RCODEZERO_API_KEY"
- name: RC0_ENC_VAR
value: "YOUR_ENCRYPTION_KEY_STRING"
```
## Deploying an Nginx Service
After you have deployed ExternalDNS with RcodeZero, you can deploy a simple service based on Nginx to test the setup. This is optional, though highly recommended before using ExternalDNS in production.
Create a service file called 'nginx.yaml' with the following contents:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
annotations:
external-dns.alpha.kubernetes.io/hostname: example.com
external-dns.alpha.kubernetes.io/ttl: "120" #optional
spec:
selector:
app: nginx
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: 80
```
Change the file as follows:
- Replace the annotation of the service; use the same hostname as the RcodeZero DNS zone created above. The annotation may also be a subdomain
of the DNS zone (e.g. 'www.example.com').
- Set the TTL annotation of the service. A valid TTL of 120 or above must be given. This annotation is optional, and defaults to "300" if no value is given.
These annotations will be used to determine what services should be registered with DNS. Removing these annotations will cause ExternalDNS to remove the corresponding DNS records.
Create the Deployment and Service:
```bash
$ kubectl create -f nginx.yaml
```
Depending on your cloud provider, it might take a while to create an external IP for the service. Once an external IP address is assigned to the service, ExternalDNS will notice the new address and synchronize the RcodeZero DNS records accordingly.
## Verifying RcodeZero DNS records
Check your [RcodeZero Configured Zones](https://my.rcodezero.at/domain) and select the respective zone name. The zone should now contain the external IP address of the service as an A record.
## Cleanup
Once you have verified that ExternalDNS successfully manages RcodeZero DNS records for external services, you can delete the tutorial example as follows:
```bash
$ kubectl delete -f nginx.yaml
$ kubectl delete -f externaldns.yaml
```

View File

@ -1,6 +1,9 @@
# Setting up ExternalDNS for RancherDNS(RDNS) with kubernetes # RancherDNS
This tutorial describes how to setup ExternalDNS for usage within a kubernetes cluster that makes use of [RDNS](https://github.com/rancher/rdns-server) and [nginx ingress controller](https://github.com/kubernetes/ingress-nginx). This tutorial describes how to setup ExternalDNS for usage within a kubernetes cluster that makes use of [RDNS](https://github.com/rancher/rdns-server) and [nginx ingress controller](https://github.com/kubernetes/ingress-nginx).
You need to: You need to:
* install RDNS with [etcd](https://github.com/etcd-io/etcd) enabled * install RDNS with [etcd](https://github.com/etcd-io/etcd) enabled
* install external-dns with rdns as a provider * install external-dns with rdns as a provider
@ -54,7 +57,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=ingress - --source=ingress
- --provider=rdns - --provider=rdns
@ -123,7 +126,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=ingress - --source=ingress
- --provider=rdns - --provider=rdns

View File

@ -1,17 +1,21 @@
# Configuring RFC2136 provider # RFC2136 provider
This tutorial describes how to use the RFC2136 with either BIND or Windows DNS. This tutorial describes how to use the RFC2136 with either BIND or Windows DNS.
## Using with BIND ## Using with BIND
To use external-dns with BIND: generate/procure a key, configure DNS and add a To use external-dns with BIND: generate/procure a key, configure DNS and add a
deployment of external-dns. deployment of external-dns.
### Server credentials: ### Server credentials:
- RFC2136 was developed for and tested with [BIND](https://www.isc.org/downloads/bind/) DNS server. - RFC2136 was developed for and tested with [BIND](https://www.isc.org/downloads/bind/) DNS server.
This documentation assumes that you already have a configured and working server. If you don't, This documentation assumes that you already have a configured and working server. If you don't,
please check BIND documents or tutorials. please check BIND documents or tutorials.
- If your DNS is provided for you, ask for a TSIG key authorized to update and - If your DNS is provided for you, ask for a TSIG key authorized to update and
transfer the zone you wish to update. The key will look something like below. transfer the zone you wish to update. The key will look something like below.
Skip the next steps wrt BIND setup. Skip the next steps wrt BIND setup.
```text ```text
key "externaldns-key" { key "externaldns-key" {
algorithm hmac-sha256; algorithm hmac-sha256;
@ -25,6 +29,7 @@ a key printed to standard out like above (or in the case of dnssec-keygen in a
file called `Kexternaldns......key`). file called `Kexternaldns......key`).
### BIND Configuration: ### BIND Configuration:
If you do not administer your own DNS, skip to RFC provider configuration If you do not administer your own DNS, skip to RFC provider configuration
- Edit your named.conf file (or appropriate included file) and add/change the - Edit your named.conf file (or appropriate included file) and add/change the
@ -75,9 +80,11 @@ following.
### Using external-dns ### Using external-dns
To use external-dns add an ingress or a LoadBalancer service with a host that To use external-dns add an ingress or a LoadBalancer service with a host that
is part of the domain-filter. For example both of the following would produce is part of the domain-filter. For example both of the following would produce
A records. A records.
```text ```text
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
@ -231,7 +238,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --registry=txt - --registry=txt
- --txt-prefix=external-dns- - --txt-prefix=external-dns-
@ -274,7 +281,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --registry=txt - --registry=txt
- --txt-prefix=external-dns- - --txt-prefix=external-dns-

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on Scaleway # Scaleway
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Scaleway DNS. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Scaleway DNS.
@ -60,7 +60,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
@ -140,7 +140,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.

View File

@ -20,7 +20,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- ... # your arguments here - ... # your arguments here
securityContext: securityContext:

View File

@ -1,6 +1,7 @@
# Setting up ExternalDNS for Tencent Cloud # Tencent Cloud
## External Dns Version ## External Dns Version
* Make sure to use **>=0.13.1** version of ExternalDNS for this tutorial * Make sure to use **>=0.13.1** version of ExternalDNS for this tutorial
## Set up PrivateDns or DNSPod ## Set up PrivateDns or DNSPod
@ -19,6 +20,7 @@ Tencent Cloud PrivateDNS Service is the domain name resolution and management se
## Set up CAM for API Key ## Set up CAM for API Key
In Tencent CAM Console. you may get the secretId and secretKey pair. make sure the key pair has those Policy. In Tencent CAM Console. you may get the secretId and secretKey pair. make sure the key pair has those Policy.
```json ```json
{ {
"version": "2.0", "version": "2.0",
@ -129,7 +131,7 @@ spec:
- --policy=sync # set `upsert-only` would prevent ExternalDNS from deleting any records - --policy=sync # set `upsert-only` would prevent ExternalDNS from deleting any records
- --tencent-cloud-zone-type=private # only look at private hosted zones. set `public` to use the public dns service. - --tencent-cloud-zone-type=private # only look at private hosted zones. set `public` to use the public dns service.
- --tencent-cloud-config-file=/etc/kubernetes/tencent-cloud.json - --tencent-cloud-config-file=/etc/kubernetes/tencent-cloud.json
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
imagePullPolicy: Always imagePullPolicy: Always
name: external-dns name: external-dns
resources: {} resources: {}

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on TransIP # TransIP
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using TransIP. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using TransIP.
@ -36,7 +36,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains - --domain-filter=example.com # (optional) limit to only example.com domains
@ -107,7 +107,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service # ingress is also possible - --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains - --domain-filter=example.com # (optional) limit to only example.com domains

View File

@ -1,4 +1,4 @@
# Setting up ExternalDNS for Services on UltraDNS # UltraDNS
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using UltraDNS. This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using UltraDNS.
@ -44,7 +44,7 @@ spec:
spec: spec:
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress # ingress is also possible - --source=ingress # ingress is also possible
@ -116,7 +116,7 @@ spec:
serviceAccountName: external-dns serviceAccountName: external-dns
containers: containers:
- name: external-dns - name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2 image: registry.k8s.io/external-dns/external-dns:v0.15.0
args: args:
- --source=service - --source=service
- --source=ingress - --source=ingress

View File

@ -1,190 +0,0 @@
# Setting up ExternalDNS for VinylDNS
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using VinylDNS.
The environment vars `VINYLDNS_ACCESS_KEY`, `VINYLDNS_SECRET_KEY`, and `VINYLDNS_HOST` will be needed to run ExternalDNS with VinylDNS.
## Create a sample deployment and service for external-dns to use
Run an application and expose it via a Kubernetes Service:
```console
$ kubectl run nginx --image=nginx --replicas=1 --port=80
$ kubectl expose deployment nginx --port=80 --target-port=80 --type=LoadBalancer
```
Annotate the Service with your desired external DNS name. Make sure to change `example.org` to your domain.
```console
$ kubectl annotate service nginx "external-dns.alpha.kubernetes.io/hostname=nginx.example.org."
```
After the service is up and running, it should get an EXTERNAL-IP. At first this may showing as `<pending>`
```console
$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.0.0.1 <none> 443/TCP 1h
nginx 10.0.0.115 <pending> 80:30543/TCP 10s
```
Once it's available
```console
% kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.0.0.1 <none> 443/TCP 1h
nginx 10.0.0.115 34.x.x.x 80:30543/TCP 2m
```
## Deploy ExternalDNS to Kubernetes
Connect your `kubectl` client to the cluster you want to test ExternalDNS with.
Then apply one of the following manifests file to deploy ExternalDNS.
**Note for examples below**
When using `registry=txt` option, make sure to also use the `txt-prefix` and `txt-owner-id` options as well. If you try to create a `TXT` record in VinylDNS without a prefix, it will try to create a `TXT` record with the same name as your actual DNS record and fail (creating a stranded record `external-dns` cannot manage).
### Manifest (for clusters without RBAC enabled)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --provider=vinyldns
- --source=service
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
- --registry=txt
- --txt-owner-id=grizz
- --txt-prefix=txt-
env:
- name: VINYLDNS_HOST
value: "YOUR_VINYLDNS_HOST"
- name: VINYLDNS_ACCESS_KEY
value: "YOUR_VINYLDNS_ACCESS_KEY"
- name: VINYLDNS_SECRET_KEY
value: "YOUR_VINYLDNS_SECRET_KEY"
```
### Manifest (for clusters with RBAC enabled)
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --provider=vinyldns
- --source=service
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
- --registry=txt
- --txt-owner-id=grizz
- --txt-prefix=txt-
env:
env:
- name: VINYLDNS_HOST
value: "YOUR_VINYLDNS_HOST"
- name: VINYLDNS_ACCESS_KEY
value: "YOUR_VINYLDNS_ACCESS_KEY"
- name: VINYLDNS_SECRET_KEY
value: "YOUR_VINYLDNS_SECRET_KEYY
```
## Running a locally built version pointed to the above nginx service
Make sure your kubectl is configured correctly. Assuming you have the sources, build and run it like below.
The vinyl access details needs to exported to the environment before running.
```bash
make
# output skipped
export VINYLDNS_HOST=<fqdn of vinyl dns api>
export VINYLDNS_ACCESS_KEY=<access key>
export VINYLDNS_SECRET_KEY=<secret key>
./build/external-dns \
--provider=vinyldns \
--source=service \
--domain-filter=elements.capsps.comcast.net. \
--zone-id-filter=20e8bfd2-3a70-4e1b-8e11-c9c1948528d3 \
--registry=txt \
--txt-owner-id=grizz \
--txt-prefix=txt- \
--namespace=default \
--once \
--dry-run \
--log-level debug
INFO[0000] running in dry-run mode. No changes to DNS records will be made.
INFO[0000] Created Kubernetes client https://some-k8s-cluster.example.com
INFO[0001] Zone: [nginx.example.org.]
# output skipped
```
Having `--dry-run=true` and `--log-level=debug` is a great way to see _exactly_ what VinylDNS is doing or is about to do.

View File

@ -1,225 +0,0 @@
# Setting up ExternalDNS for Services on Vultr
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Vultr DNS.
Make sure to use **>=0.6** version of ExternalDNS for this tutorial.
## Managing DNS with Vultr
If you want to read up on vultr DNS service you can read the following tutorial:
[Introduction to Vultr DNS](https://www.vultr.com/docs/introduction-to-vultr-dns)
Create a new DNS Zone where you want to create your records in. For the examples we will be using `example.com`
## Creating Vultr Credentials
You will need to create a new API Key which can be found on the [Vultr Dashboard](https://my.vultr.com/settings/#settingsapi).
The environment variable `VULTR_API_KEY` will be needed to run ExternalDNS with Vultr.
## Deploy ExternalDNS
Connect your `kubectl` client to the cluster you want to test ExternalDNS with.
Begin by creating a Kubernetes secret to securely store your Akamai Edge DNS Access Tokens. This key will enable ExternalDNS to authenticate with Akamai Edge DNS:
```shell
kubectl create secret generic VULTR_API_KEY --from-literal=VULTR_API_KEY=YOUR_VULTR_API_KEY
```
Ensure to replace YOUR_VULTR_API_KEY, with your actual Vultr API key.
Then apply one of the following manifests file to deploy ExternalDNS.
### Using Helm
reate a values.yaml file to configure ExternalDNS to use Akamai Edge DNS as the DNS provider. This file should include the necessary environment variables:
```shell
provider:
name: akamai
env:
- name: VULTR_API_KEY
valueFrom:
secretKeyRef:
name: VULTR_API_KEY
key: VULTR_API_KEY
```
Finally, install the ExternalDNS chart with Helm using the configuration specified in your values.yaml file:
```shell
helm upgrade --install external-dns external-dns/external-dns --values values.yaml
```
### Manifest (for clusters without RBAC enabled)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
- --provider=vultr
env:
- name: VULTR_API_KEY
valueFrom:
secretKeyRef:
name: VULTR_API_KEY
key: VULTR_API_KEY
```
### Manifest (for clusters with RBAC enabled)
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.2
args:
- --source=service # ingress is also possible
- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above.
- --provider=vultr
env:
- name: VULTR_API_KEY
valueFrom:
secretKeyRef:
name: VULTR_API_KEY
key: VULTR_API_KEY
```
## Deploying a Nginx Service
Create a service file called 'nginx.yaml' with the following contents:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
annotations:
external-dns.alpha.kubernetes.io/hostname: my-app.example.com
spec:
selector:
app: nginx
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: 80
```
Note the annotation on the service; use the same hostname as the Vultr DNS zone created above.
ExternalDNS uses this annotation to determine what services should be registered with DNS. Removing the annotation will cause ExternalDNS to remove the corresponding DNS records.
Create the deployment and service:
```console
$ kubectl create -f nginx.yaml
```
Depending where you run your service it can take a little while for your cloud provider to create an external IP for the service.
Once the service has an external IP assigned, ExternalDNS will notice the new service IP address and synchronize the Vultr DNS records.
## Verifying Vultr DNS records
Check your [Vultr UI](https://my.vultr.com/dns/) to view the records for your Vultr DNS zone.
Click on the zone for the one created above if a different domain was used.
This should show the external IP address of the service as the A record for your domain.
## Cleanup
Now that we have verified that ExternalDNS will automatically manage Vultr DNS records, we can delete the tutorial's example:
```
$ kubectl delete service -f nginx.yaml
$ kubectl delete service -f externaldns.yaml
```

View File

@ -16,24 +16,32 @@ Providers implementing the HTTP API have to keep in sync with changes to the JSO
The following table represents the methods to implement mapped to their HTTP method and route. The following table represents the methods to implement mapped to their HTTP method and route.
| Provider method | HTTP Method | Route |
| --- | --- | --- | ### Provider endpoints
| Records | GET | /records |
| AdjustEndpoints | POST | /adjustendpoints | | Provider method | HTTP Method | Route | Description |
| ApplyChanges | POST | /records | | --------------- | ----------- | ---------------- | ---------------------------------------- |
| K8s probe | GET | /healthz | | Negotiate | GET | / | Negotiate `DomainFilter` |
| Records | GET | /records | Get records |
| AdjustEndpoints | POST | /adjustendpoints | Provider specific adjustments of records |
| ApplyChanges | POST | /records | Apply record |
ExternalDNS will also make requests to the `/` endpoint for negotiation and for deserialization of the `DomainFilter`. ExternalDNS will also make requests to the `/` endpoint for negotiation and for deserialization of the `DomainFilter`.
The server needs to respond to those requests by reading the `Accept` header and responding with a corresponding `Content-Type` header specifying the supported media type format and version. The server needs to respond to those requests by reading the `Accept` header and responding with a corresponding `Content-Type` header specifying the supported media type format and version.
The default recommended port is 8888, and should listen only on localhost (ie: only accessible for k8s probes and external-dns). The default recommended port for the provider endpoints is `8888`, and should listen only on `localhost` (ie: only accessible for external-dns).
**NOTE**: only `5xx` responses will be retried and only `20x` will be considered as successful. All status codes different from those will be considered a failure on ExternalDNS's side. **NOTE**: only `5xx` responses will be retried and only `20x` will be considered as successful. All status codes different from those will be considered a failure on ExternalDNS's side.
## Metrics support ### Exposed endpoints
The metrics should listen ":8080" on `/metrics` following [Open Metrics](https://github.com/OpenObservability/OpenMetrics) format. | Provider method | HTTP Method | Route | Description |
| --------------- | ----------- | -------- | -------------------------------------------------------------------------------------------- |
| K8s probe | GET | /healthz | Used by `livenessProbe` and `readinessProbe` |
| Open Metrics | GET | /metrics | Optional endpoint to expose [Open Metrics](https://github.com/OpenObservability/OpenMetrics) |
The default recommended port for the exposed endpoints is `8080`, and it should be bound to all interfaces (`0.0.0.0`)
## Custom Annotations ## Custom Annotations

View File

@ -25,7 +25,7 @@ import (
"strings" "strings"
) )
type MatchAllDomainFilters []*DomainFilter type MatchAllDomainFilters []DomainFilterInterface
func (f MatchAllDomainFilters) Match(domain string) bool { func (f MatchAllDomainFilters) Match(domain string) bool {
for _, filter := range f { for _, filter := range f {
@ -39,6 +39,10 @@ func (f MatchAllDomainFilters) Match(domain string) bool {
return true return true
} }
type DomainFilterInterface interface {
Match(domain string) bool
}
// DomainFilter holds a lists of valid domain names // DomainFilter holds a lists of valid domain names
type DomainFilter struct { type DomainFilter struct {
// Filters define what domains to match // Filters define what domains to match
@ -51,6 +55,8 @@ type DomainFilter struct {
regexExclusion *regexp.Regexp regexExclusion *regexp.Regexp
} }
var _ DomainFilterInterface = &DomainFilter{}
// domainFilterSerde is a helper type for serializing and deserializing DomainFilter. // domainFilterSerde is a helper type for serializing and deserializing DomainFilter.
type domainFilterSerde struct { type domainFilterSerde struct {
Include []string `json:"include,omitempty"` Include []string `json:"include,omitempty"`

163
go.mod
View File

@ -1,30 +1,37 @@
module sigs.k8s.io/external-dns module sigs.k8s.io/external-dns
go 1.22.4 go 1.23
require ( require (
cloud.google.com/go/compute/metadata v0.3.0 cloud.google.com/go/compute/metadata v0.5.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.2.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.2.0
github.com/F5Networks/k8s-bigip-ctlr/v2 v2.17.0 github.com/F5Networks/k8s-bigip-ctlr/v2 v2.17.1
github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.4.0 github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.5.0
github.com/IBM/go-sdk-core/v5 v5.17.3 github.com/IBM/go-sdk-core/v5 v5.17.4
github.com/IBM/networking-go-sdk v0.47.1 github.com/IBM/networking-go-sdk v0.49.0
github.com/Yamashou/gqlgenc v0.24.0
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2
github.com/alecthomas/kingpin/v2 v2.4.0 github.com/alecthomas/kingpin/v2 v2.4.0
github.com/aliyun/alibaba-cloud-sdk-go v1.62.771 github.com/aliyun/alibaba-cloud-sdk-go v1.63.0
github.com/ans-group/sdk-go v1.17.0 github.com/aws/aws-sdk-go-v2 v1.30.3
github.com/aws/aws-sdk-go v1.54.4 github.com/aws/aws-sdk-go-v2/config v1.27.27
github.com/aws/aws-sdk-go-v2/credentials v1.17.27
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.14.10
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.4
github.com/aws/aws-sdk-go-v2/service/route53 v1.42.3
github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.31.3
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3
github.com/bodgit/tsig v1.2.2 github.com/bodgit/tsig v1.2.2
github.com/cenkalti/backoff/v4 v4.3.0 github.com/cenkalti/backoff/v4 v4.3.0
github.com/civo/civogo v0.3.70 github.com/civo/civogo v0.3.73
github.com/cloudflare/cloudflare-go v0.98.0 github.com/cloudflare/cloudflare-go v0.102.0
github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381
github.com/datawire/ambassador v1.12.4 github.com/datawire/ambassador v1.12.4
github.com/denverdino/aliyungo v0.0.0-20230411124812-ab98a9173ace github.com/denverdino/aliyungo v0.0.0-20230411124812-ab98a9173ace
github.com/digitalocean/godo v1.118.0 github.com/digitalocean/godo v1.120.0
github.com/dnsimple/dnsimple-go v1.7.0 github.com/dnsimple/dnsimple-go v1.7.0
github.com/exoscale/egoscale v0.102.3 github.com/exoscale/egoscale v0.102.3
github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99
@ -32,77 +39,82 @@ require (
github.com/go-logr/logr v1.4.2 github.com/go-logr/logr v1.4.2
github.com/google/go-cmp v0.6.0 github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/gophercloud/gophercloud v1.12.0 github.com/gophercloud/gophercloud v1.14.0
github.com/hooklift/gowsdl v0.5.0
github.com/linki/instrumented_http v0.3.0 github.com/linki/instrumented_http v0.3.0
github.com/linode/linodego v1.35.0 github.com/linode/linodego v1.39.0
github.com/maxatome/go-testdeep v1.14.0 github.com/maxatome/go-testdeep v1.14.0
github.com/miekg/dns v1.1.61 github.com/miekg/dns v1.1.62
github.com/nesv/go-dynect v0.6.0
github.com/nic-at/rc0go v1.1.1
github.com/onsi/ginkgo v1.16.5 github.com/onsi/ginkgo v1.16.5
github.com/openshift/api v0.0.0-20230607130528-611114dca681 github.com/openshift/api v0.0.0-20230607130528-611114dca681
github.com/openshift/client-go v0.0.0-20230607134213-3cd0021bbee3 github.com/openshift/client-go v0.0.0-20230607134213-3cd0021bbee3
github.com/oracle/oci-go-sdk/v65 v65.67.2 github.com/oracle/oci-go-sdk/v65 v65.71.1
github.com/ovh/go-ovh v1.6.0 github.com/ovh/go-ovh v1.6.0
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/pluralsh/gqlclient v1.11.0 github.com/pluralsh/gqlclient v1.12.2
github.com/projectcontour/contour v1.29.1 github.com/projectcontour/contour v1.30.0
github.com/prometheus/client_golang v1.19.1 github.com/prometheus/client_golang v1.20.0
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.28 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.29
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.945 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.984
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.945 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.984
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.945 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.984
github.com/transip/gotransip/v6 v6.24.0 github.com/transip/gotransip/v6 v6.25.0
github.com/ultradns/ultradns-sdk-go v1.3.7 github.com/ultradns/ultradns-sdk-go v1.3.7
github.com/vinyldns/go-vinyldns v0.9.16 go.etcd.io/etcd/api/v3 v3.5.15
github.com/vultr/govultr/v2 v2.17.2 go.etcd.io/etcd/client/v3 v3.5.15
go.etcd.io/etcd/api/v3 v3.5.14
go.etcd.io/etcd/client/v3 v3.5.14
go.uber.org/ratelimit v0.3.1 go.uber.org/ratelimit v0.3.1
golang.org/x/net v0.26.0 golang.org/x/net v0.28.0
golang.org/x/oauth2 v0.21.0 golang.org/x/oauth2 v0.22.0
golang.org/x/sync v0.7.0 golang.org/x/sync v0.8.0
golang.org/x/time v0.5.0 golang.org/x/time v0.6.0
google.golang.org/api v0.185.0 google.golang.org/api v0.192.0
gopkg.in/ns1/ns1-go.v2 v2.11.0 gopkg.in/ns1/ns1-go.v2 v2.12.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
istio.io/api v1.22.1 istio.io/api v1.23.0
istio.io/client-go v1.22.1 istio.io/client-go v1.23.0
k8s.io/api v0.30.2 k8s.io/api v0.31.0
k8s.io/apimachinery v0.30.2 k8s.io/apimachinery v0.31.0
k8s.io/client-go v0.30.2 k8s.io/client-go v0.31.0
k8s.io/klog/v2 v2.130.0 k8s.io/klog/v2 v2.130.1
sigs.k8s.io/gateway-api v1.1.0 sigs.k8s.io/gateway-api v1.1.0
) )
require ( require (
cloud.google.com/go/auth v0.5.1 // indirect cloud.google.com/go/auth v0.8.1 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect
code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect github.com/99designs/gqlgen v0.17.44 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/Masterminds/semver v1.4.2 // indirect github.com/Masterminds/semver v1.4.2 // indirect
github.com/Yamashou/gqlgenc v0.14.0 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 // indirect github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 // indirect
github.com/ans-group/go-durationstring v1.2.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.22.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.16 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect
github.com/aws/smithy-go v1.20.3 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/deepmap/oapi-codegen v1.9.1 // indirect github.com/deepmap/oapi-codegen v1.9.1 // indirect
github.com/emicklei/go-restful/v3 v3.12.0 // indirect github.com/emicklei/go-restful/v3 v3.12.0 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/fatih/structs v1.1.0 // indirect github.com/fatih/structs v1.1.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/errors v0.21.0 // indirect github.com/go-openapi/errors v0.21.0 // indirect
@ -124,16 +136,15 @@ require (
github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect github.com/google/s2a-go v0.1.8 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.4 // indirect github.com/googleapis/gax-go/v2 v2.13.0 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
github.com/imdario/mergo v0.3.16 // indirect github.com/imdario/mergo v0.3.16 // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
@ -145,9 +156,9 @@ require (
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
@ -160,32 +171,24 @@ require (
github.com/oklog/ulid v1.3.1 // indirect github.com/oklog/ulid v1.3.1 // indirect
github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b // indirect github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/peterhellberg/link v1.1.0 // indirect github.com/peterhellberg/link v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.53.0 // indirect github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/schollz/progressbar/v3 v3.8.6 // indirect github.com/schollz/progressbar/v3 v3.8.6 // indirect
github.com/shopspring/decimal v1.3.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
github.com/smartystreets/gunit v1.3.4 // indirect
github.com/sony/gobreaker v0.5.0 // indirect github.com/sony/gobreaker v0.5.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect github.com/sosodev/duration v1.2.0 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.17.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/terra-farm/udnssdk v1.3.5 // indirect github.com/terra-farm/udnssdk v1.3.5 // indirect
github.com/vektah/gqlparser/v2 v2.5.14 // indirect github.com/vektah/gqlparser/v2 v2.5.14 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect
go.mongodb.org/mongo-driver v1.14.0 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
@ -195,25 +198,23 @@ require (
go.uber.org/atomic v1.10.0 // indirect go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.24.0 // indirect golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
golang.org/x/mod v0.18.0 // indirect golang.org/x/mod v0.18.0 // indirect
golang.org/x/sys v0.21.0 // indirect golang.org/x/sys v0.23.0 // indirect
golang.org/x/term v0.21.0 // indirect golang.org/x/term v0.23.0 // indirect
golang.org/x/text v0.16.0 // indirect golang.org/x/text v0.17.0 // indirect
golang.org/x/tools v0.22.0 // indirect golang.org/x/tools v0.22.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240610135401-a8a62080eff3 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect
google.golang.org/grpc v1.64.0 // indirect google.golang.org/grpc v1.65.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/go-playground/validator.v9 v9.31.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/resty.v1 v1.12.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108 // indirect k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect
k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
moul.io/http2curl v1.0.0 // indirect moul.io/http2curl v1.0.0 // indirect
sigs.k8s.io/controller-runtime v0.18.4 // indirect sigs.k8s.io/controller-runtime v0.18.4 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect

591
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ kind: Kustomization
images: images:
- name: registry.k8s.io/external-dns/external-dns - name: registry.k8s.io/external-dns/external-dns
newTag: v0.14.2 newTag: v0.15.0
resources: resources:
- ./external-dns-deployment.yaml - ./external-dns-deployment.yaml

66
main.go
View File

@ -25,10 +25,9 @@ import (
"syscall" "syscall"
"time" "time"
awsSDK "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb" "github.com/aws/aws-sdk-go-v2/service/route53"
"github.com/aws/aws-sdk-go/service/route53" sd "github.com/aws/aws-sdk-go-v2/service/servicediscovery"
sd "github.com/aws/aws-sdk-go/service/servicediscovery"
"github.com/go-logr/logr" "github.com/go-logr/logr"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -47,14 +46,12 @@ import (
"sigs.k8s.io/external-dns/provider/aws" "sigs.k8s.io/external-dns/provider/aws"
"sigs.k8s.io/external-dns/provider/awssd" "sigs.k8s.io/external-dns/provider/awssd"
"sigs.k8s.io/external-dns/provider/azure" "sigs.k8s.io/external-dns/provider/azure"
"sigs.k8s.io/external-dns/provider/bluecat"
"sigs.k8s.io/external-dns/provider/civo" "sigs.k8s.io/external-dns/provider/civo"
"sigs.k8s.io/external-dns/provider/cloudflare" "sigs.k8s.io/external-dns/provider/cloudflare"
"sigs.k8s.io/external-dns/provider/coredns" "sigs.k8s.io/external-dns/provider/coredns"
"sigs.k8s.io/external-dns/provider/designate" "sigs.k8s.io/external-dns/provider/designate"
"sigs.k8s.io/external-dns/provider/digitalocean" "sigs.k8s.io/external-dns/provider/digitalocean"
"sigs.k8s.io/external-dns/provider/dnsimple" "sigs.k8s.io/external-dns/provider/dnsimple"
"sigs.k8s.io/external-dns/provider/dyn"
"sigs.k8s.io/external-dns/provider/exoscale" "sigs.k8s.io/external-dns/provider/exoscale"
"sigs.k8s.io/external-dns/provider/gandi" "sigs.k8s.io/external-dns/provider/gandi"
"sigs.k8s.io/external-dns/provider/godaddy" "sigs.k8s.io/external-dns/provider/godaddy"
@ -68,16 +65,12 @@ import (
"sigs.k8s.io/external-dns/provider/pdns" "sigs.k8s.io/external-dns/provider/pdns"
"sigs.k8s.io/external-dns/provider/pihole" "sigs.k8s.io/external-dns/provider/pihole"
"sigs.k8s.io/external-dns/provider/plural" "sigs.k8s.io/external-dns/provider/plural"
"sigs.k8s.io/external-dns/provider/rcode0"
"sigs.k8s.io/external-dns/provider/rdns" "sigs.k8s.io/external-dns/provider/rdns"
"sigs.k8s.io/external-dns/provider/rfc2136" "sigs.k8s.io/external-dns/provider/rfc2136"
"sigs.k8s.io/external-dns/provider/safedns"
"sigs.k8s.io/external-dns/provider/scaleway" "sigs.k8s.io/external-dns/provider/scaleway"
"sigs.k8s.io/external-dns/provider/tencentcloud" "sigs.k8s.io/external-dns/provider/tencentcloud"
"sigs.k8s.io/external-dns/provider/transip" "sigs.k8s.io/external-dns/provider/transip"
"sigs.k8s.io/external-dns/provider/ultradns" "sigs.k8s.io/external-dns/provider/ultradns"
"sigs.k8s.io/external-dns/provider/vinyldns"
"sigs.k8s.io/external-dns/provider/vultr"
"sigs.k8s.io/external-dns/provider/webhook" "sigs.k8s.io/external-dns/provider/webhook"
webhookapi "sigs.k8s.io/external-dns/provider/webhook/api" webhookapi "sigs.k8s.io/external-dns/provider/webhook/api"
"sigs.k8s.io/external-dns/registry" "sigs.k8s.io/external-dns/registry"
@ -179,6 +172,7 @@ func main() {
// Combine multiple sources into a single, deduplicated source. // Combine multiple sources into a single, deduplicated source.
endpointsSource := source.NewDedupSource(source.NewMultiSource(sources, sourceCfg.DefaultTargets)) endpointsSource := source.NewDedupSource(source.NewMultiSource(sources, sourceCfg.DefaultTargets))
endpointsSource = source.NewNAT64Source(endpointsSource, cfg.NAT64Networks)
endpointsSource = source.NewTargetFilterSource(endpointsSource, targetFilter) endpointsSource = source.NewTargetFilterSource(endpointsSource, targetFilter)
// RegexDomainFilter overrides DomainFilter // RegexDomainFilter overrides DomainFilter
@ -211,10 +205,10 @@ func main() {
case "alibabacloud": case "alibabacloud":
p, err = alibabacloud.NewAlibabaCloudProvider(cfg.AlibabaCloudConfigFile, domainFilter, zoneIDFilter, cfg.AlibabaCloudZoneType, cfg.DryRun) p, err = alibabacloud.NewAlibabaCloudProvider(cfg.AlibabaCloudConfigFile, domainFilter, zoneIDFilter, cfg.AlibabaCloudZoneType, cfg.DryRun)
case "aws": case "aws":
sessions := aws.CreateSessions(cfg) configs := aws.CreateV2Configs(cfg)
clients := make(map[string]aws.Route53API, len(sessions)) clients := make(map[string]aws.Route53API, len(configs))
for profile, session := range sessions { for profile, config := range configs {
clients[profile] = route53.New(session) clients[profile] = route53.NewFromConfig(config)
} }
p, err = aws.NewAWSProvider( p, err = aws.NewAWSProvider(
@ -241,25 +235,17 @@ func main() {
log.Infof("Registry \"%s\" cannot be used with AWS Cloud Map. Switching to \"aws-sd\".", cfg.Registry) log.Infof("Registry \"%s\" cannot be used with AWS Cloud Map. Switching to \"aws-sd\".", cfg.Registry)
cfg.Registry = "aws-sd" cfg.Registry = "aws-sd"
} }
p, err = awssd.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.DryRun, cfg.AWSSDServiceCleanup, cfg.TXTOwnerID, sd.New(aws.CreateDefaultSession(cfg))) p, err = awssd.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.DryRun, cfg.AWSSDServiceCleanup, cfg.TXTOwnerID, sd.NewFromConfig(aws.CreateDefaultV2Config(cfg)))
case "azure-dns", "azure": case "azure-dns", "azure":
p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.AzureActiveDirectoryAuthorityHost, cfg.DryRun) p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.AzureActiveDirectoryAuthorityHost, cfg.DryRun)
case "azure-private-dns": case "azure-private-dns":
p, err = azure.NewAzurePrivateDNSProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.AzureActiveDirectoryAuthorityHost, cfg.DryRun) p, err = azure.NewAzurePrivateDNSProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.AzureActiveDirectoryAuthorityHost, cfg.DryRun)
case "bluecat":
p, err = bluecat.NewBluecatProvider(cfg.BluecatConfigFile, cfg.BluecatDNSConfiguration, cfg.BluecatDNSServerName, cfg.BluecatDNSDeployType, cfg.BluecatDNSView, cfg.BluecatGatewayHost, cfg.BluecatRootZone, cfg.TXTPrefix, cfg.TXTSuffix, domainFilter, zoneIDFilter, cfg.DryRun, cfg.BluecatSkipTLSVerify)
case "vinyldns":
p, err = vinyldns.NewVinylDNSProvider(domainFilter, zoneIDFilter, cfg.DryRun)
case "vultr":
p, err = vultr.NewVultrProvider(ctx, domainFilter, cfg.DryRun)
case "ultradns": case "ultradns":
p, err = ultradns.NewUltraDNSProvider(domainFilter, cfg.DryRun) p, err = ultradns.NewUltraDNSProvider(domainFilter, cfg.DryRun)
case "civo": case "civo":
p, err = civo.NewCivoProvider(domainFilter, cfg.DryRun) p, err = civo.NewCivoProvider(domainFilter, cfg.DryRun)
case "cloudflare": case "cloudflare":
p, err = cloudflare.NewCloudFlareProvider(domainFilter, zoneIDFilter, cfg.CloudflareProxied, cfg.DryRun, cfg.CloudflareDNSRecordsPerPage) p, err = cloudflare.NewCloudFlareProvider(domainFilter, zoneIDFilter, cfg.CloudflareProxied, cfg.DryRun, cfg.CloudflareDNSRecordsPerPage)
case "rcodezero":
p, err = rcode0.NewRcodeZeroProvider(domainFilter, cfg.DryRun, cfg.RcodezeroTXTEncrypt)
case "google": case "google":
p, err = google.NewGoogleProvider(ctx, cfg.GoogleProject, domainFilter, zoneIDFilter, cfg.GoogleBatchChangeSize, cfg.GoogleBatchChangeInterval, cfg.GoogleZoneVisibility, cfg.DryRun) p, err = google.NewGoogleProvider(ctx, cfg.GoogleProject, domainFilter, zoneIDFilter, cfg.GoogleBatchChangeSize, cfg.GoogleBatchChangeInterval, cfg.GoogleZoneVisibility, cfg.DryRun)
case "digitalocean": case "digitalocean":
@ -270,19 +256,6 @@ func main() {
p, err = linode.NewLinodeProvider(domainFilter, cfg.DryRun, externaldns.Version) p, err = linode.NewLinodeProvider(domainFilter, cfg.DryRun, externaldns.Version)
case "dnsimple": case "dnsimple":
p, err = dnsimple.NewDnsimpleProvider(domainFilter, zoneIDFilter, cfg.DryRun) p, err = dnsimple.NewDnsimpleProvider(domainFilter, zoneIDFilter, cfg.DryRun)
case "dyn":
p, err = dyn.NewDynProvider(
dyn.DynConfig{
DomainFilter: domainFilter,
ZoneIDFilter: zoneIDFilter,
DryRun: cfg.DryRun,
CustomerName: cfg.DynCustomerName,
Username: cfg.DynUsername,
Password: cfg.DynPassword,
MinTTLSeconds: cfg.DynMinTTLSeconds,
AppVersion: externaldns.Version,
},
)
case "coredns", "skydns": case "coredns", "skydns":
p, err = coredns.NewCoreDNSProvider(domainFilter, cfg.CoreDNSPrefix, cfg.DryRun) p, err = coredns.NewCoreDNSProvider(domainFilter, cfg.CoreDNSPrefix, cfg.DryRun)
case "rdns": case "rdns":
@ -381,8 +354,6 @@ func main() {
) )
case "ibmcloud": case "ibmcloud":
p, err = ibmcloud.NewIBMCloudProvider(cfg.IBMCloudConfigFile, domainFilter, zoneIDFilter, endpointsSource, cfg.IBMCloudProxied, cfg.DryRun) p, err = ibmcloud.NewIBMCloudProvider(cfg.IBMCloudConfigFile, domainFilter, zoneIDFilter, endpointsSource, cfg.IBMCloudProxied, cfg.DryRun)
case "safedns":
p, err = safedns.NewSafeDNSProvider(domainFilter, cfg.DryRun)
case "plural": case "plural":
p, err = plural.NewPluralProvider(cfg.PluralCluster, cfg.PluralProvider) p, err = plural.NewPluralProvider(cfg.PluralCluster, cfg.PluralProvider)
case "tencentcloud": case "tencentcloud":
@ -401,20 +372,31 @@ func main() {
os.Exit(0) os.Exit(0)
} }
if cfg.ProviderCacheTime > 0 {
p = provider.NewCachedProvider(
p,
cfg.ProviderCacheTime,
)
}
var r registry.Registry var r registry.Registry
switch cfg.Registry { switch cfg.Registry {
case "dynamodb": case "dynamodb":
config := awsSDK.NewConfig() var dynamodbOpts []func(*dynamodb.Options)
if cfg.AWSDynamoDBRegion != "" { if cfg.AWSDynamoDBRegion != "" {
config = config.WithRegion(cfg.AWSDynamoDBRegion) dynamodbOpts = []func(*dynamodb.Options){
func(opts *dynamodb.Options) {
opts.Region = cfg.AWSDynamoDBRegion
},
}
} }
r, err = registry.NewDynamoDBRegistry(p, cfg.TXTOwnerID, dynamodb.New(aws.CreateDefaultSession(cfg), config), cfg.AWSDynamoDBTable, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes, cfg.ExcludeDNSRecordTypes, []byte(cfg.TXTEncryptAESKey), cfg.TXTCacheInterval) r, err = registry.NewDynamoDBRegistry(p, cfg.TXTOwnerID, dynamodb.NewFromConfig(aws.CreateDefaultV2Config(cfg), dynamodbOpts...), cfg.AWSDynamoDBTable, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes, cfg.ExcludeDNSRecordTypes, []byte(cfg.TXTEncryptAESKey), cfg.TXTCacheInterval)
case "noop": case "noop":
r, err = registry.NewNoopRegistry(p) r, err = registry.NewNoopRegistry(p)
case "txt": case "txt":
r, err = registry.NewTXTRegistry(p, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTOwnerID, cfg.TXTCacheInterval, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes, cfg.ExcludeDNSRecordTypes, cfg.TXTEncryptEnabled, []byte(cfg.TXTEncryptAESKey)) r, err = registry.NewTXTRegistry(p, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTOwnerID, cfg.TXTCacheInterval, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes, cfg.ExcludeDNSRecordTypes, cfg.TXTEncryptEnabled, []byte(cfg.TXTEncryptAESKey))
case "aws-sd": case "aws-sd":
r, err = registry.NewAWSSDRegistry(p.(*awssd.AWSSDProvider), cfg.TXTOwnerID) r, err = registry.NewAWSSDRegistry(p, cfg.TXTOwnerID)
default: default:
log.Fatalf("unknown registry: %s", cfg.Registry) log.Fatalf("unknown registry: %s", cfg.Registry)
} }

View File

@ -2,7 +2,6 @@ site_name: external-dns
site_author: external-dns maintainers site_author: external-dns maintainers
repo_name: kubernetes-sigs/external-dns repo_name: kubernetes-sigs/external-dns
repo_url: https://github.com/kubernetes-sigs/external-dns/ repo_url: https://github.com/kubernetes-sigs/external-dns/
trademark: https://www.linuxfoundation.org/legal/trademark-usage
docs_dir: . docs_dir: .
@ -19,11 +18,7 @@ nav:
- Tutorials: docs/tutorials/* - Tutorials: docs/tutorials/*
- Annotations: - Annotations:
- About: docs/annotations/annotations.md - About: docs/annotations/annotations.md
- Sources: - Sources: docs/sources/*
- About: docs/sources/sources.md
- Gateway: docs/sources/gateway.md
- Ingress: docs/sources/ingress.md
- Service: docs/sources/service.md
- Registries: - Registries:
- About: docs/registry/registry.md - About: docs/registry/registry.md
- TXT: docs/registry/txt.md - TXT: docs/registry/txt.md
@ -31,7 +26,9 @@ nav:
- Advanced Topics: - Advanced Topics:
- Initial Design: docs/initial-design.md - Initial Design: docs/initial-design.md
- TTL: docs/ttl.md - TTL: docs/ttl.md
- NAT64: docs/nat64.md
- MultiTarget: docs/proposal/multi-target.md - MultiTarget: docs/proposal/multi-target.md
- Rate Limits: docs/rate-limits.md
- Contributing: - Contributing:
- Kubernetes Contributions: CONTRIBUTING.md - Kubernetes Contributions: CONTRIBUTING.md
- Release: docs/release.md - Release: docs/release.md

View File

@ -67,6 +67,7 @@ type Config struct {
AlwaysPublishNotReadyAddresses bool AlwaysPublishNotReadyAddresses bool
ConnectorSourceServer string ConnectorSourceServer string
Provider string Provider string
ProviderCacheTime time.Duration
GoogleProject string GoogleProject string
GoogleBatchChangeSize int GoogleBatchChangeSize int
GoogleBatchChangeInterval time.Duration GoogleBatchChangeInterval time.Duration
@ -103,28 +104,15 @@ type Config struct {
AzureSubscriptionID string AzureSubscriptionID string
AzureUserAssignedIdentityClientID string AzureUserAssignedIdentityClientID string
AzureActiveDirectoryAuthorityHost string AzureActiveDirectoryAuthorityHost string
BluecatDNSConfiguration string
BluecatConfigFile string
BluecatDNSView string
BluecatGatewayHost string
BluecatRootZone string
BluecatDNSServerName string
BluecatDNSDeployType string
BluecatSkipTLSVerify bool
CloudflareProxied bool CloudflareProxied bool
CloudflareDNSRecordsPerPage int CloudflareDNSRecordsPerPage int
CoreDNSPrefix string CoreDNSPrefix string
RcodezeroTXTEncrypt bool
AkamaiServiceConsumerDomain string AkamaiServiceConsumerDomain string
AkamaiClientToken string AkamaiClientToken string
AkamaiClientSecret string AkamaiClientSecret string
AkamaiAccessToken string AkamaiAccessToken string
AkamaiEdgercPath string AkamaiEdgercPath string
AkamaiEdgercSection string AkamaiEdgercSection string
DynCustomerName string
DynUsername string
DynPassword string `secure:"yes"`
DynMinTTLSeconds int
OCIConfigFile string OCIConfigFile string
OCICompartmentOCID string OCICompartmentOCID string
OCIAuthInstancePrincipal bool OCIAuthInstancePrincipal bool
@ -213,6 +201,7 @@ type Config struct {
WebhookServer bool WebhookServer bool
TraefikDisableLegacy bool TraefikDisableLegacy bool
TraefikDisableNew bool TraefikDisableNew bool
NAT64Networks []string
} }
var defaultConfig = &Config{ var defaultConfig = &Config{
@ -239,6 +228,7 @@ var defaultConfig = &Config{
PublishHostIP: false, PublishHostIP: false,
ConnectorSourceServer: "localhost:8080", ConnectorSourceServer: "localhost:8080",
Provider: "", Provider: "",
ProviderCacheTime: 0,
GoogleProject: "", GoogleProject: "",
GoogleBatchChangeSize: 1000, GoogleBatchChangeSize: 1000,
GoogleBatchChangeInterval: time.Second, GoogleBatchChangeInterval: time.Second,
@ -270,12 +260,9 @@ var defaultConfig = &Config{
AzureConfigFile: "/etc/kubernetes/azure.json", AzureConfigFile: "/etc/kubernetes/azure.json",
AzureResourceGroup: "", AzureResourceGroup: "",
AzureSubscriptionID: "", AzureSubscriptionID: "",
BluecatConfigFile: "/etc/kubernetes/bluecat.json",
BluecatDNSDeployType: "no-deploy",
CloudflareProxied: false, CloudflareProxied: false,
CloudflareDNSRecordsPerPage: 100, CloudflareDNSRecordsPerPage: 100,
CoreDNSPrefix: "/skydns/", CoreDNSPrefix: "/skydns/",
RcodezeroTXTEncrypt: false,
AkamaiServiceConsumerDomain: "", AkamaiServiceConsumerDomain: "",
AkamaiClientToken: "", AkamaiClientToken: "",
AkamaiClientSecret: "", AkamaiClientSecret: "",
@ -363,6 +350,7 @@ var defaultConfig = &Config{
WebhookServer: false, WebhookServer: false,
TraefikDisableLegacy: false, TraefikDisableLegacy: false,
TraefikDisableNew: false, TraefikDisableNew: false,
NAT64Networks: []string{},
} }
// NewConfig returns new Config object // NewConfig returns new Config object
@ -428,7 +416,7 @@ func (cfg *Config) ParseFlags(args []string) error {
app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName) app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName)
app.Flag("namespace", "Limit resources queried for endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("namespace", "Limit resources queried for endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
app.Flag("annotation-filter", "Filter resources queried for endpoints by annotation, using label selector semantics").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) app.Flag("annotation-filter", "Filter resources queried for endpoints by annotation, using label selector semantics").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
app.Flag("label-filter", "Filter resources queried for endpoints by label selector; currently supported by source types crd, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, ingress, node, openshift-route, and service").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter) app.Flag("label-filter", "Filter resources queried for endpoints by label selector; currently supported by source types crd, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, ingress, node, openshift-route, service and ambassador-host").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter)
app.Flag("ingress-class", "Require an Ingress to have this class name (defaults to any class; specify multiple times to allow more than one class)").StringsVar(&cfg.IngressClassNames) app.Flag("ingress-class", "Require an Ingress to have this class name (defaults to any class; specify multiple times to allow more than one class)").StringsVar(&cfg.IngressClassNames)
app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate) app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate)
app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation) app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation)
@ -452,10 +440,12 @@ func (cfg *Config) ParseFlags(args []string) error {
app.Flag("exclude-target-net", "Exclude target nets (optional)").StringsVar(&cfg.ExcludeTargetNets) app.Flag("exclude-target-net", "Exclude target nets (optional)").StringsVar(&cfg.ExcludeTargetNets)
app.Flag("traefik-disable-legacy", "Disable listeners on Resources under the traefik.containo.us API Group").Default(strconv.FormatBool(defaultConfig.TraefikDisableLegacy)).BoolVar(&cfg.TraefikDisableLegacy) app.Flag("traefik-disable-legacy", "Disable listeners on Resources under the traefik.containo.us API Group").Default(strconv.FormatBool(defaultConfig.TraefikDisableLegacy)).BoolVar(&cfg.TraefikDisableLegacy)
app.Flag("traefik-disable-new", "Disable listeners on Resources under the traefik.io API Group").Default(strconv.FormatBool(defaultConfig.TraefikDisableNew)).BoolVar(&cfg.TraefikDisableNew) app.Flag("traefik-disable-new", "Disable listeners on Resources under the traefik.io API Group").Default(strconv.FormatBool(defaultConfig.TraefikDisableNew)).BoolVar(&cfg.TraefikDisableNew)
app.Flag("nat64-networks", "Adding an A record for each AAAA record in NAT64-enabled networks; specify multiple times for multiple possible nets (optional)").StringsVar(&cfg.NAT64Networks)
// Flags related to providers // Flags related to providers
providers := []string{"akamai", "alibabacloud", "aws", "aws-sd", "azure", "azure-dns", "azure-private-dns", "bluecat", "civo", "cloudflare", "coredns", "designate", "digitalocean", "dnsimple", "dyn", "exoscale", "gandi", "godaddy", "google", "ibmcloud", "inmemory", "linode", "ns1", "oci", "ovh", "pdns", "pihole", "plural", "rcodezero", "rdns", "rfc2136", "safedns", "scaleway", "skydns", "tencentcloud", "transip", "ultradns", "vinyldns", "vultr", "webhook"} providers := []string{"akamai", "alibabacloud", "aws", "aws-sd", "azure", "azure-dns", "azure-private-dns", "civo", "cloudflare", "coredns", "designate", "digitalocean", "dnsimple", "exoscale", "gandi", "godaddy", "google", "ibmcloud", "inmemory", "linode", "ns1", "oci", "ovh", "pdns", "pihole", "plural", "rdns", "rfc2136", "scaleway", "skydns", "tencentcloud", "transip", "ultradns", "webhook"}
app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: "+strings.Join(providers, ", ")+")").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, providers...) app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: "+strings.Join(providers, ", ")+")").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, providers...)
app.Flag("provider-cache-time", "The time to cache the DNS provider record list requests.").Default(defaultConfig.ProviderCacheTime.String()).DurationVar(&cfg.ProviderCacheTime)
app.Flag("domain-filter", "Limit possible target zones by a domain suffix; specify multiple times for multiple domains (optional)").Default("").StringsVar(&cfg.DomainFilter) app.Flag("domain-filter", "Limit possible target zones by a domain suffix; specify multiple times for multiple domains (optional)").Default("").StringsVar(&cfg.DomainFilter)
app.Flag("exclude-domains", "Exclude subdomains (optional)").Default("").StringsVar(&cfg.ExcludeDomains) app.Flag("exclude-domains", "Exclude subdomains (optional)").Default("").StringsVar(&cfg.ExcludeDomains)
app.Flag("regex-domain-filter", "Limit possible domains and target zones by a Regex filter; Overrides domain-filter (optional)").Default(defaultConfig.RegexDomainFilter.String()).RegexpVar(&cfg.RegexDomainFilter) app.Flag("regex-domain-filter", "Limit possible domains and target zones by a Regex filter; Overrides domain-filter (optional)").Default(defaultConfig.RegexDomainFilter.String()).RegexpVar(&cfg.RegexDomainFilter)
@ -490,16 +480,6 @@ func (cfg *Config) ParseFlags(args []string) error {
app.Flag("tencent-cloud-config-file", "When using the Tencent Cloud provider, specify the Tencent Cloud configuration file (required when --provider=tencentcloud)").Default(defaultConfig.TencentCloudConfigFile).StringVar(&cfg.TencentCloudConfigFile) app.Flag("tencent-cloud-config-file", "When using the Tencent Cloud provider, specify the Tencent Cloud configuration file (required when --provider=tencentcloud)").Default(defaultConfig.TencentCloudConfigFile).StringVar(&cfg.TencentCloudConfigFile)
app.Flag("tencent-cloud-zone-type", "When using the Tencent Cloud provider, filter for zones with visibility (optional, options: public, private)").Default(defaultConfig.TencentCloudZoneType).EnumVar(&cfg.TencentCloudZoneType, "", "public", "private") app.Flag("tencent-cloud-zone-type", "When using the Tencent Cloud provider, filter for zones with visibility (optional, options: public, private)").Default(defaultConfig.TencentCloudZoneType).EnumVar(&cfg.TencentCloudZoneType, "", "public", "private")
// Flags related to BlueCat provider
app.Flag("bluecat-dns-configuration", "When using the Bluecat provider, specify the Bluecat DNS configuration string (optional when --provider=bluecat)").Default("").StringVar(&cfg.BluecatDNSConfiguration)
app.Flag("bluecat-config-file", "When using the Bluecat provider, specify the Bluecat configuration file (optional when --provider=bluecat)").Default(defaultConfig.BluecatConfigFile).StringVar(&cfg.BluecatConfigFile)
app.Flag("bluecat-dns-view", "When using the Bluecat provider, specify the Bluecat DNS view string (optional when --provider=bluecat)").Default("").StringVar(&cfg.BluecatDNSView)
app.Flag("bluecat-gateway-host", "When using the Bluecat provider, specify the Bluecat Gateway Host (optional when --provider=bluecat)").Default("").StringVar(&cfg.BluecatGatewayHost)
app.Flag("bluecat-root-zone", "When using the Bluecat provider, specify the Bluecat root zone (optional when --provider=bluecat)").Default("").StringVar(&cfg.BluecatRootZone)
app.Flag("bluecat-skip-tls-verify", "When using the Bluecat provider, specify to skip TLS verification (optional when --provider=bluecat) (default: false)").BoolVar(&cfg.BluecatSkipTLSVerify)
app.Flag("bluecat-dns-server-name", "When using the Bluecat provider, specify the Bluecat DNS Server to initiate deploys against. This is only used if --bluecat-dns-deploy-type is not 'no-deploy' (optional when --provider=bluecat)").Default("").StringVar(&cfg.BluecatDNSServerName)
app.Flag("bluecat-dns-deploy-type", "When using the Bluecat provider, specify the type of DNS deployment to initiate after records are updated. Valid options are 'full-deploy' and 'no-deploy'. Deploy will only execute if --bluecat-dns-server-name is set (optional when --provider=bluecat)").Default(defaultConfig.BluecatDNSDeployType).StringVar(&cfg.BluecatDNSDeployType)
app.Flag("cloudflare-proxied", "When using the Cloudflare provider, specify if the proxy mode must be enabled (default: disabled)").BoolVar(&cfg.CloudflareProxied) app.Flag("cloudflare-proxied", "When using the Cloudflare provider, specify if the proxy mode must be enabled (default: disabled)").BoolVar(&cfg.CloudflareProxied)
app.Flag("cloudflare-dns-records-per-page", "When using the Cloudflare provider, specify how many DNS records listed per page, max possible 5,000 (default: 100)").Default(strconv.Itoa(defaultConfig.CloudflareDNSRecordsPerPage)).IntVar(&cfg.CloudflareDNSRecordsPerPage) app.Flag("cloudflare-dns-records-per-page", "When using the Cloudflare provider, specify how many DNS records listed per page, max possible 5,000 (default: 100)").Default(strconv.Itoa(defaultConfig.CloudflareDNSRecordsPerPage)).IntVar(&cfg.CloudflareDNSRecordsPerPage)
app.Flag("coredns-prefix", "When using the CoreDNS provider, specify the prefix name").Default(defaultConfig.CoreDNSPrefix).StringVar(&cfg.CoreDNSPrefix) app.Flag("coredns-prefix", "When using the CoreDNS provider, specify the prefix name").Default(defaultConfig.CoreDNSPrefix).StringVar(&cfg.CoreDNSPrefix)
@ -509,16 +489,11 @@ func (cfg *Config) ParseFlags(args []string) error {
app.Flag("akamai-access-token", "When using the Akamai provider, specify the access token (required when --provider=akamai and edgerc-path not specified)").Default(defaultConfig.AkamaiAccessToken).StringVar(&cfg.AkamaiAccessToken) app.Flag("akamai-access-token", "When using the Akamai provider, specify the access token (required when --provider=akamai and edgerc-path not specified)").Default(defaultConfig.AkamaiAccessToken).StringVar(&cfg.AkamaiAccessToken)
app.Flag("akamai-edgerc-path", "When using the Akamai provider, specify the .edgerc file path. Path must be reachable form invocation environment. (required when --provider=akamai and *-token, secret serviceconsumerdomain not specified)").Default(defaultConfig.AkamaiEdgercPath).StringVar(&cfg.AkamaiEdgercPath) app.Flag("akamai-edgerc-path", "When using the Akamai provider, specify the .edgerc file path. Path must be reachable form invocation environment. (required when --provider=akamai and *-token, secret serviceconsumerdomain not specified)").Default(defaultConfig.AkamaiEdgercPath).StringVar(&cfg.AkamaiEdgercPath)
app.Flag("akamai-edgerc-section", "When using the Akamai provider, specify the .edgerc file path (Optional when edgerc-path is specified)").Default(defaultConfig.AkamaiEdgercSection).StringVar(&cfg.AkamaiEdgercSection) app.Flag("akamai-edgerc-section", "When using the Akamai provider, specify the .edgerc file path (Optional when edgerc-path is specified)").Default(defaultConfig.AkamaiEdgercSection).StringVar(&cfg.AkamaiEdgercSection)
app.Flag("dyn-customer-name", "When using the Dyn provider, specify the Customer Name").Default("").StringVar(&cfg.DynCustomerName)
app.Flag("dyn-username", "When using the Dyn provider, specify the Username").Default("").StringVar(&cfg.DynUsername)
app.Flag("dyn-password", "When using the Dyn provider, specify the password").Default("").StringVar(&cfg.DynPassword)
app.Flag("dyn-min-ttl", "Minimal TTL (in seconds) for records. This value will be used if the provided TTL for a service/ingress is lower than this.").IntVar(&cfg.DynMinTTLSeconds)
app.Flag("oci-config-file", "When using the OCI provider, specify the OCI configuration file (required when --provider=oci").Default(defaultConfig.OCIConfigFile).StringVar(&cfg.OCIConfigFile) app.Flag("oci-config-file", "When using the OCI provider, specify the OCI configuration file (required when --provider=oci").Default(defaultConfig.OCIConfigFile).StringVar(&cfg.OCIConfigFile)
app.Flag("oci-compartment-ocid", "When using the OCI provider, specify the OCID of the OCI compartment containing all managed zones and records. Required when using OCI IAM instance principal authentication.").StringVar(&cfg.OCICompartmentOCID) app.Flag("oci-compartment-ocid", "When using the OCI provider, specify the OCID of the OCI compartment containing all managed zones and records. Required when using OCI IAM instance principal authentication.").StringVar(&cfg.OCICompartmentOCID)
app.Flag("oci-zone-scope", "When using OCI provider, filter for zones with this scope (optional, options: GLOBAL, PRIVATE). Defaults to GLOBAL, setting to empty value will target both.").Default(defaultConfig.OCIZoneScope).EnumVar(&cfg.OCIZoneScope, "", "GLOBAL", "PRIVATE") app.Flag("oci-zone-scope", "When using OCI provider, filter for zones with this scope (optional, options: GLOBAL, PRIVATE). Defaults to GLOBAL, setting to empty value will target both.").Default(defaultConfig.OCIZoneScope).EnumVar(&cfg.OCIZoneScope, "", "GLOBAL", "PRIVATE")
app.Flag("oci-auth-instance-principal", "When using the OCI provider, specify whether OCI IAM instance principal authentication should be used (instead of key-based auth via the OCI config file).").Default(strconv.FormatBool(defaultConfig.OCIAuthInstancePrincipal)).BoolVar(&cfg.OCIAuthInstancePrincipal) app.Flag("oci-auth-instance-principal", "When using the OCI provider, specify whether OCI IAM instance principal authentication should be used (instead of key-based auth via the OCI config file).").Default(strconv.FormatBool(defaultConfig.OCIAuthInstancePrincipal)).BoolVar(&cfg.OCIAuthInstancePrincipal)
app.Flag("oci-zones-cache-duration", "When using the OCI provider, set the zones list cache TTL (0s to disable).").Default(defaultConfig.OCIZoneCacheDuration.String()).DurationVar(&cfg.OCIZoneCacheDuration) app.Flag("oci-zones-cache-duration", "When using the OCI provider, set the zones list cache TTL (0s to disable).").Default(defaultConfig.OCIZoneCacheDuration.String()).DurationVar(&cfg.OCIZoneCacheDuration)
app.Flag("rcodezero-txt-encrypt", "When using the Rcodezero provider with txt registry option, set if TXT rrs are encrypted (default: false)").Default(strconv.FormatBool(defaultConfig.RcodezeroTXTEncrypt)).BoolVar(&cfg.RcodezeroTXTEncrypt)
app.Flag("inmemory-zone", "Provide a list of pre-configured zones for the inmemory provider; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.InMemoryZones) app.Flag("inmemory-zone", "Provide a list of pre-configured zones for the inmemory provider; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.InMemoryZones)
app.Flag("ovh-endpoint", "When using the OVH provider, specify the endpoint (default: ovh-eu)").Default(defaultConfig.OVHEndpoint).StringVar(&cfg.OVHEndpoint) app.Flag("ovh-endpoint", "When using the OVH provider, specify the endpoint (default: ovh-eu)").Default(defaultConfig.OVHEndpoint).StringVar(&cfg.OVHEndpoint)
app.Flag("ovh-api-rate-limit", "When using the OVH provider, specify the API request rate limit, X operations by seconds (default: 20)").Default(strconv.Itoa(defaultConfig.OVHApiRateLimit)).IntVar(&cfg.OVHApiRateLimit) app.Flag("ovh-api-rate-limit", "When using the OVH provider, specify the API request rate limit, X operations by seconds (default: 20)").Default(strconv.Itoa(defaultConfig.OVHApiRateLimit)).IntVar(&cfg.OVHApiRateLimit)

View File

@ -72,14 +72,6 @@ var (
AzureConfigFile: "/etc/kubernetes/azure.json", AzureConfigFile: "/etc/kubernetes/azure.json",
AzureResourceGroup: "", AzureResourceGroup: "",
AzureSubscriptionID: "", AzureSubscriptionID: "",
BluecatDNSConfiguration: "",
BluecatDNSServerName: "",
BluecatConfigFile: "/etc/kubernetes/bluecat.json",
BluecatDNSView: "",
BluecatGatewayHost: "",
BluecatRootZone: "",
BluecatDNSDeployType: defaultConfig.BluecatDNSDeployType,
BluecatSkipTLSVerify: false,
CloudflareProxied: false, CloudflareProxied: false,
CloudflareDNSRecordsPerPage: 100, CloudflareDNSRecordsPerPage: 100,
CoreDNSPrefix: "/skydns/", CoreDNSPrefix: "/skydns/",
@ -117,7 +109,6 @@ var (
ExoscaleAPISecret: "", ExoscaleAPISecret: "",
CRDSourceAPIVersion: "externaldns.k8s.io/v1alpha1", CRDSourceAPIVersion: "externaldns.k8s.io/v1alpha1",
CRDSourceKind: "DNSEndpoint", CRDSourceKind: "DNSEndpoint",
RcodezeroTXTEncrypt: false,
TransIPAccountName: "", TransIPAccountName: "",
TransIPPrivateKeyFile: "", TransIPPrivateKeyFile: "",
DigitalOceanAPIPageSize: 50, DigitalOceanAPIPageSize: 50,
@ -179,14 +170,6 @@ var (
AzureConfigFile: "azure.json", AzureConfigFile: "azure.json",
AzureResourceGroup: "arg", AzureResourceGroup: "arg",
AzureSubscriptionID: "arg", AzureSubscriptionID: "arg",
BluecatDNSConfiguration: "arg",
BluecatDNSServerName: "arg",
BluecatConfigFile: "bluecat.json",
BluecatDNSView: "arg",
BluecatGatewayHost: "arg",
BluecatRootZone: "arg",
BluecatDNSDeployType: "full-deploy",
BluecatSkipTLSVerify: true,
CloudflareProxied: true, CloudflareProxied: true,
CloudflareDNSRecordsPerPage: 5000, CloudflareDNSRecordsPerPage: 5000,
CoreDNSPrefix: "/coredns/", CoreDNSPrefix: "/coredns/",
@ -228,7 +211,6 @@ var (
ExoscaleAPISecret: "2", ExoscaleAPISecret: "2",
CRDSourceAPIVersion: "test.k8s.io/v1alpha1", CRDSourceAPIVersion: "test.k8s.io/v1alpha1",
CRDSourceKind: "Endpoint", CRDSourceKind: "Endpoint",
RcodezeroTXTEncrypt: true,
NS1Endpoint: "https://api.example.com/v1", NS1Endpoint: "https://api.example.com/v1",
NS1IgnoreSSL: true, NS1IgnoreSSL: true,
TransIPAccountName: "transip", TransIPAccountName: "transip",
@ -289,14 +271,6 @@ func TestParseFlags(t *testing.T) {
"--azure-config-file=azure.json", "--azure-config-file=azure.json",
"--azure-resource-group=arg", "--azure-resource-group=arg",
"--azure-subscription-id=arg", "--azure-subscription-id=arg",
"--bluecat-dns-configuration=arg",
"--bluecat-config-file=bluecat.json",
"--bluecat-dns-view=arg",
"--bluecat-dns-server-name=arg",
"--bluecat-gateway-host=arg",
"--bluecat-root-zone=arg",
"--bluecat-dns-deploy-type=full-deploy",
"--bluecat-skip-tls-verify",
"--cloudflare-proxied", "--cloudflare-proxied",
"--cloudflare-dns-records-per-page=5000", "--cloudflare-dns-records-per-page=5000",
"--coredns-prefix=/coredns/", "--coredns-prefix=/coredns/",
@ -370,7 +344,6 @@ func TestParseFlags(t *testing.T) {
"--exoscale-apisecret=2", "--exoscale-apisecret=2",
"--crd-source-apiversion=test.k8s.io/v1alpha1", "--crd-source-apiversion=test.k8s.io/v1alpha1",
"--crd-source-kind=Endpoint", "--crd-source-kind=Endpoint",
"--rcodezero-txt-encrypt",
"--ns1-endpoint=https://api.example.com/v1", "--ns1-endpoint=https://api.example.com/v1",
"--ns1-ignoressl", "--ns1-ignoressl",
"--transip-account=transip", "--transip-account=transip",
@ -414,14 +387,6 @@ func TestParseFlags(t *testing.T) {
"EXTERNAL_DNS_AZURE_CONFIG_FILE": "azure.json", "EXTERNAL_DNS_AZURE_CONFIG_FILE": "azure.json",
"EXTERNAL_DNS_AZURE_RESOURCE_GROUP": "arg", "EXTERNAL_DNS_AZURE_RESOURCE_GROUP": "arg",
"EXTERNAL_DNS_AZURE_SUBSCRIPTION_ID": "arg", "EXTERNAL_DNS_AZURE_SUBSCRIPTION_ID": "arg",
"EXTERNAL_DNS_BLUECAT_DNS_CONFIGURATION": "arg",
"EXTERNAL_DNS_BLUECAT_DNS_SERVER_NAME": "arg",
"EXTERNAL_DNS_BLUECAT_DNS_DEPLOY_TYPE": "full-deploy",
"EXTERNAL_DNS_BLUECAT_CONFIG_FILE": "bluecat.json",
"EXTERNAL_DNS_BLUECAT_DNS_VIEW": "arg",
"EXTERNAL_DNS_BLUECAT_GATEWAY_HOST": "arg",
"EXTERNAL_DNS_BLUECAT_ROOT_ZONE": "arg",
"EXTERNAL_DNS_BLUECAT_SKIP_TLS_VERIFY": "1",
"EXTERNAL_DNS_CLOUDFLARE_PROXIED": "1", "EXTERNAL_DNS_CLOUDFLARE_PROXIED": "1",
"EXTERNAL_DNS_CLOUDFLARE_DNS_RECORDS_PER_PAGE": "5000", "EXTERNAL_DNS_CLOUDFLARE_DNS_RECORDS_PER_PAGE": "5000",
"EXTERNAL_DNS_COREDNS_PREFIX": "/coredns/", "EXTERNAL_DNS_COREDNS_PREFIX": "/coredns/",
@ -488,7 +453,6 @@ func TestParseFlags(t *testing.T) {
"EXTERNAL_DNS_EXOSCALE_APISECRET": "2", "EXTERNAL_DNS_EXOSCALE_APISECRET": "2",
"EXTERNAL_DNS_CRD_SOURCE_APIVERSION": "test.k8s.io/v1alpha1", "EXTERNAL_DNS_CRD_SOURCE_APIVERSION": "test.k8s.io/v1alpha1",
"EXTERNAL_DNS_CRD_SOURCE_KIND": "Endpoint", "EXTERNAL_DNS_CRD_SOURCE_KIND": "Endpoint",
"EXTERNAL_DNS_RCODEZERO_TXT_ENCRYPT": "1",
"EXTERNAL_DNS_NS1_ENDPOINT": "https://api.example.com/v1", "EXTERNAL_DNS_NS1_ENDPOINT": "https://api.example.com/v1",
"EXTERNAL_DNS_NS1_IGNORESSL": "1", "EXTERNAL_DNS_NS1_IGNORESSL": "1",
"EXTERNAL_DNS_TRANSIP_ACCOUNT": "transip", "EXTERNAL_DNS_TRANSIP_ACCOUNT": "transip",
@ -536,14 +500,12 @@ func restoreEnv(t *testing.T, originalEnv map[string]string) {
func TestPasswordsNotLogged(t *testing.T) { func TestPasswordsNotLogged(t *testing.T) {
cfg := Config{ cfg := Config{
DynPassword: "dyn-pass",
PDNSAPIKey: "pdns-api-key", PDNSAPIKey: "pdns-api-key",
RFC2136TSIGSecret: "tsig-secret", RFC2136TSIGSecret: "tsig-secret",
} }
s := cfg.String() s := cfg.String()
assert.False(t, strings.Contains(s, "dyn-pass"))
assert.False(t, strings.Contains(s, "pdns-api-key")) assert.False(t, strings.Contains(s, "pdns-api-key"))
assert.False(t, strings.Contains(s, "tsig-secret")) assert.False(t, strings.Contains(s, "tsig-secret"))
} }

View File

@ -61,19 +61,6 @@ func ValidateConfig(cfg *externaldns.Config) error {
} }
} }
if cfg.Provider == "dyn" {
if cfg.DynUsername == "" {
return errors.New("no Dyn username specified")
}
if cfg.DynCustomerName == "" {
return errors.New("no Dyn customer name specified")
}
if cfg.DynMinTTLSeconds < 0 {
return errors.New("TTL specified for Dyn is negative")
}
}
if cfg.Provider == "rfc2136" { if cfg.Provider == "rfc2136" {
if cfg.RFC2136MinTTL < 0 { if cfg.RFC2136MinTTL < 0 {
return errors.New("TTL specified for rfc2136 is negative") return errors.New("TTL specified for rfc2136 is negative")

View File

@ -64,59 +64,6 @@ func newValidConfig(t *testing.T) *externaldns.Config {
return cfg return cfg
} }
func addRequiredFieldsForDyn(cfg *externaldns.Config) {
cfg.LogFormat = "json"
cfg.Sources = []string{"ingress"}
cfg.Provider = "dyn"
}
func TestValidateBadDynConfig(t *testing.T) {
badConfigs := []*externaldns.Config{
{},
{
// only username
DynUsername: "test",
},
{
// only customer name
DynCustomerName: "test",
},
{
// negative timeout
DynUsername: "test",
DynCustomerName: "test",
DynMinTTLSeconds: -1,
},
}
for _, cfg := range badConfigs {
addRequiredFieldsForDyn(cfg)
err := ValidateConfig(cfg)
assert.NotNil(t, err, "Configuration %+v should NOT have passed validation", cfg)
}
}
func TestValidateGoodDynConfig(t *testing.T) {
goodConfigs := []*externaldns.Config{
{
DynUsername: "test",
DynCustomerName: "test",
DynMinTTLSeconds: 600,
},
{
DynUsername: "test",
DynCustomerName: "test",
DynMinTTLSeconds: 0,
},
}
for _, cfg := range goodConfigs {
addRequiredFieldsForDyn(cfg)
err := ValidateConfig(cfg)
assert.Nil(t, err, "Configuration should be valid, got this error instead", err)
}
}
func TestValidateBadIgnoreHostnameAnnotationsConfig(t *testing.T) { func TestValidateBadIgnoreHostnameAnnotationsConfig(t *testing.T) {
cfg := externaldns.NewConfig() cfg := externaldns.NewConfig()
cfg.IgnoreHostnameAnnotation = true cfg.IgnoreHostnameAnnotation = true

View File

@ -17,13 +17,16 @@ limitations under the License.
package aws package aws
import ( import (
"context"
"fmt" "fmt"
"net/http"
"strings" "strings"
"github.com/aws/aws-sdk-go/aws" awsv2 "github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go-v2/aws/retry"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go/aws/session" stscredsv2 "github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/linki/instrumented_http" "github.com/linki/instrumented_http"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -38,8 +41,8 @@ type AWSSessionConfig struct {
Profile string Profile string
} }
func CreateDefaultSession(cfg *externaldns.Config) *session.Session { func CreateDefaultV2Config(cfg *externaldns.Config) awsv2.Config {
result, err := newSession( result, err := newV2Config(
AWSSessionConfig{ AWSSessionConfig{
AssumeRole: cfg.AWSAssumeRole, AssumeRole: cfg.AWSAssumeRole,
AssumeRoleExternalID: cfg.AWSAssumeRoleExternalID, AssumeRoleExternalID: cfg.AWSAssumeRoleExternalID,
@ -52,24 +55,14 @@ func CreateDefaultSession(cfg *externaldns.Config) *session.Session {
return result return result
} }
func CreateSessions(cfg *externaldns.Config) map[string]*session.Session { func CreateV2Configs(cfg *externaldns.Config) map[string]awsv2.Config {
result := make(map[string]*session.Session) result := make(map[string]awsv2.Config)
if len(cfg.AWSProfiles) == 0 || (len(cfg.AWSProfiles) == 1 && cfg.AWSProfiles[0] == "") { if len(cfg.AWSProfiles) == 0 || (len(cfg.AWSProfiles) == 1 && cfg.AWSProfiles[0] == "") {
session, err := newSession( cfg := CreateDefaultV2Config(cfg)
AWSSessionConfig{ result[defaultAWSProfile] = cfg
AssumeRole: cfg.AWSAssumeRole,
AssumeRoleExternalID: cfg.AWSAssumeRoleExternalID,
APIRetries: cfg.AWSAPIRetries,
},
)
if err != nil {
logrus.Fatal(err)
}
result[defaultAWSProfile] = session
} else { } else {
for _, profile := range cfg.AWSProfiles { for _, profile := range cfg.AWSProfiles {
session, err := newSession( cfg, err := newV2Config(
AWSSessionConfig{ AWSSessionConfig{
AssumeRole: cfg.AWSAssumeRole, AssumeRole: cfg.AWSAssumeRole,
AssumeRoleExternalID: cfg.AWSAssumeRoleExternalID, AssumeRoleExternalID: cfg.AWSAssumeRoleExternalID,
@ -80,46 +73,47 @@ func CreateSessions(cfg *externaldns.Config) map[string]*session.Session {
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
result[profile] = session result[profile] = cfg
} }
} }
return result return result
} }
func newSession(awsConfig AWSSessionConfig) (*session.Session, error) { func newV2Config(awsConfig AWSSessionConfig) (awsv2.Config, error) {
config := aws.NewConfig().WithMaxRetries(awsConfig.APIRetries) defaultOpts := []func(*config.LoadOptions) error{
config.WithRetryer(func() awsv2.Retryer {
config.WithHTTPClient( return retry.AddWithMaxAttempts(retry.NewStandard(), awsConfig.APIRetries)
instrumented_http.NewClient(config.HTTPClient, &instrumented_http.Callbacks{ }),
config.WithHTTPClient(instrumented_http.NewClient(&http.Client{}, &instrumented_http.Callbacks{
PathProcessor: func(path string) string { PathProcessor: func(path string) string {
parts := strings.Split(path, "/") parts := strings.Split(path, "/")
return parts[len(parts)-1] return parts[len(parts)-1]
}, },
}), })),
) config.WithSharedConfigProfile(awsConfig.Profile),
}
session, err := session.NewSessionWithOptions(session.Options{ cfg, err := config.LoadDefaultConfig(context.Background(), defaultOpts...)
Config: *config,
SharedConfigState: session.SharedConfigEnable,
Profile: awsConfig.Profile,
})
if err != nil { if err != nil {
return nil, fmt.Errorf("instantiating AWS session: %w", err) return awsv2.Config{}, fmt.Errorf("instantiating AWS config: %w", err)
} }
if awsConfig.AssumeRole != "" { if awsConfig.AssumeRole != "" {
stsSvc := sts.NewFromConfig(cfg)
var assumeRoleOpts []func(*stscredsv2.AssumeRoleOptions)
if awsConfig.AssumeRoleExternalID != "" { if awsConfig.AssumeRoleExternalID != "" {
logrus.Infof("Assuming role: %s with external id %s", awsConfig.AssumeRole, awsConfig.AssumeRoleExternalID) logrus.Infof("Assuming role: %s with external id %s", awsConfig.AssumeRole, awsConfig.AssumeRoleExternalID)
session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole, func(p *stscreds.AssumeRoleProvider) { assumeRoleOpts = []func(*stscredsv2.AssumeRoleOptions){
p.ExternalID = &awsConfig.AssumeRoleExternalID func(opts *stscredsv2.AssumeRoleOptions) {
})) opts.ExternalID = &awsConfig.AssumeRoleExternalID
},
}
} else { } else {
logrus.Infof("Assuming role: %s", awsConfig.AssumeRole) logrus.Infof("Assuming role: %s", awsConfig.AssumeRole)
session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole))
} }
creds := stscredsv2.NewAssumeRoleProvider(stsSvc, awsConfig.AssumeRole, assumeRoleOpts...)
cfg.Credentials = awsv2.NewCredentialsCache(creds)
} }
session.Handlers.Build.PushBack(request.MakeAddToUserAgentHandler("ExternalDNS", externaldns.Version)) return cfg, nil
return session, nil
} }

View File

@ -17,6 +17,7 @@ limitations under the License.
package aws package aws
import ( import (
"context"
"os" "os"
"testing" "testing"
@ -24,7 +25,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func Test_newSession(t *testing.T) { func Test_newV2Config(t *testing.T) {
t.Run("should use profile from credentials file", func(t *testing.T) { t.Run("should use profile from credentials file", func(t *testing.T) {
// setup // setup
credsFile, err := prepareCredentialsFile(t) credsFile, err := prepareCredentialsFile(t)
@ -34,9 +35,9 @@ func Test_newSession(t *testing.T) {
defer os.Unsetenv("AWS_SHARED_CREDENTIALS_FILE") defer os.Unsetenv("AWS_SHARED_CREDENTIALS_FILE")
// when // when
s, err := newSession(AWSSessionConfig{Profile: "profile2"}) cfg, err := newV2Config(AWSSessionConfig{Profile: "profile2"})
require.NoError(t, err) require.NoError(t, err)
creds, err := s.Config.Credentials.Get() creds, err := cfg.Credentials.Retrieve(context.Background())
// then // then
assert.NoError(t, err) assert.NoError(t, err)
@ -52,9 +53,9 @@ func Test_newSession(t *testing.T) {
defer os.Unsetenv("AWS_SECRET_ACCESS_KEY") defer os.Unsetenv("AWS_SECRET_ACCESS_KEY")
// when // when
s, err := newSession(AWSSessionConfig{}) cfg, err := newV2Config(AWSSessionConfig{})
require.NoError(t, err) require.NoError(t, err)
creds, err := s.Config.Credentials.Get() creds, err := cfg.Credentials.Retrieve(context.Background())
// then // then
assert.NoError(t, err) assert.NoError(t, err)

Some files were not shown because too many files have changed in this diff Show More