summaryrefslogtreecommitdiffstats
path: root/tools/docker
diff options
context:
space:
mode:
Diffstat (limited to 'tools/docker')
-rw-r--r--tools/docker/demo_deploy.sh60
-rw-r--r--tools/docker/docker-cluster.sh221
-rw-r--r--tools/docker/nginx.json67
3 files changed, 348 insertions, 0 deletions
diff --git a/tools/docker/demo_deploy.sh b/tools/docker/demo_deploy.sh
new file mode 100644
index 0000000..cbfe949
--- /dev/null
+++ b/tools/docker/demo_deploy.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# Copyright 2017 AT&T Intellectual Property, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#. What this is: Complete scripted deployment of an experimental Docker-based
+#. cloud-native application platform. When complete, Docker-CE and the following
+#. will be installed:
+#. - nginx as demo application
+#. - prometheus + grafana for cluster monitoring/stats
+#. Prometheus dashboard: http://<master_public_ip>:9090
+#. Grafana dashboard: http://<master_public_ip>:3000
+#.
+#. Prerequisites:
+#. - Ubuntu server for cluster nodes (admin/master and worker nodes)
+#. - MAAS server as cluster admin for Rancher master/worker nodes
+#. - Password-less ssh key provided for node setup
+#. Usage: on the MAAS server
+#. $ git clone https://gerrit.opnfv.org/gerrit/models ~/models
+#. $ bash ~/models/tools/docker/demo_deploy.sh <key> "<hosts>" <master_ip>
+#. "<worker_ips>" [<extras>]
+#. <key>: name of private key for cluster node ssh (in current folder)
+#. <hosts>: space separated list of hostnames managed by MAAS
+#. <master_ip>: IP of master node
+#. <worker_ips>: space separated list of worker node IPs
+#. <extras>: optional name of script for extra setup functions as needed
+
+key=$1
+nodes="$2"
+master=$3
+workers="$4"
+extras=$5
+
+source ~/models/tools/maas/deploy.sh $1 "$2" $5
+eval `ssh-agent`
+ssh-add $key
+echo "Setting up Docker..."
+bash ~/models/tools/docker/docker-cluster.sh all $master "$workers"
+# TODO: Figure this out... Have to break the setup into two steps as something
+# causes the ssh session to end before the prometheus setup, if both scripts
+# (k8s-cluster and prometheus-tools) are in the same ssh session
+echo "Setting up Prometheus..."
+scp -o StrictHostKeyChecking=no $key ubuntu@$master:/home/ubuntu/$key
+ssh -x -o StrictHostKeyChecking=no ubuntu@$master <<EOF
+git clone https://gerrit.opnfv.org/gerrit/models
+exec ssh-agent bash
+ssh-add $key
+bash models/tools/prometheus/prometheus-tools.sh all "$master $workers"
+EOF
+echo "All done!"
diff --git a/tools/docker/docker-cluster.sh b/tools/docker/docker-cluster.sh
new file mode 100644
index 0000000..8c0aa69
--- /dev/null
+++ b/tools/docker/docker-cluster.sh
@@ -0,0 +1,221 @@
+#!/bin/bash
+# Copyright 2017 AT&T Intellectual Property, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#. What this is: Deployment script for a mult-node docker-ce cluster.
+#. Prerequisites:
+#. - Ubuntu server for master and worker nodes
+#. Usage:
+#. $ git clone https://gerrit.opnfv.org/gerrit/models ~/models
+#. $ cd ~/models/tools/docker
+#.
+#. Usage:
+#. $ bash docker_cluster.sh all <master> "<workers>"
+#. Automate setup and start demo services.
+#. <master>: master node IPs
+#. <workers>: space-separated list of worker node IPs
+#. $ bash docker_cluster.sh setup <master> "<workers>"
+#. Installs and starts master and worker nodes.
+#. $ bash docker_cluster.sh create <service>
+#. <service>: Demo service name to start.
+#. Currently supported: nginx
+#. $ bash docker_cluster.sh delete <service>
+#. <service>: Service name to delete.
+#. $ bash docker_cluster.sh clean [<node>]
+#. <node>: optional IP address of node to clean.
+#. By default, cleans the entire cluster.
+#.
+
+# Setup master and worker hosts
+function setup() {
+ # Per https://docs.docker.com/engine/swarm/swarm-tutorial/
+ cat >/tmp/env.sh <<EOF
+master=$1
+workers="$2"
+EOF
+ source /tmp/env.sh
+ cat >/tmp/prereqs.sh <<'EOF'
+#!/bin/bash
+# Per https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/
+sudo apt-get remove -y docker docker-engine docker.io docker-ce
+sudo apt-get update
+sudo apt-get install -y \
+ linux-image-extra-$(uname -r) \
+ linux-image-extra-virtual
+sudo apt-get install -y \
+ apt-transport-https \
+ ca-certificates \
+ curl \
+ software-properties-common
+curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
+sudo add-apt-repository \
+ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
+ $(lsb_release -cs) \
+ stable"
+sudo apt-get update
+sudo apt-get install -y docker-ce
+EOF
+
+ # jq is used for parsing API reponses
+ sudo apt-get install -y jq
+ scp -o StrictHostKeyChecking=no /tmp/prereqs.sh ubuntu@$master:/home/ubuntu/prereqs.sh
+ ssh -x -o StrictHostKeyChecking=no ubuntu@$master bash /home/ubuntu/prereqs.sh
+ # activate docker API
+ # Per https://www.ivankrizsan.se/2016/05/18/enabling-docker-remote-api-on-ubuntu-16-04/
+ ssh -x -o StrictHostKeyChecking=no ubuntu@$master <<EOF
+sudo sed -i -- 's~fd://~fd:// -H tcp://0.0.0.0:4243~' /lib/systemd/system/docker.service
+sudo systemctl daemon-reload
+sudo service docker restart
+# Activate swarm mode
+# Per https://docs.docker.com/engine/swarm/swarm-tutorial/create-swarm/
+sudo docker swarm init --advertise-addr $master
+EOF
+
+ if ! curl http://$master:4243/version ; then
+ echo "${FUNCNAME[0]}: docker API failed to initialize"
+ exit 1
+ fi
+
+ # Per https://docs.docker.com/engine/swarm/swarm-tutorial/add-nodes/
+ token=$(ssh -o StrictHostKeyChecking=no -x ubuntu@$master sudo docker swarm join-token worker | grep docker)
+ for worker in $workers; do
+ echo "${FUNCNAME[0]}: setting up worker at $worker"
+ scp -o StrictHostKeyChecking=no /tmp/prereqs.sh ubuntu@$worker:/home/ubuntu/.
+ ssh -x -o StrictHostKeyChecking=no ubuntu@$worker bash /home/ubuntu/prereqs.sh
+ ssh -x -o StrictHostKeyChecking=no ubuntu@$worker sudo $token
+ done
+
+ echo "${FUNCNAME[0]}: testing service creation"
+ reps=1; for a in $workers; do ((reps++)); done
+ create_service nginx $reps
+}
+
+
+function create_service() {
+ echo "${FUNCNAME[0]}: creating service $1 with $2 replicas"
+ # sudo docker service create -p 80:80 --replicas $reps --name nginx nginx
+ # per https://docs.docker.com/engine/api/v1.27/
+ source /tmp/env.sh
+ case "$1" in
+ nginx)
+ match="Welcome to nginx!"
+ ;;
+ *)
+ echo "${FUNCNAME[0]}: service $1 not setup for use with this script"
+ esac
+
+ if ! curl -X POST http://$master:4243/services/create -d @$1.json ; then
+ echo "${FUNCNAME[0]}: service creation failed"
+ exit 1
+ fi
+
+ check_service $1 $match
+}
+
+function check_service() {
+ echo "${FUNCNAME[0]}: checking service state for $1 with match string $2"
+ source /tmp/env.sh
+ service=$1
+ match="$2"
+ services=$(curl http://$master:4243/services)
+ n=$(echo $services | jq '. | length')
+ ((n--))
+ while [[ $n -ge 0 ]]; do
+ if [[ $(echo $services | jq -r ".[$n].Spec.Name") == $service ]]; then
+ id=$(echo $services | jq -r ".[$n].ID")
+ port=$(echo $services | jq -r ".[$n].Endpoint.Ports[0].PublishedPort")
+ nodes="$master $workers"
+ for node in $nodes; do
+ not=""
+ while ! curl -s -o /tmp/resp http://$node:$port ; do
+ echo "${FUNCNAME[0]}: service is not yet active, waiting 10 seconds"
+ sleep 10
+ done
+ curl -s -o /tmp/resp http://$node:$port
+ if [[ $(grep -c "$match" /tmp/resp) == 0 ]]; then
+ not="NOT"
+ fi
+ echo "$service service is $not active at address http://$node:$port"
+ done
+ break
+ fi
+ ((n--))
+ done
+}
+
+function delete_service() {
+ echo "${FUNCNAME[0]}: deleting service $1"
+ source /tmp/env.sh
+ service=$1
+ services=$(curl http://$master:4243/services)
+ n=$(echo $services | jq '. | length')
+ ((n--))
+ while [[ $n -ge 0 ]]; do
+ if [[ $(echo $services | jq -r ".[$n].Spec.Name") == $service ]]; then
+ id=$(echo $services | jq -r ".[$n].ID")
+ if ! curl -X DELETE http://$master:4243/services/$id ; then
+ echo "${FUNCNAME[0]}: failed to delete service $1"
+ else
+ echo "${FUNCNAME[0]}: deleted service $1"
+ fi
+ break
+ fi
+ ((n--))
+ done
+}
+
+# Clean the installation
+function clean() {
+ source /tmp/env.sh
+ nodes="$master $workers"
+ for node in $nodes; do
+ ssh -o StrictHostKeyChecking=no -x ubuntu@$node <<EOF
+sudo docker swarm leave --force
+sudo systemctl stop docker
+sudo apt-get remove -y docker-ce
+EOF
+ done
+}
+
+export WORK_DIR=$(pwd)
+case "$1" in
+ setup)
+ setup $2 "$3"
+ ;;
+ ceph)
+ # TODO Ceph support for docker, e.g. re
+ # http://docker.com/docs/docker/latest/en/docker-services/storage-service/
+ # https://github.com/docker/docker/issues/8722
+ # setup_ceph "$2" $3 $4 $5
+ ;;
+ all)
+ start=`date +%s`
+ setup $2 "$3"
+ end=`date +%s`
+ runtime=$((end-start))
+ runtime=$((runtime/60))
+ echo "${FUNCNAME[0]}: Demo duration = $runtime minutes"
+ ;;
+ create)
+ create_service "$2" $3
+ ;;
+ delete)
+ delete_service "$2"
+ ;;
+ clean)
+ clean $2
+ ;;
+ *)
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then grep '#. ' $0; fi
+esac
diff --git a/tools/docker/nginx.json b/tools/docker/nginx.json
new file mode 100644
index 0000000..a74681f
--- /dev/null
+++ b/tools/docker/nginx.json
@@ -0,0 +1,67 @@
+{
+ "Name": "nginx",
+ "TaskTemplate": {
+ "ContainerSpec": {
+ "Image": "nginx",
+ "Mounts": [
+ {
+ "ReadOnly": true,
+ "Source": "web-data",
+ "Target": "/usr/share/nginx/html",
+ "Type": "volume",
+ "VolumeOptions": {
+ "DriverConfig": { },
+ "Labels": { "com.example.something": "something-value" }
+ }
+ }
+ ],
+ "DNSConfig": {
+ "Nameservers": [ "8.8.8.8" ],
+ "Search": [ "example.org" ],
+ "Options": [ "timeout:3" ]
+ }
+ },
+ "LogDriver": {
+ "Name": "json-file",
+ "Options": {
+ "max-file": "3",
+ "max-size": "10M"
+ }
+ },
+ "Placement": { },
+ "Resources": {
+ "Limits": {
+ "MemoryBytes": 104857600
+ },
+ "Reservations": { }
+ },
+ "RestartPolicy": {
+ "Condition": "on-failure",
+ "Delay": 10000000000,
+ "MaxAttempts": 10
+ }
+ },
+ "Mode": {
+ "Replicated": {
+ "Replicas": 3
+ }
+ },
+ "UpdateConfig": {
+ "Delay": 30000000000,
+ "Parallelism": 2,
+ "FailureAction": "pause"
+ },
+ "EndpointSpec": {
+ "Ports": [
+ {
+ "Protocol": "tcp",
+ "PublishedPort": 8080,
+ "TargetPort": 80
+ }
+ ]
+ },
+ "Labels": {
+ "foo": "bar"
+ }
+}
+