Add Azure Based Docker Cluster Templates
|
@ -0,0 +1,3 @@
|
|||
# Docker Clusters on Azure
|
||||
|
||||
The templates in this repository enable you to deploy docker clusters on Azure with orchestrators of type: DCOS, Mesos, or Swarm.
|
|
@ -0,0 +1,66 @@
|
|||
# DCOS Templates for a 3 master clusters with attached disks
|
||||
|
||||
This template deploys a DCOS cluster on Azure an attached disk.
|
||||
|
||||
# Approach to enable larger persistent data disks on machines
|
||||
|
||||
Instructions below contributed by @Radek44
|
||||
|
||||
Disclaimer: this approach is not a replacement for the current DCOS given as it has a few tradeoffs however a potential alternative approach for customers that need large amounts of persistent storage within the cluster for running.
|
||||
|
||||
Step 1 : Deploy the 3 cluster DCOS template in this project.
|
||||
|
||||
Step 2: In the template it is possible to configure additional Data Disks . Maximum size of a single data disk is 1023Gb, depending on VM class up to 32 disks can be attached to a single VM.
|
||||
"dataDisks" : [
|
||||
{
|
||||
"name": ....
|
||||
"diskSizeGb": "1023" ...
|
||||
}
|
||||
]
|
||||
|
||||
Step 3: Once the cluster is created the disks should be configured before anything else is deployed on the agents.
|
||||
In order to prepare the disks and register them permanently here is a quick bash script
|
||||
```#!/bin/bash
|
||||
# Create a folder for the dcos first extended volume
|
||||
# Volumes have to be made discoverable by mesos by being created as /dcos/volume{n}
|
||||
# Create a partition table and one partition spawning the entire disk
|
||||
# Format the partition as ext4
|
||||
# Mount the partition
|
||||
# Register the partition in fstab
|
||||
# Reboot the machine after 1 minute
|
||||
#
|
||||
sudo mkdir -p /dcos/volume0&&sudo parted -s /dev/sdc mklabel gpt mkpart primary ext4 0% 100%&&sudo mkfs -t ext4 /dev/sdc1&&sudo mount /dev/sdc1 /dcos/volume0&&sudo sh -c "echo '/dev/sdc1\t/dcos/volume0\text4\tdefaults\t0\t2' >> /etc/fstab"&&sudo shutdown --reboot 1
|
||||
Notice that the Azure documentation suggests that volumes are registered using their UUID. However doing that I have had failures with agents restarting
|
||||
In cases anyone still wants to try this is the alternate approach for the registration step becomes:
|
||||
sudo sh -c "echo 'UUID=$(sudo blkid | grep '/dev/sdc1' | sed -n 's/.*UUID=\"\([^\"]*\)\".*/\1/p')\t/dcos/volume0\text4\tdefaults\t0\t2' >> /etc/fstab"
|
||||
```
|
||||
Step 4: Once the machine rebooted, edit the DCOS configuration in order to start leveraging the new volume.
|
||||
```#!/bin/bash
|
||||
#
|
||||
# This script will take a disk previsouly mounted on /dcos/volume0 and ensure that it is visible and used by mesos
|
||||
# It removes current mesos resource configuration
|
||||
# It then restarts relevant dcos services to have them pick up the config
|
||||
# Then quick reboot and we are golden
|
||||
sudo rm /var/lib/dcos/mesos-resources&&sudo rm -f /var/lib/mesos/slave/meta/slaves/latest&&sudo systemctl restart dcos-vol-discovery-priv-agent&&sleep 5&&sudo systemctl restart dcos-mesos-slave&&sudo shutdown --reboot 1
|
||||
```
|
||||
Step 5: Once the machine rebooted Mesos should now be reporting ~1Gb extra for each node on which this was executed.
|
||||
A quick helper script to execute the above in parallel on all target agents (requires a private_agents file listing the target IPs).
|
||||
```#!/bin/bash
|
||||
#
|
||||
# Assumes you have a file called private_agents that contains the list of hosts that you want impacted by the script (typically your private agent pool IPs so 10.32.0.x range
|
||||
# Install parallel-ssh
|
||||
sudo apt-get install pssh
|
||||
#
|
||||
# First part of the parallel executions creates and mounts the disks and restarts the agent
|
||||
parallel-ssh -O StrictHostKeyChecking=no -l loopadmin -h private_agents -P -I < ~/datadisk.sh
|
||||
#
|
||||
# Get a coffee - wait a bit for agent to restart
|
||||
sleep 2m
|
||||
#
|
||||
# Second part of the parallel execution configures mesos to see the new disks and restarts
|
||||
parallel-ssh -O StrictHostKeyChecking=no -l loopadmin -h private_agents -P -I < ~/mesosdisk.sh
|
||||
#
|
||||
echo "When You Play The Game Of Thrones, You Win Or You Die"
|
||||
```
|
||||
|
||||
For further reading on attached disks browse to https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-classic-attach-disk/.
|
|
@ -0,0 +1,3 @@
|
|||
# DCOS Templates for 1, 3, and 5 master clusters
|
||||
|
||||
These templates deploy a DCOS cluster on Azure with 1, 3, and 5 master combinations.
|
|
@ -0,0 +1,242 @@
|
|||
# Clusters with Mesos/Marathon/Chronos or Swarm Orchestrators
|
||||
|
||||
These Microsoft Azure templates create various cluster combinations with Mesos/Marathon/Chronos or Swarm Orchestrators.
|
||||
|
||||
Portal Launch Button|Cluster Type|Walkthrough Instructions
|
||||
--- | --- | ---
|
||||
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fanhowe%2Fscratch%2Fmaster%2Fmesos-marathon-vmss%2Fmesos-cluster-with-no-jumpbox.json" target="_blank"><img src="http://azuredeploy.net/deploybutton.png"/></a>|Mesos with no jumpbox|[Mesos Cluster Walkthrough](#mesos-cluster-walkthrough)
|
||||
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fanhowe%2Fscratch%2Fmaster%2Fmesos-marathon-vmss%2Fmesos-cluster-with-windows-jumpbox.json" target="_blank"><img src="http://azuredeploy.net/deploybutton.png"/></a>|Mesos with windows jumpbox|[Mesos Cluster Walkthrough](#mesos-cluster-walkthrough)
|
||||
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fanhowe%2Fscratch%2Fmaster%2Fmesos-marathon-vmss%2Fmesos-cluster-with-linux-jumpbox.json" target="_blank"><img src="http://azuredeploy.net/deploybutton.png"/></a>|Mesos with linux jumpbox|[Mesos Cluster Walkthrough](#mesos-cluster-walkthrough)
|
||||
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fanhowe%2Fscratch%2Fmaster%2Fmesos-marathon-vmss%2Fswarm-cluster-with-no-jumpbox.json" target="_blank"><img src="http://azuredeploy.net/deploybutton.png"/></a>|Swarm Cluster|[Swarm Cluster Walkthrough](#swarm-cluster-walkthrough)
|
||||
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fanhowe%2Fscratch%2Fmaster%2Fmesos-marathon-vmss%2Fswarm-cluster-with-windows.json" target="_blank"><img src="http://azuredeploy.net/deploybutton.png"/></a>|Swarm Windows Cluster|[Swarm Windows Cluster Walkthrough](#swarm-windows-cluster-walkthrough)
|
||||
|
||||
# Mesos Cluster Walkthrough
|
||||
|
||||
Once your cluster has been created you will have a resource group containing 3 parts:
|
||||
|
||||
1. a set of 1,3,5 masters in a master specific availability set. Each master's SSH can be accessed via the public dns address at ports 2200..2204
|
||||
|
||||
2. a set of agents behind in an agent specific availability set. The agent VMs must be accessed through the master, or jumpbox
|
||||
|
||||
3. if chosen, a windows or linux jumpbox
|
||||
|
||||
The following image is an example of a cluster with 1 jumpbox, 3 masters, and 3 agents:
|
||||
|
||||
![Image of Mesos cluster on azure](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/mesos.png)
|
||||
|
||||
You can see the following parts:
|
||||
|
||||
1. **Mesos on port 5050** - Mesos is the distributed systems kernel that abstracts cpu, memory and other resources, and offers these to services named "frameworks" for scheduling of workloads.
|
||||
2. **Marathon on port 8080** - Marathon is a scheduler for Mesos that is equivalent to init on a single linux machine: it schedules long running tasks for the whole cluster.
|
||||
3. **Chronos on port 4400** - Chronos is a scheduler for Mesos that is equivalent to cron on a single linux machine: it schedules periodic tasks for the whole cluster.
|
||||
4. **Docker on port 2375** - The Docker engine runs containerized workloads and each Master and Agent run the Docker engine. Mesos runs Docker workloads, and examples on how to do this are provided in the Marathon and Chronos walkthrough sections of this readme.
|
||||
5. **Swarm on port 2376** - Swarm is an experimental framework from Docker used for scheduling docker style workloads. The Swarm framework is disabled by default because it has a showstopper bug where it grabs all the resources [link to Swarm show stopper!](https://github.com/docker/swarm/issues/1183). As a workaround, you will notice in the walkthrough below, you can run your Docker workloads in Marathon and Chronos.
|
||||
|
||||
All VMs are on the same private subnet, 10.0.0.0/18, and fully accessible to each other.
|
||||
|
||||
## Installation Notes
|
||||
|
||||
Here are notes for troubleshooting:
|
||||
* the installation log for the linux jumpbox, masters, and agents are in /var/log/azure/cluster-bootstrap.log
|
||||
* event though the VMs finish quickly Mesos can take 5-15 minutes to install, check /var/log/azure/cluster-bootstrap.log for the completion status.
|
||||
* the linux jumpbox is based on https://github.com/anhowe/ubuntu-devbox and will take 1 hour to configure. Visit https://github.com/anhowe/ubuntu-devbox to learn how to know when setup is completed, and then how to access the desktop via VNC and an SSH tunnel.
|
||||
|
||||
## Template Parameters
|
||||
When you launch the installation of the cluster, you need to specify the following parameters:
|
||||
* `adminPassword`: self-explanatory
|
||||
* `jumpboxEndpointDNSName`: this is the public DNS name for the entrypoint that SWARM is going to use to deploy containers in the cluster.
|
||||
* `managementEndpointDNSName`: this is the public DNS name for the jumpbox that you will use to connect to the cluster. You just need to specify an unique name, the FQDN will be created by adding the necessary subdomains based on where the cluster is going to be created. Ex. <userID>MesosCluster, Azure will add westus.cloudapp.azure.com to create the FQDN for the jumpbox.
|
||||
* `applicationEndpointDNSName`: this is the public DNS for the application. It has a load balancer with ports 80 and 443 open.
|
||||
* `agentCount`: the number of Mesos Agents that you want to create in the cluster. You are allowed to create 1 to 100 agents
|
||||
* `masterCount`: Number of Masters. Currently the template supports 3 configurations: 1, 3 and 5 Masters cluster configuration.
|
||||
* `agentVMSize`: The type of VM that you want to use for each node in the cluster. The default size is D1 (1 core 3.5GB RAM) but you can change that if you expect to run workloads that require more RAM or CPU resources.
|
||||
* `sshRSAPublicKey`: Configure all linux machines with the SSH rsa public key string. Use 'disabled' to not configure access with SSH rsa public key.
|
||||
|
||||
## Marathon
|
||||
|
||||
Latest Steps can be found here: https://github.com/rgardler/azure-quickstart-templates/tree/acs/acs-mesos-full-template#marathon
|
||||
|
||||
This walk through is based the wonderful digital ocean tutorial: https://www.digitalocean.com/community/tutorials/how-to-configure-a-production-ready-mesosphere-cluster-on-ubuntu-14-04
|
||||
|
||||
1. Get your endpoints to cluster
|
||||
1. browse to https://portal.azure.com
|
||||
|
||||
2. then click browse all, followed by "resource groups", and choose your resource group
|
||||
|
||||
![Image of resource groups in portal](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/portal-resourcegroups.png)
|
||||
|
||||
3. then expand your resources, and copy the dns names of your jumpbox (if chosen), and your NAT public ip addresses.
|
||||
|
||||
![Image of public ip addresses in portal](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/portal-publicipaddresses.png)
|
||||
|
||||
2. Connect to your cluster
|
||||
1. linux jumpbox - start a VNC to the jumpbox using instructions https://github.com/anhowe/ubuntu-devbox. The jumpbox takes an hour to configure. If the desktop is not ready, you can tail /var/log/azure/cluster-bootstrap.log to watch installation.
|
||||
2. windows jumpbox - remote desktop to the windows jumpbox
|
||||
3. no jumpbox - SSH to port 2200 on your NAT creating a tunnel to port 5050 and port 8080. Then use the browser of your desktop to browse these ports.
|
||||
|
||||
3. browse to the Mesos UI http://master0:5050
|
||||
1. linux jumpbox - in top right corner choose Applications->Internet->Chrome and browse to http://master0:5050
|
||||
2. windows jumpbox - open browser and browse to http://master0:5050
|
||||
3. no jumpbox - browse to http://localhost:5050
|
||||
|
||||
4. Browse Mesos:
|
||||
1. scroll down the page and notice your resources of CPU and memory. These are your agents
|
||||
|
||||
![Image of Mesos cluster on azure](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/mesos-webui.png)
|
||||
|
||||
2. On top of page, click frameworks and notice your Marathon and Chronos frameworks
|
||||
|
||||
![Image of Mesos cluster frameworks on azure](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/mesos-frameworks.png)
|
||||
|
||||
3. On top of page, click agents and you can see your agents. On windows or linux jumpbox you can also drill down into the slave and see its logs.
|
||||
|
||||
![Image of Mesos agents on azure](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/mesos-agents.png)
|
||||
|
||||
5. browse and explore Marathon UI http://master0:8080 (or if using tunnel http://localhost:8080 )
|
||||
|
||||
6. start a long running job in Marathon
|
||||
1. click "+New App"
|
||||
2. type "myfirstapp" for the id
|
||||
3. type "/bin/bash -c "for i in {1..5}; do echo MyFirstApp $i; sleep 1; done" for the command
|
||||
4. scroll to bottom and click create
|
||||
|
||||
![Image of Marathon new app dialog](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/marathon-newapp.png)
|
||||
|
||||
7. you will notice the new app change state from not running to running
|
||||
|
||||
![Image of the new application status](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/marathon-newapp-status.png)
|
||||
|
||||
8. browse back to Mesos http://master0:5050. You will notice the running tasks and the completed tasks. Click on the host of the completed tasks and also look at the sandbox.
|
||||
|
||||
![Image of Mesos completed tasks](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/mesos-completed-tasks.png)
|
||||
|
||||
9. All nodes are running docker, so to run a docker app browse back to Marathon http://master0:8080, and create an application to run "sudo docker run hello-world". Once running browse back to Mesos in a similar fashion to the above instructions to see that it has run:
|
||||
|
||||
![Image of setting up docker application in Marathon](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/marathon-docker.png)
|
||||
|
||||
## Chronos Walkthrough
|
||||
|
||||
1. from the jumpbox browse to http://master0:4400/, and verify you see the Marathon Web UI:
|
||||
|
||||
![Image of Chronos UI](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/chronos-ui.png)
|
||||
|
||||
2. Click Add and fill in the following details:
|
||||
1. Name - "MyFirstApp"
|
||||
2. Command - "echo "my first app on Chronos""
|
||||
3. Owner, and Owner Name - you can put random information Here
|
||||
4. Schedule - Set to P"T1M" in order to run this every minute
|
||||
|
||||
![Image of adding a new scheduled operation in Chronos](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/chronos.png)
|
||||
|
||||
3. Click Create
|
||||
|
||||
4. Watch the task run, and then browse back to the Mesos UI http://master0:5050 and observe the output in the completed task.
|
||||
|
||||
5. All nodes are running docker, so to run a docker app browse back to Chronos http://master0:4400, and create an application to run "sudo docker run hello-world". Once running browse back to Mesos in a similar fashion to the above instructions to verify that it has run:
|
||||
|
||||
![Image of setting up docker application in Marathon](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/chronos-docker.png)
|
||||
|
||||
# Swarm Cluster Walkthrough
|
||||
|
||||
Once your cluster has been created you will have a resource group containing 2 parts:
|
||||
|
||||
1. a set of 1,3,5 masters in a master specific availability set. Each master's SSH can be accessed via the public dns address at ports 2200..2204
|
||||
|
||||
2. a set of agents behind in an agent specific availability set. The agent VMs must be accessed through the master.
|
||||
|
||||
The following image is an example of a cluster with 3 masters, and 3 agents:
|
||||
|
||||
![Image of Swarm cluster on azure](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/swarm.png)
|
||||
|
||||
All VMs are on the same private subnet, 10.0.0.0/18, and fully accessible to each other.
|
||||
|
||||
## Explore Swarm with Simple hello world
|
||||
1. After successfully deploying the template write down the two output master and agent FQDNs.
|
||||
2. SSH to port 2200 of the master FQDN
|
||||
3. Type `docker -H :2375 info` to see the status of the agent nodes.
|
||||
![Image of docker info](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/dockerinfo.png)
|
||||
4. Type `docker -H :2375 run -it hello-world` to see the hello-world test app run on one of the agents
|
||||
|
||||
## Explore Swarm with a web-based Compose Script, then scale the script to all agents
|
||||
1. After successfully deploying the template write down the two output master and agent FQDNs.
|
||||
2. create the following docker-compose.yml file with the following content:
|
||||
```
|
||||
web:
|
||||
image: "yeasy/simple-web"
|
||||
ports:
|
||||
- "80:80"
|
||||
restart: "always"
|
||||
```
|
||||
3. type `export DOCKER_HOST=:2375` so that docker-compose automatically hits the swarm endpoints
|
||||
4. type `docker-compose up -d` to create the simple web server. this will take about a minute to pull the image
|
||||
5. once completed, type `docker ps` to see the running image.
|
||||
![Image of docker ps](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/dockerps.png)
|
||||
6. in your web browser hit the agent FQDN endpoint you recorded in step #1 and you should see the following page, with a counter that increases on each refresh.
|
||||
![Image of the web page](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/swarmbrowser.png)
|
||||
7. You can now scale the web application by typing `docker-compose scale web=3`, and this will scale to the rest of your agents. The Azure load balancer will automatically pick up the new containers.
|
||||
![Image of docker scaling](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/dockercomposescale.png)
|
||||
|
||||
# Swarm Windows Cluster Walkthrough
|
||||
|
||||
Once your Swarm Windows cluster has been created you will have a resource group containing 2 parts:
|
||||
|
||||
1. a set of 1,3,5 masters in a master specific availability set. Each master's SSH can be accessed via the public dns address at ports 2200..2204
|
||||
2. a set of agents behind in an agent specific availability set. Each Windows Agent can be access via RDP through ports 3389 for agent0, 3390 for agent1, 3391 for agent2 and so on.
|
||||
|
||||
The following image is an example of a cluster with 3 masters, and 3 agents:
|
||||
|
||||
![Image of Swarm Windows cluster on azure](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/swarmwindows.png)
|
||||
|
||||
All VMs are on the same private vnet and masters on subnet 172.16.0.0/24, and agents on subnet 10.0.0.0/8, and fully accessible to each other.
|
||||
|
||||
## Explore Swarm with Simple hello world
|
||||
1. After successfully deploying the template write down the two output master and agent FQDNs.
|
||||
2. SSH to port 2200 of the master FQDN
|
||||
3. Type `docker -H :2375 info` to see the status of the agent nodes.
|
||||
![Image of docker info](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/dockerinfowindows.png)
|
||||
4. Type `docker -H :2375 run --rm -i windowsservercore powershell -command "Write-Output 'hello world'"` to see the hello-world test app run on one of the agents
|
||||
|
||||
## Explore Swarm with a web-based Compose Script, then scale the script to all agents
|
||||
1. After successfully deploying the template write down the two output master and agent FQDNs.
|
||||
2. type `export DOCKER_HOST=:2375` so that docker-compose automatically hits the swarm endpoints
|
||||
3. create the following docker-compose.yml file with the following content:
|
||||
```
|
||||
web:
|
||||
image: "windowsservercore"
|
||||
command: [powershell.exe, -command, "<#code used from https://gist.github.com/wagnerandrade/5424431#> ; $$ip = (Get-NetIPAddress | where {$$_.IPAddress -Like '*.*.*.*'})[0].IPAddress ; $$url = 'http://'+$$ip+':80/' ; $$listener = New-Object System.Net.HttpListener ; $$listener.Prefixes.Add($$url) ; $$listener.Start() ; $$callerCounts = @{} ; Write-Host('Listening at {0}...' -f $$url) ; while ($$listener.IsListening) { ;$$context = $$listener.GetContext() ;$$requestUrl = $$context.Request.Url ;$$clientIP = $$context.Request.RemoteEndPoint.Address ;$$response = $$context.Response ;Write-Host '' ;Write-Host('> {0}' -f $$requestUrl) ; ;$$count = 1 ;$$k=$$callerCounts.Get_Item($$clientIP) ;if ($$k -ne $$null) { $$count += $$k } ;$$callerCounts.Set_Item($$clientIP, $$count) ;$$header='<html><body><H1>Windows Container Web Server</H1>' ;$$callerCountsString='' ;$$callerCounts.Keys | % { $$callerCountsString+='<p>IP {0} callerCount {1} ' -f $$_,$$callerCounts.Item($$_) } ;$$footer='</body></html>' ;$$content='{0}{1}{2}' -f $$header,$$callerCountsString,$$footer ;Write-Output $$content ;$$buffer = [System.Text.Encoding]::UTF8.GetBytes($$content) ;$$response.ContentLength64 = $$buffer.Length ;$$response.OutputStream.Write($$buffer, 0, $$buffer.Length) ;$$response.Close() ;$$responseStatus = $$response.StatusCode ;Write-Host('< {0}' -f $$responseStatus) } ; "]
|
||||
ports:
|
||||
- "80:80"
|
||||
restart: "always"
|
||||
```
|
||||
4. type `docker-compose up -d` to create the simple web server. this will take about a minute to start the image
|
||||
|
||||
5. once completed, type `docker ps` to see the running image.
|
||||
|
||||
![Image of docker ps](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/dockerpswindows.png)
|
||||
|
||||
6. in your web browser hit the agent FQDN endpoint you recorded in step #1 and you should see the following page, with a counter that increases on each refresh.
|
||||
|
||||
![Image of the web page](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/swarmbrowserwindows.png)
|
||||
|
||||
7. You can now scale the web application by typing `docker-compose scale web=3`, and this will scale to the rest of your agents. The Azure load balancer will automatically pick up the new containers.
|
||||
|
||||
![Image of docker scaling](https://raw.githubusercontent.com/anhowe/scratch/master/mesos-marathon-vmss/images/dockercomposescalewindows.png)
|
||||
|
||||
# Sample Workloads
|
||||
|
||||
Try the following workloads to test your new mesos cluster. Run these on Marathon using the examples above
|
||||
|
||||
1. **Folding@Home** - [docker run rgardler/fah](https://hub.docker.com/r/rgardler/fah/) - Folding@Home is searching for a cure for Cancer, Alzheimers, Parkinsons and other such diseases. Donate some compute time to this fantastic effort.
|
||||
|
||||
2. **Mount Azure Files volume within Docker Container** - [docker run --privileged anhowe/azure-file-workload STORAGEACCOUNTNAME STORAGEACCOUNTKEY SHARENAME](https://github.com/anhowe/azure-file-workload) - From each container mount your Azure storage by using Azure files
|
||||
|
||||
3. **Explore Docker Hub** - explore Docker Hub for 100,000+ different container workloads: https://hub.docker.com/explore/
|
||||
|
||||
# Questions
|
||||
**Q.** Why is there a jumpbox for the mesos Cluster?
|
||||
|
||||
**A.** The jumpbox is used for easy troubleshooting on the private subnet. The Mesos Web UI requires access to all machines. Also the web UI. You could also consider using OpenVPN to access the private subnet.
|
||||
|
||||
**Q.** My cluster just completed but Mesos is not up.
|
||||
|
||||
**A.** After your template finishes, your cluster is still running installation. You can run "tail -f /var/log/azure/cluster-bootstrap.log" to verify the status has completed.
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"windowsAdminPassword": {
|
||||
"value": "password1234$"
|
||||
},
|
||||
"jumpboxEndpointDNSNamePrefix": {
|
||||
"value": "anhowejb21h"
|
||||
},
|
||||
"masterEndpointDNSNamePrefix": {
|
||||
"value": "anhowemgmt21h"
|
||||
},
|
||||
"agentEndpointDNSNamePrefix": {
|
||||
"value": "anhoweapp21h"
|
||||
},
|
||||
"agentCount": {
|
||||
"value": 3
|
||||
},
|
||||
"masterCount": {
|
||||
"value": 3
|
||||
},
|
||||
"agentVMSize" : {
|
||||
"value": "Standard_A2"
|
||||
},
|
||||
"sshRSAPublicKey": {
|
||||
"value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
$VerbosePreference="Continue"
|
||||
$deployName="anhowe21h"
|
||||
$RGName=$deployName
|
||||
$locName="SouthEast Asia"
|
||||
#$locName="East US2"
|
||||
#$locName="West US"
|
||||
#$locName="Brazil South"
|
||||
#$locName="Central US"
|
||||
#$locName="East US"
|
||||
#$locName="SouthCentral US"
|
||||
#$locName="Japan East"
|
||||
#$locName="Japan West"
|
||||
#$locName="West Europe"
|
||||
#$locName="North Europe"
|
||||
#$locName="NorthCentral US"
|
||||
#$templateFile= "mesos-cluster-with-linux-jumpbox.json"
|
||||
#$templateFile= "mesos-cluster-with-windows-jumpbox.json"
|
||||
#$templateFile= "mesos-cluster-with-no-jumpbox.json"
|
||||
$templateFile= "swarm-cluster-with-no-jumpbox.json"
|
||||
$templateParameterFile= "cluster.parameters.json"
|
||||
New-AzureRmResourceGroup -Name $RGName -Location $locName -Force
|
||||
|
||||
echo New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateFile $templateFile
|
||||
New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile
|
После Ширина: | Высота: | Размер: 207 KiB |
После Ширина: | Высота: | Размер: 32 KiB |
После Ширина: | Высота: | Размер: 123 KiB |
После Ширина: | Высота: | Размер: 65 KiB |
После Ширина: | Высота: | Размер: 10 KiB |
После Ширина: | Высота: | Размер: 10 KiB |
После Ширина: | Высота: | Размер: 35 KiB |
После Ширина: | Высота: | Размер: 63 KiB |
После Ширина: | Высота: | Размер: 9.8 KiB |
После Ширина: | Высота: | Размер: 9.5 KiB |
После Ширина: | Высота: | Размер: 19 KiB |
После Ширина: | Высота: | Размер: 18 KiB |
После Ширина: | Высота: | Размер: 49 KiB |
После Ширина: | Высота: | Размер: 60 KiB |
После Ширина: | Высота: | Размер: 86 KiB |
После Ширина: | Высота: | Размер: 77 KiB |
После Ширина: | Высота: | Размер: 21 KiB |
После Ширина: | Высота: | Размер: 22 KiB |
После Ширина: | Высота: | Размер: 50 KiB |
После Ширина: | Высота: | Размер: 44 KiB |
После Ширина: | Высота: | Размер: 37 KiB |
После Ширина: | Высота: | Размер: 20 KiB |
После Ширина: | Высота: | Размер: 22 KiB |
После Ширина: | Высота: | Размер: 14 KiB |
После Ширина: | Высота: | Размер: 24 KiB |
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"itemDisplayName": "Create a Marathon/Chronos/Swarm enabled Mesos cluster",
|
||||
"description": "This template creates a Docker capable Apache Mesos cluster with Marathon, Chronos, and Swarm on a configurable number of nodes.",
|
||||
"summary": "Create a Docker capable Apache Mesos cluster on Microsoft Azure with the Marathon/Chronos/Swarm frameworks.",
|
||||
"githubUsername": "anhowe",
|
||||
"dateUpdated": "2015-10-26"
|
||||
}
|
|
@ -0,0 +1,879 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"linuxAdminUsername": {
|
||||
"type": "string",
|
||||
"defaultValue": "azureuser",
|
||||
"metadata": {
|
||||
"description": "User name for the Linux Virtual Machines (SSH or Password)."
|
||||
}
|
||||
},
|
||||
"linuxAdminPassword": {
|
||||
"type": "securestring",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "Password for the Linux Virtual Machine. Not Required. If not set, you must provide a SSH key."
|
||||
}
|
||||
},
|
||||
"sshRSAPublicKey": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "SSH public key used for auth to all Linux machines. Not Required. If not set, you must provide a password key."
|
||||
}
|
||||
},
|
||||
"windowsAdminUsername": {
|
||||
"type": "string",
|
||||
"defaultValue": "azureuser",
|
||||
"metadata": {
|
||||
"description": "User name for the Windows Jumpbox Virtual Machine (Password Only Supported)."
|
||||
}
|
||||
},
|
||||
"windowsAdminPassword": {
|
||||
"type": "securestring",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "Password for the Windows Jumpbox Virtual Machine."
|
||||
}
|
||||
},
|
||||
"jumpboxEndpointDNSNamePrefix": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "Sets the Domain name label for the jumpbox. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address."
|
||||
}
|
||||
},
|
||||
"masterEndpointDNSNamePrefix": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Sets the Domain name label for the master IP Address. The concatenation of the domain name label and the regional DNS zone make up the fully qualified domain name associated with the public IP address."
|
||||
}
|
||||
},
|
||||
"agentEndpointDNSNamePrefix": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Sets the Domain name label for the agent pool IP Address. The concatenation of the domain name label and the regional DNS zone make up the fully qualified domain name associated with the public IP address."
|
||||
}
|
||||
},
|
||||
"agentCount": {
|
||||
"type": "int",
|
||||
"defaultValue": 1,
|
||||
"metadata": {
|
||||
"description": "The number of Mesos agents for the cluster. This value can be from 1 to 100"
|
||||
},
|
||||
"allowedValues": [
|
||||
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
|
||||
21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
|
||||
41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,
|
||||
61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
|
||||
81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
|
||||
]
|
||||
},
|
||||
"masterCount": {
|
||||
"type": "int",
|
||||
"defaultValue": 1,
|
||||
"allowedValues": [
|
||||
1,
|
||||
3,
|
||||
5
|
||||
],
|
||||
"metadata": {
|
||||
"description": "The number of Mesos masters for the cluster."
|
||||
}
|
||||
},
|
||||
"agentVMSize": {
|
||||
"type": "string",
|
||||
"defaultValue": "Standard_D2",
|
||||
"allowedValues": [
|
||||
"Standard_A0", "Standard_A1", "Standard_A2", "Standard_A3", "Standard_A4", "Standard_A5",
|
||||
"Standard_A6", "Standard_A7", "Standard_A8", "Standard_A9", "Standard_A10", "Standard_A11",
|
||||
"Standard_D1", "Standard_D2", "Standard_D3", "Standard_D4",
|
||||
"Standard_D11", "Standard_D12", "Standard_D13", "Standard_D14",
|
||||
"Standard_D1_v2", "Standard_D2_v2", "Standard_D3_v2", "Standard_D4_v2", "Standard_D5_v2",
|
||||
"Standard_D11_v2", "Standard_D12_v2", "Standard_D13_v2", "Standard_D14_v2",
|
||||
"Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5",
|
||||
"Standard_DS1", "Standard_DS2", "Standard_DS3", "Standard_DS4",
|
||||
"Standard_DS11", "Standard_DS12", "Standard_DS13", "Standard_DS14",
|
||||
"Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5"
|
||||
],
|
||||
"metadata": {
|
||||
"description": "The size of the Virtual Machine."
|
||||
}
|
||||
},
|
||||
"enableVMDiagnostics": {
|
||||
"type": "bool",
|
||||
"defaultValue": true,
|
||||
"metadata": {
|
||||
"description": "Allows user to enable/disable Boot and VM diagnostics."
|
||||
}
|
||||
},
|
||||
"linuxPublisher": {
|
||||
"type": "string",
|
||||
"defaultValue": "Canonical",
|
||||
"metadata": {
|
||||
"description": "This is the publisher of the image used by the linux cluster"
|
||||
}
|
||||
},
|
||||
"linuxOffer": {
|
||||
"type": "string",
|
||||
"defaultValue": "UbuntuServer",
|
||||
"metadata": {
|
||||
"description": "This is the offer of the image used by the linux cluster"
|
||||
}
|
||||
},
|
||||
"linuxSku": {
|
||||
"type": "string",
|
||||
"defaultValue": "14.04.4-LTS",
|
||||
"metadata": {
|
||||
"description": "This is the linux sku used by the linux cluster"
|
||||
}
|
||||
},
|
||||
"linuxVersion": {
|
||||
"type": "string",
|
||||
"defaultValue": "latest",
|
||||
"metadata": {
|
||||
"description": "This is the linux version used by the linux cluster"
|
||||
}
|
||||
},
|
||||
"windowsJumpboxPublisher": {
|
||||
"type": "string",
|
||||
"defaultValue": "MicrosoftVisualStudio",
|
||||
"metadata": {
|
||||
"description": "This is the windows publisher used by the windows jumpbox"
|
||||
}
|
||||
},
|
||||
"windowsJumpboxOffer": {
|
||||
"type": "string",
|
||||
"defaultValue": "VisualStudio",
|
||||
"metadata": {
|
||||
"description": "This is the windows offer used by the windows jumpbox"
|
||||
}
|
||||
},
|
||||
"windowsJumpboxSku": {
|
||||
"type": "string",
|
||||
"defaultValue": "VS-2015-Ent-AzureSDK-2.8-WS2012R2.2",
|
||||
"metadata": {
|
||||
"description": "This is the windows sku used by the windows jumpbox"
|
||||
}
|
||||
},
|
||||
"isValidation": {
|
||||
"type": "int",
|
||||
"defaultValue": 0,
|
||||
"allowedValues": [0,1],
|
||||
"metadata": {
|
||||
"description": "This is testing in the validation region"
|
||||
}
|
||||
},
|
||||
"disablePasswordAuthentication": {
|
||||
"type": "bool",
|
||||
"defaultValue": true,
|
||||
"metadata": {
|
||||
"description": "This setting controls whether password auth is disabled for Linux VMs provisioned by this template. Default is true which disables password and makes SSH key required."
|
||||
}
|
||||
},
|
||||
"setLinuxConfigurationForVMCreate": {
|
||||
"type": "int",
|
||||
"defaultValue": 1,
|
||||
"allowedValues": [0,1],
|
||||
"metadata": {
|
||||
"description": "This setting controls whether Linux configuration with SSH Key is passed in VM PUT Payload. Defaults to 1. If SSH Key is blank, this must be set to 0."
|
||||
}
|
||||
},
|
||||
"nameSuffix": {
|
||||
"type": "string",
|
||||
"defaultValue": "01234567",
|
||||
"metadata": {
|
||||
"description": "A string to include in the names of resources created. Defaults to 0. Can not be blank."
|
||||
}
|
||||
},
|
||||
"vmsPerStorageAccount": {
|
||||
"type": "int",
|
||||
"defaultValue": 20,
|
||||
"metadata": {
|
||||
"description": "This specifies the number of VMs per storage accounts"
|
||||
}
|
||||
},
|
||||
"postInstallScriptURI": {
|
||||
"type": "string",
|
||||
"defaultValue": "disabled",
|
||||
"metadata": {
|
||||
"description": "After installation, this specifies a script to download and install. To disabled, set value to 'disabled'."
|
||||
}
|
||||
},
|
||||
"enableNewStorageAccountNaming": {
|
||||
"type": "bool",
|
||||
"defaultValue": true,
|
||||
"metadata": {
|
||||
"description": "If true: uses DNS name prefix + Orchestrator name + Region to create storage account name to reduce name collision probability. If false: uses DNS name prefix + Orchestrator name to create storage account name to maintain template idempotency."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"adminUsername": "[parameters('linuxAdminUsername')]",
|
||||
"adminPassword": "[parameters('linuxAdminPassword')]",
|
||||
"masterEndpointDNSNamePrefix": "[tolower(parameters('masterEndpointDNSNamePrefix'))]",
|
||||
"agentEndpointDNSNamePrefix": "[tolower(parameters('agentEndpointDNSNamePrefix'))]",
|
||||
"agentCount": "[parameters('agentCount')]",
|
||||
"masterCount": "[parameters('masterCount')]",
|
||||
"agentVMSize": "[parameters('agentVMSize')]",
|
||||
"sshRSAPublicKey": "[parameters('sshRSAPublicKey')]",
|
||||
"linuxPublisher": "[parameters('linuxPublisher')]",
|
||||
"linuxOffer": "[parameters('linuxOffer')]",
|
||||
"linuxSku": "[parameters('linuxSku')]",
|
||||
"linuxVersion": "[parameters('linuxVersion')]",
|
||||
"vmsPerStorageAccount": "[parameters('vmsPerStorageAccount')]",
|
||||
"postInstallScriptURI": "[parameters('postInstallScriptURI')]",
|
||||
|
||||
"nameSuffix": "[parameters('nameSuffix')]",
|
||||
|
||||
"isValidation": "[parameters('isValidation')]",
|
||||
"storageLocations": [
|
||||
"[resourceGroup().location]",
|
||||
"East US 2 (Stage)"
|
||||
],
|
||||
"storageLocation": "[variables('storageLocations')[variables('isValidation')]]",
|
||||
|
||||
"sshKeyPath": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]",
|
||||
"disablePasswordAuthentication": "[parameters('disablePasswordAuthentication')]",
|
||||
"setLinuxConfigurationForVMCreate": "[parameters('setLinuxConfigurationForVMCreate')]",
|
||||
"linuxConfigurations": [
|
||||
{},
|
||||
{
|
||||
"disablePasswordAuthentication": "[variables('disablePasswordAuthentication')]",
|
||||
"ssh": {
|
||||
"publicKeys": [
|
||||
{
|
||||
"path": "[variables('sshKeyPath')]",
|
||||
"keyData": "[variables('sshRSAPublicKey')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"linuxConfiguration": "[variables('linuxConfigurations')[variables('setLinuxConfigurationForVMCreate')]]",
|
||||
|
||||
"orchestratorName": "swarm",
|
||||
|
||||
"masterPublicIPAddressName": "[concat(variables('orchestratorName'), '-master-ip-', variables('masterEndpointDNSNamePrefix'), '-', variables('nameSuffix'))]",
|
||||
"agentPublicIPAddressName": "[concat(variables('orchestratorName'), '-agent-ip-', variables('agentEndpointDNSNamePrefix'), '-', variables('nameSuffix'))]",
|
||||
|
||||
"osImagePublisher": "[variables('linuxPublisher')]",
|
||||
"osImageOffer": "[variables('linuxOffer')]",
|
||||
"osImageSKU": "[variables('linuxSku')]",
|
||||
"osImageVersion": "[variables('linuxVersion')]",
|
||||
|
||||
"virtualNetworkName": "[concat(variables('orchestratorName'), '-vnet-', variables('nameSuffix'))]",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
|
||||
"masterSubnetName": "[concat(variables('orchestratorName'), '-masterSubnet')]",
|
||||
"masterSubnetRef": "[concat(variables('vnetID'),'/subnets/',variables('masterSubnetName'))]",
|
||||
"masterAddressPrefix": "172.16.0.0/24",
|
||||
"subnetName": "[concat(variables('orchestratorName'), '-subnet')]",
|
||||
"subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]",
|
||||
"addressPrefix": "10.0.0.0/8",
|
||||
"subnetPrefix": "10.0.0.0/11",
|
||||
"storageAccountPrefixes": [
|
||||
"0","6","c","i","o","u","1","7","d","j","p","v",
|
||||
"2","8","e","k","q","w","3","9","f","l","r","x",
|
||||
"4","a","g","m","s","y","5","b","h","n","t","z"
|
||||
],
|
||||
"storageAccountPrefixesCount": "[length(variables('storageAccountPrefixes'))]",
|
||||
"enableNewStorageAccountNaming": "[parameters('enableNewStorageAccountNaming')]",
|
||||
"storageAccountBaseNameNewSuffix-true":"[resourceGroup().location]",
|
||||
"storageAccountBaseNameNewSuffix-false":"",
|
||||
"storageAccountBaseName": "[concat(uniqueString(concat(variables('masterEndpointDNSNamePrefix'),variables(concat('storageAccountBaseNameNewSuffix', '-', variables('enableNewStorageAccountNaming'))))), variables('orchestratorName'))]",
|
||||
"masterStorageAccountName": "[concat(variables('storageAccountBaseName'), '0')]",
|
||||
"omsStorageAccount": "none",
|
||||
"omsStorageAccountKey": "none",
|
||||
"clusterInstallParameters": "[concat(variables('masterCount'), ' ',variables('masterVMNamePrefix'), ' ',variables('masterFirstAddr'), ' ',variables('adminUsername'),' ',variables('postInstallScriptURI'),' ',split(variables('masterAddressPrefix'),'0/24')[0])]",
|
||||
|
||||
"masterVMNamePrefix": "[concat(variables('orchestratorName'), '-master-', variables('nameSuffix'), '-')]",
|
||||
"masterFirstAddr": 5,
|
||||
"masterAvailabilitySet": "[concat(variables('orchestratorName'), '-master-availabilitySet-', variables('nameSuffix'))]",
|
||||
"masterLbName": "[concat(variables('orchestratorName'), '-master-lb-', variables('nameSuffix'))]",
|
||||
"masterSizes": ["Standard_D2", "Standard_A1"],
|
||||
"masterVMSize": "[variables('masterSizes')[variables('isValidation')]]",
|
||||
"masterLbID": "[resourceId('Microsoft.Network/loadBalancers',variables('masterLbName'))]",
|
||||
"masterLbIPConfigName": "[concat(variables('orchestratorName'), '-master-lbFrontEnd-', variables('nameSuffix'))]",
|
||||
"masterLbIPConfigID": "[concat(variables('masterLbID'),'/frontendIPConfigurations/', variables('masterLbIPConfigName'))]",
|
||||
"masterLbBackendPoolName": "[concat(variables('orchestratorName'), '-master-pool-', variables('nameSuffix'))]",
|
||||
"masterCustomScript": "[concat('/bin/bash -c \"/bin/bash /opt/azure/containers/configure-swarm-cluster.sh ',variables('clusterInstallParameters'),' >> /var/log/azure/cluster-bootstrap.log 2>&1\"')]",
|
||||
|
||||
"agentFirstAddr": 20,
|
||||
"agentVMNamePrefix": "[concat(variables('orchestratorName'), '-agent-', variables('nameSuffix'))]",
|
||||
"agentsLbName": "[concat(variables('orchestratorName'), '-agent-lb-', variables('nameSuffix'))]",
|
||||
"agentsLbID": "[resourceId('Microsoft.Network/loadBalancers',variables('agentsLbName'))]",
|
||||
"agentsLbIPConfigName": "[concat(variables('orchestratorName'), '-agent-lbFrontEnd-', variables('nameSuffix'))]",
|
||||
"agentsLbIPConfigID": "[concat(variables('agentsLbID'),'/frontendIPConfigurations/', variables('agentsLbIPConfigName'))]",
|
||||
"agentsLbBackendPoolName": "[concat(variables('orchestratorName'), '-agent-pool-', variables('nameSuffix'))]",
|
||||
"agentMaxVMs" : 100,
|
||||
"agentStorageAccountsCount": "[div(variables('agentMaxVMs'), variables('vmsPerStorageAccount'))]",
|
||||
"agentsPerIPv4Octet": 200,
|
||||
"agentCustomScript": "[concat('/usr/bin/nohup /bin/bash -c \"/bin/bash /opt/azure/containers/configure-swarm-cluster.sh ',variables('clusterInstallParameters'),' >> /var/log/azure/cluster-bootstrap.log 2>&1 &\" &')]",
|
||||
"agentRunCmdFile": "[concat(' - content: |\n #!/bin/bash\n ',variables('agentCustomScript'),'\n path: /opt/azure/containers/install-cluster.sh\n permissions: \"0744\"\n')]",
|
||||
"agentRunCmd": "[concat('runcmd:\n - [ /bin/bash, /opt/azure/containers/install-cluster.sh ]\n\n')]",
|
||||
|
||||
"enableVMDiagnostics": "[parameters('enableVMDiagnostics')]",
|
||||
"diagnosticsStorageAccountName": "[concat(variables('storageAccountBaseName'), 'diag', '0')]",
|
||||
"diagnosticsStorageAccountName-true" : "[variables('diagnosticsStorageAccountName')]",
|
||||
"diagnosticsStorageAccountName-false" : "",
|
||||
"diagnosticsStorageAccountResourceGroup": "[resourceGroup().name]",
|
||||
"accountid": "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/',variables('diagnosticsStorageAccountResourceGroup'),'/providers/','Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName'))]",
|
||||
"wadlogs": "<WadCfg><DiagnosticMonitorConfiguration>",
|
||||
"wadperfcounters1-true": "<PerformanceCounters scheduledTransferPeriod=\"PT1M\"><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\AvailableMemory\" sampleRate=\"PT15S\" unit=\"Bytes\"><annotation displayName=\"Memory available\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\PercentAvailableMemory\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"Mem. percent available\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\UsedMemory\" sampleRate=\"PT15S\" unit=\"Bytes\"><annotation displayName=\"Memory used\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\PercentUsedMemory\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"Memory percentage\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\PercentUsedByCache\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"Mem. used by cache\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Processor\\PercentIdleTime\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"CPU idle time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Processor\\PercentUserTime\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"CPU user time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Processor\\PercentProcessorTime\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"CPU percentage guest OS\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Processor\\PercentIOWaitTime\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"CPU IO wait time\" locale=\"en-us\"/></PerformanceCounterConfiguration>",
|
||||
"wadperfcounters2-true": "<PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\BytesPerSecond\" sampleRate=\"PT15S\" unit=\"BytesPerSecond\"><annotation displayName=\"Disk total bytes\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\ReadBytesPerSecond\" sampleRate=\"PT15S\" unit=\"BytesPerSecond\"><annotation displayName=\"Disk read guest OS\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\WriteBytesPerSecond\" sampleRate=\"PT15S\" unit=\"BytesPerSecond\"><annotation displayName=\"Disk write guest OS\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\TransfersPerSecond\" sampleRate=\"PT15S\" unit=\"CountPerSecond\"><annotation displayName=\"Disk transfers\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\ReadsPerSecond\" sampleRate=\"PT15S\" unit=\"CountPerSecond\"><annotation displayName=\"Disk reads\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\WritesPerSecond\" sampleRate=\"PT15S\" unit=\"CountPerSecond\"><annotation displayName=\"Disk writes\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\AverageReadTime\" sampleRate=\"PT15S\" unit=\"Seconds\"><annotation displayName=\"Disk read time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\AverageWriteTime\" sampleRate=\"PT15S\" unit=\"Seconds\"><annotation displayName=\"Disk write time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\AverageTransferTime\" sampleRate=\"PT15S\" unit=\"Seconds\"><annotation displayName=\"Disk transfer time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\AverageDiskQueueLength\" sampleRate=\"PT15S\" unit=\"Count\"><annotation displayName=\"Disk queue length\" locale=\"en-us\"/></PerformanceCounterConfiguration></PerformanceCounters>",
|
||||
"wadperfcounters1-false": "",
|
||||
"wadperfcounters2-false": "",
|
||||
"wadcfgxstart": "[concat(variables('wadlogs'),variables(concat('wadperfcounters1','-',variables('enableVMDiagnostics'))),variables(concat('wadperfcounters2','-',variables('enableVMDiagnostics'))),'<Metrics resourceId=\"')]",
|
||||
"wadcfgxend": "[concat('\"><MetricAggregation scheduledTransferPeriod=\"PT1H\"/><MetricAggregation scheduledTransferPeriod=\"PT1M\"/></Metrics></DiagnosticMonitorConfiguration></WadCfg>')]",
|
||||
|
||||
"computeApiVersion": "2016-03-30",
|
||||
"networkApiVersion": "2016-03-30",
|
||||
"storageApiVersion": "2015-06-15",
|
||||
|
||||
#vmsizemapping
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[variables('masterStorageAccountName')]",
|
||||
"apiVersion": "[variables('storageApiVersion')]",
|
||||
"location": "[variables('storageLocation')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"accountType":"[variables('vmSizesMap')[variables('masterVMSize')].storageAccountType]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[variables('diagnosticsStorageAccountName')]",
|
||||
"apiVersion": "[variables('storageApiVersion')]",
|
||||
"location": "[variables('storageLocation')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"accountType": "[variables('vmSizesMap')[variables('masterVMSize')].storageAccountType]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[variables('virtualNetworkName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]",
|
||||
"[variables('masterAddressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "[variables('masterSubnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('masterAddressPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"type": "Microsoft.Compute/availabilitySets",
|
||||
"name": "[variables('masterAvailabilitySet')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('masterPublicIPAddressName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('masterEndpointDNSNamePrefix')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"name": "[variables('masterLbName')]",
|
||||
"type": "Microsoft.Network/loadBalancers",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"frontendIPConfigurations": [
|
||||
{
|
||||
"name": "[variables('masterLbIPConfigName')]",
|
||||
"properties": {
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('masterPublicIPAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"backendAddressPools": [
|
||||
{
|
||||
"name": "[variables('masterLbBackendPoolName')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/loadBalancers/inboundNatRules",
|
||||
"name": "[concat(variables('masterLbName'), '/', 'SSH-', variables('masterVMNamePrefix'), copyIndex())]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "masterLbLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[variables('masterLbID')]"
|
||||
],
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[variables('masterLbIPConfigID')]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": "[copyIndex(2200)]",
|
||||
"backendPort": 22,
|
||||
"enableFloatingIP": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[concat(variables('masterVMNamePrefix'), 'nic-', copyIndex())]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "nicLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[variables('masterLbID')]",
|
||||
"[variables('vnetID')]",
|
||||
"[concat(variables('masterLbID'),'/inboundNatRules/SSH-',variables('masterVMNamePrefix'),copyIndex())]"
|
||||
],
|
||||
"properties": {
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipConfigNode",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Static",
|
||||
"privateIPAddress": "[concat(split(variables('masterAddressPrefix'),'0/24')[0], copyIndex(variables('masterFirstAddr')))]",
|
||||
"subnet": {
|
||||
"id": "[variables('masterSubnetRef')]"
|
||||
},
|
||||
"loadBalancerBackendAddressPools": [
|
||||
{
|
||||
"id": "[concat(variables('masterLbID'), '/backendAddressPools/', variables('masterLbBackendPoolName'))]"
|
||||
}
|
||||
],
|
||||
"loadBalancerInboundNatRules": [
|
||||
{
|
||||
"id": "[concat(variables('masterLbID'),'/inboundNatRules/SSH-',variables('masterVMNamePrefix'),copyIndex())]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[concat(variables('masterVMNamePrefix'), copyIndex())]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "vmLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('masterVMNamePrefix'), 'nic-', copyIndex())]",
|
||||
"[concat('Microsoft.Compute/availabilitySets/',variables('masterAvailabilitySet'))]",
|
||||
"[variables('masterStorageAccountName')]",
|
||||
"[variables('diagnosticsStorageAccountName')]"
|
||||
],
|
||||
"properties": {
|
||||
"availabilitySet": {
|
||||
"id": "[resourceId('Microsoft.Compute/availabilitySets',variables('masterAvailabilitySet'))]"
|
||||
},
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('masterVMSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computername": "[concat(variables('masterVMNamePrefix'), copyIndex())]",
|
||||
"adminUsername": "[variables('adminUsername')]",
|
||||
"adminPassword": "[variables('adminPassword')]",
|
||||
"customData": "[base64('#clusterCustomDataInstallYaml')]",
|
||||
"linuxConfiguration": "[variables('linuxConfiguration')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('osImagePublisher')]",
|
||||
"offer": "[variables('osImageOffer')]",
|
||||
"sku": "[variables('osImageSKU')]",
|
||||
"version": "[variables('osImageVersion')]"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[concat(variables('masterVMNamePrefix'), copyIndex(),'-osdisk')]",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('masterStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob, 'vhds/', variables('masterVMNamePrefix'), copyIndex(), '-osdisk.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('masterVMNamePrefix'), 'nic-', copyIndex()))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "[variables('enableVMDiagnostics')]",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('masterVMNamePrefix'), copyIndex(), '/linuxdiagnostic')]",
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "vmLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', concat(variables('masterVMNamePrefix'), copyIndex()))]"
|
||||
],
|
||||
"properties":
|
||||
{
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "LinuxDiagnostic",
|
||||
"typeHandlerVersion": "2.3",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"xmlCfg": "[base64(concat(variables('wadcfgxstart'), variables('masterVMNamePrefix'), copyIndex(), variables('wadcfgxend')))]",
|
||||
"StorageAccount": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]"
|
||||
},
|
||||
"protectedSettings": {
|
||||
"storageAccountName": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]",
|
||||
"storageAccountKey": "[listKeys(variables('accountid'), variables('storageApiVersion')).key1]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('masterVMNamePrefix'), copyIndex(), '/configuremaster')]",
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "vmLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('masterVMNamePrefix'), copyIndex(), '/extensions/linuxdiagnostic')]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"settings": {
|
||||
"fileUris": [],
|
||||
"commandToExecute": "[variables('masterCustomScript')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[concat(variables('storageAccountPrefixes')[mod(copyIndex(),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(copyIndex(),variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),copyIndex(1))]",
|
||||
"apiVersion": "[variables('storageApiVersion')]",
|
||||
"location": "[variables('storageLocation')]",
|
||||
"copy": {
|
||||
"name": "vmLoopNode",
|
||||
"count": "[variables('agentStorageAccountsCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('agentPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"accountType": "[variables('vmSizesMap')[variables('agentVMSize')].storageAccountType]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('agentPublicIPAddressName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('agentEndpointDNSNamePrefix')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"name": "[variables('agentsLbName')]",
|
||||
"type": "Microsoft.Network/loadBalancers",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('agentPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"frontendIPConfigurations": [
|
||||
{
|
||||
"name": "[variables('agentsLbIPConfigName')]",
|
||||
"properties": {
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('agentPublicIPAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"backendAddressPools": [
|
||||
{
|
||||
"name": "[variables('agentsLbBackendPoolName')]"
|
||||
}
|
||||
],
|
||||
"loadBalancingRules": [
|
||||
{
|
||||
"name": "LBRuleHTTP",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[variables('agentsLbIPConfigID')]"
|
||||
},
|
||||
"backendAddressPool": {
|
||||
"id": "[concat(variables('agentsLbID'), '/backendAddressPools/', variables('agentsLbBackendPoolName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": 80,
|
||||
"backendPort": 80,
|
||||
"enableFloatingIP": false,
|
||||
"idleTimeoutInMinutes": 5,
|
||||
"loadDistribution": "Default",
|
||||
"probe": {
|
||||
"id": "[concat(variables('agentsLbID'),'/probes/tcpHTTPProbe')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "LBRuleHTTPS",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[variables('agentsLbIPConfigID')]"
|
||||
},
|
||||
"backendAddressPool": {
|
||||
"id": "[concat(variables('agentsLbID'), '/backendAddressPools/', variables('agentsLbBackendPoolName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": 443,
|
||||
"backendPort": 443,
|
||||
"enableFloatingIP": false,
|
||||
"idleTimeoutInMinutes": 5,
|
||||
"loadDistribution": "Default",
|
||||
"probe": {
|
||||
"id": "[concat(variables('agentsLbID'),'/probes/tcpHTTPSProbe')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "LBRulePort8080",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[variables('agentsLbIPConfigID')]"
|
||||
},
|
||||
"backendAddressPool": {
|
||||
"id": "[concat(variables('agentsLbID'), '/backendAddressPools/', variables('agentsLbBackendPoolName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": 8080,
|
||||
"backendPort": 8080,
|
||||
"enableFloatingIP": false,
|
||||
"idleTimeoutInMinutes": 5,
|
||||
"loadDistribution": "Default",
|
||||
"probe": {
|
||||
"id": "[concat(variables('agentsLbID'),'/probes/tcpPort8080Probe')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"name": "tcpHTTPProbe",
|
||||
"properties": {
|
||||
"protocol": "tcp",
|
||||
"port": 80,
|
||||
"intervalInSeconds": "5",
|
||||
"numberOfProbes": "2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tcpHTTPSProbe",
|
||||
"properties": {
|
||||
"protocol": "tcp",
|
||||
"port": 443,
|
||||
"intervalInSeconds": "5",
|
||||
"numberOfProbes": "2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tcpPort8080Probe",
|
||||
"properties": {
|
||||
"protocol": "tcp",
|
||||
"port": 8080,
|
||||
"intervalInSeconds": "5",
|
||||
"numberOfProbes": "2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"inboundNatRules": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"type": "Microsoft.Compute/virtualMachineScaleSets",
|
||||
"name": "[concat(variables('agentVMNamePrefix'), '-vmss')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountPrefixes')[mod(0,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(0,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),1)]",
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountPrefixes')[mod(1,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(1,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),2)]",
|
||||
"[concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(2,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(2,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),3)]",
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountPrefixes')[mod(3,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(3,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),4)]",
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountPrefixes')[mod(4,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(4,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),5)]",
|
||||
"[variables('agentsLbID')]",
|
||||
"[variables('vnetID')]",
|
||||
"[variables('diagnosticsStorageAccountName')]"
|
||||
],
|
||||
"sku": {
|
||||
"name": "[variables('agentVMSize')]",
|
||||
"tier": "Standard",
|
||||
"capacity": "[variables('agentCount')]"
|
||||
},
|
||||
"properties": {
|
||||
"upgradePolicy": {
|
||||
"mode": "Automatic"
|
||||
},
|
||||
"virtualMachineProfile": {
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('osImagePublisher')]",
|
||||
"offer": "[variables('osImageOffer')]",
|
||||
"sku": "[variables('osImageSKU')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[concat(variables('agentVMNamePrefix'), 'vmssosdisk', 0)]",
|
||||
"vhdContainers": [
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(0,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(0,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),1), variables('storageApiVersion') ).primaryEndpoints.blob, 'osdisk')]",
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(1,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(1,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),2), variables('storageApiVersion')).primaryEndpoints.blob, 'osdisk')]",
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(2,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(2,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),3), variables('storageApiVersion')).primaryEndpoints.blob, 'osdisk')]",
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(3,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(3,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),4), variables('storageApiVersion')).primaryEndpoints.blob, 'osdisk')]",
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(4,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(4,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),5), variables('storageApiVersion')).primaryEndpoints.blob, 'osdisk')]"
|
||||
|
||||
],
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"osProfile": {
|
||||
"computerNamePrefix": "[variables('agentVMNamePrefix')]",
|
||||
"adminUsername": "[variables('adminUsername')]",
|
||||
"customData": "[base64(concat('#clusterCustomDataInstallYaml',variables('agentRunCmdFile'),variables('agentRunCmd')))]",
|
||||
"linuxConfiguration": "[variables('linuxConfiguration')]"
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaceConfigurations": [
|
||||
{
|
||||
"name": "agentNodeNic",
|
||||
"properties": {
|
||||
"primary": "true",
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "nicipconfig",
|
||||
"properties": {
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
},
|
||||
"loadBalancerBackendAddressPools": [
|
||||
{
|
||||
"id": "[concat(variables('agentsLbID'), '/backendAddressPools/', variables('agentsLbBackendPoolName'))]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"extensionProfile": {
|
||||
"extensions": [
|
||||
{
|
||||
"name": "LinuxDiagnostic",
|
||||
"properties":
|
||||
{
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "LinuxDiagnostic",
|
||||
"typeHandlerVersion": "2.3",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"xmlCfg": "[base64(concat(variables('wadcfgxstart'), variables('agentVMNamePrefix'), variables('wadcfgxend')))]",
|
||||
"StorageAccount": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]"
|
||||
},
|
||||
"protectedSettings": {
|
||||
"storageAccountName": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]",
|
||||
"storageAccountKey": "[listKeys(variables('accountid'), variables('storageApiVersion')).key1]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "[variables('enableVMDiagnostics')]",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"jumpboxFQDN": {
|
||||
"type": "string",
|
||||
"value": ""
|
||||
},
|
||||
"masterFQDN": {
|
||||
"type": "string",
|
||||
"value": "[reference(concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))).dnsSettings.fqdn]"
|
||||
},
|
||||
"agentFQDN": {
|
||||
"type": "string",
|
||||
"value": "[reference(concat('Microsoft.Network/publicIPAddresses/', variables('agentPublicIPAddressName'))).dnsSettings.fqdn]"
|
||||
},
|
||||
"diagnosticsStorageAccountUri": {
|
||||
"type": "string",
|
||||
"value": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,899 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"linuxAdminUsername": {
|
||||
"type": "string",
|
||||
"defaultValue": "azureuser",
|
||||
"metadata": {
|
||||
"description": "User name for the Linux Virtual Machines (SSH or Password)."
|
||||
}
|
||||
},
|
||||
"linuxAdminPassword": {
|
||||
"type": "securestring",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "Password for the Linux Virtual Machine. Not Required. If not set, you must provide a SSH key."
|
||||
}
|
||||
},
|
||||
"sshRSAPublicKey": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "SSH public key used for auth to all Linux machines. Not Required. If not set, you must provide a password key."
|
||||
}
|
||||
},
|
||||
"windowsAdminUsername": {
|
||||
"type": "string",
|
||||
"defaultValue": "azureuser",
|
||||
"metadata": {
|
||||
"description": "User name for the Windows Jumpbox Virtual Machine (Password Only Supported)."
|
||||
}
|
||||
},
|
||||
"windowsAdminPassword": {
|
||||
"type": "securestring",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "Password for the Windows Jumpbox Virtual Machine."
|
||||
}
|
||||
},
|
||||
"jumpboxEndpointDNSNamePrefix": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Sets the Domain name label for the jumpbox. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address."
|
||||
}
|
||||
},
|
||||
"masterEndpointDNSNamePrefix": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Sets the Domain name label for the master IP Address. The concatenation of the domain name label and the regional DNS zone make up the fully qualified domain name associated with the public IP address."
|
||||
}
|
||||
},
|
||||
"agentEndpointDNSNamePrefix": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Sets the Domain name label for the agent pool IP Address. The concatenation of the domain name label and the regional DNS zone make up the fully qualified domain name associated with the public IP address."
|
||||
}
|
||||
},
|
||||
"agentCount": {
|
||||
"type": "int",
|
||||
"defaultValue": 1,
|
||||
"metadata": {
|
||||
"description": "The number of Mesos agents for the cluster. This value can be from 1 to 100"
|
||||
},
|
||||
"allowedValues": [
|
||||
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
|
||||
21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
|
||||
41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,
|
||||
61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
|
||||
81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
|
||||
]
|
||||
},
|
||||
"masterCount": {
|
||||
"type": "int",
|
||||
"defaultValue": 1,
|
||||
"allowedValues": [
|
||||
1,
|
||||
3,
|
||||
5
|
||||
],
|
||||
"metadata": {
|
||||
"description": "The number of Mesos masters for the cluster."
|
||||
}
|
||||
},
|
||||
"agentVMSize": {
|
||||
"type": "string",
|
||||
"defaultValue": "Standard_D2",
|
||||
"allowedValues": [
|
||||
"Standard_A0", "Standard_A1", "Standard_A2", "Standard_A3", "Standard_A4", "Standard_A5",
|
||||
"Standard_A6", "Standard_A7", "Standard_A8", "Standard_A9", "Standard_A10", "Standard_A11",
|
||||
"Standard_D1", "Standard_D2", "Standard_D3", "Standard_D4",
|
||||
"Standard_D11", "Standard_D12", "Standard_D13", "Standard_D14",
|
||||
"Standard_D1_v2", "Standard_D2_v2", "Standard_D3_v2", "Standard_D4_v2", "Standard_D5_v2",
|
||||
"Standard_D11_v2", "Standard_D12_v2", "Standard_D13_v2", "Standard_D14_v2",
|
||||
"Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5",
|
||||
"Standard_DS1", "Standard_DS2", "Standard_DS3", "Standard_DS4",
|
||||
"Standard_DS11", "Standard_DS12", "Standard_DS13", "Standard_DS14",
|
||||
"Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5"
|
||||
],
|
||||
"metadata": {
|
||||
"description": "The size of the Virtual Machine."
|
||||
}
|
||||
},
|
||||
"enableVMDiagnostics": {
|
||||
"type": "bool",
|
||||
"defaultValue": true,
|
||||
"metadata": {
|
||||
"description": "Allows user to enable/disable Boot and VM diagnostics."
|
||||
}
|
||||
},
|
||||
"linuxPublisher": {
|
||||
"type": "string",
|
||||
"defaultValue": "Canonical",
|
||||
"metadata": {
|
||||
"description": "This is the publisher of the image used by the linux cluster"
|
||||
}
|
||||
},
|
||||
"linuxOffer": {
|
||||
"type": "string",
|
||||
"defaultValue": "UbuntuServer",
|
||||
"metadata": {
|
||||
"description": "This is the offer of the image used by the linux cluster"
|
||||
}
|
||||
},
|
||||
"linuxSku": {
|
||||
"type": "string",
|
||||
"defaultValue": "14.04.4-LTS",
|
||||
"metadata": {
|
||||
"description": "This is the linux sku used by the linux cluster"
|
||||
}
|
||||
},
|
||||
"linuxVersion": {
|
||||
"type": "string",
|
||||
"defaultValue": "latest",
|
||||
"metadata": {
|
||||
"description": "This is the linux version used by the linux cluster"
|
||||
}
|
||||
},
|
||||
"windowsJumpboxPublisher": {
|
||||
"type": "string",
|
||||
"defaultValue": "MicrosoftVisualStudio",
|
||||
"metadata": {
|
||||
"description": "This is the windows publisher used by the windows jumpbox"
|
||||
}
|
||||
},
|
||||
"windowsJumpboxOffer": {
|
||||
"type": "string",
|
||||
"defaultValue": "VisualStudio",
|
||||
"metadata": {
|
||||
"description": "This is the windows offer used by the windows jumpbox"
|
||||
}
|
||||
},
|
||||
"windowsJumpboxSku": {
|
||||
"type": "string",
|
||||
"defaultValue": "VS-2015-Ent-AzureSDK-2.8-WS2012R2.2",
|
||||
"metadata": {
|
||||
"description": "This is the windows sku used by the windows jumpbox"
|
||||
}
|
||||
},
|
||||
"isValidation": {
|
||||
"type": "int",
|
||||
"defaultValue": 0,
|
||||
"allowedValues": [0,1],
|
||||
"metadata": {
|
||||
"description": "This is testing in the validation region"
|
||||
}
|
||||
},
|
||||
"disablePasswordAuthentication": {
|
||||
"type": "bool",
|
||||
"defaultValue": true,
|
||||
"metadata": {
|
||||
"description": "This setting controls whether password auth is disabled for Linux VMs provisioned by this template. Default is true which disables password and makes SSH key required."
|
||||
}
|
||||
},
|
||||
"setLinuxConfigurationForVMCreate": {
|
||||
"type": "int",
|
||||
"defaultValue": 1,
|
||||
"allowedValues": [0,1],
|
||||
"metadata": {
|
||||
"description": "This setting controls whether Linux configuration with SSH Key is passed in VM PUT Payload. Defaults to 1. If SSH Key is blank, this must be set to 0."
|
||||
}
|
||||
},
|
||||
"nameSuffix": {
|
||||
"type": "string",
|
||||
"defaultValue": "01234567",
|
||||
"metadata": {
|
||||
"description": "A string to include in the names of resources created. Defaults to 0. Can not be blank."
|
||||
}
|
||||
},
|
||||
"vmsPerStorageAccount": {
|
||||
"type": "int",
|
||||
"defaultValue": 20,
|
||||
"metadata": {
|
||||
"description": "This specifies the number of VMs per storage accounts"
|
||||
}
|
||||
},
|
||||
"postInstallScriptURI": {
|
||||
"type": "string",
|
||||
"defaultValue": "disabled",
|
||||
"metadata": {
|
||||
"description": "After installation, this specifies a script to download and install. To disabled, set value to 'disabled'."
|
||||
}
|
||||
},
|
||||
"enableNewStorageAccountNaming": {
|
||||
"type": "bool",
|
||||
"defaultValue": true,
|
||||
"metadata": {
|
||||
"description": "If true: uses DNS name prefix + Orchestrator name + Region to create storage account name to reduce name collision probability. If false: uses DNS name prefix + Orchestrator name to create storage account name to maintain template idempotency."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"adminUsername": "[parameters('linuxAdminUsername')]",
|
||||
"adminPassword": "[parameters('linuxAdminPassword')]",
|
||||
"jumpboxEndpointDNSNamePrefix": "[tolower(parameters('jumpboxEndpointDNSNamePrefix'))]",
|
||||
"masterEndpointDNSNamePrefix": "[tolower(parameters('masterEndpointDNSNamePrefix'))]",
|
||||
"agentEndpointDNSNamePrefix": "[tolower(parameters('agentEndpointDNSNamePrefix'))]",
|
||||
"agentCount": "[parameters('agentCount')]",
|
||||
"masterCount": "[parameters('masterCount')]",
|
||||
"agentVMSize": "[parameters('agentVMSize')]",
|
||||
"sshRSAPublicKey": "[parameters('sshRSAPublicKey')]",
|
||||
"linuxPublisher": "[parameters('linuxPublisher')]",
|
||||
"linuxOffer": "[parameters('linuxOffer')]",
|
||||
"linuxSku": "[parameters('linuxSku')]",
|
||||
"linuxVersion": "[parameters('linuxVersion')]",
|
||||
"windowsJumpboxPublisher": "[parameters('windowsJumpboxPublisher')]",
|
||||
"windowsJumpboxOffer": "[parameters('windowsJumpboxOffer')]",
|
||||
"windowsJumpboxSku": "[parameters('windowsJumpboxSku')]",
|
||||
"windowsAdminUsername": "[parameters('windowsAdminUsername')]",
|
||||
"windowsAdminPassword": "[parameters('windowsAdminPassword')]",
|
||||
"vmsPerStorageAccount": "[parameters('vmsPerStorageAccount')]",
|
||||
"postInstallScriptURI": "[parameters('postInstallScriptURI')]",
|
||||
|
||||
"nameSuffix": "[parameters('nameSuffix')]",
|
||||
|
||||
"isValidation": "[parameters('isValidation')]",
|
||||
"storageLocations": [
|
||||
"[resourceGroup().location]",
|
||||
"East US 2 (Stage)"
|
||||
],
|
||||
"storageLocation": "[variables('storageLocations')[variables('isValidation')]]",
|
||||
|
||||
"sshKeyPath": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]",
|
||||
"disablePasswordAuthentication": "[parameters('disablePasswordAuthentication')]",
|
||||
"setLinuxConfigurationForVMCreate": "[parameters('setLinuxConfigurationForVMCreate')]",
|
||||
"linuxConfigurations": [
|
||||
{},
|
||||
{
|
||||
"disablePasswordAuthentication": "[variables('disablePasswordAuthentication')]",
|
||||
"ssh": {
|
||||
"publicKeys": [
|
||||
{
|
||||
"path": "[variables('sshKeyPath')]",
|
||||
"keyData": "[variables('sshRSAPublicKey')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"linuxConfiguration": "[variables('linuxConfigurations')[variables('setLinuxConfigurationForVMCreate')]]",
|
||||
|
||||
"orchestratorName": "mesos",
|
||||
|
||||
"masterPublicIPAddressName": "[concat(variables('orchestratorName'), '-master-ip-', variables('masterEndpointDNSNamePrefix'), '-', variables('nameSuffix'))]",
|
||||
"agentPublicIPAddressName": "[concat(variables('orchestratorName'), '-agent-ip-', variables('agentEndpointDNSNamePrefix'), '-', variables('nameSuffix'))]",
|
||||
"jumpboxPublicIPAddressName": "[concat(variables('orchestratorName'), '-jumpbox-ip-', variables('jumpboxEndpointDNSNamePrefix'), '-', variables('nameSuffix'))]",
|
||||
"marathonEnabled": true,
|
||||
"chronosEnabled": true,
|
||||
"swarmEnabled": false,
|
||||
"osImagePublisher": "[variables('linuxPublisher')]",
|
||||
"osImageOffer": "[variables('linuxOffer')]",
|
||||
"osImageSKU": "[variables('linuxSku')]",
|
||||
"osImageVersion": "[variables('linuxVersion')]",
|
||||
"virtualNetworkName": "[concat(variables('orchestratorName'), '-vnet-', variables('nameSuffix'))]",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
|
||||
"masterSubnetName": "[concat(variables('orchestratorName'), '-masterSubnet')]",
|
||||
"masterSubnetRef": "[concat(variables('vnetID'),'/subnets/',variables('masterSubnetName'))]",
|
||||
"masterAddressPrefix": "172.16.0.0/24",
|
||||
"subnetName": "[concat(variables('orchestratorName'), '-subnet')]",
|
||||
"subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]",
|
||||
"addressPrefix": "10.0.0.0/8",
|
||||
"subnetPrefix": "10.0.0.0/11",
|
||||
"storageAccountPrefixes": [
|
||||
"0","6","c","i","o","u","1","7","d","j","p","v",
|
||||
"2","8","e","k","q","w","3","9","f","l","r","x",
|
||||
"4","a","g","m","s","y","5","b","h","n","t","z"
|
||||
],
|
||||
"storageAccountPrefixesCount": "[length(variables('storageAccountPrefixes'))]",
|
||||
"enableNewStorageAccountNaming": "[parameters('enableNewStorageAccountNaming')]",
|
||||
"storageAccountBaseNameNewSuffix-true":"[resourceGroup().location]",
|
||||
"storageAccountBaseNameNewSuffix-false":"",
|
||||
"storageAccountBaseName": "[concat(uniqueString(concat(variables('masterEndpointDNSNamePrefix'),variables(concat('storageAccountBaseNameNewSuffix', '-', variables('enableNewStorageAccountNaming'))))), variables('orchestratorName'))]",
|
||||
"masterStorageAccountName": "[concat(variables('storageAccountBaseName'), '0')]",
|
||||
"omsStorageAccount": "none",
|
||||
"omsStorageAccountKey": "none",
|
||||
"clusterInstallParameters": "[concat(variables('masterCount'), ' ',variables('masterVMNamePrefix'), ' ',variables('masterFirstAddr'), ' ',variables('swarmEnabled'),' ',variables('marathonEnabled'),' ',variables('chronosEnabled'),' ',variables('omsStorageAccount'),' ',variables('omsStorageAccountKey'),' ', variables('adminUsername'),' ',variables('postInstallScriptURI'),' ',split(variables('masterAddressPrefix'),'0/24')[0])]",
|
||||
|
||||
"jumpboxNSGName": "[concat(variables('orchestratorName'), '-jumpbox-nsg-', variables('nameSuffix'))]",
|
||||
"jumpboxNSGID": "[resourceId('Microsoft.Network/networkSecurityGroups',variables('jumpboxNSGName'))]",
|
||||
"jumpboxAddr": 4,
|
||||
"jumpboxVMName": "[concat('jb-', variables('nameSuffix'))]",
|
||||
"jumpboxVMSize": "Standard_A1",
|
||||
|
||||
"jumpboxLinuxInstallParameters": "[concat(variables('adminUsername'), ' ', variables('masterCount'), ' ', variables('masterFirstAddr'))]",
|
||||
"jumpboxLinuxCustomScript": "[concat('/usr/bin/nohup /bin/bash -c \"/bin/bash /opt/azure/containers/configure-ubuntu.sh ',variables('jumpboxLinuxInstallParameters'),' >> /var/log/azure/jumpbox-bootstrap.log 2>&1 &\" &')]",
|
||||
|
||||
"setBrowserFirstTabDefaultPrefix": "powershell.exe -ExecutionPolicy Unrestricted -command \"New-Item -Path HKLM:'\\SOFTWARE\\Policies\\Microsoft\\Internet Explorer' ; New-Item -Path HKLM:'\\SOFTWARE\\Policies\\Microsoft\\Internet Explorer\\BrowserEmulation' ; New-ItemProperty -Path HKLM:'\\SOFTWARE\\Policies\\Microsoft\\Internet Explorer\\BrowserEmulation' -Name IntranetCompatibilityMode -Value 0 -Type DWord; New-Item -Path HKLM:'\\SOFTWARE\\Policies\\Microsoft\\Internet Explorer\\Main' ; New-ItemProperty -Path HKLM:'\\SOFTWARE\\Policies\\Microsoft\\Internet Explorer\\Main' -Name 'Start Page' -Type String -Value http://\"",
|
||||
"setBrowserFirstTabDefaultSuffix": "0:5050",
|
||||
"jumpboxWindowsCustomScript": "[concat(variables('setBrowserFirstTabDefaultPrefix'),variables('masterVMNamePrefix'),variables('setBrowserFirstTabDefaultSuffix'))]",
|
||||
|
||||
"masterVMNamePrefix": "[concat(variables('orchestratorName'), '-master-', variables('nameSuffix'), '-')]",
|
||||
"masterFirstAddr": 5,
|
||||
"masterAvailabilitySet": "[concat(variables('orchestratorName'), '-master-availabilitySet-', variables('nameSuffix'))]",
|
||||
"masterLbName": "[concat(variables('orchestratorName'), '-master-lb-', variables('nameSuffix'))]",
|
||||
"masterSizes": ["Standard_D2", "Standard_A1"],
|
||||
"masterVMSize": "[variables('masterSizes')[variables('isValidation')]]",
|
||||
"masterLbID": "[resourceId('Microsoft.Network/loadBalancers',variables('masterLbName'))]",
|
||||
"masterLbIPConfigName": "[concat(variables('orchestratorName'), '-master-lbFrontEnd-', variables('nameSuffix'))]",
|
||||
"masterLbIPConfigID": "[concat(variables('masterLbID'),'/frontendIPConfigurations/', variables('masterLbIPConfigName'))]",
|
||||
"masterLbBackendPoolName": "[concat(variables('orchestratorName'), '-master-pool-', variables('nameSuffix'))]",
|
||||
"masterCustomScript": "[concat('/bin/bash -c \"/bin/bash /opt/azure/containers/configure-mesos-cluster.sh ',variables('clusterInstallParameters'),' >> /var/log/azure/cluster-bootstrap.log 2>&1\"')]",
|
||||
|
||||
"agentFirstAddr": 20,
|
||||
"agentVMNamePrefix": "[concat(variables('orchestratorName'), '-agent-', variables('nameSuffix'))]",
|
||||
"agentsLbName": "[concat(variables('orchestratorName'), '-agent-lb-', variables('nameSuffix'))]",
|
||||
"agentsLbID": "[resourceId('Microsoft.Network/loadBalancers',variables('agentsLbName'))]",
|
||||
"agentsLbIPConfigName": "[concat(variables('orchestratorName'), '-agent-lbFrontEnd-', variables('nameSuffix'))]",
|
||||
"agentsLbIPConfigID": "[concat(variables('agentsLbID'),'/frontendIPConfigurations/', variables('agentsLbIPConfigName'))]",
|
||||
"agentsLbBackendPoolName": "[concat(variables('orchestratorName'), '-agent-pool-', variables('nameSuffix'))]",
|
||||
"agentMaxVMs" : 100,
|
||||
"agentStorageAccountsCount": "[div(variables('agentMaxVMs'), variables('vmsPerStorageAccount'))]",
|
||||
"agentsPerIPv4Octet": 200,
|
||||
"agentCustomScript": "[concat('/bin/bash /opt/azure/containers/configure-mesos-cluster.sh ',variables('clusterInstallParameters'),' >> /var/log/azure/cluster-bootstrap.log 2>&1')]",
|
||||
"agentRunCmdFile": "[concat(' - content: |\n #!/bin/bash\n ',variables('agentCustomScript'),'\n path: /opt/azure/containers/install-cluster.sh\n permissions: \"0744\"\n')]",
|
||||
"agentRunCmd": "[concat('runcmd:\n - [ /bin/bash, /opt/azure/containers/install-cluster.sh ]\n\n')]",
|
||||
|
||||
"enableVMDiagnostics": "[parameters('enableVMDiagnostics')]",
|
||||
"diagnosticsStorageAccountName": "[concat(variables('storageAccountBaseName'), 'diag', '0')]",
|
||||
"diagnosticsStorageAccountName-true" : "[variables('diagnosticsStorageAccountName')]",
|
||||
"diagnosticsStorageAccountName-false" : "",
|
||||
"diagnosticsStorageAccountResourceGroup": "[resourceGroup().name]",
|
||||
"accountid": "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/',variables('diagnosticsStorageAccountResourceGroup'),'/providers/','Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName'))]",
|
||||
"wadlogs": "<WadCfg><DiagnosticMonitorConfiguration>",
|
||||
"wadperfcounters1-true": "<PerformanceCounters scheduledTransferPeriod=\"PT1M\"><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\AvailableMemory\" sampleRate=\"PT15S\" unit=\"Bytes\"><annotation displayName=\"Memory available\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\PercentAvailableMemory\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"Mem. percent available\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\UsedMemory\" sampleRate=\"PT15S\" unit=\"Bytes\"><annotation displayName=\"Memory used\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\PercentUsedMemory\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"Memory percentage\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Memory\\PercentUsedByCache\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"Mem. used by cache\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Processor\\PercentIdleTime\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"CPU idle time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Processor\\PercentUserTime\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"CPU user time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Processor\\PercentProcessorTime\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"CPU percentage guest OS\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\Processor\\PercentIOWaitTime\" sampleRate=\"PT15S\" unit=\"Percent\"><annotation displayName=\"CPU IO wait time\" locale=\"en-us\"/></PerformanceCounterConfiguration>",
|
||||
"wadperfcounters2-true": "<PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\BytesPerSecond\" sampleRate=\"PT15S\" unit=\"BytesPerSecond\"><annotation displayName=\"Disk total bytes\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\ReadBytesPerSecond\" sampleRate=\"PT15S\" unit=\"BytesPerSecond\"><annotation displayName=\"Disk read guest OS\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\WriteBytesPerSecond\" sampleRate=\"PT15S\" unit=\"BytesPerSecond\"><annotation displayName=\"Disk write guest OS\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\TransfersPerSecond\" sampleRate=\"PT15S\" unit=\"CountPerSecond\"><annotation displayName=\"Disk transfers\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\ReadsPerSecond\" sampleRate=\"PT15S\" unit=\"CountPerSecond\"><annotation displayName=\"Disk reads\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\WritesPerSecond\" sampleRate=\"PT15S\" unit=\"CountPerSecond\"><annotation displayName=\"Disk writes\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\AverageReadTime\" sampleRate=\"PT15S\" unit=\"Seconds\"><annotation displayName=\"Disk read time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\AverageWriteTime\" sampleRate=\"PT15S\" unit=\"Seconds\"><annotation displayName=\"Disk write time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\AverageTransferTime\" sampleRate=\"PT15S\" unit=\"Seconds\"><annotation displayName=\"Disk transfer time\" locale=\"en-us\"/></PerformanceCounterConfiguration><PerformanceCounterConfiguration counterSpecifier=\"\\PhysicalDisk\\AverageDiskQueueLength\" sampleRate=\"PT15S\" unit=\"Count\"><annotation displayName=\"Disk queue length\" locale=\"en-us\"/></PerformanceCounterConfiguration></PerformanceCounters>",
|
||||
"wadperfcounters1-false": "",
|
||||
"wadperfcounters2-false": "",
|
||||
"wadcfgxstart": "[concat(variables('wadlogs'),variables(concat('wadperfcounters1','-',variables('enableVMDiagnostics'))),variables(concat('wadperfcounters2','-',variables('enableVMDiagnostics'))),'<Metrics resourceId=\"')]",
|
||||
"wadcfgxend": "[concat('\"><MetricAggregation scheduledTransferPeriod=\"PT1H\"/><MetricAggregation scheduledTransferPeriod=\"PT1M\"/></Metrics></DiagnosticMonitorConfiguration></WadCfg>')]",
|
||||
|
||||
"computeApiVersion": "2016-03-30",
|
||||
"networkApiVersion": "2016-03-30",
|
||||
"storageApiVersion": "2015-06-15",
|
||||
|
||||
#vmsizemapping
|
||||
},
|
||||
"resources": [
|
||||
#jumpboxFragment
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[variables('masterStorageAccountName')]",
|
||||
"apiVersion": "[variables('storageApiVersion')]",
|
||||
"location": "[variables('storageLocation')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"accountType":"[variables('vmSizesMap')[variables('masterVMSize')].storageAccountType]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[variables('diagnosticsStorageAccountName')]",
|
||||
"apiVersion": "[variables('storageApiVersion')]",
|
||||
"location": "[variables('storageLocation')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"accountType": "[variables('vmSizesMap')[variables('masterVMSize')].storageAccountType]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[variables('virtualNetworkName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]",
|
||||
"[variables('masterAddressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "[variables('masterSubnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('masterAddressPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"type": "Microsoft.Compute/availabilitySets",
|
||||
"name": "[variables('masterAvailabilitySet')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('masterPublicIPAddressName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('masterEndpointDNSNamePrefix')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"name": "[variables('masterLbName')]",
|
||||
"type": "Microsoft.Network/loadBalancers",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"frontendIPConfigurations": [
|
||||
{
|
||||
"name": "[variables('masterLbIPConfigName')]",
|
||||
"properties": {
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('masterPublicIPAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"backendAddressPools": [
|
||||
{
|
||||
"name": "[variables('masterLbBackendPoolName')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/loadBalancers/inboundNatRules",
|
||||
"name": "[concat(variables('masterLbName'), '/', 'SSH-', variables('masterVMNamePrefix'), copyIndex())]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "masterLbLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[variables('masterLbID')]"
|
||||
],
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[variables('masterLbIPConfigID')]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": "[copyIndex(2200)]",
|
||||
"backendPort": 22,
|
||||
"enableFloatingIP": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[concat(variables('masterVMNamePrefix'), 'nic-', copyIndex())]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "nicLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[variables('masterLbID')]",
|
||||
"[variables('vnetID')]",
|
||||
"[concat(variables('masterLbID'),'/inboundNatRules/SSH-',variables('masterVMNamePrefix'),copyIndex())]"
|
||||
],
|
||||
"properties": {
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipConfigNode",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Static",
|
||||
"privateIPAddress": "[concat(split(variables('masterAddressPrefix'),'0/24')[0], copyIndex(variables('masterFirstAddr')))]",
|
||||
"subnet": {
|
||||
"id": "[variables('masterSubnetRef')]"
|
||||
},
|
||||
"loadBalancerBackendAddressPools": [
|
||||
{
|
||||
"id": "[concat(variables('masterLbID'), '/backendAddressPools/', variables('masterLbBackendPoolName'))]"
|
||||
}
|
||||
],
|
||||
"loadBalancerInboundNatRules": [
|
||||
{
|
||||
"id": "[concat(variables('masterLbID'),'/inboundNatRules/SSH-',variables('masterVMNamePrefix'),copyIndex())]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[concat(variables('masterVMNamePrefix'), copyIndex())]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "vmLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('masterVMNamePrefix'), 'nic-', copyIndex())]",
|
||||
"[concat('Microsoft.Compute/availabilitySets/',variables('masterAvailabilitySet'))]",
|
||||
"[variables('masterStorageAccountName')]",
|
||||
"[variables('diagnosticsStorageAccountName')]"
|
||||
],
|
||||
"properties": {
|
||||
"availabilitySet": {
|
||||
"id": "[resourceId('Microsoft.Compute/availabilitySets',variables('masterAvailabilitySet'))]"
|
||||
},
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('masterVMSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computername": "[concat(variables('masterVMNamePrefix'), copyIndex())]",
|
||||
"adminUsername": "[variables('adminUsername')]",
|
||||
"adminPassword": "[variables('adminPassword')]",
|
||||
"customData": "[base64('#clusterCustomDataInstallYaml')]",
|
||||
"linuxConfiguration": "[variables('linuxConfiguration')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('osImagePublisher')]",
|
||||
"offer": "[variables('osImageOffer')]",
|
||||
"sku": "[variables('osImageSKU')]",
|
||||
"version": "[variables('osImageVersion')]"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[concat(variables('masterVMNamePrefix'), copyIndex(),'-osdisk')]",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('masterStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob, 'vhds/', variables('masterVMNamePrefix'), copyIndex(), '-osdisk.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('masterVMNamePrefix'), 'nic-', copyIndex()))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "[variables('enableVMDiagnostics')]",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName')), variables('storageApiVersion') ).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('masterVMNamePrefix'), copyIndex(), '/linuxdiagnostic')]",
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "vmLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', concat(variables('masterVMNamePrefix'), copyIndex()))]"
|
||||
],
|
||||
"properties":
|
||||
{
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "LinuxDiagnostic",
|
||||
"typeHandlerVersion": "2.3",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"xmlCfg": "[base64(concat(variables('wadcfgxstart'), variables('masterVMNamePrefix'), copyIndex(), variables('wadcfgxend')))]",
|
||||
"StorageAccount": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]"
|
||||
},
|
||||
"protectedSettings": {
|
||||
"storageAccountName": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]",
|
||||
"storageAccountKey": "[listKeys(variables('accountid'), variables('storageApiVersion')).key1]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('masterVMNamePrefix'), copyIndex(), '/configuremaster')]",
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "vmLoopNode",
|
||||
"count": "[variables('masterCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('masterVMNamePrefix'), copyIndex(), '/extensions/linuxdiagnostic')]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"settings": {
|
||||
"fileUris": [],
|
||||
"commandToExecute": "[variables('masterCustomScript')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[concat(variables('storageAccountPrefixes')[mod(copyIndex(),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(copyIndex(),variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),copyIndex(1))]",
|
||||
"apiVersion": "[variables('storageApiVersion')]",
|
||||
"location": "[variables('storageLocation')]",
|
||||
"copy": {
|
||||
"name": "vmLoopNode",
|
||||
"count": "[variables('agentStorageAccountsCount')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('agentPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"accountType": "[variables('vmSizesMap')[variables('agentVMSize')].storageAccountType]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('agentPublicIPAddressName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('agentEndpointDNSNamePrefix')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('networkApiVersion')]",
|
||||
"name": "[variables('agentsLbName')]",
|
||||
"type": "Microsoft.Network/loadBalancers",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('agentPublicIPAddressName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"frontendIPConfigurations": [
|
||||
{
|
||||
"name": "[variables('agentsLbIPConfigName')]",
|
||||
"properties": {
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('agentPublicIPAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"backendAddressPools": [
|
||||
{
|
||||
"name": "[variables('agentsLbBackendPoolName')]"
|
||||
}
|
||||
],
|
||||
"loadBalancingRules": [
|
||||
{
|
||||
"name": "LBRuleHTTP",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[variables('agentsLbIPConfigID')]"
|
||||
},
|
||||
"backendAddressPool": {
|
||||
"id": "[concat(variables('agentsLbID'), '/backendAddressPools/', variables('agentsLbBackendPoolName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": 80,
|
||||
"backendPort": 80,
|
||||
"enableFloatingIP": false,
|
||||
"idleTimeoutInMinutes": 5,
|
||||
"loadDistribution": "Default",
|
||||
"probe": {
|
||||
"id": "[concat(variables('agentsLbID'),'/probes/tcpHTTPProbe')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "LBRuleHTTPS",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[variables('agentsLbIPConfigID')]"
|
||||
},
|
||||
"backendAddressPool": {
|
||||
"id": "[concat(variables('agentsLbID'), '/backendAddressPools/', variables('agentsLbBackendPoolName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": 443,
|
||||
"backendPort": 443,
|
||||
"enableFloatingIP": false,
|
||||
"idleTimeoutInMinutes": 5,
|
||||
"loadDistribution": "Default",
|
||||
"probe": {
|
||||
"id": "[concat(variables('agentsLbID'),'/probes/tcpHTTPSProbe')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "LBRulePort8080",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[variables('agentsLbIPConfigID')]"
|
||||
},
|
||||
"backendAddressPool": {
|
||||
"id": "[concat(variables('agentsLbID'), '/backendAddressPools/', variables('agentsLbBackendPoolName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": 8080,
|
||||
"backendPort": 8080,
|
||||
"enableFloatingIP": false,
|
||||
"idleTimeoutInMinutes": 5,
|
||||
"loadDistribution": "Default",
|
||||
"probe": {
|
||||
"id": "[concat(variables('agentsLbID'),'/probes/tcpPort8080Probe')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"name": "tcpHTTPProbe",
|
||||
"properties": {
|
||||
"protocol": "tcp",
|
||||
"port": 80,
|
||||
"intervalInSeconds": "5",
|
||||
"numberOfProbes": "2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tcpHTTPSProbe",
|
||||
"properties": {
|
||||
"protocol": "tcp",
|
||||
"port": 443,
|
||||
"intervalInSeconds": "5",
|
||||
"numberOfProbes": "2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tcpPort8080Probe",
|
||||
"properties": {
|
||||
"protocol": "tcp",
|
||||
"port": 8080,
|
||||
"intervalInSeconds": "5",
|
||||
"numberOfProbes": "2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"inboundNatRules": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('computeApiVersion')]",
|
||||
"type": "Microsoft.Compute/virtualMachineScaleSets",
|
||||
"name": "[concat(variables('agentVMNamePrefix'), '-vmss')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountPrefixes')[mod(0,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(0,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),1)]",
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountPrefixes')[mod(1,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(1,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),2)]",
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountPrefixes')[mod(2,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(2,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),3)]",
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountPrefixes')[mod(3,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(3,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),4)]",
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountPrefixes')[mod(4,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(4,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),5)]",
|
||||
"[variables('agentsLbID')]",
|
||||
"[variables('vnetID')]",
|
||||
"[variables('diagnosticsStorageAccountName')]"
|
||||
],
|
||||
"sku": {
|
||||
"name": "[variables('agentVMSize')]",
|
||||
"tier": "Standard",
|
||||
"capacity": "[variables('agentCount')]"
|
||||
},
|
||||
"properties": {
|
||||
"upgradePolicy": {
|
||||
"mode": "Automatic"
|
||||
},
|
||||
"virtualMachineProfile": {
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('osImagePublisher')]",
|
||||
"offer": "[variables('osImageOffer')]",
|
||||
"sku": "[variables('osImageSKU')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[concat(variables('agentVMNamePrefix'), 'vmssosdisk', 0)]",
|
||||
"vhdContainers": [
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(0,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(0,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),1), variables('storageApiVersion')).primaryEndpoints.blob, 'osdisk')]",
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(1,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(1,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),2), variables('storageApiVersion')).primaryEndpoints.blob, 'osdisk')]",
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(2,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(2,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),3), variables('storageApiVersion')).primaryEndpoints.blob, 'osdisk')]",
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(3,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(3,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),4), variables('storageApiVersion')).primaryEndpoints.blob, 'osdisk')]",
|
||||
"[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(4,variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(4,variables('storageAccountPrefixesCount'))],variables('storageAccountBaseName'),5), variables('storageApiVersion')).primaryEndpoints.blob, 'osdisk')]"
|
||||
|
||||
],
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"osProfile": {
|
||||
"computerNamePrefix": "[variables('agentVMNamePrefix')]",
|
||||
"adminUsername": "[variables('adminUsername')]",
|
||||
"customData": "[base64(concat('#clusterCustomDataInstallYaml',variables('agentRunCmdFile'),variables('agentRunCmd')))]",
|
||||
"linuxConfiguration": "[variables('linuxConfiguration')]"
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaceConfigurations": [
|
||||
{
|
||||
"name": "agentNodeNic",
|
||||
"properties": {
|
||||
"primary": "true",
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "nicipconfig",
|
||||
"properties": {
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
},
|
||||
"loadBalancerBackendAddressPools": [
|
||||
{
|
||||
"id": "[concat(variables('agentsLbID'), '/backendAddressPools/', variables('agentsLbBackendPoolName'))]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"extensionProfile": {
|
||||
"extensions": [
|
||||
{
|
||||
"name": "LinuxDiagnostic",
|
||||
"properties":
|
||||
{
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "LinuxDiagnostic",
|
||||
"typeHandlerVersion": "2.3",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"xmlCfg": "[base64(concat(variables('wadcfgxstart'), variables('agentVMNamePrefix'), variables('wadcfgxend')))]",
|
||||
"StorageAccount": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]"
|
||||
},
|
||||
"protectedSettings": {
|
||||
"storageAccountName": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]",
|
||||
"storageAccountKey": "[listKeys(variables('accountid'), variables('storageApiVersion')).key1]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "[variables('enableVMDiagnostics')]",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"jumpboxFQDN": {
|
||||
"type": "string",
|
||||
"value": "#jumpboxFQDN"
|
||||
},
|
||||
"masterFQDN": {
|
||||
"type": "string",
|
||||
"value": "[reference(concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))).dnsSettings.fqdn]"
|
||||
},
|
||||
"agentFQDN": {
|
||||
"type": "string",
|
||||
"value": "[reference(concat('Microsoft.Network/publicIPAddresses/', variables('agentPublicIPAddressName'))).dnsSettings.fqdn]"
|
||||
},
|
||||
"diagnosticsStorageAccountUri": {
|
||||
"type": "string",
|
||||
"value": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName')), variables('storageApiVersion')).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"windowsAdminPassword": {
|
||||
"value": "password1234$"
|
||||
},
|
||||
"jumpboxEndpointDNSNamePrefix": {
|
||||
"value": "swarmjb1122g"
|
||||
},
|
||||
"masterEndpointDNSNamePrefix": {
|
||||
"value": "swarmmgmt1122g"
|
||||
},
|
||||
"agentEndpointDNSNamePrefix": {
|
||||
"value": "swarmapp1122g"
|
||||
},
|
||||
"agentCount": {
|
||||
"value": 3
|
||||
},
|
||||
"masterCount": {
|
||||
"value": 3
|
||||
},
|
||||
"agentVMSize" : {
|
||||
"value": "Standard_A1"
|
||||
},
|
||||
"sshRSAPublicKey": {
|
||||
"value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,528 @@
|
|||
#!/bin/bash
|
||||
|
||||
###########################################################
|
||||
# Configure Mesos One Box
|
||||
#
|
||||
# This installs the following components
|
||||
# - zookeepr
|
||||
# - mesos master
|
||||
# - marathon
|
||||
# - mesos agent
|
||||
###########################################################
|
||||
set -x
|
||||
|
||||
echo "starting mesos cluster configuration"
|
||||
date
|
||||
ps ax
|
||||
|
||||
SWARM_VERSION="swarm:1.1.0"
|
||||
#############
|
||||
# Parameters
|
||||
#############
|
||||
MASTERCOUNT=${1}
|
||||
MASTERPREFIX=${2}
|
||||
MASTERFIRSTADDR=${3}
|
||||
SWARMENABLED=`echo ${4} | awk '{print tolower($0)}'`
|
||||
MARATHONENABLED=`echo ${5} | awk '{print tolower($0)}'`
|
||||
CHRONOSENABLED=`echo ${6} | awk '{print tolower($0)}'`
|
||||
ACCOUNTNAME=${7}
|
||||
set +x
|
||||
ACCOUNTKEY=${8}
|
||||
set -x
|
||||
AZUREUSER=${9}
|
||||
POSTINSTALLSCRIPTURI=${10}
|
||||
BASESUBNET=${11}
|
||||
HOMEDIR="/home/$AZUREUSER"
|
||||
VMNAME=`hostname`
|
||||
VMNUMBER=`echo $VMNAME | sed 's/.*[^0-9]\([0-9]\+\)*$/\1/'`
|
||||
VMPREFIX=`echo $VMNAME | sed 's/\(.*[^0-9]\)*[0-9]\+$/\1/'`
|
||||
|
||||
echo "Master Count: $MASTERCOUNT"
|
||||
echo "Master Prefix: $MASTERPREFIX"
|
||||
echo "Master First Addr: $MASTERFIRSTADDR"
|
||||
echo "vmname: $VMNAME"
|
||||
echo "VMNUMBER: $VMNUMBER, VMPREFIX: $VMPREFIX"
|
||||
echo "SWARMENABLED: $SWARMENABLED, MARATHONENABLED: $MARATHONENABLED, CHRONOSENABLED: $CHRONOSENABLED"
|
||||
echo "ACCOUNTNAME: $ACCOUNTNAME"
|
||||
echo "BASESUBNET: $BASESUBNET"
|
||||
|
||||
###################
|
||||
# Common Functions
|
||||
###################
|
||||
ensureAzureNetwork()
|
||||
{
|
||||
# ensure the host name is resolvable
|
||||
hostResolveHealthy=1
|
||||
for i in {1..120}; do
|
||||
host $VMNAME
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
hostResolveHealthy=0
|
||||
echo "the host name resolves"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ $hostResolveHealthy -ne 0 ]
|
||||
then
|
||||
echo "host name does not resolve, aborting install"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ensure the network works
|
||||
networkHealthy=1
|
||||
for i in {1..12}; do
|
||||
wget -O/dev/null http://bing.com
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
networkHealthy=0
|
||||
echo "the network is healthy"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
if [ $networkHealthy -ne 0 ]
|
||||
then
|
||||
echo "the network is not healthy, cannot download from bing, aborting install"
|
||||
ifconfig
|
||||
ip a
|
||||
exit 2
|
||||
fi
|
||||
# ensure the hostname -i works
|
||||
networkHealthy=1
|
||||
for i in {1..120}; do
|
||||
hostname -i
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
networkHealthy=0
|
||||
echo "the network is healthy"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ $networkHealthy -ne 0 ]
|
||||
then
|
||||
echo "the network is not healthy, cannot resolve ip address, aborting install"
|
||||
ifconfig
|
||||
ip a
|
||||
exit 2
|
||||
fi
|
||||
# ensure hostname -f works
|
||||
networkHealthy=1
|
||||
for i in {1..120}; do
|
||||
hostname -f
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
networkHealthy=0
|
||||
echo "the network is healthy"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ $networkHealthy -ne 0 ]
|
||||
then
|
||||
echo "the network is not healthy, cannot resolve hostname, aborting install"
|
||||
ifconfig
|
||||
ip a
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
ensureAzureNetwork
|
||||
HOSTADDR=`hostname -i`
|
||||
|
||||
ismaster ()
|
||||
{
|
||||
if [ "$MASTERPREFIX" == "$VMPREFIX" ]
|
||||
then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
if ismaster ; then
|
||||
echo "this node is a master"
|
||||
fi
|
||||
|
||||
isagent()
|
||||
{
|
||||
if ismaster ; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
if isagent ; then
|
||||
echo "this node is an agent"
|
||||
fi
|
||||
|
||||
isomsrequired()
|
||||
{
|
||||
if [ $ACCOUNTNAME != "none" ]
|
||||
then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
if isomsrequired ; then
|
||||
echo "this node requires oms"
|
||||
fi
|
||||
|
||||
zkhosts()
|
||||
{
|
||||
zkhosts=""
|
||||
for i in `seq 0 $((MASTERCOUNT-1))` ;
|
||||
do
|
||||
if [ "$i" -gt "0" ]
|
||||
then
|
||||
zkhosts="${zkhosts},"
|
||||
fi
|
||||
|
||||
MASTEROCTET=`expr $MASTERFIRSTADDR + $i`
|
||||
IPADDR="${BASESUBNET}${MASTEROCTET}"
|
||||
zkhosts="${zkhosts}${IPADDR}:2181"
|
||||
# due to mesos team experience ip addresses are chosen over dns names
|
||||
#zkhosts="${zkhosts}${MASTERPREFIX}${i}:2181"
|
||||
done
|
||||
echo $zkhosts
|
||||
}
|
||||
|
||||
zkconfig()
|
||||
{
|
||||
postfix="$1"
|
||||
zkhosts=$(zkhosts)
|
||||
zkconfigstr="zk://${zkhosts}/${postfix}"
|
||||
echo $zkconfigstr
|
||||
}
|
||||
|
||||
######################
|
||||
# resolve self in DNS
|
||||
######################
|
||||
echo "$HOSTADDR $VMNAME" | sudo tee -a /etc/hosts
|
||||
|
||||
################
|
||||
# Install Docker
|
||||
################
|
||||
echo "Installing and configuring docker and swarm"
|
||||
installDocker()
|
||||
{
|
||||
for i in {1..10}; do
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO- https://get.docker.com | sh
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
echo "Docker installed successfully"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
}
|
||||
|
||||
time installDocker
|
||||
|
||||
sudo usermod -aG docker $AZUREUSER
|
||||
if isagent ; then
|
||||
# Start Docker and listen on :2375 (no auth, but in vnet)
|
||||
echo 'DOCKER_OPTS="-H unix:///var/run/docker.sock -H 0.0.0.0:2375"' | sudo tee -a /etc/default/docker
|
||||
fi
|
||||
|
||||
if isomsrequired ; then
|
||||
# the following insecure registry is for OMS
|
||||
echo 'DOCKER_OPTS="$DOCKER_OPTS --insecure-registry 137.135.93.9"' | sudo tee -a /etc/default/docker
|
||||
fi
|
||||
|
||||
sudo service docker restart
|
||||
|
||||
ensureDocker()
|
||||
{
|
||||
# ensure that docker is healthy
|
||||
dockerHealthy=1
|
||||
for i in {1..3}; do
|
||||
sudo docker info
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
dockerHealthy=0
|
||||
echo "Docker is healthy"
|
||||
sudo docker ps -a
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
if [ $dockerHealthy -ne 0 ]
|
||||
then
|
||||
echo "Docker is not healthy"
|
||||
fi
|
||||
}
|
||||
|
||||
ensureDocker
|
||||
|
||||
############
|
||||
# setup OMS
|
||||
############
|
||||
if isomsrequired ; then
|
||||
set +x
|
||||
EPSTRING="DefaultEndpointsProtocol=https;AccountName=${ACCOUNTNAME};AccountKey=${ACCOUNTKEY}"
|
||||
docker run --restart=always -d 137.135.93.9/msdockeragentv3 http://${VMNAME}:2375 "${EPSTRING}"
|
||||
set -x
|
||||
fi
|
||||
|
||||
##################
|
||||
# Install Mesos
|
||||
##################
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E56151BF
|
||||
DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
|
||||
CODENAME=$(lsb_release -cs)
|
||||
echo "deb http://repos.mesosphere.io/${DISTRO} ${CODENAME} main" | sudo tee /etc/apt/sources.list.d/mesosphere.list
|
||||
time sudo add-apt-repository -y ppa:openjdk-r/ppa
|
||||
time sudo apt-get -y update
|
||||
time sudo DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes install openjdk-8-jre-headless
|
||||
if ismaster ; then
|
||||
time sudo DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes install mesosphere
|
||||
else
|
||||
time sudo DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes install mesos
|
||||
fi
|
||||
|
||||
#########################
|
||||
# Configure ZooKeeper
|
||||
#########################
|
||||
zkmesosconfig=$(zkconfig "mesos")
|
||||
echo $zkmesosconfig | sudo tee /etc/mesos/zk
|
||||
|
||||
if ismaster ; then
|
||||
echo $VMNUMBER | sudo tee /etc/zookeeper/conf/myid
|
||||
for i in `seq 0 $((MASTERCOUNT-1))` ;
|
||||
do
|
||||
MASTEROCTET=`expr $MASTERFIRSTADDR + $i`
|
||||
IPADDR="${BASESUBNET}${MASTEROCTET}"
|
||||
echo "server.${i}=${IPADDR}:2888:3888" | sudo tee -a /etc/zookeeper/conf/zoo.cfg
|
||||
# due to mesos team experience ip addresses are chosen over dns names
|
||||
#echo "server.${i}=${MASTERPREFIX}${i}:2888:3888" | sudo tee -a /etc/zookeeper/conf/zoo.cfg
|
||||
done
|
||||
fi
|
||||
|
||||
#########################################
|
||||
# Configure Mesos Master and Frameworks
|
||||
#########################################
|
||||
if ismaster ; then
|
||||
quorum=`expr $MASTERCOUNT / 2 + 1`
|
||||
echo $quorum | sudo tee /etc/mesos-master/quorum
|
||||
hostname -i | sudo tee /etc/mesos-master/ip
|
||||
hostname | sudo tee /etc/mesos-master/hostname
|
||||
echo 'Mesos Cluster on Microsoft Azure' | sudo tee /etc/mesos-master/cluster
|
||||
fi
|
||||
|
||||
if ismaster && [ "$MARATHONENABLED" == "true" ] ; then
|
||||
# setup marathon
|
||||
sudo mkdir -p /etc/marathon/conf
|
||||
sudo cp /etc/mesos-master/hostname /etc/marathon/conf
|
||||
sudo cp /etc/mesos/zk /etc/marathon/conf/master
|
||||
zkmarathonconfig=$(zkconfig "marathon")
|
||||
echo $zkmarathonconfig | sudo tee /etc/marathon/conf/zk
|
||||
# enable marathon to failover tasks to other nodes immediately
|
||||
echo 0 | sudo tee /etc/marathon/conf/failover_timeout
|
||||
#echo false | sudo tee /etc/marathon/conf/checkpoint
|
||||
fi
|
||||
|
||||
#########################################
|
||||
# Configure Mesos Master and Frameworks
|
||||
#########################################
|
||||
if ismaster ; then
|
||||
# Download and install mesos-dns
|
||||
sudo mkdir -p /usr/local/mesos-dns
|
||||
sudo wget --tries 4 --retry-connrefused --waitretry=15 https://github.com/mesosphere/mesos-dns/releases/download/v0.5.1/mesos-dns-v0.5.1-linux-amd64 -O mesos-dns-linux
|
||||
sudo chmod +x mesos-dns-linux
|
||||
sudo mv mesos-dns-linux /usr/local/mesos-dns/mesos-dns
|
||||
RESOLVER=`cat /etc/resolv.conf | grep nameserver | tail -n 1 | awk '{print $2}'`
|
||||
|
||||
COUNT=$((MASTERCOUNT-1))
|
||||
#generate a list of master's for input to zk config
|
||||
MASTERS=""
|
||||
for i in `seq 0 $COUNT` ;
|
||||
do
|
||||
MASTEROCTET=`expr $MASTERFIRSTADDR + $i`
|
||||
IPADDR="$BASESUBNET$MASTEROCTET:5050"
|
||||
MASTERS="$MASTERS\"${IPADDR}\""
|
||||
if [ "$i" -lt "$COUNT" ]; then
|
||||
MASTERS="$MASTERS,"
|
||||
fi
|
||||
done
|
||||
echo "
|
||||
{
|
||||
\"zk\": \"${zkmesosconfig}\",
|
||||
\"masters\": ["${MASTERS}"],
|
||||
\"refreshSeconds\": 1,
|
||||
\"ttl\": 1,
|
||||
\"domain\": \"mesos\",
|
||||
\"port\": 53,
|
||||
\"timeout\": 1,
|
||||
\"listener\": \"0.0.0.0\",
|
||||
\"email\": \"root.mesos-dns.mesos\",
|
||||
\"resolvers\": [\"$RESOLVER\"]
|
||||
}
|
||||
" > mesos-dns.json
|
||||
sudo mv mesos-dns.json /usr/local/mesos-dns/mesos-dns.json
|
||||
|
||||
echo "
|
||||
description \"mesos dns\"
|
||||
|
||||
# Start just after the System-V jobs (rc) to ensure networking and zookeeper
|
||||
# are started. This is as simple as possible to ensure compatibility with
|
||||
# Ubuntu, Debian, CentOS, and RHEL distros. See:
|
||||
# http://upstart.ubuntu.com/cookbook/#standard-idioms
|
||||
start on stopped rc RUNLEVEL=[2345]
|
||||
respawn
|
||||
|
||||
exec /usr/local/mesos-dns/mesos-dns -config /usr/local/mesos-dns/mesos-dns.json" > mesos-dns.conf
|
||||
sudo mv mesos-dns.conf /etc/init
|
||||
fi
|
||||
|
||||
#########################
|
||||
# Configure Mesos Agent
|
||||
#########################
|
||||
if isagent ; then
|
||||
# Add docker containerizer
|
||||
echo "docker,mesos" | sudo tee /etc/mesos-slave/containerizers
|
||||
# Add timeout for agent to download docker
|
||||
echo '5mins' > /etc/mesos-slave/executor_registration_timeout
|
||||
# Add resources configuration
|
||||
if ismaster ; then
|
||||
echo "ports:[1-21,23-79,81-4399,4401-5049,5052-8079,8081-32000]" | sudo tee /etc/mesos-slave/resources
|
||||
else
|
||||
echo "ports:[1-21,23-5050,5052-32000]" | sudo tee /etc/mesos-slave/resources
|
||||
fi
|
||||
hostname -i | sudo tee /etc/mesos-slave/ip
|
||||
hostname | sudo tee /etc/mesos-slave/hostname
|
||||
fi
|
||||
# Add mesos-dns IP addresses to the head file, so they are at the top of the file
|
||||
for i in `seq 0 $((MASTERCOUNT-1))` ;
|
||||
do
|
||||
MASTEROCTET=`expr $MASTERFIRSTADDR + $i`
|
||||
IPADDR="${BASESUBNET}${MASTEROCTET}"
|
||||
echo nameserver $IPADDR | sudo tee -a /etc/resolvconf/resolv.conf.d/head
|
||||
done
|
||||
cat /etc/resolvconf/resolv.conf.d/head
|
||||
|
||||
##############################################
|
||||
# configure init rules restart all processes
|
||||
##############################################
|
||||
echo "stop mesos and framework processes, they will restart after reboot"
|
||||
if ismaster ; then
|
||||
echo manual | sudo tee /etc/init/mesos-slave.override
|
||||
sudo service mesos-slave stop
|
||||
|
||||
# stop all running services
|
||||
sudo service marathon stop
|
||||
sudo service chronos stop
|
||||
sudo service mesos-dns stop
|
||||
sudo service mesos-master stop
|
||||
sudo service zookeeper stop
|
||||
|
||||
# the following will clear out any corrupt zookeeper state, and zookeeper will
|
||||
# reconstruct this on the reboot at the end of provisioning
|
||||
sudo mkdir /var/lib/zookeeperbackup
|
||||
sudo mv /var/lib/zookeeper/* /var/lib/zookeeperbackup
|
||||
sudo cp /var/lib/zookeeperbackup/myid /var/lib/zookeeper/
|
||||
else
|
||||
echo manual | sudo tee /etc/init/zookeeper.override
|
||||
sudo service zookeeper stop
|
||||
echo manual | sudo tee /etc/init/mesos-master.override
|
||||
sudo service mesos-master stop
|
||||
fi
|
||||
|
||||
if ismaster && [ "$SWARMENABLED" == "true" ] && [ $VMNUMBER -eq "0" ]; then
|
||||
echo "starting docker swarm version $SWARM_VERSION"
|
||||
echo "sleep 10 seconds to give master time to come up"
|
||||
sleep 10
|
||||
echo sudo docker run -d --net=host -e SWARM_MESOS_USER=root \
|
||||
--restart=always \
|
||||
$SWARM_VERSION manage \
|
||||
-c mesos-experimental \
|
||||
--cluster-opt mesos.address=$HOSTADDR \
|
||||
--cluster-opt mesos.port=3375 $zkmesosconfig
|
||||
sudo docker run -d --net=host -e SWARM_MESOS_USER=root \
|
||||
--restart=always \
|
||||
$SWARM_VERSION manage \
|
||||
-c mesos-experimental \
|
||||
--cluster-opt mesos.address=$HOSTADDR \
|
||||
--cluster-opt mesos.port=3375 $zkmesosconfig
|
||||
sudo docker ps
|
||||
echo "completed starting docker swarm"
|
||||
fi
|
||||
|
||||
###################
|
||||
# Install Admin Router
|
||||
###################
|
||||
installMesosAdminRouter()
|
||||
{
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes install nginx-extras lua-cjson
|
||||
# the admin router comes from https://github.com/mesosphere/adminrouter-public
|
||||
ADMIN_ROUTER_GITHUB_URL=https://raw.githubusercontent.com/anhowe/adminrouter-public/master
|
||||
NGINX_CONF_PATH=/usr/share/nginx/conf
|
||||
sudo mkdir -p $NGINX_CONF_PATH
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO$NGINX_CONF_PATH/common.lua $ADMIN_ROUTER_GITHUB_URL/common.lua
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO$NGINX_CONF_PATH/metadata.lua $ADMIN_ROUTER_GITHUB_URL/metadata.lua
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO$NGINX_CONF_PATH/service.lua $ADMIN_ROUTER_GITHUB_URL/service.lua
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO$NGINX_CONF_PATH/slave.lua $ADMIN_ROUTER_GITHUB_URL/slave.lua
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO$NGINX_CONF_PATH/slavehostname.lua $ADMIN_ROUTER_GITHUB_URL/slavehostname.lua
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO$NGINX_CONF_PATH/url.lua $ADMIN_ROUTER_GITHUB_URL/url.lua
|
||||
|
||||
sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig
|
||||
sudo cp /opt/azure/containers/nginx.conf /etc/nginx/nginx.conf
|
||||
}
|
||||
|
||||
# only install the mesos dcos cli on the master
|
||||
if ismaster ; then
|
||||
time installMesosAdminRouter
|
||||
fi
|
||||
|
||||
###################
|
||||
# Install Mesos DCOS CLI
|
||||
###################
|
||||
installMesosDCOSCLI()
|
||||
{
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes install -y python-pip
|
||||
sudo pip install virtualenv
|
||||
sudo -i -u $AZUREUSER mkdir $HOMEDIR/dcos
|
||||
for i in {1..10}; do
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO- https://raw.githubusercontent.com/mesosphere/dcos-cli/master/bin/install/install-optout-dcos-cli.sh | sudo -i -u $AZUREUSER /bin/bash -s $HOMEDIR/dcos/. http://leader.mesos --add-path yes
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "Mesos DCOS-CLI installed successfully"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
}
|
||||
|
||||
# only install the mesos dcos cli on the master
|
||||
if ismaster ; then
|
||||
time installMesosDCOSCLI
|
||||
fi
|
||||
|
||||
###################
|
||||
# Post Install
|
||||
###################
|
||||
if [ $POSTINSTALLSCRIPTURI != "disabled" ]
|
||||
then
|
||||
echo "downloading, and kicking off post install script"
|
||||
/bin/bash -c "wget --tries 20 --retry-connrefused --waitretry=15 -qO- $POSTINSTALLSCRIPTURI | nohup /bin/bash >> /var/log/azure/cluster-bootstrap-postinstall.log 2>&1 &"
|
||||
fi
|
||||
|
||||
ps ax
|
||||
echo "Finished installing and configuring docker and swarm"
|
||||
date
|
||||
echo "completed mesos cluster configuration"
|
||||
|
||||
echo "restart system to install any remaining software"
|
||||
if isagent ; then
|
||||
shutdown -r now
|
||||
else
|
||||
# wait 30s for guest agent to communicate back success and then reboot
|
||||
/usr/bin/nohup /bin/bash -c "sleep 30s; shutdown -r now" &
|
||||
fi
|
|
@ -0,0 +1,291 @@
|
|||
#!/bin/bash
|
||||
|
||||
###########################################################
|
||||
# Configure Mesos One Box
|
||||
#
|
||||
# This installs the following components
|
||||
# - zookeepr
|
||||
# - mesos master
|
||||
# - marathon
|
||||
# - mesos agent
|
||||
###########################################################
|
||||
|
||||
set -x
|
||||
|
||||
echo "starting mesos cluster configuration"
|
||||
date
|
||||
ps ax
|
||||
|
||||
SWARM_VERSION="swarm:1.1.0"
|
||||
DOCKER_COMPOSE_VERSION="1.6.2"
|
||||
#############
|
||||
# Parameters
|
||||
#############
|
||||
|
||||
MASTERCOUNT=${1}
|
||||
MASTERPREFIX=${2}
|
||||
MASTERFIRSTADDR=${3}
|
||||
AZUREUSER=${4}
|
||||
POSTINSTALLSCRIPTURI=${5}
|
||||
BASESUBNET=${6}
|
||||
VMNAME=`hostname`
|
||||
VMNUMBER=`echo $VMNAME | sed 's/.*[^0-9]\([0-9]\+\)*$/\1/'`
|
||||
VMPREFIX=`echo $VMNAME | sed 's/\(.*[^0-9]\)*[0-9]\+$/\1/'`
|
||||
|
||||
echo "Master Count: $MASTERCOUNT"
|
||||
echo "Master Prefix: $MASTERPREFIX"
|
||||
echo "Master First Addr: $MASTERFIRSTADDR"
|
||||
echo "vmname: $VMNAME"
|
||||
echo "VMNUMBER: $VMNUMBER, VMPREFIX: $VMPREFIX"
|
||||
echo "BASESUBNET: $BASESUBNET"
|
||||
echo "AZUREUSER: $AZUREUSER"
|
||||
|
||||
###################
|
||||
# Common Functions
|
||||
###################
|
||||
|
||||
ensureAzureNetwork()
|
||||
{
|
||||
# ensure the host name is resolvable
|
||||
hostResolveHealthy=1
|
||||
for i in {1..120}; do
|
||||
host $VMNAME
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
hostResolveHealthy=0
|
||||
echo "the host name resolves"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ $hostResolveHealthy -ne 0 ]
|
||||
then
|
||||
echo "host name does not resolve, aborting install"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ensure the network works
|
||||
networkHealthy=1
|
||||
for i in {1..12}; do
|
||||
wget -O/dev/null http://bing.com
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
networkHealthy=0
|
||||
echo "the network is healthy"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
if [ $networkHealthy -ne 0 ]
|
||||
then
|
||||
echo "the network is not healthy, aborting install"
|
||||
ifconfig
|
||||
ip a
|
||||
exit 2
|
||||
fi
|
||||
# ensure the host ip can resolve
|
||||
networkHealthy=1
|
||||
for i in {1..120}; do
|
||||
hostname -i
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
networkHealthy=0
|
||||
echo "the network is healthy"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ $networkHealthy -ne 0 ]
|
||||
then
|
||||
echo "the network is not healthy, cannot resolve ip address, aborting install"
|
||||
ifconfig
|
||||
ip a
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
ensureAzureNetwork
|
||||
HOSTADDR=`hostname -i`
|
||||
|
||||
ismaster ()
|
||||
{
|
||||
if [ "$MASTERPREFIX" == "$VMPREFIX" ]
|
||||
then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
if ismaster ; then
|
||||
echo "this node is a master"
|
||||
fi
|
||||
|
||||
isagent()
|
||||
{
|
||||
if ismaster ; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
if isagent ; then
|
||||
echo "this node is an agent"
|
||||
fi
|
||||
|
||||
consulstr()
|
||||
{
|
||||
consulargs=""
|
||||
for i in `seq 0 $((MASTERCOUNT-1))` ;
|
||||
do
|
||||
MASTEROCTET=`expr $MASTERFIRSTADDR + $i`
|
||||
IPADDR="${BASESUBNET}${MASTEROCTET}"
|
||||
|
||||
if [ "$VMNUMBER" -eq "0" ]
|
||||
then
|
||||
consulargs="${consulargs}-bootstrap-expect $MASTERCOUNT "
|
||||
fi
|
||||
if [ "$VMNUMBER" -eq "$i" ]
|
||||
then
|
||||
consulargs="${consulargs}-advertise $IPADDR "
|
||||
else
|
||||
consulargs="${consulargs}-retry-join $IPADDR "
|
||||
fi
|
||||
done
|
||||
echo $consulargs
|
||||
}
|
||||
|
||||
consulargs=$(consulstr)
|
||||
MASTER0IPADDR="${BASESUBNET}${MASTERFIRSTADDR}"
|
||||
|
||||
######################
|
||||
# resolve self in DNS
|
||||
######################
|
||||
|
||||
echo "$HOSTADDR $VMNAME" | sudo tee -a /etc/hosts
|
||||
|
||||
################
|
||||
# Install Docker
|
||||
################
|
||||
|
||||
echo "Installing and configuring docker"
|
||||
|
||||
installDocker()
|
||||
{
|
||||
for i in {1..10}; do
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO- https://get.docker.com | sh
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
echo "Docker installed successfully"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
}
|
||||
time installDocker
|
||||
sudo usermod -aG docker $AZUREUSER
|
||||
if isagent ; then
|
||||
# Start Docker and listen on :2375 (no auth, but in vnet)
|
||||
echo 'DOCKER_OPTS="-H unix:///var/run/docker.sock -H 0.0.0.0:2375 --cluster-store=consul://'$MASTER0IPADDR:8500 --cluster-advertise=$HOSTADDR:2375'"' | sudo tee -a /etc/default/docker
|
||||
fi
|
||||
|
||||
echo "Installing docker compose"
|
||||
installDockerCompose()
|
||||
{
|
||||
for i in {1..10}; do
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO- https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VERSION/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
echo "docker-compose installed successfully"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
}
|
||||
time installDockerCompose
|
||||
chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
sudo service docker restart
|
||||
|
||||
ensureDocker()
|
||||
{
|
||||
# ensure that docker is healthy
|
||||
dockerHealthy=1
|
||||
for i in {1..3}; do
|
||||
sudo docker info
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
dockerHealthy=0
|
||||
echo "Docker is healthy"
|
||||
sudo docker ps -a
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
if [ $dockerHealthy -ne 0 ]
|
||||
then
|
||||
echo "Docker is not healthy"
|
||||
fi
|
||||
}
|
||||
ensureDocker
|
||||
|
||||
##############################################
|
||||
# configure init rules restart all processes
|
||||
##############################################
|
||||
|
||||
if ismaster ; then
|
||||
mkdir -p /data/consul
|
||||
echo "consul:
|
||||
image: \"progrium/consul\"
|
||||
command: -server -node $VMNAME $consulargs
|
||||
ports:
|
||||
- \"8500:8500\"
|
||||
- \"8300:8300\"
|
||||
- \"8301:8301\"
|
||||
- \"8301:8301/udp\"
|
||||
- \"8302:8302\"
|
||||
- \"8302:8302/udp\"
|
||||
- \"8400:8400\"
|
||||
volumes:
|
||||
- \"/data/consul:/data\"
|
||||
restart: \"always\"
|
||||
swarm:
|
||||
image: \"$SWARM_VERSION\"
|
||||
command: manage --replication --advertise $HOSTADDR:2375 --discovery-opt kv.path=docker/nodes consul://$MASTER0IPADDR:8500
|
||||
ports:
|
||||
- \"2375:2375\"
|
||||
links:
|
||||
- \"consul\"
|
||||
volumes:
|
||||
- \"/etc/docker:/etc/docker\"
|
||||
restart: \"always\"
|
||||
" > /opt/azure/containers/docker-compose.yml
|
||||
|
||||
pushd /opt/azure/containers/
|
||||
docker-compose up -d
|
||||
popd
|
||||
echo "completed starting docker swarm on the master"
|
||||
fi
|
||||
|
||||
if [ $POSTINSTALLSCRIPTURI != "disabled" ]
|
||||
then
|
||||
echo "downloading, and kicking off post install script"
|
||||
/bin/bash -c "wget --tries 20 --retry-connrefused --waitretry=15 -qO- $POSTINSTALLSCRIPTURI | nohup /bin/bash >> /var/log/azure/cluster-bootstrap-postinstall.log 2>&1 &"
|
||||
fi
|
||||
|
||||
echo "processes at end of script"
|
||||
ps ax
|
||||
date
|
||||
echo "completed mesos cluster configuration"
|
||||
|
||||
echo "restart system to install any remaining software"
|
||||
if isagent ; then
|
||||
shutdown -r now
|
||||
else
|
||||
# wait 1 minute to restart master
|
||||
/bin/bash -c "shutdown -r 1 &"
|
||||
fi
|
|
@ -0,0 +1,271 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
|
||||
echo "starting ubuntu devbox install on pid $$"
|
||||
date
|
||||
ps axjf
|
||||
|
||||
#############
|
||||
# Parameters
|
||||
#############
|
||||
|
||||
AZUREUSER=$1
|
||||
MASTERCOUNT=$2
|
||||
MASTERFIRSTADDR=$3
|
||||
HOMEDIR="/home/$AZUREUSER"
|
||||
VMNAME=`hostname`
|
||||
BASESUBNET="172.16.0."
|
||||
echo "User: $AZUREUSER"
|
||||
echo "User home dir: $HOMEDIR"
|
||||
echo "vmname: $VMNAME"
|
||||
echo "Num of Masters:$MASTERCOUNT"
|
||||
echo "Master Initial Addr: $MASTERFIRSTADDR"
|
||||
|
||||
###################
|
||||
# Common Functions
|
||||
###################
|
||||
|
||||
ensureAzureNetwork()
|
||||
{
|
||||
# ensure the host name is resolvable
|
||||
hostResolveHealthy=1
|
||||
for i in {1..120}; do
|
||||
host $VMNAME
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
hostResolveHealthy=0
|
||||
echo "the host name resolves"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ $hostResolveHealthy -ne 0 ]
|
||||
then
|
||||
echo "host name does not resolve, aborting install"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ensure the network works
|
||||
networkHealthy=1
|
||||
for i in {1..12}; do
|
||||
wget -O/dev/null http://bing.com
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
networkHealthy=0
|
||||
echo "the network is healthy"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
if [ $networkHealthy -ne 0 ]
|
||||
then
|
||||
echo "the network is not healthy, cannot download from bing, aborting install"
|
||||
ifconfig
|
||||
ip a
|
||||
exit 2
|
||||
fi
|
||||
# ensure the hostname -i works
|
||||
networkHealthy=1
|
||||
for i in {1..120}; do
|
||||
hostname -i
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
networkHealthy=0
|
||||
echo "the network is healthy"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ $networkHealthy -ne 0 ]
|
||||
then
|
||||
echo "the network is not healthy, cannot resolve ip address, aborting install"
|
||||
ifconfig
|
||||
ip a
|
||||
exit 2
|
||||
fi
|
||||
# ensure hostname -f works
|
||||
networkHealthy=1
|
||||
for i in {1..120}; do
|
||||
hostname -f
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
networkHealthy=0
|
||||
echo "the network is healthy"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ $networkHealthy -ne 0 ]
|
||||
then
|
||||
echo "the network is not healthy, cannot resolve hostname, aborting install"
|
||||
ifconfig
|
||||
ip a
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
ensureAzureNetwork
|
||||
|
||||
################
|
||||
# Install Docker
|
||||
################
|
||||
|
||||
echo "Installing and configuring docker and swarm"
|
||||
|
||||
installDocker()
|
||||
{
|
||||
for i in {1..10}; do
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO- https://get.docker.com | sh
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
echo "Docker installed successfully"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
}
|
||||
|
||||
time installDocker
|
||||
# AZUREUSER can run docker without sudo
|
||||
sudo usermod -aG docker $AZUREUSER
|
||||
sudo service docker restart
|
||||
|
||||
ensureDocker()
|
||||
{
|
||||
# ensure that docker is healthy
|
||||
dockerHealthy=1
|
||||
for i in {1..3}; do
|
||||
sudo docker info
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# hostname has been found continue
|
||||
dockerHealthy=0
|
||||
echo "Docker is healthy"
|
||||
sudo docker ps -a
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
if [ $dockerHealthy -ne 0 ]
|
||||
then
|
||||
echo "Docker is not healthy"
|
||||
fi
|
||||
}
|
||||
|
||||
ensureDocker
|
||||
|
||||
###################################################
|
||||
# Update Ubuntu and install all necessary binaries
|
||||
###################################################
|
||||
|
||||
time sudo apt-get -y update
|
||||
# kill the waagent and uninstall, otherwise, adding the desktop will do this and kill this script
|
||||
sudo pkill waagent
|
||||
time sudo apt-get -y remove walinuxagent
|
||||
time sudo DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes install ubuntu-desktop firefox vnc4server ntp nodejs npm expect gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal gnome-core
|
||||
|
||||
#####################
|
||||
# setup the Azure CLI
|
||||
#####################
|
||||
time sudo npm install azure-cli -g
|
||||
time sudo update-alternatives --install /usr/bin/node nodejs /usr/bin/nodejs 100
|
||||
|
||||
####################
|
||||
# Setup Chrome
|
||||
####################
|
||||
cd /tmp
|
||||
time wget --tries 4 --retry-connrefused --waitretry=15 https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
|
||||
time sudo dpkg -i google-chrome-stable_current_amd64.deb
|
||||
time sudo apt-get -y --force-yes install -f
|
||||
time rm /tmp/google-chrome-stable_current_amd64.deb
|
||||
|
||||
###################
|
||||
# Install Mesos DCOS CLI
|
||||
###################
|
||||
installMesosDCOSCLI()
|
||||
{
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes install -y python-pip openjdk-7-jre-headless
|
||||
sudo pip install virtualenv
|
||||
sudo -i -u $AZUREUSER mkdir $HOMEDIR/dcos
|
||||
for i in {1..10}; do
|
||||
wget --tries 4 --retry-connrefused --waitretry=15 -qO- https://raw.githubusercontent.com/mesosphere/dcos-cli/master/bin/install/install-optout-dcos-cli.sh | sudo -i -u $AZUREUSER /bin/bash -s $HOMEDIR/dcos/. http://leader.mesos --add-path yes
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "Mesos DCOS-CLI installed successfully"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
}
|
||||
|
||||
time installMesosDCOSCLI
|
||||
|
||||
#########################################
|
||||
# Setup Azure User Account including VNC
|
||||
#########################################
|
||||
sudo -i -u $AZUREUSER mkdir $HOMEDIR/bin
|
||||
sudo -i -u $AZUREUSER touch $HOMEDIR/bin/startvnc
|
||||
sudo -i -u $AZUREUSER chmod 755 $HOMEDIR/bin/startvnc
|
||||
sudo -i -u $AZUREUSER touch $HOMEDIR/bin/stopvnc
|
||||
sudo -i -u $AZUREUSER chmod 755 $HOMEDIR/bin/stopvnc
|
||||
echo "vncserver -geometry 1280x1024 -depth 16 -SecurityTypes None" | sudo tee $HOMEDIR/bin/startvnc
|
||||
echo "vncserver -kill :1" | sudo tee $HOMEDIR/bin/stopvnc
|
||||
echo "export PATH=\$PATH:~/bin" | sudo tee -a $HOMEDIR/.bashrc
|
||||
|
||||
prog=/usr/bin/vncpasswd
|
||||
mypass="password"
|
||||
|
||||
sudo -i -u $AZUREUSER /usr/bin/expect <<EOF
|
||||
spawn "$prog"
|
||||
expect "Password:"
|
||||
send "$mypass\r"
|
||||
expect "Verify:"
|
||||
send "$mypass\r"
|
||||
expect eof
|
||||
exit
|
||||
EOF
|
||||
|
||||
sudo -i -u $AZUREUSER startvnc
|
||||
sudo -i -u $AZUREUSER stopvnc
|
||||
|
||||
echo "#!/bin/sh" | sudo tee $HOMEDIR/.vnc/xstartup
|
||||
echo "" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "export XKL_XMODMAP_DISABLE=1" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "unset SESSION_MANAGER" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "unset DBUS_SESSION_BUS_ADDRESS" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "xsetroot -solid grey" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "vncconfig -iconic &" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "gnome-panel &" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "gnome-settings-daemon &" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "metacity &" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "nautilus &" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
echo "gnome-terminal &" | sudo tee -a $HOMEDIR/.vnc/xstartup
|
||||
|
||||
sudo -i -u $AZUREUSER $HOMEDIR/bin/startvnc
|
||||
|
||||
########################################
|
||||
# generate nameserver IPs for resolvconf/resolv.conf.d/head file
|
||||
# for mesos_dns so service names can be resolve from the jumpbox as well
|
||||
########################################
|
||||
for ((i=MASTERFIRSTADDR; i<MASTERFIRSTADDR+MASTERCOUNT; i++)); do
|
||||
echo "nameserver $BASESUBNET$i" | sudo tee -a /etc/resolvconf/resolv.conf.d/head
|
||||
done
|
||||
echo "/etc/resolvconf/resolv.conf.d/head"
|
||||
cat /etc/resolvconf/resolv.conf.d/head
|
||||
sudo service resolvconf restart
|
||||
|
||||
date
|
||||
echo "completed ubuntu devbox install on pid $$"
|
||||
|
||||
echo "restart system to install any remaining software"
|
||||
shutdown -r now
|
|
@ -0,0 +1,129 @@
|
|||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('jumpboxPublicIPAddressName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('jumpboxEndpointDNSNamePrefix')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('jumpboxNSGName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "ssh",
|
||||
"properties": {
|
||||
"description": "Allow SSH",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "22",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 200,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[concat(variables('jumpboxVMName'), '-nic')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('jumpboxPublicIPAddressName'))]",
|
||||
"[variables('vnetID')]",
|
||||
"[variables('jumpboxNSGID')]"
|
||||
],
|
||||
"properties": {
|
||||
"networkSecurityGroup": {
|
||||
"id": "[variables('jumpboxNSGID')]"
|
||||
},
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipConfig",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Static",
|
||||
"privateIPAddress": "[concat(split(variables('masterAddressPrefix'),'0/24')[0], variables('jumpboxAddr'))]",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('jumpboxPublicIPAddressName'))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('masterSubnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[variables('jumpboxVMName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('jumpboxVMName'), '-nic')]",
|
||||
"[variables('masterStorageAccountName')]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('jumpboxVMSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computername": "[variables('jumpboxVMName')]",
|
||||
"adminUsername": "[variables('adminUsername')]",
|
||||
"adminPassword": "[variables('adminPassword')]",
|
||||
"customData": "[base64('#jumpboxLinuxCustomDataInstallYaml')]",
|
||||
"linuxConfiguration": "[variables('linuxConfiguration')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('linuxPublisher')]",
|
||||
"offer": "[variables('linuxOffer')]",
|
||||
"sku": "[variables('linuxSku')]",
|
||||
"version": "[variables('linuxVersion')]"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[concat(variables('jumpboxVMName'),'-osdisk')]",
|
||||
"vhd": {
|
||||
"uri": "[concat('http://', variables('masterStorageAccountName'), '.blob.core.windows.net/vhds/', variables('jumpboxVMName'), '-osdisk.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('jumpboxVMName'), '-nic'))]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('jumpboxVMName'),'/installcustomscript')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('jumpboxVMName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"settings": {
|
||||
"commandToExecute": "[variables('jumpboxLinuxCustomScript')]"
|
||||
}
|
||||
}
|
||||
},
|
|
@ -0,0 +1,19 @@
|
|||
,
|
||||
{
|
||||
"name": "AzureDiagnostic",
|
||||
"properties":
|
||||
{
|
||||
"publisher": "Microsoft.Azure.Diagnostics",
|
||||
"type": "IaaSDiagnostics",
|
||||
"typeHandlerVersion": "1.5",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"xmlCfg": "[base64(concat(variables('windowswadcfgxstart'), variables('agentVMNamePrefix'), variables('windowswadcfgxend')))]",
|
||||
"StorageAccount": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]"
|
||||
},
|
||||
"protectedSettings": {
|
||||
"storageAccountName": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]",
|
||||
"storageAccountKey": "[listKeys(variables('accountid'), variables('storageApiVersion')).key1]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('jumpboxPublicIPAddressName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('jumpboxEndpointDNSNamePrefix')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('jumpboxNSGName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "ssh",
|
||||
"properties": {
|
||||
"description": "Allow RDP",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "3389",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 200,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[concat(variables('jumpboxVMName'), '-nic')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('jumpboxPublicIPAddressName'))]",
|
||||
"[variables('vnetID')]",
|
||||
"[variables('jumpboxNSGID')]"
|
||||
],
|
||||
"properties": {
|
||||
"networkSecurityGroup": {
|
||||
"id": "[variables('jumpboxNSGID')]"
|
||||
},
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipConfig",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Static",
|
||||
"privateIPAddress": "[concat(split(variables('masterAddressPrefix'),'0/24')[0], variables('jumpboxAddr'))]",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('jumpboxPublicIPAddressName'))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('masterSubnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[variables('jumpboxVMName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('jumpboxVMName'), '-nic')]",
|
||||
"[variables('masterStorageAccountName')]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('jumpboxVMSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computername": "[variables('jumpboxVMName')]",
|
||||
"adminUsername": "[variables('windowsAdminUsername')]",
|
||||
"adminPassword": "[variables('windowsAdminPassword')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('windowsJumpboxPublisher')]",
|
||||
"offer": "[variables('windowsJumpboxOffer')]",
|
||||
"sku": "[variables('windowsJumpboxSku')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[concat(variables('jumpboxVMName'),'-osdisk')]",
|
||||
"vhd": {
|
||||
"uri": "[concat('http://', variables('masterStorageAccountName'), '.blob.core.windows.net/vhds/', variables('jumpboxVMName'), '-osdisk.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('jumpboxVMName'), '-nic'))]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('jumpboxVMName'),'/installcustomscript')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('jumpboxVMName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.Compute",
|
||||
"type": "CustomScriptExtension",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"settings": {
|
||||
"commandToExecute": "[variables('jumpboxWindowsCustomScript')]"
|
||||
}
|
||||
}
|
||||
},
|
|
@ -0,0 +1,242 @@
|
|||
#!/usr/bin/python
|
||||
import base64
|
||||
import os
|
||||
import gzip
|
||||
import StringIO
|
||||
import sys
|
||||
import shutil
|
||||
import json
|
||||
import argparse
|
||||
|
||||
def buildb64GzipStringFromFile(file):
|
||||
# read the script file
|
||||
with open(file) as f:
|
||||
content = f.read()
|
||||
compressedbuffer=StringIO.StringIO()
|
||||
|
||||
# gzip the script file
|
||||
# mtime=0 sets a fixed timestamp in GZip header to the Epoch which is January 1st, 1970
|
||||
# Make sure it doens't change unless the stream changes
|
||||
with gzip.GzipFile(fileobj=compressedbuffer, mode='wb', mtime=0) as f:
|
||||
f.write(content)
|
||||
b64GzipStream=base64.b64encode(compressedbuffer.getvalue())
|
||||
|
||||
return b64GzipStream
|
||||
|
||||
# Function reads the files from disk,
|
||||
# and embeds it in a Yaml file as a base-64 enconded string to be
|
||||
# executed later by template
|
||||
def buildYamlFileWithWriteFiles(files):
|
||||
gzipBuffer=StringIO.StringIO()
|
||||
|
||||
clusterYamlFile="""#cloud-config
|
||||
|
||||
write_files:
|
||||
%s
|
||||
"""
|
||||
writeFileBlock=""" - encoding: gzip
|
||||
content: !!binary |
|
||||
%s
|
||||
path: /opt/azure/containers/%s
|
||||
permissions: "0744"
|
||||
"""
|
||||
filelines=""
|
||||
for encodeFile in files:
|
||||
b64GzipString = buildb64GzipStringFromFile(encodeFile)
|
||||
filelines=filelines+(writeFileBlock % (b64GzipString,encodeFile))
|
||||
|
||||
return clusterYamlFile % (filelines)
|
||||
|
||||
# processes a Yaml file to be included properly in ARM template
|
||||
def convertToOneArmTemplateLine(clusterYamlFile):
|
||||
# remove the \r\n and include \n in body and escape " to \"
|
||||
return clusterYamlFile.replace("\n", "\\n").replace('"', '\\"')
|
||||
|
||||
# Loads the base ARM template file and injects the Yaml for the shell scripts into it.
|
||||
def processBaseTemplate(baseTemplatePath,
|
||||
clusterInstallScript,
|
||||
jumpboxTemplatePath = None,
|
||||
linuxJumpboxInstallScript = None,
|
||||
swarmWindowsAgentInstallScript = None,
|
||||
additionalFiles = [],
|
||||
windowsAgentDiagnosticsExtensionTemplatePath = None):
|
||||
|
||||
#String to replace in JSON file
|
||||
CLUSTER_YAML_REPLACE_STRING = "#clusterCustomDataInstallYaml"
|
||||
JUMPBOX_FRAGMENT_REPLACE_STRING = "#jumpboxFragment"
|
||||
JUMPBOX_FQDN_REPLACE_STRING = "#jumpboxFQDN"
|
||||
JUMPBOX_LINUX_YAML_REPLACE_STRING = "#jumpboxLinuxCustomDataInstallYaml"
|
||||
SWARM_WINDOWS_AGENT_CUSTOMDATA_REPLACE_STRING = "#swarmWindowsAgentCustomData"
|
||||
WINDOWS_AGENT_DIAGNOSTICS_EXTENSION_REPLACE_STRING = "#windowsAgentDiagnosticsExtension"
|
||||
|
||||
# Load Base Template
|
||||
armTemplate = []
|
||||
with open(baseTemplatePath) as f:
|
||||
armTemplate = f.read()
|
||||
|
||||
# All templates have vmsizemapping. Add it to base template
|
||||
ARM_INPUT_VMSIZE_MAPPING_TEMPLATE = "vmsizes-storage-account-mappings.json"
|
||||
VMSIZE_MAPPINGS_STRING = "#vmsizemapping"
|
||||
|
||||
vmsizeMappings = ""
|
||||
with open(ARM_INPUT_VMSIZE_MAPPING_TEMPLATE) as f:
|
||||
vmsizeMappings = f.read()
|
||||
|
||||
armTemplate = armTemplate.replace(VMSIZE_MAPPINGS_STRING, vmsizeMappings)
|
||||
|
||||
# Generate cluster Yaml file for ARM
|
||||
clusterYamlFile = convertToOneArmTemplateLine(buildYamlFileWithWriteFiles([clusterInstallScript]+additionalFiles))
|
||||
armTemplate = armTemplate.replace(CLUSTER_YAML_REPLACE_STRING, clusterYamlFile)
|
||||
|
||||
# Add Jumpbox YAML, ARM and FQDN Fragment if jumpboxTemplatePath is defined
|
||||
jumpboxTemplate = ""
|
||||
jumpboxFQDN = ""
|
||||
linuxJumpboxYamlFile = ""
|
||||
swarmWindowsAgentCustomData = ""
|
||||
windowsAgentDiagnosticsExtension = ""
|
||||
|
||||
if jumpboxTemplatePath != None :
|
||||
# Add Jumpbox FQDN Fragment if jumpboxTemplatePath is defined
|
||||
jumpboxFQDN = "[reference(concat('Microsoft.Network/publicIPAddresses/', variables('jumpboxPublicIPAddressName'))).dnsSettings.fqdn]"
|
||||
|
||||
with open(jumpboxTemplatePath) as f:
|
||||
jumpboxTemplate = f.read()
|
||||
|
||||
# Generate jumpbox Yaml file for ARM
|
||||
if linuxJumpboxInstallScript != None :
|
||||
# the linux jumpbox does not need the nginx configuration file
|
||||
linuxJumpboxYamlFile = convertToOneArmTemplateLine(buildYamlFileWithWriteFiles([linuxJumpboxInstallScript]))
|
||||
|
||||
# Add windows agent install script if passed in
|
||||
if swarmWindowsAgentInstallScript != None:
|
||||
swarmWindowsAgentCustomData = buildb64GzipStringFromFile(swarmWindowsAgentInstallScript)
|
||||
|
||||
# Add windows IaaS Diagnsotics extension JSON payload if passed in
|
||||
if windowsAgentDiagnosticsExtensionTemplatePath != None :
|
||||
with open(windowsAgentDiagnosticsExtensionTemplatePath) as f:
|
||||
windowsAgentDiagnosticsExtension = f.read()
|
||||
|
||||
# Want these to be replaced with blank strings if not defined
|
||||
armTemplate = armTemplate.replace(JUMPBOX_FRAGMENT_REPLACE_STRING, jumpboxTemplate)
|
||||
armTemplate = armTemplate.replace(JUMPBOX_FQDN_REPLACE_STRING, jumpboxFQDN)
|
||||
armTemplate = armTemplate.replace(JUMPBOX_LINUX_YAML_REPLACE_STRING, linuxJumpboxYamlFile)
|
||||
armTemplate = armTemplate.replace(SWARM_WINDOWS_AGENT_CUSTOMDATA_REPLACE_STRING, swarmWindowsAgentCustomData)
|
||||
armTemplate = armTemplate.replace(WINDOWS_AGENT_DIAGNOSTICS_EXTENSION_REPLACE_STRING, windowsAgentDiagnosticsExtension)
|
||||
|
||||
# Make sure the final string is valid JSON
|
||||
try:
|
||||
json_object = json.loads(armTemplate)
|
||||
except ValueError, e:
|
||||
print e
|
||||
errorFileName = baseTemplatePath + ".err"
|
||||
with open(errorFileName, "w") as f:
|
||||
f.write(armTemplate)
|
||||
print "Invalid armTemplate saved to: " + errorFileName
|
||||
raise
|
||||
|
||||
return armTemplate;
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Parse Arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-o", "--output_directory", help="Directory to write templates files to. Default is current directory.")
|
||||
parser.add_argument("-wpf", "--write_parameter_files", help="Write separate parameter file for each template. Default is false.",
|
||||
action="store_true" )
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if (args.output_directory == None) :
|
||||
args.output_directory = os.getcwd()
|
||||
|
||||
args.output_directory = os.path.expandvars(os.path.normpath(args.output_directory))
|
||||
|
||||
if ( os.path.exists(args.output_directory) == False ):
|
||||
os.mkdir(args.output_directory)
|
||||
|
||||
# Input Arm Template Artifacts to be processed in
|
||||
# Note: These files are not useable ARM templates on thier own or valid JSON
|
||||
# They require processing by this script.
|
||||
ARM_INPUT_TEMPLATE_TEMPLATE = "base-template.json"
|
||||
ARM_INPUT_PARAMETER_TEMPLATE = "base-template.parameters.json"
|
||||
ARM_INPUT_WINDOWS_JUMPBOX_TEMPLATE = "fragment-windows-jumpbox.json"
|
||||
ARM_INPUT_WINDOWS_AGENT_DIAGNOSTICS_TEMPLATE = "fragment-windows-agent-diagnostics-extension.json"
|
||||
ARM_INPUT_LINUX_JUMPBOX_TEMPLATE = "fragment-linux-jumpbox.json"
|
||||
ARM_INPUT_SWARM_TEMPLATE_TEMPLATE = "base-swarm-template.json"
|
||||
ARM_INPUT_SWARM_WINDOWS_TEMPLATE_TEMPLATE = "base-swarm-windows-template.json"
|
||||
|
||||
# Shell Scripts to load into YAML
|
||||
MESOS_CLUSTER_INSTALL_SCRIPT = "configure-mesos-cluster.sh"
|
||||
SWARM_CLUSTER_INSTALL_SCRIPT = "configure-swarm-cluster.sh"
|
||||
LINUX_JUMPBOX_INSTALL_SCRIPT = "configure-ubuntu.sh"
|
||||
SWARM_WINDOWS_AGENT_INSTALL_SCRIPT = "Install-ContainerHost-And-Join-Swarm.ps1"
|
||||
|
||||
# admin router configuration file
|
||||
ADMIN_ROUTER_CONF = "nginx.conf"
|
||||
|
||||
# Output ARM Template Files. WIll Also Output name.parameters.json for each
|
||||
ARM_OUTPUT_TEMPLATE = "mesos-cluster-with-no-jumpbox.json"
|
||||
ARM_OUTPUT_TEMPLATE_WINDOWS_JUMPBOX = "mesos-cluster-with-windows-jumpbox.json"
|
||||
ARM_OUTPUT_TEMPLATE_LINUX_JUMPBOX = "mesos-cluster-with-linux-jumpbox.json"
|
||||
ARM_OUTPUT_SWARM_TEMPLATE = "swarm-cluster-with-no-jumpbox.json"
|
||||
ARM_OUTPUT_SWARM_WINDOWS_TEMPLATE = "swarm-cluster-with-windows.json"
|
||||
ARM_OUTPUT_SWARM_WINDOWS_TEMPLATE_NO_DIAGNOSTICS = "swarm-cluster-with-windows-no-diagnostics.json"
|
||||
|
||||
# build the ARM template for jumpboxless
|
||||
with open(os.path.join(args.output_directory, ARM_OUTPUT_TEMPLATE), "w") as armTemplate:
|
||||
clusterTemplate = processBaseTemplate(
|
||||
baseTemplatePath=ARM_INPUT_TEMPLATE_TEMPLATE,
|
||||
clusterInstallScript=MESOS_CLUSTER_INSTALL_SCRIPT,
|
||||
additionalFiles=[ADMIN_ROUTER_CONF])
|
||||
armTemplate.write(clusterTemplate)
|
||||
|
||||
# build the ARM template for linux jumpbox
|
||||
with open(os.path.join(args.output_directory,ARM_OUTPUT_TEMPLATE_LINUX_JUMPBOX), "w") as armTemplate:
|
||||
clusterTemplate = processBaseTemplate(
|
||||
baseTemplatePath=ARM_INPUT_TEMPLATE_TEMPLATE,
|
||||
clusterInstallScript=MESOS_CLUSTER_INSTALL_SCRIPT,
|
||||
jumpboxTemplatePath=ARM_INPUT_LINUX_JUMPBOX_TEMPLATE,
|
||||
linuxJumpboxInstallScript=LINUX_JUMPBOX_INSTALL_SCRIPT,
|
||||
additionalFiles=[ADMIN_ROUTER_CONF])
|
||||
armTemplate.write(clusterTemplate)
|
||||
|
||||
# build the ARM template for windows jumpbox
|
||||
with open(os.path.join(args.output_directory, ARM_OUTPUT_TEMPLATE_WINDOWS_JUMPBOX), "w") as armTemplate:
|
||||
clusterTemplate = processBaseTemplate(
|
||||
baseTemplatePath=ARM_INPUT_TEMPLATE_TEMPLATE,
|
||||
clusterInstallScript=MESOS_CLUSTER_INSTALL_SCRIPT,
|
||||
jumpboxTemplatePath=ARM_INPUT_WINDOWS_JUMPBOX_TEMPLATE,
|
||||
additionalFiles=[ADMIN_ROUTER_CONF])
|
||||
armTemplate.write(clusterTemplate)
|
||||
|
||||
# build the SWARM ARM template
|
||||
with open(os.path.join(args.output_directory, ARM_OUTPUT_SWARM_TEMPLATE), "w") as armTemplate:
|
||||
clusterTemplate = processBaseTemplate(
|
||||
baseTemplatePath=ARM_INPUT_SWARM_TEMPLATE_TEMPLATE,
|
||||
clusterInstallScript=SWARM_CLUSTER_INSTALL_SCRIPT)
|
||||
armTemplate.write(clusterTemplate)
|
||||
|
||||
# build the SWARM WINDOWS ARM template with Windows diagnostics extension
|
||||
with open(os.path.join(args.output_directory, ARM_OUTPUT_SWARM_WINDOWS_TEMPLATE), "w") as armTemplate:
|
||||
clusterTemplate = processBaseTemplate(
|
||||
baseTemplatePath=ARM_INPUT_SWARM_WINDOWS_TEMPLATE_TEMPLATE,
|
||||
clusterInstallScript=SWARM_CLUSTER_INSTALL_SCRIPT,
|
||||
swarmWindowsAgentInstallScript=SWARM_WINDOWS_AGENT_INSTALL_SCRIPT,
|
||||
windowsAgentDiagnosticsExtensionTemplatePath=ARM_INPUT_WINDOWS_AGENT_DIAGNOSTICS_TEMPLATE)
|
||||
armTemplate.write(clusterTemplate)
|
||||
|
||||
# build the SWARM WINDOWS ARM template with NO winodws diagnostics extension
|
||||
with open(os.path.join(args.output_directory, ARM_OUTPUT_SWARM_WINDOWS_TEMPLATE_NO_DIAGNOSTICS), "w") as armTemplate:
|
||||
clusterTemplate = processBaseTemplate(
|
||||
baseTemplatePath=ARM_INPUT_SWARM_WINDOWS_TEMPLATE_TEMPLATE,
|
||||
clusterInstallScript=SWARM_CLUSTER_INSTALL_SCRIPT,
|
||||
swarmWindowsAgentInstallScript=SWARM_WINDOWS_AGENT_INSTALL_SCRIPT)
|
||||
armTemplate.write(clusterTemplate)
|
||||
|
||||
# Write parameter files if specified
|
||||
if (args.write_parameter_files == True) :
|
||||
shutil.copyfile(ARM_INPUT_PARAMETER_TEMPLATE, os.path.join(args.output_directory, ARM_OUTPUT_TEMPLATE).replace(".json", ".parameters.json") )
|
||||
shutil.copyfile(ARM_INPUT_PARAMETER_TEMPLATE, os.path.join(args.output_directory, ARM_OUTPUT_TEMPLATE_LINUX_JUMPBOX).replace(".json", ".parameters.json") )
|
||||
shutil.copyfile(ARM_INPUT_PARAMETER_TEMPLATE, os.path.join(args.output_directory, ARM_OUTPUT_TEMPLATE_WINDOWS_JUMPBOX).replace(".json", ".parameters.json") )
|
||||
shutil.copyfile(ARM_INPUT_PARAMETER_TEMPLATE, os.path.join(args.output_directory, ARM_OUTPUT_SWARM_TEMPLATE).replace(".json", ".parameters.json") )
|
||||
shutil.copyfile(ARM_INPUT_PARAMETER_TEMPLATE, os.path.join(args.output_directory, ARM_OUTPUT_SWARM_WINDOWS_TEMPLATE).replace(".json", ".parameters.json") )
|
||||
shutil.copyfile(ARM_INPUT_PARAMETER_TEMPLATE, os.path.join(args.output_directory, ARM_OUTPUT_SWARM_WINDOWS_TEMPLATE_NO_DIAGNOSTICS).replace(".json", ".parameters.json") )
|
|
@ -0,0 +1,57 @@
|
|||
#!/usr/bin/python
|
||||
import base64
|
||||
import os
|
||||
import gzip
|
||||
import re
|
||||
import StringIO
|
||||
import sys
|
||||
|
||||
# goal "commandToExecute": "[variables('jumpboxWindowsCustomScript')]"
|
||||
|
||||
def convertToOneArmTemplateLine(file):
|
||||
with open(file) as f:
|
||||
content = f.read()
|
||||
|
||||
oneline=""
|
||||
lines = content.split("\n")
|
||||
for line in lines:
|
||||
if (line.find("{") == -1 and line.find("}") == -1) or (line.find("{") > -1 and line.find("}") > -1):
|
||||
oneline=oneline + " ; " + line
|
||||
else:
|
||||
oneline=oneline + line
|
||||
|
||||
oneline="'".join(oneline.split('"'))
|
||||
|
||||
codeRegEx=re.compile(r".arguments\s*=\s*'([^']*)'\s*;")
|
||||
matchArray=codeRegEx.findall(oneline)
|
||||
if len(matchArray)>1:
|
||||
print oneline
|
||||
raise AssertionError, "incorrect number of matches"
|
||||
argumentList=''
|
||||
if len(matchArray) == 1:
|
||||
argumentList = matchArray[0]
|
||||
oneline=codeRegEx.sub('',oneline)
|
||||
|
||||
return oneline,argumentList
|
||||
|
||||
def usage():
|
||||
print
|
||||
print " usage: %s file1" % os.path.basename(sys.argv[0])
|
||||
print
|
||||
print " builds a one line string to send to commandToExecute"
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv)!=2:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
file = sys.argv[1]
|
||||
if not os.path.exists(file):
|
||||
print "Error: file %s does not exist"
|
||||
sys.exit(2)
|
||||
|
||||
# build the yml file for cluster
|
||||
oneline, argumentList = convertToOneArmTemplateLine(file)
|
||||
|
||||
print 'powershell.exe -ExecutionPolicy Unrestricted -command "%s"' % oneline
|
||||
#print '"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -command \\"%s\\""' % (oneline)
|
|
@ -0,0 +1,156 @@
|
|||
error_log stderr;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
env COREOS_PUBLIC_IPV4;
|
||||
|
||||
http {
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
|
||||
lua_package_path '$prefix/conf/?.lua;;';
|
||||
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
# use mesos-dns
|
||||
resolver 127.0.0.1;
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name dcos.*;
|
||||
root /opt/mesosphere/active/dcos-ui/usr;
|
||||
|
||||
location = /mesos {
|
||||
rewrite ^/mesos$ $scheme://$http_host/mesos/ permanent;
|
||||
}
|
||||
location ~ ^/mesos/(?<url>.*)$ {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header Accept-Encoding "";
|
||||
subs_filter_types application/json;
|
||||
subs_filter [a-zA-Z0-9-]+:8080 $host/marathon/ rg;
|
||||
subs_filter [a-zA-Z0-9-]+:4400 $host/chronos/ rg;
|
||||
# instead of using upstream we must force a re-resolve,
|
||||
# in case leader changes
|
||||
proxy_pass http://leader.mesos:5050/$url$is_args$args;
|
||||
}
|
||||
|
||||
location = /static {
|
||||
rewrite ^/static$ $scheme://$http_host/mesos/static/ permanent;
|
||||
}
|
||||
location /static/ {
|
||||
proxy_set_header Host $http_host;
|
||||
# instead of using upstream we must force a re-resolve,
|
||||
# in case leader changes
|
||||
proxy_pass http://leader.mesos:5050$uri$is_args$args;
|
||||
proxy_set_header Accept-Encoding "";
|
||||
subs_filter_types application/x-javascript;
|
||||
subs_filter "'//' + host + '/" "'//$host/mesosredir/' + host + '/" g;
|
||||
}
|
||||
|
||||
location = /files {
|
||||
rewrite ^/files$ $scheme://$http_host/mesos/files/ permanent;
|
||||
}
|
||||
location /files/ {
|
||||
proxy_set_header Host $http_host;
|
||||
# instead of using upstream we must force a re-resolve,
|
||||
# in case leader changes
|
||||
proxy_pass http://leader.mesos:5050$uri$is_args$args;
|
||||
}
|
||||
|
||||
location ~ ^/mesosredir/[^/]+:80(?<url>.*)$ {
|
||||
rewrite ^/mesosredir/.*$ $url last;
|
||||
}
|
||||
|
||||
location ~ ^/mesosredir/(?<slavehostname>[^/]+)(?<url>.*)$ {
|
||||
set $slaveaddr '';
|
||||
|
||||
more_clear_input_headers Accept-Encoding;
|
||||
rewrite ^/mesosredir/.*$ $url break;
|
||||
rewrite_by_lua_file conf/slavehostname.lua;
|
||||
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass http://$slaveaddr;
|
||||
}
|
||||
|
||||
location ~ ^/slave/(?<slaveid>[0-9a-zA-Z-]+)(?<url>.*)$ {
|
||||
set $slaveaddr '';
|
||||
|
||||
more_clear_input_headers Accept-Encoding;
|
||||
rewrite ^/slave/[0-9a-zA-Z-]+/.*$ $url break;
|
||||
rewrite_by_lua_file conf/slave.lua;
|
||||
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass http://$slaveaddr;
|
||||
}
|
||||
|
||||
location ~ ^/service/(?<serviceid>[0-9a-zA-Z-.]+)/?(?<url>.*) {
|
||||
set $serviceurl '';
|
||||
|
||||
more_clear_input_headers Accept-Encoding;
|
||||
rewrite ^/service/[0-9a-zA-Z-.]+/?.*$ /$url break;
|
||||
rewrite_by_lua_file conf/service.lua;
|
||||
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass $serviceurl;
|
||||
proxy_redirect http://$host/service/$serviceid/ /service/$serviceid/;
|
||||
proxy_redirect http://$host/ /service/$serviceid/;
|
||||
proxy_redirect / /service/$serviceid/;
|
||||
}
|
||||
|
||||
location /metadata {
|
||||
content_by_lua_file conf/metadata.lua;
|
||||
}
|
||||
|
||||
location /dcos-metadata/ {
|
||||
alias /opt/mesosphere/active/dcos-metadata/etc/;
|
||||
}
|
||||
|
||||
location = /marathon {
|
||||
rewrite ^/marathon$ $scheme://$http_host/marathon/ permanent;
|
||||
}
|
||||
# TODO(cmaloney): Make the Web UI work in a subdirectory.
|
||||
location ~ ^/marathon/(.*) {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_pass http://master.mesos:8080/$1$is_args$args;
|
||||
}
|
||||
|
||||
location = /chronos {
|
||||
rewrite ^/chronos$ $scheme://$http_host/chronos/ permanent;
|
||||
}
|
||||
location ~ ^/chronos/(.*) {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_pass http://master.mesos:4400/$1$is_args$args;
|
||||
}
|
||||
|
||||
location /pkgpanda/active.buildinfo.full.json {
|
||||
add_header Cache-Control "no-cache";
|
||||
alias /opt/mesosphere/active.buildinfo.full.json;
|
||||
}
|
||||
|
||||
location = /mesos_dns {
|
||||
rewrite ^/mesos_dns$ $scheme://$http_host/mesos_dns/ permanent;
|
||||
}
|
||||
location ~ ^/mesos_dns/(.*) {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_pass http://master.mesos:8123/$1$is_args$args;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/python
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
|
||||
def jsonLines(jsonFile):
|
||||
with open(jsonFile) as f:
|
||||
content = f.read()
|
||||
return content
|
||||
|
||||
def prettyPrintAndSort(jsonLines):
|
||||
jsonContent = json.loads(jsonLines)
|
||||
return json.dumps(jsonContent, sort_keys=True, indent=2).__str__()
|
||||
|
||||
def translateJson(jsonContent, translateParams, reverseTranslate):
|
||||
for a, b in translateParams:
|
||||
if reverseTranslate:
|
||||
jsonContent=jsonContent.replace(b, a)
|
||||
else:
|
||||
jsonContent=jsonContent.replace(a, b)
|
||||
return jsonContent
|
||||
|
||||
def usage(programName):
|
||||
print "usage: %s AZURE_TEMPLATE_FILE" % (programName)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 2:
|
||||
print "Error: incorrect number of elements"
|
||||
print
|
||||
usage(sys.argv[0])
|
||||
jsonFile=sys.argv[1]
|
||||
|
||||
if not(os.path.exists(jsonFile)) or not(os.path.isfile(jsonFile)):
|
||||
print "Error: %s is not a valid json file"
|
||||
print
|
||||
usage(sys.argv[0])
|
||||
|
||||
# read the lines of the file
|
||||
jsonLines = jsonLines(jsonFile)
|
||||
|
||||
translateParams = [
|
||||
["parameters", "dparameters"],
|
||||
["variables", "eparameters"],
|
||||
["resources", "fresources"],
|
||||
["outputs", "zoutputs"]
|
||||
]
|
||||
|
||||
# translate the outer parameters
|
||||
jsonLines = translateJson(jsonLines, translateParams, False)
|
||||
|
||||
# pretty print and sort
|
||||
prettyPrintLines = prettyPrintAndSort(jsonLines)
|
||||
|
||||
# translate the parameters back
|
||||
prettyPrintLines = translateJson(prettyPrintLines, translateParams, True)
|
||||
|
||||
# print the string
|
||||
print prettyPrintLines
|
|
@ -0,0 +1,37 @@
|
|||
<#code used from https://gist.github.com/wagnerandrade/5424431#>
|
||||
$ip = (Get-NetIPAddress | where {$_.IPAddress -Like '*.*.*.*'})[0].IPAddress
|
||||
$url = "http://"+$ip+":80/"
|
||||
$listener = New-Object System.Net.HttpListener
|
||||
$listener.Prefixes.Add($url)
|
||||
$listener.Start()
|
||||
$callerCounts = @{}
|
||||
|
||||
Write-Host('Listening at {0}...' -f $url)
|
||||
|
||||
while ($listener.IsListening) {
|
||||
$context = $listener.GetContext()
|
||||
$requestUrl = $context.Request.Url
|
||||
$clientIP = $context.Request.RemoteEndPoint.Address
|
||||
$response = $context.Response
|
||||
|
||||
Write-Host ''
|
||||
Write-Host('> {0}' -f $requestUrl)
|
||||
|
||||
$count = 1
|
||||
$k=$callerCounts.Get_Item($clientIP)
|
||||
if ($k -ne $null) { $count += $k }
|
||||
$callerCounts.Set_Item($clientIP, $count)
|
||||
$header="<html><body><H1>Windows Container Web Server</H1>"
|
||||
$callerCountsString=""
|
||||
$callerCounts.Keys | % { $callerCountsString+='<p>IP {0} callerCount {1} ' -f $_,$callerCounts.Item($_) }
|
||||
$footer="</body></html>"
|
||||
$content='{0}{1}{2}' -f $header,$callerCountsString,$footer
|
||||
Write-Output $content
|
||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes($content)
|
||||
$response.ContentLength64 = $buffer.Length
|
||||
$response.OutputStream.Write($buffer, 0, $buffer.Length)
|
||||
$response.Close()
|
||||
|
||||
$responseStatus = $response.StatusCode
|
||||
Write-Host('< {0}' -f $responseStatus)
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<#code used from https://gist.github.com/wagnerandrade/5424431#>
|
||||
$ip = (Get-NetIPAddress | where {$_.IPAddress -Like '*.*.*.*'})[0].IPAddress
|
||||
$url = 'http://{0}:80/' -f $ip
|
||||
$listener = New-Object System.Net.HttpListener
|
||||
$listener.Prefixes.Add($url)
|
||||
$listener.Start()
|
||||
|
||||
Write-Host('Listening at {0}...' -f $url)
|
||||
|
||||
while ($listener.IsListening) {
|
||||
$context = $listener.GetContext()
|
||||
$requestUrl = $context.Request.Url
|
||||
$clientIP = $context.Request.RemoteEndPoint.Address
|
||||
$response = $context.Response
|
||||
Write-Host ''
|
||||
Write-Host('> {0}' -f $requestUrl)
|
||||
$content='<html><body><H1>helloworld</H1></body></html>'
|
||||
Write-Output $content
|
||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes($content)
|
||||
$response.ContentLength64 = $buffer.Length
|
||||
$response.OutputStream.Write($buffer, 0, $buffer.Length)
|
||||
$response.Close()
|
||||
$responseStatus = $response.StatusCode
|
||||
Write-Host('< {0}' -f $responseStatus)
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
"vmSizesMap": {
|
||||
"Standard_A0": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A1": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A3": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A4": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A5": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A6": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A7": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A8": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A9": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A10": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_A11": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D1": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D3": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D4": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D11": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D12": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D13": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D14": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D1_v2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D2_v2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D3_v2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D4_v2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D5_v2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D11_v2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D12_v2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D13_v2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_D14_v2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_G1": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_G2": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_G3": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_G4": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_G5": {
|
||||
"storageAccountType":"Standard_LRS"
|
||||
},
|
||||
"Standard_DS1": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_DS2": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_DS3": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_DS4": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_DS11": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_DS12": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_DS13": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_DS14": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_GS1": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_GS2": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_GS3": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_GS4": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
},
|
||||
"Standard_GS5": {
|
||||
"storageAccountType":"Premium_LRS"
|
||||
}
|
||||
}
|