Skip to content

Latest commit

 

History

History
183 lines (145 loc) · 5.39 KB

crd.md

File metadata and controls

183 lines (145 loc) · 5.39 KB

CRD Source

CRD source provides a generic mechanism to manage DNS records in your favourite DNS provider supported by external-dns.

Details

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.

Registering CRD

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.

Usage

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

Creating DNS Records

Create the objects of CRD type by filling in the fields of CRD and DNS record would be created accordingly.

Example

Here is an example CRD manifest generated by kubebuilder. Apply this to register the CRD

$ kubectl apply --validate=false -f docs/sources/crd/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/sources/crd/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"

Using CRD source to manage DNS records in different DNS providers

CRD source provides a generic mechanism and declarative way to manage DNS records in different DNS providers using external-dns.

Not all the record types are enabled by default so the required record types must be enabled by using --managed-record-types.

external-dns --source=crd \
  --domain-filter=example.com \
  --managed-record-types=A \
  --managed-record-types=CNAME \
  --managed-record-types=NS
  • Example for record type A
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
  name: examplearecord
spec:
  endpoints:
  - dnsName: example.com
    recordTTL: 60
    recordType: A
    targets:
    - 10.0.0.1
  • Example for record type CNAME
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
  name: examplecnamerecord
spec:
  endpoints:
  - dnsName: test-a.example.com
    recordTTL: 300
    recordType: CNAME
    targets:
    - example.com
  • Example for record type NS
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
  name: ns-record
spec:
  endpoints:
  - dnsName: zone.example.com
    recordTTL: 300
    recordType: NS
    targets:
    - ns1.example.com
    - ns2.example.com

RBAC configuration

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: ["*"]