This is the multi-page printable view of this section. Click here to print.
Guides
- 1: Create DNS records from Ingress
- 2: Monitoring with Prometheus
- 3: Dynamic DNS with IP objects
- 4: Fetch IP from a Kubernetes object
- 5: Migration to cloudflare-operator
1 - Create DNS records from Ingress
cloudflare-operator can create DNS records from Ingress resources. This guide shows how to configure the controller to automatically create DNS records for your Ingress resources.
Ingress annotations
One of the following annotations is required: cloudflare-operator.io/content
or cloudflare-operator.io/ip-ref
Ingress objects that do not have one of these annotations will be ignored by cloudflare-operator.
These are the available annotations:
Annotation | Value | Description | Required |
---|---|---|---|
cloudflare-operator.io/content |
IP address or domain | DNS record content (e.g. 69.42.0.69 ) |
yes if ip-ref is not set |
cloudflare-operator.io/ip-ref |
Reference to an IP object | e.g. my-external-ip |
yes if content is not set |
cloudflare-operator.io/proxied |
true or false |
Whether the record should be proxied | no |
cloudflare-operator.io/ttl |
1 or 60 - 86400 |
TTL of the DNS record | no |
cloudflare-operator.io/type |
A , AAAA or CNAME |
Desired DNS record type | no |
cloudflare-operator.io/interval |
e.g. 5m0s |
Interval at which the DNSRecord object should be reconciled | no |
An example Ingress resource with annotations:
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cloudflare-operator.io/type: CNAME
cloudflare-operator.io/content: example.com
name: blog
namespace: blog
spec:
rules:
- host: blog.example.com
http:
paths:
- backend:
service:
name: blog
port:
name: http
path: /
pathType: Prefix
This will create a DNS record for the host blog.example.com
with the content example.com
and the type CNAME
.
cloudflare-operator only supports
networking.k8s.io/v1
Ingresses.
2 - Monitoring with Prometheus
Prerequisites
The easiest way to deploy all the necessary components is to use kube-prometheus-stack.
Enable metrics
In order to enable metrics and automatically deploy the required resources, you need to reconfigure the Helm chart.
Create a values.yaml
file with the following content:
---
metrics:
podMonitor:
enabled: true
prometheusRule:
enabled: true
Now you can install / upgrade the Helm chart by following the installation guide.
Install cloudflare-operator Grafana dashboard
# Download Grafana dashboard
wget https://raw.githubusercontent.com/containeroo/cloudflare-operator/master/config/manifests/grafana/dashboards/overview.json -O /tmp/grafana-dashboard-cloudflare-operator.json
# Create the configmap
kubectl create configmap grafana-dashboard-cloudflare-operator --from-file=/tmp/grafana-dashboard-cloudflare-operator.json
# Add label so Grafana can fetch dashboard
kubectl label configmap grafana-dashboard-cloudflare-operator grafana_dashboard="1"
Available metrics
For each cloudflare-operator.io
kind, the controller exposes a gauge metric to track the status condition.
Ready status metrics:
cloudflare_operator_account_status
cloudflare_operator_dns_record_status
cloudflare_operator_ip_status
cloudflare_operator_zone_status
Alerting
The following alerting rule can be used to monitor DNS record failures:
groups:
- alert: DNSRecordFailures
annotations:
summary:
DNSRecord {{ $labels.name }} ({{ $labels.record_name }}) in namespace
{{ $labels.exported_namespace }} failed
expr: cloudflare_operator_dns_record_status > 0
for: 1m
labels:
severity: critical
3 - Dynamic DNS with IP objects
As described in the core concept, IP objects allow you to use cloudflare-operator as a dynamic DNS controller.
In this guide, we will configure an IP object to fetch the public IP address from the internet and use it as the target content for a DNS record.
Simple example
Create an IP object with the following content:
---
apiVersion: cloudflare-operator.io/v1
kind: IP
metadata:
name: external-v4
spec:
ipSources:
- requestMethod: GET
url: https://ifconfig.me/ip
- requestMethod: GET
url: https://ipecho.net/plain
- requestMethod: GET
url: https://myip.is/ip/
- requestMethod: GET
url: https://checkip.amazonaws.com
- requestMethod: GET
url: https://api.ipify.org
type: dynamic
interval: 5m0s
The IP object will fetch the public IP address from the internet using one of the specified URLs.
If the request fails, the next URL will be tried. If all URLs fail, the last known IP will be used and
the ready condition will be set to false
.
Now, create a DNS record object with the following content:
---
apiVersion: cloudflare-operator.io/v1
kind: DNSRecord
metadata:
name: example-com
namespace: cloudflare-operator
spec:
name: example.com
ipRef:
name: external-v4 # reference to the IP object
proxied: true
ttl: 1
type: A
Response filtering
Using jq
You can use jq to filter the response content.
Here is an example for ipify.org:
Request content:
$ curl 'https://api.ipify.org?format=json'
{"ip":"69.42.0.69"}
The IP object would look like this:
---
apiVersion: cloudflare-operator.io/v1
kind: IP
metadata:
name: external-v4
spec:
ipSources:
- requestMethod: GET
url: https://api.ipify.org?format=json
responseJQFilter: .ip
type: dynamic
interval: 5m0s
Using regex
If you want to use a regex, you can use the postProcessingRegex
field.
This might be useful if you want to extract the IP address from a HTML page.
The regex must contain a single capture group.
Here is an example for ifconfig.me:
Request content:
$ curl 'https://ifconfig.me/'
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
...
In this case, the IP object would look like this:
---
apiVersion: cloudflare-operator.io/v1
kind: IP
metadata:
name: external-v4
spec:
ipSources:
- requestMethod: GET
url: https://ifconfig.me/
postProcessingRegex: '(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
type: dynamic
interval: 5m0s
Fetching IP from an API
If you want to fetch the IP address from an API, you can use the responseJQFilter
field.
In this example, we are going to fetch the IP from a Hetzner cloud instance.
To authenticate with the API, you can configure the IP object to use a secret
where the secret key will be used as the header name
and the secret value will be used as the header value.
Create a secret with the following content:
---
apiVersion: v1
kind: Secret
metadata:
name: hetzner-cloud-api-key
namespace: cloudflare-operator
stringData:
Authorization: Bearer <your-api-token>
Now, create an IP object with the following content:
---
apiVersion: cloudflare-operator.io/v1
kind: IP
metadata:
name: my-instance-v4
spec:
ipSources:
- requestHeaders:
Accept: application/json
requestHeadersSecretRef:
name: hetzner-cloud-api-key
namespace: cloudflare-operator
requestMethod: GET
responseJQFilter: .servers[] | select(.name == "my-instance.example.com").public_net.ipv4.ip
url: https://api.hetzner.cloud/v1/servers
type: dynamic
interval: 5m0s
4 - Fetch IP from a Kubernetes object
If you have a Kubernetes object that contains an IP address, you can use cloudflare-operator to fetch the IP address from the object and use it as the target content for a DNS record.
This can be useful if you are using Istio or want to fetch the IP from a Kubernetes service.
This guide will show you how to configure an IP object to fetch the IP address from a Kubernetes service.
Operator configuration
Add a kubectl sidecar to the operator pod by using the following Helm values:
sidecars:
- name: proxy
image: bitnami/kubectl
args: ["proxy", "--port=8858"]
The operator will need additional permissions to access services.
In order to grant the operator these permissions, add the following Helm values:
clusterRole:
extraRules:
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
Install or update the Helm chart using this guide.
IP object
An IP object could then look like this:
---
apiVersion: cloudflare-operator.io/v1
kind: IP
metadata:
name: ingress-ip
spec:
type: dynamic
ipSources:
- url: localhost:8858/api/v1/namespaces/ingress-nginx/services/ingress-nginx
responseJQFilter: ".status.loadBalancer.ingress[0].ip"
This IP object will fetch the IP address from the Kubernetes service ingress-nginx
in the namespace ingress-nginx
using the kubectl proxy.
5 - Migration to cloudflare-operator
cloudflare-operator is designed to be the single source of truth for DNS records. This means that all records not known to cloudflare-operator will be deleted.
In order to prevent the deletion of the entire DNS zone after you have installed cloudflare-operator, you need to migrate your DNS records to cloudflare-operator.
For that we have created a migration tool that generates DNSRecord objects for all DNS records in your DNS zone.
To export your DNS records, follow this guide.
Then, run the migration tool:
cfop-generator -file <path-to-exported-file>
The migration tool will output the generated DNSRecord objects to the console.
Make sure to verify the generated objects before applying them to your cluster.
kubectl apply -f <path-to-generated-file>