Azure容器实例通过私有端点连接Azure SQL数据库超时排查
ACI通过私有端点连接Azure SQL超时问题排查
问题描述
使用Terraform部署的Azure容器实例(ACI)尝试通过私有端点连接Azure SQL数据库时出现超时,所有资源配置如下:
数据库配置
resource "azurerm_sql_server" "azure_sql_server" { name = "azure-sql-server" resource_group_name = data.azurerm_resource_group.arc_resource_group.name location = data.azurerm_resource_group.arc_resource_group.location administrator_login = var.administrator_login administrator_login_password = var.administrator_login_password version = "12.0" } resource "azurerm_sql_database" "azure_sql_database" { name = "database" server_name = azurerm_sql_server.arc_azure_sql_server.name resource_group_name = data.azurerm_resource_group.arc_resource_group.name location = data.azurerm_resource_group.arc_resource_group.location }
容器实例配置
resource "azurerm_container_group" "nginx_container" { name = "nginx-container-group" resource_group_name = data.azurerm_resource_group.arc_resource_group.name location = data.azurerm_resource_group.arc_resource_group.location ip_address_type = "Private" os_type = "Linux" subnet_ids = [azurerm_subnet.subnet_b.id] container { name = "nginx-container" image = "${var.acr_repository}.azurecr.io/docker_image:latest" cpu = "0.5" memory = "1.5" environment_variables = { "DB_HOST" = format("%s.database.windows.net", azurerm_sql_server.arc_azure_sql_server.name) } ports { port = 80 protocol = "TCP" } } }
虚拟网络配置
data "azurerm_virtual_network" "existing_vnet" { name = "vnet-uks-dev" resource_group_name = data.azurerm_resource_group.arc_resource_group.name } resource "azurerm_subnet" "subnet_a" { name = "sql-sn" resource_group_name = data.azurerm_resource_group.arc_resource_group.name virtual_network_name = data.azurerm_virtual_network.existing_vnet.name address_prefixes = ["10.2.1.0/24"] } resource "azurerm_subnet" "subnet_b" { name = "aci-sn" resource_group_name = data.azurerm_resource_group.arc_resource_group.name virtual_network_name = data.azurerm_virtual_network.existing_vnet.name address_prefixes = ["10.2.2.0/24"] service_endpoints = ["Microsoft.Sql"] delegation { name = "aci" service_delegation { name = "Microsoft.ContainerInstance/containerGroups" actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"] } } } resource "azurerm_subnet" "subnet_c" { name = "private-link-sn" resource_group_name = data.azurerm_resource_group.arc_resource_group.name virtual_network_name = data.azurerm_virtual_network.existing_vnet.name address_prefixes = ["10.2.3.0/24"] }
DNS与私有端点配置
resource "azurerm_private_dns_zone" "sql_private_dns_zone" { name = "privatelink.database.windows.net" resource_group_name = data.azurerm_resource_group.arc_resource_group.name } resource "azurerm_private_dns_zone_virtual_network_link" "vnet_link" { name = "vnet-link-to-private-dns" resource_group_name = data.azurerm_resource_group.arc_resource_group.name private_dns_zone_name = azurerm_private_dns_zone.sql_private_dns_zone.name virtual_network_id = data.azurerm_virtual_network.existing_vnet.id } resource "azurerm_sql_virtual_network_rule" "allow_aci_subnet" { name = "AllowACISubnet" resource_group_name = data.azurerm_resource_group.arc_resource_group.name server_name = azurerm_sql_server.arc_azure_sql_server.name subnet_id = azurerm_subnet.subnet_b.id } resource "azurerm_private_endpoint" "database_private_endpoint" { name = "pe-database" location = data.azurerm_resource_group.arc_resource_group.location resource_group_name = data.azurerm_resource_group.arc_resource_group.name subnet_id = azurerm_subnet.subnet_c.id private_service_connection { name = "psc-sql" private_connection_resource_id = azurerm_sql_server.arc_azure_sql_server.id subresource_names = ["sqlServer"] } private_dns_zone_group { name = "default" private_dns_zone_ids = [azurerm_private_dns_zone.sql_private_dns_zone.id] } }
注:已配置3个专用子网,私有端点和容器实例分别使用独立子网;确认数据库连接字符串正确,SQL服务器域名为azure-sql-server.database.windows.net。
可能的原因
- SQL服务器公共网络访问未禁用:若SQL服务器仍允许公网访问,DNS解析可能优先指向公网IP,但ACI在私有子网无法访问公网,导致超时;同时私有端点的DNS解析规则可能未生效。
- ACI子网服务端点与私有端点冲突:ACI所在的
subnet_b配置了Microsoft.Sql服务端点,会强制SQL流量走服务端点而非私有端点,两者路由逻辑冲突。 - 私有端点子网网络策略限制:私有端点所在的
subnet_c默认可能启用了NSG或路由表策略,阻止了ACI到私有端点的流量。 - DNS解析未验证:虽配置了私有DNS区域和VNet链接,但ACI内部可能未正确将SQL域名解析到私有端点的私有IP。
- 冗余的虚拟网络规则:使用私有端点时,
azurerm_sql_virtual_network_rule属于冗余配置,可能干扰流量路由。
解决步骤
1. 禁用SQL服务器公共网络访问
修改azurerm_sql_server资源,强制所有流量走私有端点:
resource "azurerm_sql_server" "azure_sql_server" { name = "azure-sql-server" resource_group_name = data.azurerm_resource_group.arc_resource_group.name location = data.azurerm_resource_group.arc_resource_group.location administrator_login = var.administrator_login administrator_login_password = var.administrator_login_password version = "12.0" public_network_access_enabled = false # 新增:禁用公网访问 }
2. 移除ACI子网的SQL服务端点
删除subnet_b中的service_endpoints配置,消除与私有端点的冲突:
resource "azurerm_subnet" "subnet_b" { name = "aci-sn" resource_group_name = data.azurerm_resource_group.arc_resource_group.name virtual_network_name = data.azurerm_virtual_network.existing_vnet.name address_prefixes = ["10.2.2.0/24"] # 移除service_endpoints = ["Microsoft.Sql"] delegation { name = "aci" service_delegation { name = "Microsoft.ContainerInstance/containerGroups" actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"] } } }
3. 禁用私有端点子网的网络策略
修改subnet_c,确保私有端点流量不受NSG和路由表限制:
resource "azurerm_subnet" "subnet_c" { name = "private-link-sn" resource_group_name = data.azurerm_resource_group.arc_resource_group.name virtual_network_name = data.azurerm_virtual_network.existing_vnet.name address_prefixes = ["10.2.3.0/24"] private_endpoint_network_policies_enabled = false # 新增:禁用私有端点子网网络策略 }
4. 验证DNS解析
进入ACI容器执行以下命令,确认解析结果为私有端点的私有IP(10.2.3.x段):
nslookup azure-sql-server.database.windows.net
若解析失败,检查私有DNS区域与VNet的链接是否生效,确保自动关联的DNS记录已生成。
5. 移除冗余的SQL虚拟网络规则
使用私有端点时无需配置虚拟网络规则,直接删除该资源:
# 删除以下资源 # resource "azurerm_sql_virtual_network_rule" "allow_aci_subnet" { # name = "AllowACISubnet" # resource_group_name = data.azurerm_resource_group.arc_resource_group.name # server_name = azurerm_sql_server.arc_azure_sql_server.name # subnet_id = azurerm_subnet.subnet_b.id # }
内容的提问来源于stack exchange,提问作者RAH
相关产品推荐
相关产品推荐

