Задача – добавить новую группу ресурсов, которая бы включала в себя Load Balancer и две виртуальные машины с NGINX за ним.
Машины будут использовать единую файл-шару, в которую будут деплоиться обновлённые конфиги NGINX.
Ресурс группа будет включать в себя:
- Load Balancer
- две идентичные VM с NGINX
- Storage Account, который будет подключаться как Samba-share ресурс к обеим машинам в каталог
/data/datanginx-conf.d
.
Следующие действия:
- создать ресурс группу
- добавить в неё Load Balancer
- создать Storage Account, скопировать в него ключи
- создать одну VM с NGINX, примонтировать шару, проверить что всё работает
- подключить вторую вируталку
Содержание
Подготовка
По возможности – делаем всё через Azure CLI (тут v1).
Load Balancer, сеть
Создаём группу ресурсов:
[simterm]
$ azure group create -n jm-akqa-gw-proxy-dev -l westeurope
[/simterm]
Создаём Load Balancer:
[simterm]
$ azure network lb create -g jm-akqa-gw-proxy-dev -n jm-akqa-gw-proxy-dev-lb -l westeurope
[/simterm]
Создаём Public IP:
[simterm]
$ azure network public-ip create --resource-group jm-akqa-gw-proxy-dev \ > --name jm-akqa-gw-proxy-dev-ip \ > --location westeurope \ > --domain-name-label jm-akqa-gw-proxy-dev-ip \ > --allocation-method Static
[/simterm]
Создаём сеть:
[simterm]
$ azure network vnet create --resource-group jm-akqa-gw-proxy-dev \ > --location westeurope \ > --name jm-akqa-gw-proxy-dev-vnet \ > --address-prefixes 10.0.0.0/24
[/simterm]
Примечание: тут Azure CLI сообщает об “ошибке” – “error: Cannot read property ‘dnsServers’ of undefined”, но сеть создаётся. При этом в документации property ‘dnsServers’ указана как optional. Но вызывает ошибку… Azure…
И подсеть в ней:
[simterm]
$ azure network vnet subnet create --resource-group jm-akqa-gw-proxy-dev \ > --name jm-akqa-gw-proxy-dev-gws-subnet \ > --vnet-name jm-akqa-gw-proxy-dev-vnet \ > --address-prefix 10.0.0.0/28
[/simterm]
Подключаем IP к созданному LB:
[simterm]
$ azure network lb frontend-ip create --resource-group jm-akqa-gw-proxy-dev \ > --lb-name jm-akqa-gw-proxy-dev-lb \ > --name jm-akqa-gw-proxy-dev-feip \ > --public-ip-name jm-akqa-gw-proxy-dev-ip
[/simterm]
Добавляем backend IP pool:
[simterm]
$ azure network lb address-pool create --resource-group jm-akqa-gw-proxy-dev \ > --lb-name jm-akqa-gw-proxy-dev-lb \ > --name jm-akqa-gw-proxy-dev-beip
[/simterm]
Создаём правило проброса трафика с внешнего IP, порт 80, на бекенд, порт 80:
[simterm]
$ azure network lb rule create --resource-group jm-akqa-gw-proxy-dev \ > --lb-name jm-akqa-gw-proxy-dev-lb \ > --name http \ > --protocol tcp \ > --frontend-port 80 \ > --backend-port 80 \ > --frontend-ip-name jm-akqa-gw-proxy-dev-feip \ > --backend-address-pool-name jm-akqa-gw-proxy-dev-beip
[/simterm]
Аналогично – для 443:
[simterm]
$ azure network lb rule create -g jm-akqa-gw-proxy-dev -l jm-akqa-gw-proxy-dev-lb -n https -p tcp -f 443 -b 443 -t jm-akqa-gw-proxy-dev-feip -o jm-akqa-gw-proxy-dev-beip
[/simterm]
Добавляем Health probe, по которой LB будет определять “живые” машины в бекенде:
[simterm]
$ azure network lb probe create --resource-group jm-akqa-gw-proxy-dev \ > --lb-name jm-akqa-gw-proxy-dev-lb \ > --name http_health \ > --protocol tcp \ > --port 80
[/simterm]
Создаём NAT правило для проброса порта 2200 на внутренний интерфейс порт 22:
[simterm]
$ azure network lb inbound-nat-rule create --resource-group jm-akqa-gw-proxy-dev \ > --lb-name jm-akqa-gw-proxy-dev-lb \ > --name jm-akqa-gw-proxy-dev-nat-2200-22-gw1 \ > --protocol tcp \ > --frontend-port 2200 \ > --backend-port 22 \ > --frontend-ip-name jm-akqa-gw-proxy-dev-feip
[/simterm]
Создаём Network Interface:
[simterm]
$ azure network nic create --resource-group jm-akqa-gw-proxy-dev \ > --location westeurope \ > --name jm-akqa-gw-proxy-dev-gw1-nic \ > --subnet-name jm-akqa-gw-proxy-dev-gws-subnet \ > --subnet-vnet-name jm-akqa-gw-proxy-dev-vnet \ > --lb-address-pool-ids /subscriptions/0a4f2b9c-***-***-***-40b17ef8c3ab/resourceGroups/jm-akqa-gw-proxy-dev/providers/Microsoft.Network/loadbalancers/jm-akqa-gw-proxy-dev-lb/backendAddressPools/jm-akqa-gw-proxy-dev-beip \ > --lb-inbound-nat-rule-ids /subscriptions/0a4f2b9c-***-***-***-40b17ef8c3ab/resourceGroups/jm-akqa-gw-proxy-dev/providers/Microsoft.Network/loadBalancers/jm-akqa-gw-proxy-dev-lb/inboundNatRules/jm-akqa-gw-proxy-dev-nat-2200-22-gw1
[/simterm]
На этом сеть и балансировщик нагрузки готовы.
Виртуальная машина для NGINX
Запускаем виртуальную машину:
[simterm]
$ azure vm create --resource-group jm-akqa-gw-proxy-dev \ > --location westeurope \ > --name jm-akqa-gw-proxy-dev-gw1 \ > --vnet-name jm-akqa-gw-proxy-dev-vnet \ > --vnet-subnet-name jm-akqa-gw-proxy-dev-gws-subnet \ > --nic-name jm-akqa-gw-proxy-dev-gw1-nic \ > --os-type Linux \ > --image-urn Canonical:UbuntuServer:16.04-LTS:latest \ > --admin-username jadmin --admin-password p@ssw0rd \ > --vm-size Standard_F1s info: Executing command vm create + Looking up the VM "jm-akqa-gw-proxy-dev-gw1" info: Using the VM Size "Standard_F1s" info: The [OS, Data] Disk or image configuration requires storage account + Retrieving storage accounts info: Could not find any storage accounts in the region "westeurope", trying to create new one + Creating storage account "cli21b60a27a12fbe731***" in "westeurope" + Looking up the storage account cli21b60a27a12fbe731*** + Looking up the NIC "jm-akqa-gw-proxy-dev-gw1-nic" info: Found an existing NIC "jm-akqa-gw-proxy-dev-gw1-nic" info: Found an IP configuration with virtual network subnet id "/subscriptions/0a4f2b9c-***-***-***-40b17ef8c3ab/resourceGroups/jm-akqa-gw-proxy-dev/providers/Microsoft.Network/virtualNetworks/jm-akqa-gw-proxy-dev-vnet/subnets/jm-akqa-gw-proxy-dev-gws-subnet" in the NIC "jm-akqa-gw-proxy-dev-gw1-nic" info: This is an NIC without publicIP configured info: The storage URI 'https://cli21b60a27a12fbe731***.blob.core.windows.net/' will be used for boot diagnostics settings, and it can be overwritten by the parameter input of '--boot-diagnostics-storage-uri'. + Creating VM "jm-akqa-gw-proxy-dev-gw1" info: vm create command OK
[/simterm]
Проверяем:
[simterm]
$ ssh -p 2200 jageradmin@52.***.***.82 ... jadmin@jm-akqa-gw-proxy-dev-gw1:~$
[/simterm]
Готово.
По теме:
https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-get-started-ilb-arm-cli
https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-create-vnet-arm-pportal
https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-get-started-internet-arm-cli
https://docs.microsoft.com/en-us/azure/virtual-machines/linux/sizes-compute
https://docs.microsoft.com/en-us/azure/virtual-machines/linux/cli-ps-findimage
https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-overview
Azure File share
Далее требуется создать data-диск, которые будут использоваться в роли файловых шар для конфигов NGINX на обеих машинах.
Создаём Storage account:
[simterm]
$ azure storage account create --resource-group jm-akqa-gw-proxy-dev \ > --location westeurope \ > --sku-name GRS \ > --kind storage \ > gwproxystorage
[/simterm]
Проверяем:
[simterm]
$ azure storage account show -g jm-gw-proxy-dev gwproxystorage info: Executing command storage account show + Getting storage account data: Name: gwproxystorage data: Url: /subscriptions/0a4f2b9c-***-***-***-40b17ef8c3ab/resourceGroups/jm-akqa-gw-proxy-dev/providers/Microsoft.Storage/storageAccounts/gwproxystorage data: Type: Microsoft.Storage/storageAccounts data: SKU Name: Standard_GRS data: SKU Tier: Standard data: Kind: Storage data: Resource Group: jm-akqa-gw-proxy-dev data: Location: westeurope data: Provisioning State: Succeeded data: Primary Location: westeurope data: Primary Status: available data: Secondary Location: northeurope data: Creation Time: Fri, 14 Jul 2017 12:41:15 GMT data: Primary Endpoints: blob https://gwproxystorage.blob.core.windows.net/ data: Primary Endpoints: queue https://gwproxystorage.queue.core.windows.net/ data: Primary Endpoints: table https://gwproxystorage.table.core.windows.net/ data: Primary Endpoints: file https://wproxystorage.file.core.windows.net/ info: storage account show command OK
[/simterm]
Создаём файл-шару:
[simterm]
$ azure storage share create gwproxydata \ > --account-name gwproxystorage \ > --account-key F5M***yZg== \ > info: Executing command storage share create + Creating storage file share gwproxydata + Getting Storage share information data: { data: name: 'gwproxydata', data: metadata: {}, data: etag: '"0x8D4CCEDCBBCBBF7"', data: lastModified: 'Mon, 17 Jul 2017 08:28:26 GMT', data: requestId: 'f05a9307-001a-004b-64d6-feb922000000', data: quota: '5120', data: shareUsage: '0' data: } info: storage share create command OK
[/simterm]
Создаём в этой шаре каталог для файлов NGINX с именем datanginx-conf.d
:
[simterm]
$ azure storage directory create --share gwproxydata \ > --path datanginx-conf.d \ > --account-name gwproxystorage \ > --account-key F5M***yZg== info: Executing command storage directory create + Creating storage file directory 'datanginx-conf.d' in share gwproxydata info: Directory datanginx-conf.d has been created successfully data: { data: name: 'datanginx-conf.d', data: etag: '"0x8D4CCEE3CAA3033"', data: lastModified: 'Mon, 17 Jul 2017 08:31:35 GMT', data: requestId: '3b4b92d7-001a-0009-6dd7-fe00a2000000' data: } info: storage directory create command OK
[/simterm]
Подключаем на сервер gw1
c NGINX, устанавливаем cifs-utils
:
[simterm]
root@jm-akqa-gw-proxy-dev-gw1:~# apt update && apt install cifs-utils ... cifs-utils is already the newest version (2:6.4-1ubuntu1.1).
[/simterm]
Создаём каталог:
[simterm]
root@jm-akqa-gw-proxy-dev-gw1:~# mkdir -p /data
[/simterm]
Монтируем шару:
[simterm]
root@jm-akqa-gw-proxy-dev-gw1:~# mount -t cifs //gwproxystorage.file.core.windows.net/gwproxydata /data -o vers=3.0,username=gwproxystorage,password=F5M***yZg==,dir_mode=0755,file_mode=0644
[/simterm]
Проверяем:
[simterm]
root@jm-akqa-gw-proxy-dev-gw1:~# ls -l /data/ total 0 drwxr-xr-x 2 root root 0 Jul 17 08:31 datanginx-conf.d
[/simterm]
Готово.
По теме:
https://docs.microsoft.com/en-us/azure/storage/storage-blob-storage-tiers
https://medium.com/@wimcoekaerts/creating-an-azure-file-share-and-mounting-it-in-your-linux-instance-2d011fbacdbc
https://docs.microsoft.com/en-us/azure/storage/storage-how-to-use-files-linux
NGINX
Следующим шагом – устанавливаем NGINX, и подключаем к нему каталог /data/datanginx-conf.d/
:
[simterm]
root@jm-akqa-gw-proxy-dev-gw1:~# apt install nginx -y
[/simterm]
В файл /etc/nginx/nginx.conf
в блок http {}
добавляем:
... include /data/datanginx-conf.d/*.conf; ...
Проверяем:
[simterm]
root@jm-akqa-gw-proxy-dev-gw1:~# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
[/simterm]
Добавляем тестовый файл конфигурации /data/datanginx-conf.d/jm-akqa-gw-proxy-dev.domain.ms.conf
:
[simterm]
server { server_name jm-akqa-gw-proxy-dev.domain.ms; access_log /var/log/nginx/jm-akqa-gw-proxy-dev.domain.ms-access.log; error_log /var/log/nginx/jm-akqa-gw-proxy-dev.domain.ms-error.log; root /usr/share/nginx/html; }
[/simterm]
Проверяем NGINX, перечитываем конфиги:
[simterm]
root@jm-akqa-gw-proxy-dev-gw1:~# nginx -t && service nginx reload nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
[/simterm]
Проверяем по URL:
[simterm]
$ curl jm-akqa-gw-proxy-dev.domain.ms <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
[/simterm]
Готово.