cloudflare-dns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCloudflare DNS Skill
Cloudflare DNS Skill
Complete Cloudflare DNS operations via REST API with focus on Azure integration.
通过REST API完成Cloudflare DNS操作,重点关注与Azure的集成。
Overview
概述
This skill covers Cloudflare DNS management for Azure-hosted workloads, including:
- API token configuration and security
- DNS record management (A, AAAA, CNAME, TXT, MX)
- Proxy settings (orange/gray cloud)
- External-DNS integration for Kubernetes
- Troubleshooting and monitoring
本技能涵盖针对Azure托管工作负载的Cloudflare DNS管理,包括:
- API令牌配置与安全
- DNS记录管理(A、AAAA、CNAME、TXT、MX)
- 代理设置(橙色/灰色云)
- 与Kubernetes的External-DNS集成
- 故障排查与监控
Authentication
身份验证
API Token (Recommended)
API令牌(推荐)
Create scoped API tokens instead of using Global API Key:
Required Permissions:
| Permission | Access | Purpose |
|---|---|---|
| Zone > Zone | Read | List zones |
| Zone > DNS | Edit | Manage DNS records |
Create Token:
- Cloudflare Dashboard > My Profile > API Tokens
- Create Token > Custom token
- Add permissions above
- Zone Resources: Specific zones only
- (Optional) IP filtering for extra security
Environment Setup:
bash
undefined创建限定范围的API令牌,而非使用全局API密钥:
所需权限:
| 权限 | 访问权限 | 用途 |
|---|---|---|
| Zone > Zone | 读取 | 列出区域 |
| Zone > DNS | 编辑 | 管理DNS记录 |
创建令牌:
- Cloudflare控制台 > 我的资料 > API令牌
- 创建令牌 > 自定义令牌
- 添加上述权限
- 区域资源:仅特定区域
- (可选)IP过滤以提升安全性
环境设置:
bash
undefinedExport for API calls
Export for API calls
export CF_API_TOKEN="your-api-token"
export CF_ZONE_ID="your-zone-id"
export CF_API_TOKEN="your-api-token"
export CF_ZONE_ID="your-zone-id"
Get zone ID
Get zone ID
curl -s -X GET "https://api.cloudflare.com/client/v4/zones"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, id}'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, id}'
undefinedcurl -s -X GET "https://api.cloudflare.com/client/v4/zones"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, id}'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, id}'
undefinedToken Verification
令牌验证
bash
undefinedbash
undefinedVerify token is valid
Verify token is valid
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Authorization: Bearer $CF_API_TOKEN"
undefinedcurl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Authorization: Bearer $CF_API_TOKEN"
undefinedQuick Reference
快速参考
List DNS Records
列出DNS记录
bash
undefinedbash
undefinedAll records
All records
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, type, content, proxied}'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, type, content, proxied}'
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, type, content, proxied}'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, type, content, proxied}'
Filter by type
Filter by type
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?type=A"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[]'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[]'
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?type=A"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[]'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[]'
Search by name
Search by name
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?name=app.example.com"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[]'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[]'
undefinedcurl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?name=app.example.com"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[]'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[]'
undefinedCreate DNS Records
创建DNS记录
bash
undefinedbash
undefinedA Record (proxied)
A Record (proxied)
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "app", "content": "20.185.100.50", "ttl": 1, "proxied": true }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "app", "content": "20.185.100.50", "ttl": 1, "proxied": true }'
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "app", "content": "20.185.100.50", "ttl": 1, "proxied": true }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "app", "content": "20.185.100.50", "ttl": 1, "proxied": true }'
A Record (DNS-only)
A Record (DNS-only)
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "mail", "content": "20.185.100.51", "ttl": 3600, "proxied": false }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "mail", "content": "20.185.100.51", "ttl": 3600, "proxied": false }'
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "mail", "content": "20.185.100.51", "ttl": 3600, "proxied": false }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "mail", "content": "20.185.100.51", "ttl": 3600, "proxied": false }'
CNAME Record
CNAME Record
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "CNAME", "name": "www", "content": "app.example.com", "ttl": 1, "proxied": true }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "CNAME", "name": "www", "content": "app.example.com", "ttl": 1, "proxied": true }'
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "CNAME", "name": "www", "content": "app.example.com", "ttl": 1, "proxied": true }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "CNAME", "name": "www", "content": "app.example.com", "ttl": 1, "proxied": true }'
TXT Record
TXT Record
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "TXT", "name": "_dmarc", "content": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com", "ttl": 3600 }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "TXT", "name": "_dmarc", "content": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com", "ttl": 3600 }'
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "TXT", "name": "_dmarc", "content": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com", "ttl": 3600 }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "TXT", "name": "_dmarc", "content": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com", "ttl": 3600 }'
MX Record
MX Record
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "MX", "name": "@", "content": "mail.example.com", "priority": 10, "ttl": 3600 }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "MX", "name": "@", "content": "mail.example.com", "priority": 10, "ttl": 3600 }'
undefinedcurl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "MX", "name": "@", "content": "mail.example.com", "priority": 10, "ttl": 3600 }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "MX", "name": "@", "content": "mail.example.com", "priority": 10, "ttl": 3600 }'
undefinedUpdate DNS Records
更新DNS记录
bash
undefinedbash
undefinedGet record ID first
Get record ID first
RECORD_ID=$(curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?name=app.example.com&type=A"
-H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')
-H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')
RECORD_ID=$(curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?name=app.example.com&type=A"
-H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')
-H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')
Update record
Update record
curl -X PUT "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "app", "content": "20.185.100.60", "ttl": 1, "proxied": true }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "app", "content": "20.185.100.60", "ttl": 1, "proxied": true }'
curl -X PUT "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "app", "content": "20.185.100.60", "ttl": 1, "proxied": true }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "type": "A", "name": "app", "content": "20.185.100.60", "ttl": 1, "proxied": true }'
Patch (partial update)
Patch (partial update)
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": false}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": false}'
undefinedcurl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": false}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": false}'
undefinedDelete DNS Records
删除DNS记录
bash
undefinedbash
undefinedGet record ID
Get record ID
RECORD_ID=$(curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?name=old.example.com"
-H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')
-H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')
RECORD_ID=$(curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?name=old.example.com"
-H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')
-H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')
Delete
Delete
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Authorization: Bearer $CF_API_TOKEN"
undefinedcurl -X DELETE "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Authorization: Bearer $CF_API_TOKEN"
undefinedProxy Settings (Orange/Gray Cloud)
代理设置(橙色/灰色云)
When to Enable Proxy (Orange Cloud)
何时启用代理(橙色云)
| Use Case | Proxy | Reason |
|---|---|---|
| Web applications | Yes | CDN, DDoS protection |
| REST APIs | Yes | Performance, security |
| Static websites | Yes | Caching, optimization |
| WebSockets | Yes | Supported with config |
| 使用场景 | 代理状态 | 原因 |
|---|---|---|
| Web应用 | 是 | CDN、DDoS防护 |
| REST API | 是 | 性能优化、安全防护 |
| 静态网站 | 是 | 缓存、性能优化 |
| WebSockets | 是 | 支持配置 |
When to Disable Proxy (Gray Cloud)
何时禁用代理(灰色云)
| Use Case | Proxy | Reason |
|---|---|---|
| Mail servers (MX) | No | SMTP not supported |
| SSH access | No | Non-HTTP protocol |
| FTP servers | No | Non-HTTP protocol |
| Custom TCP/UDP | No | Only HTTP/HTTPS proxied |
| VPN endpoints | No | Direct connection needed |
| 使用场景 | 代理状态 | 原因 |
|---|---|---|
| 邮件服务器(MX) | 否 | 不支持SMTP |
| SSH访问 | 否 | 非HTTP协议 |
| FTP服务器 | 否 | 非HTTP协议 |
| 自定义TCP/UDP | 否 | 仅代理HTTP/HTTPS |
| VPN端点 | 否 | 需要直接连接 |
Toggle Proxy via API
通过API切换代理状态
bash
undefinedbash
undefinedEnable proxy
Enable proxy
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": true}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": true}'
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": true}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": true}'
Disable proxy
Disable proxy
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": false}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": false}'
undefinedcurl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$RECORD_ID"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": false}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"proxied": false}'
undefinedExternal-DNS Integration
External-DNS集成
Kubernetes Secret
Kubernetes Secret
bash
kubectl create namespace external-dns
kubectl create secret generic cloudflare-api-token \
--namespace external-dns \
--from-literal=cloudflare_api_token="$CF_API_TOKEN"bash
kubectl create namespace external-dns
kubectl create secret generic cloudflare-api-token \
--namespace external-dns \
--from-literal=cloudflare_api_token="$CF_API_TOKEN"Helm Values (kubernetes-sigs/external-dns)
Helm Values (kubernetes-sigs/external-dns)
yaml
fullnameOverride: external-dns
provider:
name: cloudflare
env:
- name: CF_API_TOKEN
valueFrom:
secretKeyRef:
name: cloudflare-api-token
key: cloudflare_api_token
extraArgs:
cloudflare-proxied: true
cloudflare-dns-records-per-page: 5000
sources:
- service
- ingress
domainFilters:
- example.com
txtOwnerId: "aks-cluster-name" # MUST be unique per cluster
txtPrefix: "_externaldns."
policy: upsert-only # Production: NEVER use sync
interval: "5m"
logLevel: info
logFormat: json
resources:
requests:
memory: "64Mi"
cpu: "25m"
limits:
memory: "128Mi"
serviceMonitor:
enabled: true
interval: 30syaml
fullnameOverride: external-dns
provider:
name: cloudflare
env:
- name: CF_API_TOKEN
valueFrom:
secretKeyRef:
name: cloudflare-api-token
key: cloudflare_api_token
extraArgs:
cloudflare-proxied: true
cloudflare-dns-records-per-page: 5000
sources:
- service
- ingress
domainFilters:
- example.com
txtOwnerId: "aks-cluster-name" # MUST be unique per cluster
txtPrefix: "_externaldns."
policy: upsert-only # Production: NEVER use sync
interval: "5m"
logLevel: info
logFormat: json
resources:
requests:
memory: "64Mi"
cpu: "25m"
limits:
memory: "128Mi"
serviceMonitor:
enabled: true
interval: 30sIngress Annotations
Ingress注解
yaml
metadata:
annotations:
# Hostname for External-DNS
external-dns.alpha.kubernetes.io/hostname: "app.example.com"
# Custom TTL
external-dns.alpha.kubernetes.io/ttl: "300"
# Override proxy setting
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
# Multiple hostnames
external-dns.alpha.kubernetes.io/hostname: "app.example.com,www.example.com"yaml
metadata:
annotations:
# Hostname for External-DNS
external-dns.alpha.kubernetes.io/hostname: "app.example.com"
# Custom TTL
external-dns.alpha.kubernetes.io/ttl: "300"
# Override proxy setting
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
# Multiple hostnames
external-dns.alpha.kubernetes.io/hostname: "app.example.com,www.example.com"Zone Management
区域管理
List Zones
列出区域
bash
curl -s "https://api.cloudflare.com/client/v4/zones" \
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, id, status, plan: .plan.name}'bash
curl -s "https://api.cloudflare.com/client/v4/zones" \
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, id, status, plan: .plan.name}'Get Zone Details
获取区域详情
bash
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result'bash
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result'Zone Settings
区域设置
bash
undefinedbash
undefinedGet all settings
Get all settings
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {id, value}'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {id, value}'
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {id, value}'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {id, value}'
Get specific setting
Get specific setting
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/ssl"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result'
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/ssl"
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result'
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result'
Update SSL mode
Update SSL mode
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/ssl"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"value": "full"}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"value": "full"}'
undefinedcurl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/ssl"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"value": "full"}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"value": "full"}'
undefinedExport/Import DNS Records
导出/导入DNS记录
Export (BIND Format)
导出(BIND格式)
bash
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/export" \
-H "Authorization: Bearer $CF_API_TOKEN" > dns-backup-$(date +%Y%m%d).txtbash
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/export" \
-H "Authorization: Bearer $CF_API_TOKEN" > dns-backup-$(date +%Y%m%d).txtImport (BIND Format)
导入(BIND格式)
bash
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/import" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-F "file=@dns-backup.txt"bash
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/import" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-F "file=@dns-backup.txt"Troubleshooting
故障排查
DNS Verification
DNS验证
bash
undefinedbash
undefinedQuery Cloudflare DNS (1.1.1.1)
Query Cloudflare DNS (1.1.1.1)
dig @1.1.1.1 app.example.com A
dig @1.1.1.1 app.example.com AAAA
dig @1.1.1.1 app.example.com A
dig @1.1.1.1 app.example.com AAAA
Check if proxied (returns Cloudflare IP)
Check if proxied (returns Cloudflare IP)
dig +short app.example.com
dig +short app.example.com
Proxied: 104.x.x.x or 172.64.x.x
Proxied: 104.x.x.x or 172.64.x.x
DNS-only: Your actual IP
DNS-only: Your actual IP
Check TXT records (External-DNS ownership)
Check TXT records (External-DNS ownership)
dig @1.1.1.1 TXT _externaldns.app.example.com
dig @1.1.1.1 TXT _externaldns.app.example.com
Full trace
Full trace
dig +trace app.example.com
dig +trace app.example.com
Check nameservers
Check nameservers
dig NS example.com +short
undefineddig NS example.com +short
undefinedCommon Errors
常见错误
| Error | Cause | Solution |
|---|---|---|
| 401 Unauthorized | Invalid token | Regenerate API token |
| 403 Forbidden | Insufficient permissions | Add Zone:Read, DNS:Edit |
| 429 Rate Limited | Too many requests | Increase interval, use pagination |
| Record exists | Duplicate | Delete or update existing record |
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 401 Unauthorized | 令牌无效 | 重新生成API令牌 |
| 403 Forbidden | 权限不足 | 添加Zone:读取、DNS:编辑权限 |
| 429 Rate Limited | 请求过于频繁 | 增加请求间隔、使用分页 |
| Record exists | 重复记录 | 删除或更新现有记录 |
External-DNS Logs
External-DNS日志
bash
undefinedbash
undefinedWatch logs
Watch logs
kubectl logs -n external-dns deployment/external-dns -f
kubectl logs -n external-dns deployment/external-dns -f
Check for Cloudflare errors
Check for Cloudflare errors
kubectl logs -n external-dns deployment/external-dns | grep -i cloudflare
kubectl logs -n external-dns deployment/external-dns | grep -i cloudflare
Check sync status
Check sync status
kubectl logs -n external-dns deployment/external-dns | grep -i "All records are already up to date"
undefinedkubectl logs -n external-dns deployment/external-dns | grep -i "All records are already up to date"
undefinedSecurity Best Practices
安全最佳实践
API Token Security
API令牌安全
- Scope tokens - Use specific zones, not "All zones"
- IP filtering - Restrict to known IPs when possible
- Rotate regularly - Every 90 days for production
- Store securely - Kubernetes Secrets or Azure Key Vault
- Audit usage - Check Cloudflare audit logs
- 限定令牌范围 - 使用特定区域,而非“所有区域”
- IP过滤 - 尽可能限制为已知IP
- 定期轮换 - 生产环境每90天轮换一次
- 安全存储 - 使用Kubernetes Secrets或Azure Key Vault
- 审计使用情况 - 查看Cloudflare审计日志
Token Rotation
令牌轮换
bash
undefinedbash
undefined1. Create new token in Cloudflare dashboard
1. Create new token in Cloudflare dashboard
2. Update Kubernetes secret
2. Update Kubernetes secret
kubectl create secret generic cloudflare-api-token
--namespace external-dns
--from-literal=cloudflare_api_token="NEW_TOKEN"
--dry-run=client -o yaml | kubectl apply -f -
--namespace external-dns
--from-literal=cloudflare_api_token="NEW_TOKEN"
--dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic cloudflare-api-token
--namespace external-dns
--from-literal=cloudflare_api_token="NEW_TOKEN"
--dry-run=client -o yaml | kubectl apply -f -
--namespace external-dns
--from-literal=cloudflare_api_token="NEW_TOKEN"
--dry-run=client -o yaml | kubectl apply -f -
3. Restart External-DNS
3. Restart External-DNS
kubectl rollout restart deployment external-dns -n external-dns
kubectl rollout restart deployment external-dns -n external-dns
4. Verify
4. Verify
kubectl logs -n external-dns deployment/external-dns | head -20
kubectl logs -n external-dns deployment/external-dns | head -20
5. Revoke old token in Cloudflare dashboard
5. Revoke old token in Cloudflare dashboard
undefinedundefinedRate Limits
速率限制
Cloudflare API Limits:
- 1,200 requests per 5 minutes (per account)
- 100 requests per 5 minutes (per zone, for some endpoints)
Mitigation:
yaml
undefinedCloudflare API限制:
- 每5分钟1200次请求(每个账户)
- 每5分钟100次请求(部分端点,每个区域)
缓解措施:
yaml
undefinedExternal-DNS optimizations
External-DNS optimizations
extraArgs:
cloudflare-dns-records-per-page: 5000 # Max pagination
zone-id-filter: "specific-zone-id" # Reduce API calls
interval: "10m" # Less frequent polling
undefinedextraArgs:
cloudflare-dns-records-per-page: 5000 # Max pagination
zone-id-filter: "specific-zone-id" # Reduce API calls
interval: "10m" # Less frequent polling
undefinedAzure Integration
Azure集成
cert-manager with Cloudflare DNS-01
cert-manager与Cloudflare DNS-01
yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cloudflare
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-cloudflare-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
selector:
dnsZones:
- example.comyaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cloudflare
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-cloudflare-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
selector:
dnsZones:
- example.comAKS Ingress Configuration
AKS Ingress配置
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
annotations:
cert-manager.io/cluster-issuer: letsencrypt-cloudflare
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
annotations:
cert-manager.io/cluster-issuer: letsencrypt-cloudflare
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80References
参考资料
- - Complete Cloudflare DNS API documentation
references/api-reference.md - - Azure-specific patterns and configurations
references/azure-integration.md - - Helper script for common operations
scripts/cloudflare-dns.sh - Cloudflare API Documentation
- External-DNS Cloudflare Tutorial
- - 完整的Cloudflare DNS API文档
references/api-reference.md - - Azure特定模式与配置
references/azure-integration.md - - 常用操作辅助脚本
scripts/cloudflare-dns.sh - Cloudflare API文档
- External-DNS Cloudflare教程