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

Azure容器应用(Terraform部署):platform_reserved_dns_ip_address为空,NGINX动态代理失败

问题描述

在Azure容器应用(ACA)环境中部署NGINX作为反向代理,因需要动态代理转发,必须在NGINX配置中显式设置resolver(DNS IP地址)。此前使用消费计划时,硬编码解析器地址10.0.0.2可正常工作,但切换到专用工作负载配置后,该地址失效,且DNS地址会随环境创建动态变化。

尝试通过Terraform利用应用环境的platform_reserved_dns_ip_address动态修改配置文件,但该值为空,无法通过验证。已按照Terraform文档配置infrastructure_subnet_id,但问题依旧存在,且应用环境的JSON视图显示"platformReservedDnsIP": null。

需要解决的问题:如何获取专用工作负载配置下的解析器IP,或通过其他方式在ACA环境中实现NGINX动态代理?


相关代码片段

Terraform 代码片段

# 不同模块中的Terraform代码片段

resource "azurerm_container_app_environment" "main" {
  name                           = "foo"
  location                       = var.location
  resource_group_name            = var.resource_group_name
  log_analytics_workspace_id     = azurerm_log_analytics_workspace.main.id
  infrastructure_subnet_id       = azurerm_subnet.containerEnv.id
  internal_load_balancer_enabled = var.ingress_vnet_only

  # 仅在专用工作负载配置下出现问题,消费计划无此问题
  workload_profile {
    name                  = local.workload_profile.name
    workload_profile_type = local.workload_profile.workload_profile_type
    minimum_count         = local.workload_profile.minimum_count
    maximum_count         = local.workload_profile.maximum_count
  }
}

# 输出应用环境的DNS IP
output "dns_ip_address" {
  value = azurerm_container_app_environment.main.platform_reserved_dns_ip_address
}

# NGINX模块的输入变量
variable "dns_ip_address" {
  description = "DNS服务器的IP地址"
  type        = string

  validation {
    condition     = length(var.dns_ip_address) > 0
    error_message = "dns_ip_address不能为空"
  }
}

# 动态生成NGINX配置文件
resource "local_file" "nginx_config" {
  content = templatefile("${path.module}/config/nginx-template.conf", {
    dns_ip_address = var.dns_ip_address
  })
  filename = "${path.module}/auto-generated/nginx.conf"
}

NGINX 配置片段

resolver ${dns_ip_address}; 
server {
    listen 80;
    server_name ~^(.*)\.foo\.bar$;

    location / {
        set $upstream_url http://$dynamic_address;

        proxy_pass $upstream_url;
        proxy_http_version 1.1;
    }
}

可行解决方案

方案1:使用Azure VNet内置DNS服务器地址

在专用工作负载配置的ACA环境中,若使用自定义VNet,可直接使用VNet的内置DNS服务器地址:

  • 对于Azure默认VNet,DNS服务器地址为VNet地址空间的第2个IP(例如VNet地址段为10.0.0.0/16,则DNS地址为10.0.0.2);若配置了自定义DNS,则需使用对应的自定义DNS地址。
  • 可通过Terraform获取VNet的DNS服务器配置,示例代码:
data "azurerm_virtual_network" "main" {
  name                = "your-vnet-name"
  resource_group_name = var.resource_group_name
}

output "vnet_dns_servers" {
  value = data.azurerm_virtual_network.main.dns_servers
}

将获取到的DNS地址传入NGINX配置即可。

方案2:跳过显式resolver配置(NGINX 1.1.9+)

从NGINX 1.1.9版本开始,若未显式指定resolver,NGINX会自动使用系统默认的DNS服务器。在ACA容器中,系统默认DNS已配置为环境的专用DNS服务器,因此可以移除resolver配置,直接使用动态变量进行代理转发。

修改后的NGINX配置示例:

server {
    listen 80;
    server_name ~^(.*)\.foo\.bar$;

    location / {
        set $upstream_url http://$dynamic_address;

        proxy_pass $upstream_url;
        proxy_http_version 1.1;
    }
}

此方法无需依赖外部DNS IP,直接利用容器内的系统DNS配置,适配ACA环境的动态DNS变化。

方案3:通过容器内部动态获取DNS地址

可在容器启动时,读取/etc/resolv.conf文件动态获取DNS地址,再生成NGINX配置。例如,在容器启动脚本中添加以下逻辑:

# 获取DNS地址
DNS_IP=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
# 替换NGINX配置中的占位符
sed -i "s/\${dns_ip_address}/$DNS_IP/g" /etc/nginx/nginx.conf
# 启动NGINX
nginx -g 'daemon off;'

此方法无需依赖Terraform传递参数,完全在容器内部动态获取DNS地址,适配各种ACA环境配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 01:16:10