Задача — поднять реверс-прокси на NGINX, который будет проксировать данные к WebApp в Azure.
NGINX будет работать на виртуальной машине.
Содержание
Создание VM
Используем Azure CLI для создания машины.
Логинимся:
$ azure login
Проверяем режим Azure CLI — нужен arm
(Resource Manager mode):
$ azure config list | grep arm data: mode arm
Если сейчас CLI находится в режиме Service Management mode — переключиться можно с помощью:
$ azure config mode arm info: Executing command config mode info: New mode is arm info: config mode command OK
Переключаемся на нужную подписку:
$ azure account list info: Executing command account list data: Name Id Current State data: ------------- ------------------------------------ ------- -------- data: Free Trial 97214f99-***-***-***-715556cd5906 true Enabled data: Pay-As-You-Go fe37db50-***-***-***-66145cdbd735 false Disabled data: Pay-As-You-Go 0a4f2b9c-***-***-***-40b17ef8c3ab false Enabled
$ azure account set 97214f99-***-***-***-715556cd5906 info: Executing command account set info: Setting subscription to "Free Trial" with id "97214f99-***-***-***-715556cd5906". info: Changes saved
Для создания виртуальной машины (далее — VM) — используем vm quick-create
, подробнее — тут>>>:
$ azure vm quick-create -h help: Create a virtual machine with default resources in a resource group help: help: Usage: vm quick-create [options] <resource-group> <name> <location> <os-type> <image-urn> <admin-username> <admin-password> help: help: Options: help: -h, --help output usage information help: -v, --verbose use verbose output help: -vv more verbose with debug output help: --json use json output help: -g, --resource-group <resource-group> the resource group name help: -n, --name <name> the virtual machine name help: -l, --location <location> the location help: -y, --os-type <os-type> the operating system Type, valid values are Windows, Linux help: -Q, --image-urn <image-urn> the image URN in the form "publisherName:offer:skus:version", help: or the VHD link of a user image, help: e.g. https://foo.blob.core.windows.net/bar/vhds/baz.vhd help: -z, --vm-size <vm-size> the virtual machine size [Standard_D1] help: -u, --admin-username <admin-username> the user name help: -p, --admin-password <admin-password> the password, skipped if SSH public key file is specified for Linux VMs help: -M, --ssh-publickey-file <ssh-publickey-file> the path to public key file for SSH authentication, help: & this parameter is valid only when os-type is Linux. help: -s, --subscription <subscription> the subscription identifier help: help: Current Mode: arm (Azure Resource Management)
Проверяем доступные локации:
$ azure location list info: Executing command location list warn: The "location list" commands is changed to list subscription's locations. For old information, use "provider list or show" commands. info: Getting locations... data: Name Display Name Latitude Longitude data: ------------------ ------------------- -------- --------- data: eastasia East Asia 22.267 114.188 data: southeastasia Southeast Asia 1.283 103.833 data: centralus Central US 41.5908 -93.6208 data: eastus East US 37.3719 -79.8164 data: eastus2 East US 2 36.6681 -78.3889 data: westus West US 37.783 -122.417 data: northcentralus North Central US 41.8819 -87.6278 data: southcentralus South Central US 29.4167 -98.5 data: northeurope North Europe 53.3478 -6.2597 data: westeurope West Europe 52.3667 4.9 data: japanwest Japan West 34.6939 135.5022 data: japaneast Japan East 35.68 139.77 data: brazilsouth Brazil South -23.55 -46.633 data: australiaeast Australia East -33.86 151.2094 data: australiasoutheast Australia Southeast -37.8136 144.9631 data: southindia South India 12.9822 80.1636 data: centralindia Central India 18.5822 73.9197 data: westindia West India 19.088 72.868
Выбираем группу ресурсов:
$ azure group list info: Executing command group list + Listing resource groups data: Name Location Provisioning State Tags: data: ---------------------- ---------- ------------------ ----- data: CDN_testing westus Succeeded null data: D2 westeurope Succeeded null data: Default-Storage-EastUS eastus Succeeded null
Находим URN образа с Ubuntu 14.04:
$ azure vm image list westeurope canonical ubuntuserver | grep 14.04 data: canonical ubuntuserver 14.04.0-LTS Linux 14.04.201404140 westeurope canonical:ubuntuserver:14.04.0-LTS:14.04.201404140 ...
Подробнее — тут>>> и в посте Azure: деплой VM из образа с помощью Azure CLI.
И обращайте внимание на последние цифры версии — *.201604060 — последний билд.
Создаем машину:
$ azure vm quick-create -g D2 -n gw -l westeurope -y Linux -Q canonical:ubuntuserver:14.04.4-LTS:14.04.201604060 -u setevoy -p p@ssw0rd info: Executing command vm quick-create + Looking up the VM "gw" info: Using the VM Size "Standard_D1" info: The [OS, Data] Disk or image configuration requires storage account + Looking up the storage account cli3879857892351853844 info: Could not find the storage account "cli3879857892351853844", trying to create new one + Creating storage account "cli3879857892351853844" in "westeurope" + Looking up the storage account cli3879857892351853844 + Looking up the NIC "gw-weste-387985789-nic" info: An nic with given name "gw-weste-387985789-nic" not found, creating a new one + Looking up the virtual network "gw-weste-387985789-vnet" info: Preparing to create new virtual network and subnet + Creating a new virtual network "gw-weste-387985789-vnet" [address prefix: "10.0.0.0/16"] with subnet "gw-weste-387985789-snet" [address prefix: "10.0.1.0/24"] + Looking up the virtual network "gw-weste-387985789-vnet" + Looking up the subnet "gw-weste-387985789-snet" under the virtual network "gw-weste-387985789-vnet" info: Found public ip parameters, trying to setup PublicIP profile + Looking up the public ip "gw-weste-387985789-pip" info: PublicIP with given name "gw-weste-387985789-pip" not found, creating a new one + Creating public ip "gw-weste-387985789-pip" + Looking up the public ip "gw-weste-387985789-pip" + Creating NIC "gw-weste-387985789-nic" + Looking up the NIC "gw-weste-387985789-nic" + Creating VM "gw" + Looking up the VM "gw" + Looking up the NIC "gw-weste-387985789-nic" + Looking up the public ip "gw-weste-387985789-pip" data: Id :/subscriptions/97214f99-***-***-***-715556cd5906/resourceGroups/D2/providers/Microsoft.Compute/virtualMachines/gw data: ProvisioningState :Succeeded data: Name :gw data: Location :westeurope data: Type :Microsoft.Compute/virtualMachines data: data: Hardware Profile: data: Size :Standard_D1 data: data: Storage Profile: data: Image reference: data: Publisher :canonical data: Offer :ubuntuserver data: Sku :14.04.4-LTS data: Version :14.04.201604060 data: data: OS Disk: data: OSType :Linux data: Name :cli6f0fe23acedc08d4-os-1462018191934 data: Caching :ReadWrite data: CreateOption :FromImage data: Vhd: data: Uri :https://cli3879857892351853844.blob.core.windows.net/vhds/cli6f0fe23acedc08d4-os-1462018191934.vhd data: data: OS Profile: data: Computer Name :gw data: User Name :setevoy data: Linux Configuration: data: Disable Password Auth :false data: data: Network Profile: data: Network Interfaces: data: Network Interface #1: data: Primary :true data: MAC Address :00-0D-3A-23-20-8B data: Provisioning State :Succeeded data: Name :gw-weste-387985789-nic data: Location :westeurope data: Public IP address :13.80.9.248 data: FQDN :gw-weste-387985789-pip.westeurope.cloudapp.azure.com data: data: Diagnostics Profile: data: BootDiagnostics Enabled :true data: BootDiagnostics StorageUri :https://cli3879857892351853844.blob.core.windows.net/ data: data: Diagnostics Instance View: info: vm quick-create command OK
Проверяем:
$ azure vm list info: Executing command vm list + Getting virtual machines data: ResourceGroupName Name ProvisioningState PowerState Location Size data: ----------------- ---- ----------------- ---------- ---------- ----------- data: D2 gw Succeeded VM running westeurope Standard_D1 info: vm list command OK
Находим IP, который потребуется при создании субдомена:
$ azure vm show -g D2 -n gw | grep IP data: Public IP address :13.80.9.248
Пробуем подключиться:
$ ssh [email protected] The authenticity of host '13.80.9.248 (13.80.9.248)' can't be established. ECDSA key fingerprint is 20:a7:0b:33:61:11:ec:98:3a:83:77:2b:e3:0f:7e:83. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '13.80.9.248' (ECDSA) to the list of known hosts. [email protected]'s password: Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 3.19.0-58-generic x86_64) ... setevoy@gw:~$
Там же находим Network interface
— его Name
понадобится при создании Security group:
... data: Network Profile: data: Network Interfaces: data: Network Interface #1: data: Primary :true data: MAC Address :00-0D-3A-23-20-8B data: Provisioning State :Succeeded data: Name :gw-weste-387985789-nic data: Location :westeurope data: Public IP address :13.80.9.248 data: FQDN :gw-weste-387985789-pip.westeurope.cloudapp.azure.com ...
Далее треубется открыть порт 80 для входящих соединений, т.к. по умолчанию доступ открыт только на порт 22:
$ telnet 13.80.9.248 80 Trying 13.80.9.248... telnet: Unable to connect to remote host: Connection timed out
Проверяем текущие Security группы:
$ azure network nsg list info: Executing command network nsg list + Getting the network security groups warn: No network security groups found
Создаем новую группу с именем gw_in:
$ azure network nsg create -g D2 -n gw_in -l westeurope info: Executing command network nsg create + Looking up the network security group "gw_in" + Creating a network security group "gw_in" data: Id : /subscriptions/97214f99-***-***-***-715556cd5906/resourceGroups/D2/providers/Microsoft.Network/networkSecurityGroups/gw_in data: Name : gw_in data: Type : Microsoft.Network/networkSecurityGroups data: Location : westeurope data: Provisioning state : Succeeded data: Security rules: data: Name Source IP Source Port Destination IP Destination Port Protocol Direction Access Priority data: ----------------------------- ----------------- ----------- -------------- ---------------- -------- --------- ------ -------- data: AllowVnetInBound VirtualNetwork * VirtualNetwork * * Inbound Allow 65000 data: AllowAzureLoadBalancerInBound AzureLoadBalancer * * * * Inbound Allow 65001 data: DenyAllInBound * * * * * Inbound Deny 65500 data: AllowVnetOutBound VirtualNetwork * VirtualNetwork * * Outbound Allow 65000 data: AllowInternetOutBound * * Internet * * Outbound Allow 65001 data: DenyAllOutBound * * * * * Outbound Deny 65500
Добавляем к ней правило для входящих соединений на порт 80 с именем 80inallow:
$ azure network nsg rule create -g D2 -a gw_in -n 80inallow -p tcp -o '*' -u 80 -c Allow info: Executing command network nsg rule create warn: Using default source port: 80 warn: Using default source address prefix: * warn: Using default destination address prefix: * warn: Using default priority: 100 warn: Using default direction: Inbound + Looking up the network security group "gw_in" + Looking up the network security rule "80inallow" + Creating a network security rule "80inallow" data: Id : /subscriptions/97214f99-***-***-***-715556cd5906/resourceGroups/D2/providers/Microsoft.Network/networkSecurityGroups/gw_in/securityRules/80inallow data: Name : 80inallow data: Type : Microsoft.Network/networkSecurityGroups/securityRules data: Provisioning state : Succeeded data: Source IP : * data: Source Port : 80 data: Destination IP : * data: Destination Port : 80 data: Protocol : Tcp data: Direction : Inbound data: Access : Allow data: Priority : 100 info: network nsg rule create command OK
Аналогично — для порта 22, SSH, но с более высоким приоритетом, что бы избежать ошибки вида:
error: Security rule 80inallow conflicts with rule sshallow. Rules cannot have the same Priority and Direction.
$ azure network nsg rule create -g D2 -a gw_in -n sshallow -p tcp -o '*' -u 22 -c Allow -y 101
Подключаем интерфейс к этой группе безопасности:
$ azure network nic set -g D2 -n gw-weste-387985789-nic --network-security-group-name gw_in info: Executing command network nic set + Looking up the network interface "gw-weste-387985789-nic" + Looking up the network security group "gw_in" + Updating network interface "gw-weste-387985789-nic" data: Id : /subscriptions/97214f99-***-***-***-715556cd5906/resourceGroups/D2/providers/Microsoft.Network/networkInterfaces/gw-weste-387985789-nic data: Name : gw-weste-387985789-nic data: Type : Microsoft.Network/networkInterfaces data: Location : westeurope data: Provisioning state : Succeeded data: MAC address : 00-0D-3A-23-20-8B data: Enable IP forwarding : false data: Network security group : /subscriptions/97214f99-***-***-***-715556cd5906/resourceGroups/D2/providers/Microsoft.Network/networkSecurityGroups/gw_in data: Virtual machine : /subscriptions/97214f99-***-***-***-715556cd5906/resourceGroups/D2/providers/Microsoft.Compute/virtualMachines/gw data: IP configurations: data: Name : ipconfig1462018264060 data: Provisioning state : Succeeded data: Public IP address : /subscriptions/97214f99-***-***-***-715556cd5906/resourceGroups/D2/providers/Microsoft.Network/publicIPAddresses/gw-weste-387985789-pip data: Private IP address : 10.0.1.4 data: Private IP allocation method : Dynamic data: Subnet : /subscriptions/97214f99-***-***-***-715556cd5906/resourceGroups/D2/providers/Microsoft.Network/virtualNetworks/gw-weste-387985789-vnet/subnets/gw-weste-387985789-snet
Проверяем:
$ telnet 13.80.9.248 80 Trying 13.80.9.248... Connected to 13.80.9.248. Escape character is '^]'.
Создание WebApp
В WebApp у нас будет работать приложение, к которому мы будем проксировать данные через созданную VM.
Проверяем имеющиеся приложения:
$ azure webapp list -g D2 info: Executing command webapp list + Listing webapps info: No web apps found.
Создаем WebApp:
$ azure webapp create -g D2 -n backappforgw -l westeurope -p WEgwapp info: Executing command webapp create + Creating webapp backappforgw info: Webapp backappforgw has been created
Проверяем:
$ azure webapp show -g D2 -n backappforgw info: Executing command webapp show + Getting webapp data: Web app Name : backappforgw data: SKU : Standard data: Enabled : true data: Last Modified : 2016-04-30T13:52:36.29 data: Location : West Europe data: data: Host Name data: ------------------------------ data: backappforgw.azurewebsites.net
$ curl -sr 0-1024 http://backappforgw.azurewebsites.net <!DOCTYPE html><html><head> <title>Microsoft Azure Web App - Welcome</title> ...
Настройка DNS
Далее будут использоваться два субдомена:
- gw.setevoy.org.ua: шлюз с NGINX;
- app.setevoy.org.ua: созданное приложение, к которому будет проксироваться трафик, но с
IN A
созданной VM;
Что бы подключить внешний домен к приложению в Azure — необходимо создать запись авторизации вида:
awverify.app.setevoy.kiev.ua CNAME awverify.backappforgw.azurewebsites.net
При создания app.setevoy.org.ua — указываем IP шлюза, в результате получается примерно такая картина:
Подключаем новый субдомен в Portal > App Services > backappforgw > Settings > Custom domains and SSL > Bring External Domains:
И оттуда же записываем IP — 104.47.151.115, который далее используем при настройке NGINX.
Настройка NGINX
На созданной VM устанавливаем NGINX:
$ sudo -s # apt-get update # apt-get install nginx
Создаем файл конфигурации /etc/nginx/sites-available/app.setevoy.kiev.ua.conf
:
server { server_name app.setevoy.kiev.ua; access_log /var/log/nginx/app.setevoy.kiev.ua-access.log; error_log /var/log/nginx/app.setevoy.kiev.ua-error.log; root /usr/share/nginx/html; location / { proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://104.47.151.115; } }
Создаём симлинк в каталог sites-enabled
(Debian/Ubuntu):
# ln -s /etc/nginx/sites-available/app.setevoy.kiev.ua.conf /etc/nginx/sites-enabled/
Проверяем:
# ls -l /etc/nginx/sites-enabled/ total 0 lrwxrwxrwx 1 root root 51 Apr 30 14:23 app.setevoy.kiev.ua.conf -> /etc/nginx/sites-available/app.setevoy.kiev.ua.conf lrwxrwxrwx 1 root root 34 Apr 30 13:06 default -> /etc/nginx/sites-available/default
# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Перегружаем конфиги:
# service nginx reload * Reloading nginx configuration nginx
И пробуем зайти:
Готово.
Ссылки по теме
Create a Linux VM on Azure using the CLI
Navigate and select Linux virtual machine images in Azure with CLI or Powershell
Configure a custom domain name in Azure App Service
Create a Linux VM from the ground up using the Azure CLI (замечательный почти cheat-sheet)
How to create NSGs in the Azure CLI
Azure: деплой VM из образа с помощью Azure CLI
Reverse Proxy on Windows Azure using Nginx