feat: support webhook provider in Chart (#4032)

* BREAKING CHANGE: 💥 support webhook provider in Chart

* add /healthz to webhook tutorial

* keep backward compatibility

* moved images to values

* Update charts/external-dns/values.yaml

Co-authored-by: Steve Hipwell <steve.hipwell@gmail.com>

* fixed name for sidecar + doc update + externalVolumeMounts

* add serviceMonitor endpoint, improve webhook provider tutorial and differentiate probes

* doc: use helm-docs for README

* fix rebase error

* Apply suggestions from code review

Co-authored-by: Steve Hipwell <steve.hipwell@gmail.com>

* introduce external-dns.webhookImage to match current image function

* fix port name of probes

* update template with webhook provider support

* Apply suggestions from code review

Co-authored-by: Steve Hipwell <steve.hipwell@gmail.com>

* Update charts/external-dns/templates/deployment.yaml

Co-authored-by: Steve Hipwell <steve.hipwell@gmail.com>

* Update charts/external-dns/templates/deployment.yaml

Co-authored-by: Steve Hipwell <steve.hipwell@gmail.com>

* following review on provider.name doc

* remove secretConfiguration on webhook

---------

Co-authored-by: Steve Hipwell <steve.hipwell@gmail.com>
This commit is contained in:
Michel Loiseleur 2024-01-09 15:32:57 +01:00 committed by GitHub
parent 70a70892a8
commit 0009a6b67b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 170 additions and 20 deletions

View File

@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added the option to explicitly enable or disable service account token automounting. ([#3983](https://github.com/kubernetes-sigs/external-dns/pull/3983)) [@gilles-gosuin](https://github.com/gilles-gosuin) - Added the option to explicitly enable or disable service account token automounting. ([#3983](https://github.com/kubernetes-sigs/external-dns/pull/3983)) [@gilles-gosuin](https://github.com/gilles-gosuin)
- Added the option to configure revisionHistoryLimit on the K8s Deployment resource. ([#4008](https://github.com/kubernetes-sigs/external-dns/pull/4008)) [@arnisoph](https://github.com/arnisoph) - Added the option to configure revisionHistoryLimit on the K8s Deployment resource. ([#4008](https://github.com/kubernetes-sigs/external-dns/pull/4008)) [@arnisoph](https://github.com/arnisoph)
- Added support for webhook providers, as a sidecar. ([#4032](https://github.com/kubernetes-sigs/external-dns/pull/4032) [@mloiseleur](https://github.com/mloiseleur)
- Added the option to configure ipFamilyPolicy and ipFamilies of external-dns Service. ([#4153](https://github.com/kubernetes-sigs/external-dns/pull/4153)) [@dongjiang1989](https://github.com/dongjiang1989) - Added the option to configure ipFamilyPolicy and ipFamilies of external-dns Service. ([#4153](https://github.com/kubernetes-sigs/external-dns/pull/4153)) [@dongjiang1989](https://github.com/dongjiang1989)
### Changed ### Changed

View File

@ -32,15 +32,14 @@ helm upgrade --install external-dns external-dns/external-dns --version 1.13.1
## Providers ## Providers
Configuring the _ExternalDNS_ provider should be done via the `provider.name` value with provider specific configuration being set via the Configuring the _ExternalDNS_ provider should be done via the `provider.name` value with provider specific configuration being set via the `provider.<name>.<key>` values, where supported, and the `extraArgs` value. For legacy support `provider` can be set to the name of the provider with all additional configuration being set via the `extraArgs` value.
`provider.<name>.<key>` values, where supported, and the `extraArgs` value. For legacy support `provider` can be set to the name of the See [documentation](https://kubernetes-sigs.github.io/external-dns/#new-providers) for more info on available providers and tutorials.
provider with all additional configuration being set via the `extraArgs` value.
### Providers with Specific Configuration Support ### Providers with Specific Configuration Support
| Provider | Supported | | Provider | Supported |
|------------------------|------------| |------------------------|------------|
| `webhook` | | | `webhook` | |
## Namespaced Scoped Installation ## Namespaced Scoped Installation
@ -108,10 +107,21 @@ If `namespaced` is set to `true`, please ensure that `sources` my only contains
| podSecurityContext | object | See _values.yaml_ | [Pod security context](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core), this supports full customisation. | | podSecurityContext | object | See _values.yaml_ | [Pod security context](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core), this supports full customisation. |
| policy | string | `"upsert-only"` | How DNS records are synchronized between sources and providers; available values are `sync` & `upsert-only`. | | policy | string | `"upsert-only"` | How DNS records are synchronized between sources and providers; available values are `sync` & `upsert-only`. |
| priorityClassName | string | `nil` | Priority class name for the `Pod`. | | priorityClassName | string | `nil` | Priority class name for the `Pod`. |
| provider.name | string | `"aws"` | _ExternalDNS_ provider name; for the available providers and how to configure them see the [README](https://github.com/kubernetes-sigs/external-dns#deploying-to-a-cluster). | | provider.name | string | `"aws"` | _ExternalDNS_ provider name; for the available providers and how to configure them see [README](https://github.com/kubernetes-sigs/external-dns/blob/master/charts/external-dns/README.md#providers). |
| provider.webhook.args | list | `[]` | Extra arguments to provide for the `webhook` container. |
| provider.webhook.env | list | `[]` | [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for the `webhook` container. |
| provider.webhook.extraVolumeMounts | list | `[]` | Extra [volume mounts](https://kubernetes.io/docs/concepts/storage/volumes/) for the `webhook` container. |
| provider.webhook.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy for the `webhook` container. |
| provider.webhook.image.repository | string | `nil` | Image repository for the `webhook` container. |
| provider.webhook.image.tag | string | `nil` | Image tag for the `webhook` container. |
| provider.webhook.livenessProbe | object | See _values.yaml_ | [Liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `external-dns` 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.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.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. |
| readinessProbe | object | See _values.yaml_ | Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `external-dns` container. | | readinessProbe | object | See _values.yaml_ | [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `external-dns` container. |
| registry | string | `"txt"` | Specify the registry for storing ownership and labels. Valid values are `txt`, `aws-sd`, `dynamodb` & `noop`. | | registry | string | `"txt"` | Specify the registry for storing ownership and labels. Valid values are `txt`, `aws-sd`, `dynamodb` & `noop`. |
| resources | object | `{}` | [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the `external-dns` container. | | resources | object | `{}` | [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the `external-dns` container. |
| revisionHistoryLimit | int | `nil` | Specify the number of old `ReplicaSets` to retain to allow rollback of the `Deployment``. | | revisionHistoryLimit | int | `nil` | Specify the number of old `ReplicaSets` to retain to allow rollback of the `Deployment``. |
@ -119,7 +129,7 @@ If `namespaced` is set to `true`, please ensure that `sources` my only contains
| secretConfiguration.enabled | bool | `false` | If `true`, create a `Secret` to store sensitive provider configuration (**DEPRECATED**). | | secretConfiguration.enabled | bool | `false` | If `true`, create a `Secret` to store sensitive provider configuration (**DEPRECATED**). |
| secretConfiguration.mountPath | string | `nil` | Mount path for the `Secret`, this can be templated. | | secretConfiguration.mountPath | string | `nil` | Mount path for the `Secret`, this can be templated. |
| secretConfiguration.subPath | string | `nil` | Sub-path for mounting the `Secret`, this can be templated. | | secretConfiguration.subPath | string | `nil` | Sub-path for mounting the `Secret`, this can be templated. |
| securityContext | object | See _values.yaml_ | [Security context](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#securitycontext-v1-core) for the `external-dns` container. | | securityContext | object | See _values.yaml_ | [Security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) for the `external-dns` container. |
| service.annotations | object | `{}` | Service annotations. | | service.annotations | object | `{}` | Service annotations. |
| service.ipFamilies | list | `[]` | Service IP families. | | service.ipFamilies | list | `[]` | Service IP families. |
| service.ipFamilyPolicy | string | `nil` | Service IP family policy. | | service.ipFamilyPolicy | string | `nil` | Service IP family policy. |

View File

@ -27,15 +27,14 @@ helm upgrade --install {{ template "chart.name" . }} external-dns/{{ template "c
## Providers ## Providers
Configuring the _ExternalDNS_ provider should be done via the `provider.name` value with provider specific configuration being set via the Configuring the _ExternalDNS_ provider should be done via the `provider.name` value with provider specific configuration being set via the `provider.<name>.<key>` values, where supported, and the `extraArgs` value. For legacy support `provider` can be set to the name of the provider with all additional configuration being set via the `extraArgs` value.
`provider.<name>.<key>` values, where supported, and the `extraArgs` value. For legacy support `provider` can be set to the name of the See [documentation](https://kubernetes-sigs.github.io/external-dns/#new-providers) for more info on available providers and tutorials.
provider with all additional configuration being set via the `extraArgs` value.
### Providers with Specific Configuration Support ### Providers with Specific Configuration Support
| Provider | Supported | | Provider | Supported |
|------------------------|------------| |------------------------|------------|
| `webhook` | | | `webhook` | |
## Namespaced Scoped Installation ## Namespaced Scoped Installation

View File

@ -81,3 +81,15 @@ Provider name, Keeps backward compatibility on provider
{{- .Values.provider.name }} {{- .Values.provider.name }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{/*
The image to use for optional webhook sidecar
*/}}
{{- define "external-dns.webhookImage" -}}
{{- with .image }}
{{- if or (empty .repository) (empty .tag) }}
{{- fail "ERROR: webhook provider needs an image repository and a tag" }}
{{- end }}
{{- printf "%s:%s" .repository .tag }}
{{- end }}
{{- end }}

View File

@ -1,3 +1,4 @@
{{- $providerName := include "external-dns.providerName" . }}
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
@ -103,7 +104,7 @@ spec:
{{- range .Values.domainFilters }} {{- range .Values.domainFilters }}
- --domain-filter={{ . }} - --domain-filter={{ . }}
{{- end }} {{- end }}
- --provider={{ include "external-dns.providerName" . }} - --provider={{ $providerName }}
{{- range .Values.extraArgs }} {{- range .Values.extraArgs }}
- {{ tpl . $ }} - {{ tpl . $ }}
{{- end }} {{- end }}
@ -132,6 +133,43 @@ spec:
resources: resources:
{{- toYaml . | nindent 12 }} {{- toYaml . | nindent 12 }}
{{- end }} {{- end }}
{{- if eq $providerName "webhook" }}
{{- with .Values.provider.webhook }}
- name: webhook
image: {{ include "external-dns.webhookImage" . }}
imagePullPolicy: {{ $.Values.image.pullPolicy }}
{{- with .env }}
env:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .args }}
args:
- {{ toYaml . | nindent 12 }}
{{- end }}
ports:
- name: http-webhook
protocol: TCP
containerPort: 8888
- name: http-webhook-metrics
protocol: TCP
containerPort: 8080
livenessProbe:
{{- toYaml .livenessProbe | nindent 12 }}
readinessProbe:
{{- toYaml .readinessProbe | nindent 12 }}
{{- if .extraVolumeMounts }}
volumeMounts:
{{- with .extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- end }}
{{- with .securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- end }}
{{- end }}
{{- if or .Values.secretConfiguration.enabled .Values.extraVolumes }} {{- if or .Values.secretConfiguration.enabled .Values.extraVolumes }}
volumes: volumes:
{{- if .Values.secretConfiguration.enabled }} {{- if .Values.secretConfiguration.enabled }}

View File

@ -1,4 +1,5 @@
{{- if .Values.serviceMonitor.enabled -}} {{- if .Values.serviceMonitor.enabled -}}
{{- $providerName := include "external-dns.providerName" . }}
apiVersion: monitoring.coreos.com/v1 apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor kind: ServiceMonitor
metadata: metadata:
@ -48,6 +49,36 @@ spec:
relabelings: relabelings:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
{{- if eq $providerName "webhook" }}
{{- with .Values.provider.webhook.serviceMonitor }}
- port: webhook-metrics
path: /metrics
{{- with .interval }}
interval: {{ . }}
{{- end }}
{{- with .scheme }}
scheme: {{ . }}
{{- end }}
{{- with .bearerTokenFile }}
bearerTokenFile: {{ . }}
{{- end }}
{{- with .tlsConfig }}
tlsConfig:
{{- toYaml .| nindent 8 }}
{{- end }}
{{- with .scrapeTimeout }}
scrapeTimeout: {{ . }}
{{- end }}
{{- with .metricRelabelings }}
metricRelabelings:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .relabelings }}
relabelings:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.serviceMonitor.targetLabels }} {{- with .Values.serviceMonitor.targetLabels }}
targetLabels: targetLabels:
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}

View File

@ -92,7 +92,7 @@ dnsPolicy:
# -- [Init containers](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) to add to the `Pod` definition. # -- [Init containers](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) to add to the `Pod` definition.
initContainers: [] initContainers: []
# -- [Security context](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#securitycontext-v1-core) for the `external-dns` container. # -- [Security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) for the `external-dns` container.
# @default -- See _values.yaml_ # @default -- See _values.yaml_
securityContext: securityContext:
privileged: false privileged: false
@ -119,7 +119,7 @@ livenessProbe:
failureThreshold: 2 failureThreshold: 2
successThreshold: 1 successThreshold: 1
# -- Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `external-dns` container. # -- [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `external-dns` container.
# @default -- See _values.yaml_ # @default -- See _values.yaml_
readinessProbe: readinessProbe:
httpGet: httpGet:
@ -217,8 +217,59 @@ txtSuffix:
domainFilters: [] domainFilters: []
provider: provider:
# -- _ExternalDNS_ provider name; for the available providers and how to configure them see the [README](https://github.com/kubernetes-sigs/external-dns#deploying-to-a-cluster). # -- _ExternalDNS_ provider name; for the available providers and how to configure them see [README](https://github.com/kubernetes-sigs/external-dns/blob/master/charts/external-dns/README.md#providers).
name: aws name: aws
webhook:
image:
# -- (string) Image repository for the `webhook` container.
repository:
# -- (string) Image tag for the `webhook` container.
tag:
# -- Image pull policy for the `webhook` container.
pullPolicy: IfNotPresent
# -- [Environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) for the `webhook` container.
env: []
# -- Extra arguments to provide for the `webhook` container.
args: []
# -- Extra [volume mounts](https://kubernetes.io/docs/concepts/storage/volumes/) for the `webhook` container.
extraVolumeMounts: []
# -- [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the `webhook` container.
resources: {}
# -- [Pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) for the `webhook` container.
# @default -- See _values.yaml_
securityContext: {}
# -- [Liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `external-dns` container.
# @default -- See _values.yaml_
livenessProbe:
httpGet:
path: /healthz
port: http-webhook
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 2
successThreshold: 1
# -- [Readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) configuration for the `webhook` container.
# @default -- See _values.yaml_
readinessProbe:
httpGet:
path: /healthz
port: http-webhook
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1
# -- Optional [Service Monitor](https://prometheus-operator.dev/docs/operator/design/#servicemonitor) configuration for the `webhook` container.
# @default -- See _values.yaml_
serviceMonitor:
interval:
scheme:
tlsConfig: {}
bearerTokenFile:
scrapeTimeout:
metricRelabelings: []
relabelings: []
# -- Extra arguments to provide to _ExternalDNS_. # -- Extra arguments to provide to _ExternalDNS_.
extraArgs: [] extraArgs: []

View File

@ -16,18 +16,26 @@ 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 method | HTTP Method | Route |
| --- | --- | --- | | --- | --- | --- |
| Records | GET | /records | | Records | GET | /records |
| AdjustEndpoints | POST | /adjustendpoints | | AdjustEndpoints | POST | /adjustendpoints |
| ApplyChanges | POST | /records | | ApplyChanges | POST | /records |
| K8s probe | GET | /healthz |
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).
**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
The metrics should listen ":8080" on `/metrics` following [Open Metrics](https://github.com/OpenObservability/OpenMetrics) format.
## Provider registry ## Provider registry
To simplify the discovery of providers, we will accept pull requests that will add links to providers in the [README](../../README.md) file. This list will only serve the purpose of simplifying finding providers and will not constitute an official endorsement of any of the externally implemented providers unless otherwise stated. To simplify the discovery of providers, we will accept pull requests that will add links to providers in the [README](../../README.md) file. This list will only serve the purpose of simplifying finding providers and will not constitute an official endorsement of any of the externally implemented providers unless otherwise stated.