CRD source provides a generic mechanism to manage DNS records in your favourite DNS provider supported by external-dns.
CRD source watches for a user specified CRD to extract Endpoints from its Spec
.
So users need to create such a CRD and register it to the kubernetes cluster and then create new object(s) of the CRD specifying the Endpoints.
Here is typical example of CRD API type which provides Endpoints to CRD source
:
type TTL int64
type Targets []string
type ProviderSpecificProperty struct {
Name string `json:"name,omitempty"`
Value string `json:"value,omitempty"`
}
type ProviderSpecific []ProviderSpecificProperty
type Labels map[string]string
type Endpoint struct {
// The hostname of the DNS record
DNSName string `json:"dnsName,omitempty"`
// The targets the DNS record points to
Targets Targets `json:"targets,omitempty"`
// RecordType type of record, e.g. CNAME, A, SRV, TXT etc
RecordType string `json:"recordType,omitempty"`
// TTL for the record
RecordTTL TTL `json:"recordTTL,omitempty"`
// Labels stores labels defined for the Endpoint
// +optional
Labels Labels `json:"labels,omitempty"`
// ProviderSpecific stores provider specific config
// +optional
ProviderSpecific ProviderSpecific `json:"providerSpecific,omitempty"`
}
type DNSEndpointSpec struct {
Endpoints []*Endpoint `json:"endpoints,omitempty"`
}
type DNSEndpointStatus struct {
// The generation observed by the external-dns controller.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// DNSEndpoint is the CRD wrapper for Endpoint
// +k8s:openapi-gen=true
// +kubebuilder:resource:path=dnsendpoints
// +kubebuilder:subresource:status
type DNSEndpoint struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec DNSEndpointSpec `json:"spec,omitempty"`
Status DNSEndpointStatus `json:"status,omitempty"`
}
Refer to kubebuilder to create and register the CRD.
One can use CRD source by specifying --source
flag with crd
and specifying the ApiVersion and Kind of the CRD with --crd-source-apiversion
and crd-source-kind
respectively.
for e.g:
$ build/external-dns --source crd --crd-source-apiversion externaldns.k8s.io/v1alpha1 --crd-source-kind DNSEndpoint --provider inmemory --once --dry-run
Create the objects of CRD type by filling in the fields of CRD and DNS record would be created accordingly.
Here is an example CRD manifest generated by kubebuilder. Apply this to register the CRD
$ kubectl apply --validate=false -f docs/contributing/crd-source/crd-manifest.yaml
customresourcedefinition.apiextensions.k8s.io "dnsendpoints.externaldns.k8s.io" created
Then you can create the dns-endpoint yaml similar to dnsendpoint-example
$ kubectl apply -f docs/contributing/crd-source/dnsendpoint-example.yaml
dnsendpoint.externaldns.k8s.io "examplednsrecord" created
Run external-dns in dry-mode to see whether external-dns picks up the DNS record from CRD.
$ build/external-dns --source crd --crd-source-apiversion externaldns.k8s.io/v1alpha1 --crd-source-kind DNSEndpoint --provider inmemory --once --dry-run
INFO[0000] running in dry-run mode. No changes to DNS records will be made.
INFO[0000] Connected to cluster at https://192.168.99.100:8443
INFO[0000] CREATE: foo.bar.com 180 IN A 192.168.99.216
INFO[0000] CREATE: foo.bar.com 0 IN TXT "heritage=external-dns,external-dns/owner=default"
If you use RBAC, extend the external-dns
ClusterRole with:
- apiGroups: ["externaldns.k8s.io"]
resources: ["dnsendpoints"]
verbs: ["get","watch","list"]
- apiGroups: ["externaldns.k8s.io"]
resources: ["dnsendpoints/status"]
verbs: ["*"]