You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将PowerDNS服务器配置为Docker的后端DNS并实现容器IP信息自动同步?

Absolutely, you can automate syncing Docker container IPs to PowerDNS—here are a few practical, battle-tested approaches that fit your setup:

方法1:自定义Docker事件监听脚本

Docker emits real-time events whenever containers start, stop, or have their network settings updated. You can build a simple script to listen for these events, pull container IPs and service names, then push updates to PowerDNS via its API.

步骤:

  1. 编写监听脚本(以Python为例,利用Docker SDK和requests):
    This script tracks container events for your office-net network, extracts service names/labels and IPs, then creates/updates/deletes A records in PowerDNS.

    import docker
    import requests
    import time
    
    # Configure your PowerDNS details
    PDNS_API_URL = "http://your-pdns-server:8081/api/v1/servers/localhost/zones/domain."
    PDNS_API_KEY = "your-pdns-api-key-here"
    TARGET_NETWORK = "office-net"
    DOMAIN_SUFFIX = "domain"
    
    # Initialize Docker client
    client = docker.from_env()
    
    def update_pdns_record(hostname, ip):
        headers = {"X-API-Key": PDNS_API_KEY}
        record_name = f"{hostname}.{DOMAIN_SUFFIX}."
        
        # Check if record already exists
        check_url = f"{PDNS_API_URL}records/{hostname}.{DOMAIN_SUFFIX}/A"
        response = requests.get(check_url, headers=headers)
        
        if response.status_code == 200:
            # Update existing record
            payload = {
                "rrsets": [{
                    "name": record_name,
                    "type": "A",
                    "ttl": 300,
                    "records": [{"content": ip, "disabled": False}]
                }]
            }
            requests.patch(PDNS_API_URL, json=payload, headers=headers)
        else:
            # Create new record
            payload = {
                "rrsets": [{
                    "name": record_name,
                    "type": "A",
                    "ttl": 300,
                    "changetype": "REPLACE",
                    "records": [{"content": ip, "disabled": False}]
                }]
            }
            requests.post(PDNS_API_URL, json=payload, headers=headers)
    
    def delete_pdns_record(hostname):
        headers = {"X-API-Key": PDNS_API_KEY}
        record_name = f"{hostname}.{DOMAIN_SUFFIX}."
        payload = {
            "rrsets": [{
                "name": record_name,
                "type": "A",
                "changetype": "DELETE"
            }]
        }
        requests.patch(PDNS_API_URL, json=payload, headers=headers)
    
    if __name__ == "__main__":
        print("Listening for Docker container events...")
        for event in client.events(decode=True):
            if event["Type"] == "container":
                try:
                    container = client.containers.get(event["Actor"]["ID"])
                    # Skip if container isn't in your target network
                    if TARGET_NETWORK not in container.attrs["NetworkSettings"]["Networks"]:
                        continue
                    
                    # Get service name (prioritize Compose service label first)
                    service_name = container.labels.get("com.docker.compose.service") or container.name
                    container_ip = container.attrs["NetworkSettings"]["Networks"][TARGET_NETWORK]["IPAddress"]
                    
                    if event["Action"] in ["start", "update"]:
                        print(f"Updating DNS: {service_name}.{DOMAIN_SUFFIX} -> {container_ip}")
                        update_pdns_record(service_name, container_ip)
                    elif event["Action"] == "stop":
                        print(f"Removing DNS record: {service_name}.{DOMAIN_SUFFIX}")
                        delete_pdns_record(service_name)
                except Exception as e:
                    print(f"Error processing event: {str(e)}")
            time.sleep(0.5)
    
  2. 运行脚本:

    • Install dependencies: pip install docker requests
    • Run it as a systemd service or wrap it in a Docker container to ensure it runs continuously.
方法2:使用External-DNS工具(专为DNS同步设计)

External-DNS is a mature tool that automates DNS record management for containerized services. It supports PowerDNS as a backend and can listen directly to Docker events to sync records automatically.

步骤:

  1. Deploy External-DNS as a Docker container:
    Use this command to start External-DNS, configured to watch your Docker containers and sync to PowerDNS:

    docker run -d \
      --name external-dns \
      --restart=always \
      --volume /var/run/docker.sock:/var/run/docker.sock \
      k8s.gcr.io/external-dns/external-dns:v0.13.4 \
      --provider=powerdns \
      --pdns-server=http://your-pdns-server:8081 \
      --pdns-api-key=your-pdns-api-key-here \
      --source=docker \
      --domain-filter=domain \
      --policy=sync \
      --log-level=info
    
  2. Tag your Docker Compose services:
    Add labels to each service in your docker-compose.yml to specify the hostname you want in PowerDNS:

    services:
      gitlab:
        image: gitlab/gitlab-ce
        networks:
          - office-net
        labels:
          - "external-dns.alpha.kubernetes.io/hostname=gitlab.domain"
          - "external-dns.alpha.kubernetes.io/ttl=300"
      mail:
        image: your-mail-image
        networks:
          - office-net
        labels:
          - "external-dns.alpha.kubernetes.io/hostname=mail.domain"
          - "external-dns.alpha.kubernetes.io/ttl=300"
    

    When you start these services, External-DNS will automatically create/update A records for gitlab.domain and mail.domain with their respective container IPs.

关键注意事项
  • PowerDNS API Setup: Make sure your PowerDNS server has its API enabled (check api=yes in pdns.conf) and that you've set a secure API key.
  • TTL Configuration: Use a short TTL (like 300 seconds) so DNS caches update quickly when container IPs change.
  • Network Filtering: Both approaches let you target specific networks (like office-net) to avoid syncing containers from other networks accidentally.
  • Testing: After setting up, start a test container, check PowerDNS for the new A record, then stop the container to verify the record is removed or marked for deletion.

内容的提问来源于stack exchange,提问作者Eugen Konkov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 13:27:42