为静态容器实例分配静态出站IP地址

时间:2020-05-26 08:51:53

标签: azure-resource-manager azure-container-instances vnet azure-public-ip

我需要进行设置,以便可以从驻留在azure容器实例中的python脚本读取和写入外部sql db。为了完成这项工作,我需要为容器分配一个静态IP。

由于我无法将容器实例与专用ip关联,因此必须进行设置以使用以下资源:vnet,网关和公共IP。

我从https://godatadriven.com/blog/azure-container-instance-example/中部分借鉴了设置,其绘制方式如下:

enter image description here

我已经建立了一个dev-ops构建和发布管道。我使用ARM模板创建发行版(模板的资源如下):

  "resources": [
    {
      "type": "Microsoft.Network/virtualNetworks",
      "name": "[parameters('vnetName')]",
      "apiVersion": "2019-07-01",
      "location": "[parameters('location')]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[parameters('vnetAddressPrefix')]"
          ]
        },
        "subnets": [
          {
            "name": "[parameters('subnet2Name')]",
            "properties": {
              "addressPrefix": "[parameters('subnet2AddressPrefix')]",
              "privateEndpointNetworkPolicies": "Enabled",
              "privateLinkServiceNetworkPolicies": "Enabled"
            }
          },
          {
            "name": "[parameters('subnetName')]",
            "properties": {
              "addressPrefix": "[parameters('subnetAddressPrefix')]",
              "delegations": [
                {
                  "name": "DelegationService",
                  "properties": {
                    "serviceName": "Microsoft.ContainerInstance/containerGroups"
                  }
                }
              ],
              "privateEndpointNetworkPolicies": "Enabled",
              "privateLinkServiceNetworkPolicies": "Enabled"
            }
          }
        ]
      }
    },
    {
      "apiVersion": "2018-07-01",
      "type": "Microsoft.Network/publicIPAddresses",
      "name": "[variables('publicIPAddressName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard",
        "tier": "Regional"
      },
      "properties": {
        "publicIPAddressVersion": "IPv4",
        "publicIPAllocationMethod": "Static",
        "idleTimeoutInMinutes": 4,
         "dnsSettings": {
          "domainNameLabel": "[parameters('dnsName')]"
        }
      }
    },
    {
      "apiVersion": "2019-08-01",
      "name": "[variables('applicationGatewayName')]",
      "type": "Microsoft.Network/applicationGateways",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks/', parameters('vnetName'))]",
        "[resourceId('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
        "[resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containerInstanceName'))]"
      ],
      "properties": {
        "sku": {
          "name": "[parameters('skuName')]",
          "tier": "Standard_v2",
          "capacity": "[variables('capacity')]"
        },
        "gatewayIPConfigurations": [
          {
            "name": "appGatewayIpConfig",
            "properties": {
              "subnet": {
                "id": "[variables('subnetRef')]"
              }
            }
          }
        ],
        "frontendIPConfigurations": [
          {
            "name": "appGatewayFrontendIP",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "PublicIPAddress": {
                "id": "[variables('publicIPRef')]"
              }
            }
          }
        ],
        "frontendPorts": [
          {
            "name": "appGatewayFrontendPort",
            "properties": {
              "Port": 80
            }
          }
        ],
        "backendAddressPools": [
          {
            "name": "appGatewayBackendPool",
            "properties": {
              "backendAddresses": [
                {
                  "IpAddress": "[parameters('backendIP')]"
                }
              ]
            }
          }
        ],
        "backendHttpSettingsCollection": [
          {
            "name": "appGatewayBackendHttpSettings",
            "properties": {
              "Port": 80,
              "Protocol": "Http",
              "CookieBasedAffinity": "Disabled"
            }
          }
        ],
        "httpListeners": [
          {
            "name": "appGatewayHttpListener",
            "properties": {
              "FrontendIPConfiguration": {
                "Id": "[resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', variables('applicationGatewayName'), 'appGatewayFrontendIP')]"
              },
              "FrontendPort": {
                "Id": "[resourceId('Microsoft.Network/applicationGateways/frontendPorts', variables('applicationGatewayName'), 'appGatewayFrontendPort')]"
              },
              "Protocol": "Http",
              "SslCertificate": null
            }
          }
        ],
        "requestRoutingRules": [
          {
            "Name": "rule1",
            "properties": {
              "RuleType": "Basic",
              "httpListener": {
                "id": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('applicationGatewayName'), 'appGatewayHttpListener')]"
              },
              "backendAddressPool": {
                "id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGatewayName'), 'appGatewayBackendPool')]"
              },
              "backendHttpSettings": {
                "id": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', variables('applicationGatewayName'), 'appGatewayBackendHttpSettings')]"
              }
            }
          }
        ]
      }
    },
    {
      "name": "[parameters('networkProfileName')]",
      "type": "Microsoft.Network/networkProfiles",
      "apiVersion": "2018-07-01",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"
      ],
      "properties": {
        "containerNetworkInterfaceConfigurations": [
          {
            "name": "[variables('interfaceConfigName')]",
            "properties": {
              "ipConfigurations": [
                {
                  "name": "[variables('interfaceIpConfig')]",
                  "properties": {
                    "subnet": {
                      "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]"
                    }
                  }
                }
              ]
            }
          }
        ]
      }
    },
    {
      "name": "[parameters('containerInstanceName')]",
      "type": "Microsoft.ContainerInstance/containerGroups",
      "apiVersion": "2018-10-01",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkProfiles', parameters('networkProfileName'))]"
      ],
      "properties": {
        "containers": [
          {
            "name": "[parameters('containerName')]",
            "properties": {
              "image": "[parameters('registryImageUri')]",
              "ports": [{
                "port": "[variables('port')]"
              }],
              "resources": {
                "requests": {
                  "cpu": "[variables('cpuCores')]",
                  "memoryInGb": "[variables('memoryInGb')]"
                }
              }
            }
          }
        ],
        "imageRegistryCredentials": [
          {
            "server": "[parameters('registryLoginServer')]",
            "username": "[parameters('registryUserName')]",
            "password": "[parameters('registryPassword')]"
          }
        ],
        "diagnostics": {
          "logAnalytics": {
          "workspaceId": "[parameters('LogAnalyticsID')]",
          "workspaceKey": "[parameters('LogAnalyticsKEY')]"
         }
        },
        "networkProfile": {
          "Id": "[resourceId('Microsoft.Network/networkProfiles', parameters('networkProfileName'))]"
        },
        "osType": "Linux",
        "ipAddress": {
            "ports": [{
                "protocol": "tcp",
                "port": 80
            }],
            "type": "private",
            "ip": "[parameters('backendIP')]"
        },
        "restartPolicy": "[parameters('restartPolicy')]"
      }
    }
  ]

该版本有效,但是当我运行时,我尝试运行容器实例,每次都使用不同的ip。

我在做什么错了?

2 个答案:

答案 0 :(得分:1)

从您所做的事情来看,我认为您误解了Azure容器实例的网络。 ACI的“公用”或“专用”类型仅适用于入站流量,不适用于出站流量。即使使用私有类型,实例也可以在没有任何其他资源的情况下访问Internet,但是在这种类型下,您将无法从Internet访问它。

不幸的是,当您使用公共类型时,入站和出站的公共IP地址可能甚至都不相同。对于Azure容器实例,我们无法控制可以使用的IP地址。因此,当您要使用静态公共IP地址访问SQL DB时,Azure容器实例不合适,我建议您使用VM,它更可控且更合适。

答案 1 :(得分:1)

由于您使用的是Azure提供的SQL,因此我建议您利用Azure提供的私有VNET产品。

您应该查看使用专用子网配置ACI https://docs.microsoft.com/en-us/azure/container-instances/container-instances-vnet

并为您的SQL服务器设置vnet规则

https://docs.microsoft.com/en-us/azure/sql-database/sql-database-vnet-service-endpoint-rule-overview

Virtual network rules are one firewall security feature that controls whether the database server for your single databases and elastic pool in Azure SQL Database or for your databases in Azure Synapse Analytics accepts communications that are sent from particular subnets in virtual networks.

同样重要的是,还要在ACI子网中为SQL启用SQL服务终结点。

这将避免您必须在SQL防火墙中管理出站IP白名单。