From d9ce1bd2b6fa25174b96f476768ec255b4dcec93 Mon Sep 17 00:00:00 2001 From: Alessandro Fael Garcia Date: Wed, 30 Jan 2019 16:03:17 +0100 Subject: [PATCH] Update service discovery demos to use NGINX's REST API (#12) * Update service discovery demos to use NGINX's REST API --- .gitignore | 6 + consul-api-demo/README.md | 201 +++++++++--------- consul-api-demo/Vagrantfile | 7 +- consul-api-demo/clean_containers.sh | 2 +- consul-api-demo/create-http-service.yml | 16 +- consul-api-demo/docker-compose.yml | 65 +++--- consul-api-demo/nginxplus/Dockerfile | 60 ++++-- consul-api-demo/nginxplus/app.conf | 78 +++---- consul-api-demo/nginxplus/index.html | 23 -- consul-api-demo/nginxplus/logo.png | Bin 12587 -> 0 bytes consul-api-demo/provision.sh | 11 +- consul-api-demo/script.sh | 82 +++---- consul-api-demo/setup_consul_api_demo.yml | 68 +++--- consul-dns-srv-demo/README.md | 201 +++++++++--------- consul-dns-srv-demo/Vagrantfile | 7 +- consul-dns-srv-demo/clean_containers.sh | 2 +- consul-dns-srv-demo/docker-compose.yml | 79 ++++--- consul-dns-srv-demo/nginxplus/Dockerfile | 60 ++++-- consul-dns-srv-demo/nginxplus/app.conf | 53 ++--- consul-dns-srv-demo/nginxplus/logo.png | Bin 12587 -> 0 bytes consul-dns-srv-demo/provision.sh | 11 +- .../setup_consul_dns_srv_demo.yml | 60 +++--- consul-template-demo/README.md | 69 +++--- consul-template-demo/clean_containers.sh | 2 +- consul-template-demo/docker-compose.yml | 75 ++++--- consul-template-demo/nginx/Dockerfile | 115 ++++++++-- .../nginx/consul-template.service | 6 +- consul-template-demo/nginx/logo.png | Bin 12586 -> 0 bytes consul-template-demo/nginx/nginx.conf | 35 ++- consul-template-demo/nginx/nginx.service | 5 +- etcd-demo/README.md | 172 ++++++++------- etcd-demo/Vagrantfile | 7 +- etcd-demo/clean_containers.sh | 2 +- etcd-demo/create-http-service.yml | 16 +- etcd-demo/docker-compose.yml | 53 +++-- etcd-demo/etcd_exec_watch.sh | 3 +- etcd-demo/nginxplus/Dockerfile | 60 ++++-- etcd-demo/nginxplus/app.conf | 79 +++---- etcd-demo/nginxplus/index.html | 23 -- etcd-demo/nginxplus/logo.png | Bin 12587 -> 0 bytes etcd-demo/provision.sh | 11 +- etcd-demo/script.sh | 86 ++++---- etcd-demo/setup_etcd_demo.yml | 102 ++++----- zookeeper-demo/README.md | 200 +++++++++-------- zookeeper-demo/Vagrantfile | 7 +- zookeeper-demo/clean_containers.sh | 2 +- zookeeper-demo/create-http-service.yml | 16 +- zookeeper-demo/docker-compose.yml | 61 +++--- zookeeper-demo/nginxplus/Dockerfile | 60 ++++-- zookeeper-demo/nginxplus/app.conf | 79 +++---- zookeeper-demo/nginxplus/logo.png | Bin 12587 -> 0 bytes zookeeper-demo/provision.sh | 11 +- zookeeper-demo/setup_zookeeper_demo.yml | 72 +++---- zookeeper-demo/zookeeper/Dockerfile | 50 +++-- zookeeper-demo/zookeeper/script.sh | 79 ++++--- 55 files changed, 1342 insertions(+), 1308 deletions(-) delete mode 100644 consul-api-demo/nginxplus/index.html delete mode 100644 consul-api-demo/nginxplus/logo.png delete mode 100644 consul-dns-srv-demo/nginxplus/logo.png delete mode 100644 consul-template-demo/nginx/logo.png delete mode 100644 etcd-demo/nginxplus/index.html delete mode 100644 etcd-demo/nginxplus/logo.png delete mode 100644 zookeeper-demo/nginxplus/logo.png diff --git a/.gitignore b/.gitignore index 02318e01..6c2550bc 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,9 @@ # Ignore MacOS system files .DS_Store + +# Ignore log files +*.log + +# Ignore Ansible retry files +*.retry diff --git a/consul-api-demo/README.md b/consul-api-demo/README.md index dec73d6f..a75dc255 100644 --- a/consul-api-demo/README.md +++ b/consul-api-demo/README.md @@ -1,94 +1,88 @@ -# Demo to show Nginx Plus Dynamic Reconfiguration API (upstream_conf) with Consul +# Demo to show NGINX Plus Dynamic Reconfiguration API with Consul -This demo shows NGINX Plus being used in conjuction with Consul, a service discovery platform. This demo is based on docker and spins' -up the following containers: +This demo shows NGINX Plus being used in conjuction with Consul, a service discovery platform. This demo is based on docker and spins up the following containers: -* [Consul](http://www.consul.io) for service discovery -* [Registrator](https://github.com/gliderlabs/registrator) to register services with Consul. Registrator monitors for containers being started and stopped and updates Consul when a container changes state. -* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port, request URI, local time of the webserver and the client IP address. This is to simulate backend servers NGINX Plus will be load balancing across. -* and of course [NGINX Plus](http://www.nginx.com/products) (R8 or higher) +* [Consul](http://www.consul.io) for service discovery +* [Registrator](https://github.com/gliderlabs/registrator) to register services with Consul. Registrator monitors for containers being started and stopped and updates Consul when a container changes state. +* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port, request URI, local time of the webserver and the client IP address. This is to simulate backend servers NGINX Plus will be load balancing across. +* [NGINX Plus](http://www.nginx.com/products) (R13 or higher) The demo is based off the work described in this blog post: [Service Discovery with NGINX Plus and Consul](https://www.nginx.com/blog/service-discovery-with-nginx-plus-and-consul/) - + ## Setup Options: ### Fully automated Vagrant/Ansible setup: Install Vagrant using the necessary package for your OS: -https://www.vagrantup.com/downloads.html + + +1. Install provider for vagrant to use to start VM's. -1. Install provider for vagrant to use to start VM's. + The default provider is VirtualBox (Note that only VirtualBox versions 4.0 and higher are supported), which can be downloaded from the following link: - The default provider is VirtualBox [Note that only VirtualBox versions 4.0 and higher are supported], which can be downloaded from the following link: + - https://www.virtualbox.org/wiki/Downloads + A full list of providers can be found at the following page, if you do not want to use VirtualBox: - A full list of providers can be found at the following page, if you do not want to use VirtualBox: + - https://docs.vagrantup.com/v2/providers/ +2. Install Ansible: -1. Install Ansible: + - http://docs.ansible.com/ansible/intro_installation.html +3. Clone demo repo -1. Clone demo repo + `$ git clone https://github.com/nginxinc/NGINX-Demos.git` - ```$ git clone https://github.com/nginxinc/NGINX-Demos.git``` +4. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `~/NGINX-Demos/consul-api-demo/nginxplus` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```~/NGINX-Demos/ansible/files/``` +5. Move into the consul-api-demo directory and start the Vagrant vm: -1. Move into the consul-api-demo directory and start the Vagrant vm: + ``` + $ cd ~/NGINX-Demos/consul-api-demo + $ vagrant up + ``` - ``` - $ cd ~/NGINX-Demos/consul-api-demo - $ vagrant up - ``` - The ```vagrant up``` command will start the virtualbox VM and provision it using the ansible playbook file ~/NGINX-Demos/ansible/setup_consul_api_demo.yml. The ansible playbook file also invokes another script provision.sh which sets the HOST_IP environment variable to the IP address of the eth1 interface (10.2.2.70 in this case assigned in the Vagrantfile) and invokes the ```docker-compose up -d``` command + The `vagrant up` command will start the virtualbox VM and provision it using the ansible playbook file `~/NGINX-Demos/consul-api-demo/setup_consul_api_demo.yml`. The ansible playbook file also invokes another script `provision.sh` which sets the HOST_IP environment variable to the IP address of the `enp0s8` interface (10.2.2.70 in this case - assigned in the Vagrantfile) and invokes the `docker-compose up -d` command -1. SSH into the newly created virtual machine and move into the /vagrant directory which contains the demo files: +6. SSH into the newly created virtual machine and move into the /vagrant directory which contains the demo files: - ``` - $ vagrant ssh - $ sudo su - ``` -The demo files will be in /srv/NGINX-Demos/consul-api-demo + ``` + $ vagrant ssh + $ sudo su + ``` -1. Now simply follow the steps listed under section 'Running the demo'. +The demo files will be in `/srv/NGINX-Demos/consul-api-demo` +7. Now simply follow the steps listed under section 'Running the demo'. ### Ansible only deployment -1. Create Ubuntu 14.04 VM +1. Create Ubuntu 18.04 LTS VM -1. Install Ansible on Ubuntu VM +2. Install Ansible on Ubuntu VM - ``` - $ sudo apt-get install ansible - ``` + `$ sudo apt-get install ansible` -1. Clone demo repo into ```/srv``` on Ubuntu VM: +3. Clone demo repo into `/srv` on Ubuntu VM: - ``` - $ cd /srv - $ sudo git clone https://github.com/nginxinc/NGINX-Demos.git - ``` + ``` + $ cd /srv + $ sudo git clone https://github.com/nginxinc/NGINX-Demos.git + ``` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```/srv/NGINX-Demos/ansible/files/``` +4. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `/srv/NGINX-Demos/consul-api-demo/nginxplus` -1. Move into the consul-api-demo directory which contains the demo files and make sure the IP address of your Ubuntu VM on which NGINX Plus will be listening is assigned to the ```eth1``` interface. If in case you need to use IP of another interface, replace ```eth1``` on line 6 of provision.sh with the corresponding interface name - ``` - $ cd /srv/NGINX-Demos/consul-api-demo - ``` +5. Move into the consul-api-demo directory which contains the demo files and make sure the IP address of your Ubuntu VM on which NGINX Plus will be listening is assigned to the `enp0s8` interface. If in case you need to use IP of another interface, replace `enp0s8` on line 6 of provision.sh with the corresponding interface name -1. Run the ansible playbook against localhost on Ubuntu VM: + `$ cd /srv/NGINX-Demos/consul-api-demo` - ``` - $ sudo ansible-playbook -i "localhost," -c local /srv/NGINX-Demos/ansible/setup_consul_api_demo.yml - ``` +6. Run the ansible playbook against localhost on Ubuntu VM: -1. Now simply follow the steps listed under section 'Running the demo'. + `$ sudo ansible-playbook -i "localhost," -c local /srv/NGINX-Demos/consul-api-demo/setup_consul_api_demo.yml` +7. Now simply follow the steps listed under section 'Running the demo'. ### Manual Install @@ -96,80 +90,79 @@ The demo files will be in /srv/NGINX-Demos/consul-api-demo The following software needs to be installed: -* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM -* [jq](https://stedolan.github.io/jq/), I used [brew](http://brew.sh) to install it on my Mac: `brew install jq` +* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM +* [jq](https://stedolan.github.io/jq/), I used [brew](http://brew.sh) to install it: `brew install jq` #### Setting up the demo -1. Clone demo repo - ```$ git clone https://github.com/nginxinc/NGINX-Demos.git``` +1. Clone demo repo + + `$ git clone https://github.com/nginxinc/NGINX-Demos.git` + +2. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `~/NGINX-Demos/consul-api-demo/nginxplus/` + +3. Move into the demo directory: -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```~/NGINX-Demos/consul-api-demo/nginxplus/``` + `$ cd ~/NGINX-Demos/consul-api-demo` -1. Move into the demo directory: +4. If you have run this demo previously or have any docker containers running, start with a clean slate by running - ``` - $ cd ~/NGINX-Demos/consul-api-demo - ``` + `$ ./clean_containers.sh` -1. If you have run this demo previously or have any docker containers running, start with a clean slate by running - ``` - $ ./clean_containers.sh - ``` +5. NGINX Plus will be listening on port 80 on your docker host. -1. NGINX Plus will be listening on port 80 on your docker host. - 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running + 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running - ``` - $ docker-machine ip default - 192.168.99.100 - ``` - 1. If you are using Docker for Mac, the IP address you need to use is 172.17.0.1 + ``` + $ docker-machine ip default + 192.168.99.100 + ``` - Export this IP into an environment variable named HOST_IP by running `export HOST_IP=x.x.x.x` command. This variable is used by docker-compose.yml file + 2. If you are using Docker for Mac, the IP address you need to use is 172.17.0.1 -1. Spin up the Consul, Registrator and NGINX Plus containers first: + Export this IP into an environment variable named HOST_IP by running the `$ export HOST_IP=x.x.x.x` command. This variable is used by the `docker-compose.yml` file. - ``` - $ docker-compose up -d - ``` +6. Spin up the Consul, Registrator and NGINX Plus containers first: -1. Execute the following two `docker exec` commands to install [jq](https://stedolan.github.io/jq/) inside consul container - ``` - docker exec -ti consul apk update - docker exec -ti consul apk add jq - ``` + `$ docker-compose up -d` -1. Spin up the nginxdemos/hello container which is the backend http service - ``` - $ docker-compose -f create-http-service.yml up -d - ``` +7. Execute the following two `docker exec` commands to install [jq](https://stedolan.github.io/jq/) inside consul container -1. Now follow the steps under section 'Running the demo' + ``` + docker exec -ti consul apk update + docker exec -ti consul apk add jq + ``` + +8. Spin up the nginxdemos/hello container which is the backend http service + + `$ docker-compose -f create-http-service.yml up -d` + +9. Now follow the steps under section 'Running the demo' ## Running the demo -1. You should have a bunch of containers up and running now: +1. You should have a bunch of containers up and running now: + + ``` + $ docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + b663f7ac70be nginxdemos/hello:latest "nginx -g 'daemon off" About an hour ago Up About an hour 443/tcp, 0.0.0.0:32800->80/tcp consulapidemo_http_1 + 7d6a66acff99 consulapidemo_nginxplus "nginx -g 'daemon off" About an hour ago Up About an hour 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp, 443/tcp nginxplus + 2059ad9a7926 gliderlabs/registrator:latest "/bin/registrator con" About an hour ago Up About an hour registrator + dd4b1101bb66 progrium/consul:latest "/bin/start -server -" About an hour ago Up About an hour 53/tcp, 0.0.0.0:8300->8300/tcp, 0.0.0.0:8400->8400/tcp, 8301-8302/tcp, 0.0.0.0:8500->8500/tcp, 8301-8302/udp, 0.0.0.0:8600->53/udp consul + ``` - ``` - $ docker ps - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - b663f7ac70be nginxdemos/hello:latest "nginx -g 'daemon off" About an hour ago Up About an hour 443/tcp, 0.0.0.0:32800->80/tcp consulapidemo_http_1 - 7d6a66acff99 consulapidemo_nginxplus "nginx -g 'daemon off" About an hour ago Up About an hour 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp, 443/tcp nginxplus - 2059ad9a7926 gliderlabs/registrator:latest "/bin/registrator con" About an hour ago Up About an hour registrator - dd4b1101bb66 progrium/consul:latest "/bin/start -server -" About an hour ago Up About an hour 53/tcp, 0.0.0.0:8300->8300/tcp, 0.0.0.0:8400->8400/tcp, 8301-8302/tcp, 0.0.0.0:8500->8500/tcp, 8301-8302/udp, 0.0.0.0:8600->53/udp consul - ``` +2. If you followed the Fully automated Vagrant/Ansible setup option above, HOST_IP referred below is the IP assigned to your Vagrant VM (i.e 10.2.2.70 in Vagrantfile) and is set already. And if you followed the Ansible only deployment option, HOST_IP will be the IP of your Ubuntu VM on which NGINX Plus is listening (IP of the interface set on line 6 of provision.sh, set to enp0s8 by default). For the manual install option, HOST_IP was already set above. -1. If you followed the Fully automated Vagrant/Ansible setup option above, HOST_IP referred below is the IP assigned to your Vagrant VM (i.e 10.2.2.70 in Vagrantfile) and is set already. And if you followed the Ansible only deployment option, HOST_IP will be the IP of your Ubuntu VM on which NGINX Plus is listening (IP of the interface set on line 6 of provision.sh, set to eth1 by default). For the manual install option, HOST_IP was already set above. +3. Go to `http://` (Note: Docker for Mac runs on IP address 127.0.0.1) in your favorite browser window and that will take you to the hello container printing its hostname, IP Address and port number, request URI, local time of the webserver and the client IP address. `http://:8080/` will bring up the NGINX Plus dashboard. The configuration file NGINX Plus is using here is /etc/nginx/conf.d/app.conf which is included from /etc/nginx/nginx.conf. If you would like to see all the services registered with consul go to `http://:8500`. **We are also using the persistent on-the-fly reconfiguration feature introduced in NGINX Plus R8. This means that NGINX Plus saves all the changes made by the Rest API across reloads by writing it to a file on disk specified using the [state](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#state) directive.** -1. Go to `http://` (Note: Docker for Mac runs on IP address 127.0.0.1) in your favorite browser window and that will take you to the hello container printing its hostname, IP Address and port number, request URI, local time of the webserver and the client IP address. `http://:8080/` will bring up the NGINX Plus dashboard. The configuration file NGINX Plus is using here is /etc/nginx/conf.d/app.conf which is included from /etc/nginx/nginx.conf. If you would like to see all the services registered with consul go to `http://:8500`. **We are also using the persistent on-the-fly reconfiguration feature introduced in NGINX Plus R8. This means that NGINX Plus saves all the changes made by the upstream_conf API across reloads by writing it to a file on disk specified using the [state](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#state) directive.** +4. Now scale up and scale down the http service using the commands below. Go to the Upstreams tab on Nginx Plus dashboard and observe the change in the list of servers being added/removed from the backend group accordingly. -1. Now scale up and scale down the http service using the commands below. Go to the Upstreams tab on Nginx Plus dashboard and observe the change in the list of servers being added/removed from the backend group accordingly. - ``` - $ docker-compose -f create-http-service.yml scale http=5 - $ docker-compose -f create-http-service.yml scale http=3 - ``` + ``` + $ docker-compose -f create-http-service.yml scale http=5 + $ docker-compose -f create-http-service.yml scale http=3 + ``` -1. The way this works is using [Consul Watches](https://www.consul.io/docs/agent/watches.html), eveytime there is a change in the number of containers running the http service, an external handler which is a simple bash script (script.sh) gets invoked. This script gets the list of all Nginx Plus upstreams using its status and upstream_conf APIs, loops through all the http service containers registered with consul and adds them to the upstream group using upstream_conf API if not present already. It also removes the upstreams which are not present in Consul from Nginx upstream group. +5. The way this works is using [Consul Watches](https://www.consul.io/docs/agent/watches.html), eveytime there is a change in the number of containers running the http service, an external handler which is a simple bash script (`script.sh`) gets invoked. This script gets the list of all Nginx Plus upstreams using its status and upstream_conf APIs, loops through all the http service containers registered with consul and adds them to the upstream group using Rest API if not present already. It also removes the upstreams which are not present in Consul from Nginx upstream group. All the changes should be automatically reflected in the NGINX config and show up on the NGINX Plus Dashboard. diff --git a/consul-api-demo/Vagrantfile b/consul-api-demo/Vagrantfile index 20d0e749..8ee2e57c 100644 --- a/consul-api-demo/Vagrantfile +++ b/consul-api-demo/Vagrantfile @@ -1,14 +1,15 @@ -VAGRANTFILE_API_VERSION = "2" - Vagrant.configure(2) do |config| - config.vm.box = "ubuntu/trusty64" + config.vm.box = "ubuntu/bionic64" config.vm.network "private_network", :ip => "10.2.2.70" config.vm.synced_folder "../consul-api-demo/", "/srv/NGINX-Demos/consul-api-demo" config.vm.provision :ansible do |ansible| ansible.playbook = "./setup_consul_api_demo.yml" + ansible.extra_vars = { + ansible_python_interpreter:"/usr/bin/python3" + } end end diff --git a/consul-api-demo/clean_containers.sh b/consul-api-demo/clean_containers.sh index cb70d661..452fe07c 100755 --- a/consul-api-demo/clean_containers.sh +++ b/consul-api-demo/clean_containers.sh @@ -1,2 +1,2 @@ #!/bin/bash -docker rm -f `docker ps -qa` +docker rm -f $(docker ps -qa) diff --git a/consul-api-demo/create-http-service.yml b/consul-api-demo/create-http-service.yml index cbcd4dc0..770accdb 100644 --- a/consul-api-demo/create-http-service.yml +++ b/consul-api-demo/create-http-service.yml @@ -1,7 +1,9 @@ -http: - image: nginxdemos/hello:latest - labels: - SERVICE_80_NAME: http - SERVICE_TAGS: production - ports: - - "80" +version: '3' +services: + http: + image: nginxdemos/hello:latest + labels: + SERVICE_80_NAME: http + SERVICE_TAGS: production + ports: + - "80" diff --git a/consul-api-demo/docker-compose.yml b/consul-api-demo/docker-compose.yml index 7ab3e474..ce60d7f4 100644 --- a/consul-api-demo/docker-compose.yml +++ b/consul-api-demo/docker-compose.yml @@ -1,33 +1,32 @@ -nginxplus: - build: ./nginxplus - container_name: nginxplus - links: - - consul - ports: - - "80:80" - - "8080:8080" - -consul: - command: "-server -bootstrap -node consul -advertise ${HOST_IP} -config-file /etc/consul.d/config.json" - image: progrium/consul:latest - container_name: consul - ports: - - "8300:8300" - - "8400:8400" - - "8500:8500" - - "8600:53/udp" - volumes: - - "./consul_watches_config.json:/etc/consul.d/config.json" - - "./script.sh:/tmp/script.sh" - environment: - - HOST_IP - -registrator: - command: consul://consul:8500 - image: gliderlabs/registrator:latest - container_name: registrator - links: - - consul - volumes: - - "/var/run/docker.sock:/tmp/docker.sock" - +version: '3' +services: + nginxplus: + build: ./nginxplus + container_name: nginxplus + links: + - consul + ports: + - "80:80" + - "8080:8080" + consul: + command: "-server -bootstrap -node consul -advertise ${HOST_IP} -config-file /etc/consul.d/config.json" + image: progrium/consul:latest + container_name: consul + ports: + - "8300:8300" + - "8400:8400" + - "8500:8500" + - "8600:53/udp" + volumes: + - "./consul_watches_config.json:/etc/consul.d/config.json" + - "./script.sh:/tmp/script.sh" + environment: + - HOST_IP + registrator: + command: consul://consul:8500 + image: gliderlabs/registrator:latest + container_name: registrator + links: + - consul + volumes: + - "/var/run/docker.sock:/tmp/docker.sock" diff --git a/consul-api-demo/nginxplus/Dockerfile b/consul-api-demo/nginxplus/Dockerfile index 197d55d1..8b972d71 100644 --- a/consul-api-demo/nginxplus/Dockerfile +++ b/consul-api-demo/nginxplus/Dockerfile @@ -1,35 +1,49 @@ -FROM ubuntu:14.04 +# For Debian 9 +FROM debian:stretch-slim -MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com" - -# Set the debconf front end to Noninteractive -RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections - -RUN apt-get update && apt-get install -y -q wget apt-transport-https +LABEL maintainer="NGINX Docker Maintainers " # Download certificate and key from the customer portal (https://cs.nginx.com) # and copy to the build context -ADD nginx-repo.crt /etc/ssl/nginx/ -ADD nginx-repo.key /etc/ssl/nginx/ - -# Get other files required for installation -RUN wget -q -O /etc/ssl/nginx/CA.crt https://cs.nginx.com/static/files/CA.crt -RUN wget -q -O - http://nginx.org/keys/nginx_signing.key | apt-key add - -RUN wget -q -O /etc/apt/apt.conf.d/90nginx https://cs.nginx.com/static/files/90nginx - -RUN printf "deb https://plus-pkgs.nginx.com/ubuntu `lsb_release -cs` nginx-plus\n" >/etc/apt/sources.list.d/nginx-plus.list +COPY nginx-repo.crt /etc/ssl/nginx/ +COPY nginx-repo.key /etc/ssl/nginx/ # Install NGINX Plus -RUN apt-get update && apt-get install -y nginx-plus - -# forward request logs to Docker log collector -RUN ln -sf /dev/stdout /var/log/nginx/access.log -RUN ln -sf /dev/stderr /var/log/nginx/error.log +RUN set -x \ + && apt-get update && apt-get upgrade -y \ + && apt-get install --no-install-recommends --no-install-suggests -y apt-transport-https ca-certificates gnupg1 \ + && \ + NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \ + found=''; \ + for server in \ + ha.pool.sks-keyservers.net \ + hkp://keyserver.ubuntu.com:80 \ + hkp://p80.pool.sks-keyservers.net:80 \ + pgp.mit.edu \ + ; do \ + echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ + apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \ + done; \ + test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \ + echo "Acquire::https::plus-pkgs.nginx.com::Verify-Peer \"true\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::Verify-Host \"true\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::SslCert \"/etc/ssl/nginx/nginx-repo.crt\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::SslKey \"/etc/ssl/nginx/nginx-repo.key\";" >> /etc/apt/apt.conf.d/90nginx \ + && printf "deb https://plus-pkgs.nginx.com/debian stretch nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \ + && apt-get update && apt-get install -y nginx-plus \ + && apt-get remove --purge --auto-remove -y gnupg1 \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /etc/ssl/nginx + +# Forward request logs to Docker log collector +RUN ln -sf /dev/stdout /var/log/nginx/access.log \ + && ln -sf /dev/stderr /var/log/nginx/error.log EXPOSE 80 8080 443 +STOPSIGNAL SIGTERM + RUN rm -v /etc/nginx/conf.d/* -ADD app.conf /etc/nginx/conf.d/app.conf -ADD logo.png /usr/share/nginx/html/logo.png +COPY app.conf /etc/nginx/conf.d/app.conf CMD ["nginx", "-g", "daemon off;"] diff --git a/consul-api-demo/nginxplus/app.conf b/consul-api-demo/nginxplus/app.conf index cdadb3e2..ba98961d 100644 --- a/consul-api-demo/nginxplus/app.conf +++ b/consul-api-demo/nginxplus/app.conf @@ -1,46 +1,32 @@ - upstream backend { - zone upstream_backend 64k; - state /tmp/upstream.conf; - } - - match hello { - status 200; - header Content-Type = text/html; - body ~ "Hello"; - } - - server { - listen 80; - status_zone backend; - - location / { - proxy_pass http://backend; - health_check interval=2s match=hello; # uri=/ by default - } - - location /upstream_conf { - upstream_conf; - - #allow 127.0.0.1; # permit access from localhost - #deny all; # deny access from everywhere else - } - } - - server { - listen 8080; - root /usr/share/nginx/html; - access_log off; - - # Redirect requests for / to /status.html - location = / { - return 301 /status.html; - } - - location = /status.html { } - - # Everything beginning with /status (except for /status.html) is - # processed by the status handler - location /status { - status; - } - } +upstream backend { + zone upstream_backend 64k; + state /tmp/upstream.conf; +} + +match hello { + status 200; + header Content-Type = text/html; + body ~ "Hello"; +} + +server { + listen 80; + status_zone backend; + + location / { + proxy_pass http://backend; + health_check interval=2s match=hello; +} + +server { + listen 8080; + root /usr/share/nginx/html; + + location /api { + api write=on; + } + + location = / { + return 301 /dashboard.html; + } +} diff --git a/consul-api-demo/nginxplus/index.html b/consul-api-demo/nginxplus/index.html deleted file mode 100644 index e15a473a..00000000 --- a/consul-api-demo/nginxplus/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - -Welcome to nginx! - - - -

Welcome to nginx!

- -

For online documentation and support please refer to -nginx.org.
-Commercial support is available at -nginx.com.

- -

Thank you for using nginx.

- - diff --git a/consul-api-demo/nginxplus/logo.png b/consul-api-demo/nginxplus/logo.png deleted file mode 100644 index b2f48c4d5d41aa35e3d64b1e37c75aadb5566dbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12587 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 N07*qoM6N<$f(lBXo;&~m diff --git a/consul-api-demo/provision.sh b/consul-api-demo/provision.sh index d287f5bb..eaa65e26 100755 --- a/consul-api-demo/provision.sh +++ b/consul-api-demo/provision.sh @@ -1,10 +1,9 @@ #!/bin/bash - if [ ${HOST_IP} ]; then - echo "HOST_IP=${HOST_IP}" + echo "HOST_IP=${HOST_IP}" else - ipaddr=`/sbin/ifconfig eth1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'` - echo "export HOST_IP=$ipaddr" | tee -a ~/.bash_aliases - . ~/.bash_aliases - /usr/local/bin/docker-compose up -d + ipaddr=$(ip -f inet a show enp0s8 | grep -oP "(?<=inet ).+(?=\/)") + echo "export HOST_IP=$ipaddr" | tee -a ~/.bash_aliases + . ~/.bash_aliases + /usr/local/bin/docker-compose -f /srv/NGINX-Demos/consul-api-demo/docker-compose.yml up -d fi diff --git a/consul-api-demo/script.sh b/consul-api-demo/script.sh index fe4e9ce1..a4722b39 100755 --- a/consul-api-demo/script.sh +++ b/consul-api-demo/script.sh @@ -1,60 +1,62 @@ #!/bin/bash +if [[ -z "$HOST_IP" ]]; then + echo "HOST_IP not set in consul container. Setting it to 10.2.2.70 (IP address assigned in the Vagrantfile)" + HOST_IP=10.2.2.70 +fi CURL='/usr/bin/curl' OPTIONS='-s' CONSUL_SERVICES_API="http://$HOST_IP:8500/v1/catalog/services" CONSUL_SERVICE_API="http://$HOST_IP:8500/v1/catalog/service" -STATUS_UPSTREAMS_API="http://$HOST_IP:8080/status/upstreams" -UPSTREAM_CONF_API="http://$HOST_IP/upstream_conf?" +STATUS_UPSTREAMS_API="http://$HOST_IP:8080/api/3/http/upstreams" -# Get the list of current Nginx upstreams -upstreams=$($CURL $OPTIONS $STATUS_UPSTREAMS_API | jq -r '. as $in| keys[]') -servers=$($CURL $OPTIONS {$UPSTREAM_CONF_API}upstream=$upstreams) -echo "Nginx upstreams in $upstreams:" +# Get the list of current NGINX upstreams +upstreams=$($CURL $OPTIONS $STATUS_UPSTREAMS_API | jq -r '. as $in | keys[]') +servers=$($CURL $OPTIONS ${STATUS_UPSTREAMS_API}/${upstreams}/servers) +echo "NGINX upstreams in $upstreams:" echo $servers # Loop through the registered servers in consul tagged with production (i.e backend servers to be proxied through nginx) and add the ones not present in the Nginx upstream block echo "Servers registered with consul:" -service=$($CURL $OPTIONS $CONSUL_SERVICES_API | jq --raw-output 'to_entries| .[] | select(.value[0] == "production") | .key') +service=$($CURL $OPTIONS $CONSUL_SERVICES_API | jq --raw-output 'to_entries | .[] | select(.value[0] == "production") | .key') -ports=$($CURL $OPTIONS $CONSUL_SERVICE_API/$service | jq -r '.[]|.ServicePort') +ports=$($CURL $OPTIONS $CONSUL_SERVICE_API/$service | jq -r '.[] | .ServicePort') for port in ${ports[@]}; do - entry=$HOST_IP:$port - echo $entry - if [[ ! $servers =~ $entry ]]; then - $CURL $OPTIONS "{$UPSTREAM_CONF_API}add=&upstream=$upstreams&server=$entry" - echo "Added $entry to the nginx upstream group $upstreams!" - fi + entry=$HOST_IP:$port + if [[ ! $servers =~ $entry ]]; then + $CURL -X POST -d '{"server": "'$entry'"}' $OPTIONS "${STATUS_UPSTREAMS_API}/${upstreams}/servers" + echo "Added $entry to the NGINX upstream group $upstreams!" + fi done -# Loop through the Nginx upstreams and remove the ones not present in consul -servers=$($CURL $OPTIONS {$UPSTREAM_CONF_API}upstream=$upstreams) +# Loop through the NGINX upstreams and remove the ones not present in consul +servers=($($CURL $OPTIONS ${STATUS_UPSTREAMS_API}/${upstreams}/servers | jq -c '.[]')) for params in ${servers[@]}; do - if [[ $params =~ ":" ]]; then - server=$params - continue - elif [[ $params =~ "id=" ]]; then - id=$params + if [[ $params =~ "server" ]]; then + server=$(echo $params | jq '.server') + continue + elif [[ $params =~ "id" ]]; then + id=$(echo $params | jq '.id') + else + continue + fi + + service=$($CURL $OPTIONS $CONSUL_SERVICES_API | jq --raw-output 'to_entries| .[] | select(.value[0] == "production") | .key') + ports=$($CURL $OPTIONS $CONSUL_SERVICE_API/$service | jq -r '.[]|.ServicePort') + found=0 + for port in ${ports[@]}; do + entry=$HOST_IP:$port + if [[ $server =~ $entry ]]; then + echo "$server matches consul entry $entry" + found=1 + break else - continue + continue fi + done - service=$($CURL $OPTIONS $CONSUL_SERVICES_API | jq --raw-output 'to_entries| .[] | select(.value[0] == "production") | .key') - ports=$($CURL $OPTIONS $CONSUL_SERVICE_API/$service | jq -r '.[]|.ServicePort') - found=0 - for port in ${ports[@]}; do - entry=$HOST_IP:$port - if [[ $server =~ $entry ]]; then - #echo "$server matches consul entry $entry" - found=1 - break - else - continue - fi - done - - if [ $found -eq 0 ]; then - $CURL $OPTIONS "{$UPSTREAM_CONF_API}remove=&upstream=$upstreams&$id" - echo "Removed $server # $id from nginx upstream block $upstreams!" - fi + if [ $found -eq 0 ]; then + $CURL -X DELETE $OPTIONS "{$STATUS_UPSTREAMS_API}/$upstreams/servers/$id" + echo "Removed $server # $id from nginx upstream block $upstreams!" + fi done diff --git a/consul-api-demo/setup_consul_api_demo.yml b/consul-api-demo/setup_consul_api_demo.yml index 8a20ae43..93e803fb 100644 --- a/consul-api-demo/setup_consul_api_demo.yml +++ b/consul-api-demo/setup_consul_api_demo.yml @@ -1,46 +1,38 @@ - hosts: all - sudo: true + become: true tasks: - - - name: Setup Consul API Demo | Install curl from apt - apt: update_cache=yes pkg=curl - - - name: Setup Consul API Demo | Install git from apt - apt: update_cache=yes pkg=git - - - name: Setup Consul API Demo | Install jq from apt - apt: update_cache=yes pkg=jq - - - name: Setup Consul API Demo | Install docker.io from apt - shell: curl -sSL https://get.docker.com/ | sh - - - name: Setup Consul API Demo | Install docker-compose - shell: curl -L https://github.com/docker/compose/releases/download/1.10.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose - - - name: Setup Consul API Demo | Apply executable permissions to the docker-compose binary - shell: chmod +x /usr/local/bin/docker-compose - - - name: Setup Consul API Demo | Copy docker-compose under /etc/bash_completion. - shell: curl -L https://raw.githubusercontent.com/docker/compose/1.10.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose - - - name: NGINX Plus | Copying NGINX Plus repository certificate - copy: src=files/nginx-repo.crt dest=/srv/NGINX-Demos/consul-api-demo/nginxplus/nginx-repo.crt - - - name: NGINX Plus | Copying NGINX Plus repository key - copy: src=files/nginx-repo.key dest=/srv/NGINX-Demos/consul-api-demo/nginxplus/nginx-repo.key - + - name: Setup Consul API Demo | Install curl, git and jq from apt + apt: + update_cache: yes + name: + - curl + - git + - jq + - name: Setup Consul API Demo | Download docker.io install script + get_url: + url: https://get.docker.com + dest: /tmp/get-docker.sh + mode: +x + - name: Setup Consul API Demo | Install docker + shell: /tmp/get-docker.sh + - name: Setup Consul API Demo | Delete docker.io install script + file: + path: /tmp/get-docker.sh + state: absent + - name: Setup Consul API Demo | Download docker-compose + get_url: + url: https://github.com/docker/compose/releases/download/1.23.2/docker-compose-Linux-x86_64 + dest: /usr/local/bin/docker-compose + mode: +x + - name: Setup Consul API Demo | Copy docker-compose under /etc/bash_completion + get_url: + url: https://raw.githubusercontent.com/docker/compose/1.23.2/contrib/completion/bash/docker-compose + dest: /etc/bash_completion.d/docker-compose - name: Setup Consul API Demo | Executing provision.sh (sets HOST_IP, builds the container images and starts them) - shell: ./provision.sh - args: - chdir: /srv/NGINX-Demos/consul-api-demo/ - + shell: /srv/NGINX-Demos/consul-api-demo/provision.sh - name: Setup Consul API Demo | apk update in consul container shell: docker exec -i consul apk update - - name: Setup Consul API Demo | Install jq in the consul container shell: docker exec -i consul apk add jq - - name: Setup Consul API Demo | Spin up the nginxdemos/hello container which is the backend http service - shell: /usr/local/bin/docker-compose -f create-http-service.yml up -d - args: - chdir: /srv/NGINX-Demos/consul-api-demo/ + shell: /usr/local/bin/docker-compose -f /srv/NGINX-Demos/consul-api-demo/create-http-service.yml up -d diff --git a/consul-dns-srv-demo/README.md b/consul-dns-srv-demo/README.md index 5ee16d21..917b2d14 100644 --- a/consul-dns-srv-demo/README.md +++ b/consul-dns-srv-demo/README.md @@ -3,10 +3,10 @@ This demo shows NGINX Plus being used in conjuction with [Consul's DNS interface](https://www.consul.io/docs/agent/dns.html). This demo is based on docker and spins' up the following containers: -* [Consul](http://www.consul.io) for service discovery using DNS -* [Registrator](https://github.com/gliderlabs/registrator) to register services with Consul. Registrator monitors for containers being started and stopped and updates Consul when a container changes state. -* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port to simulate backend servers -* and of course [NGINX Plus](http://www.nginx.com/products) R9 which adds support for DNS lookups over TCP & DNS SRV records +* [Consul](http://www.consul.io) for service discovery using DNS +* [Registrator](https://github.com/gliderlabs/registrator) to register services with Consul. Registrator monitors for containers being started and stopped and updates Consul when a container changes state. +* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port to simulate backend servers +* [NGINX Plus](http://www.nginx.com/products) (R13 or higher) which adds support for DNS lookups over TCP & DNS SRV records The demo is based off the work described in this blog post: [Service Discovery for NGINX Plus Using DNS SRV Records from Consul](https://www.nginx.com/blog/service-discovery-nginx-plus-srv-records-consul-dns/) @@ -16,79 +16,74 @@ The demo is based off the work described in this blog post: [Service Discovery f Install Vagrant using the necessary package for your OS: -https://www.vagrantup.com/downloads.html + -1. Install provider for vagrant to use to start VM's. +1. Install provider for vagrant to use to start VM's. - The default provider is VirtualBox [Note that only VirtualBox versions 4.0 and higher are supported], which can be downloaded from the following link: + The default provider is VirtualBox (Note that only VirtualBox versions 4.0 and higher are supported), which can be downloaded from the following link: - https://www.virtualbox.org/wiki/Downloads + - A full list of providers can be found at the following page, if you do not want to use VirtualBox: + A full list of providers can be found at the following page, if you do not want to use VirtualBox: - https://docs.vagrantup.com/v2/providers/ + -1. Install Ansible: +2. Install Ansible: - http://docs.ansible.com/ansible/intro_installation.html + -1. Clone demo repo +3. Clone demo repo - ```$ git clone https://github.com/nginxinc/NGINX-Demos.git``` + `$ git clone https://github.com/nginxinc/NGINX-Demos.git` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```~/NGINX-Demos/ansible/files/``` +4. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `~/NGINX-Demos/consul-dns-srv-demo/nginxplus` -1. Move into the consul-dns-srv-demo directory and start the Vagrant vm: +5. Move into the consul-dns-srv-demo directory and start the Vagrant vm: - ``` - $ cd ~/NGINX-Demos/consul-dns-srv-demo - $ vagrant up - ``` - The ```vagrant up``` command will start the virtualbox VM and provision it using the ansible playbook file ~/NGINX-Demos/ansible/setup_consul_dns_srv_demo.yml. The ansible playbook file also invokes another script provision.sh which sets the HOST_IP environment variable to the IP address of the eth1 interface (10.2.2.70 in this case assigned in the Vagrantfile) + ``` + $ cd ~/NGINX-Demos/consul-dns-srv-demo + $ vagrant up + ``` -1. SSH into the newly created virtual machine and move into the /vagrant directory which contains the demo files: + The `vagrant up` command will start the virtualbox VM and provision it using the ansible playbook file `~/NGINX-Demos/consul-dns-srv-demo/setup_consul_dns_srv_demo.yml`. The ansible playbook file also invokes another script `provision.sh` which sets the HOST_IP environment variable to the IP address of the `enp0s8` interface (10.2.2.70 in this case - assigned in the Vagrantfile) and invokes the `docker-compose up -d` command. - ``` - $ vagrant ssh - $ sudo su - ``` -The demo files will be in /srv/NGINX-Demos/consul-dns-srv-demo +6. SSH into the newly created virtual machine and move into the /vagrant directory which contains the demo files: -1. Now simply follow the steps listed under section 'Running the demo'. + ``` + $ vagrant ssh + $ sudo su + ``` + The demo files will be in `/srv/NGINX-Demos/consul-dns-srv-demo` + +7. Now simply follow the steps listed under section 'Running the demo'. ### Ansible only deployment -1. Create Ubuntu 14.04 VM +1. Create Ubuntu 18.04 LTS VM -1. Install Ansible on Ubuntu VM +2. Install Ansible on Ubuntu VM - ``` - $ sudo apt-get install ansible - ``` + `$ sudo apt-get install ansible` -1. Clone demo repo into ```/srv``` on Ubuntu VM: +3. Clone demo repo into `/srv` on Ubuntu VM: - ``` - $ cd /srv - $ sudo git clone https://github.com/nginxinc/NGINX-Demos.git - ``` + ``` + $ cd /srv + $ sudo git clone https://github.com/nginxinc/NGINX-Demos.git + ``` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```/srv/NGINX-Demos/ansible/files/``` +4. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `/srv/NGINX-Demos/consul-dns-srv-demo/nginxplus` -1. Move into the consul-dns-srv-demo directory which contains the demo files and make sure the IP address of your Ubuntu VM on which NGINX Plus will be listening is assigned to the ```eth1``` interface. If in case you need to use IP of another interface, replace ```eth1``` on line 6 of provision.sh with the corresponding interface name - ``` - $ cd /srv/NGINX-Demos/consul-dns-srv-demo - ``` +5. Move into the consul-dns-srv-demo directory which contains the demo files and make sure the IP address of your Ubuntu VM on which NGINX Plus will be listening is assigned to the `enp0s8` interface. If in case you need to use IP of another interface, replace `enp0s8` on line 6 of `provision.sh` with the corresponding interface name -1. Run the ansible playbook against localhost on Ubuntu VM: + `$ cd /srv/NGINX-Demos/consul-dns-srv-demo` - ``` - $ sudo ansible-playbook -i "localhost," -c local /srv/NGINX-Demos/ansible/setup_consul_dns_srv_demo.yml - ``` +6. Run the ansible playbook against localhost on Ubuntu VM: -1. Now simply follow the steps listed under section 'Running the demo'. + `$ sudo ansible-playbook -i "localhost," -c local /srv/NGINX-Demos/consul-dns-srv-demo/setup_consul_dns_srv_demo.yml` +7. Now simply follow the steps listed under section 'Running the demo'. ### Manual Install @@ -96,77 +91,75 @@ The demo files will be in /srv/NGINX-Demos/consul-dns-srv-demo The following software needs to be installed: -* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM - +* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM #### Setting up the demo -1. Clone demo repo - ```$ git clone git@github.com:nginxinc/NGINX-Demos.git``` +1. Clone demo repo + + `$ git clone https://github.com/nginxinc/NGINX-Demos.git` + +2. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `~/NGINX-Demos/consul-dns-srv-demo/nginxplus/` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```~/NGINX-Demos/consul-dns-srv-demo/nginxplus/``` +3. Move into the demo directory: -1. Move into the demo directory: + `$ cd ~/NGINX-Demos/consul-dns-srv-demo` - ``` - $ cd ~/NGINX-Demos/consul-dns-srv-demo - ``` +4. If you have run this demo previously or have any docker containers running, start with a clean slate by running -1. If you have run this demo previously or have any docker containers running, start with a clean slate by running - ``` - $ ./clean-containers.sh - ``` + `$ ./clean-containers.sh` -1. NGINX Plus will be listening on port 80 on docker host. - 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running +5. NGINX Plus will be listening on port 80 on docker host. - ``` - $ docker-machine ip default - 192.168.99.100 - ``` - 1. If you are using Docker for Mac, the IP address you need to use is 172.17.0.1 + 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running - Export this IP into an environment variable named HOST_IP by running `export HOST_IP=x.x.x.x` command. This variable is used by docker-compose.yml file + ``` + $ docker-machine ip default + 192.168.99.100 + ``` -1. Spin up Consul, Registrator, NGINX Plus & http service containers: + 2. If you are using Docker for Mac, the IP address you need to use is 172.17.0.1 - ``` - $ docker-compose up -d - ``` + Export this IP into an environment variable named HOST_IP by running `export HOST_IP=x.x.x.x` command. This variable is used by the `docker-compose.yml` file -1. Now follow the steps under section 'Running the demo' +6. Spin up Consul, Registrator, NGINX Plus & http service containers: + + `$ docker-compose up -d` + +7. Now follow the steps under section 'Running the demo' ## Running the demo -1. You should have a bunch of containers up and running now: - - ``` - $ docker ps - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - 765bc1517305 consuldnssrvdemo_nginxplus "nginx -g 'daemon off" 31 minutes ago Up 31 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp, 443/tcp nginxplus - ec1cc90d189e nginxdemos/hello:latest "nginx -g 'daemon off" 31 minutes ago Up 31 minutes 443/tcp, 0.0.0.0:32790->80/tcp consuldnssrvdemo_http_1 - 8b3c15c37bee gliderlabs/registrator:latest "/bin/registrator con" 31 minutes ago Up 31 minutes registrator - 4718ed726d26 progrium/consul:latest "/bin/start -server -" 31 minutes ago Up 31 minutes 0.0.0.0:8300->8300/tcp, 0.0.0.0:8400->8400/tcp, 0.0.0.0:8500->8500/tcp, 8301-8302/tcp, 8301-8302/udp, 0.0.0.0:8600->53/tcp, 0.0.0.0:8600->53/udp consul - ``` - -1. Go to `http://` in your favorite browser window and that will take you to the nginx-hello container printing its hostname, IP Address and the port of the container. `http://:8080/` will bring up the NGINX Plus dashboard with the Server Zones & Upstreams tab. The configuration file NGINX Plus is using here is /etc/nginx/conf.d/app.conf which is included from /etc/nginx/nginx.conf. If you would like to see all the services registered with consul go to `http://:8500`. - -1. Now scale up and scale down the http service which is the same [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as above. Go to the Upstreams tab on Nginx Plus dashboard and observe the change in the list of servers being added/removed from the backend group. - ``` - $ docker-compose scale http=5 - $ docker-compose scale http=3 - ``` - -1. We are using the DNS SRV records using the ```service``` parameter for the ```server``` directive of http upstream module and DNS lookups over TCP features introduced in NGINX Plus R9. This means that NGINX Plus can now ask for the SRV record (port,weight etc) in the DNS query and also switch the DNS query over TCP automatically if it receives a truncated DNS response over UDP. - - ``` - resolver consul:53 valid=2s; - resolver_timeout 2s; - - upstream backend { - zone upstream_backend 64k; - server service.consul service=http resolve; - } - ``` +1. You should have a bunch of containers up and running now: + + ``` + $ docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 765bc1517305 consuldnssrvdemo_nginxplus "nginx -g 'daemon off" 31 minutes ago Up 31 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp, 443/tcp nginxplus + ec1cc90d189e nginxdemos/hello:latest "nginx -g 'daemon off" 31 minutes ago Up 31 minutes 443/tcp, 0.0.0.0:32790->80/tcp consuldnssrvdemo_http_1 + 8b3c15c37bee gliderlabs/registrator:latest "/bin/registrator con" 31 minutes ago Up 31 minutes registrator + 4718ed726d26 progrium/consul:latest "/bin/start -server -" 31 minutes ago Up 31 minutes 0.0.0.0:8300->8300/tcp, 0.0.0.0:8400->8400/tcp, 0.0.0.0:8500->8500/tcp, 8301-8302/tcp, 8301-8302/udp, 0.0.0.0:8600->53/tcp, 0.0.0.0:8600->53/udp consul + ``` + +2. Go to `http://` in your favorite browser window and that will take you to the nginx-hello container printing its hostname, IP Address and the port of the container. `http://:8080/` will bring up the NGINX Plus dashboard with the Server Zones & Upstreams tab. The configuration file NGINX Plus is using here is /etc/nginx/conf.d/app.conf which is included from /etc/nginx/nginx.conf. If you would like to see all the services registered with consul go to `http://:8500`. + +3. Now scale up and scale down the http service which is the same [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as above. Go to the Upstreams tab on Nginx Plus dashboard and observe the change in the list of servers being added/removed from the backend group. + + ``` + $ docker-compose scale http=5 + $ docker-compose scale http=3 + ``` + +4. We are using the DNS SRV records using the `service` parameter for the `server` directive of http upstream module and DNS lookups over TCP features introduced in NGINX Plus R9. This means that NGINX Plus can now ask for the SRV record (port, weight, etc...) in the DNS query and also switch the DNS query over TCP automatically if it receives a truncated DNS response over UDP. + + ``` + resolver consul:53 valid=2s; + resolver_timeout 2s; + + upstream backend { + zone upstream_backend 64k; + server service.consul service=http resolve; + } + ``` All the changes should be automatically reflected in the NGINX config and show up on the NGINX Plus Dashboard. diff --git a/consul-dns-srv-demo/Vagrantfile b/consul-dns-srv-demo/Vagrantfile index ccbfa5fa..863dcb52 100644 --- a/consul-dns-srv-demo/Vagrantfile +++ b/consul-dns-srv-demo/Vagrantfile @@ -1,14 +1,15 @@ -VAGRANTFILE_API_VERSION = "2" - Vagrant.configure(2) do |config| - config.vm.box = "ubuntu/trusty64" + config.vm.box = "ubuntu/bionic64" config.vm.network "private_network", :ip => "10.2.2.70" config.vm.synced_folder "../consul-dns-srv-demo/", "/srv/NGINX-Demos/consul-dns-srv-demo" config.vm.provision :ansible do |ansible| ansible.playbook = "./setup_consul_dns_srv_demo.yml" + ansible.extra_vars = { + ansible_python_interpreter:"/usr/bin/python3" + } end end diff --git a/consul-dns-srv-demo/clean_containers.sh b/consul-dns-srv-demo/clean_containers.sh index cb70d661..452fe07c 100755 --- a/consul-dns-srv-demo/clean_containers.sh +++ b/consul-dns-srv-demo/clean_containers.sh @@ -1,2 +1,2 @@ #!/bin/bash -docker rm -f `docker ps -qa` +docker rm -f $(docker ps -qa) diff --git a/consul-dns-srv-demo/docker-compose.yml b/consul-dns-srv-demo/docker-compose.yml index 779a8f2e..a44c7106 100644 --- a/consul-dns-srv-demo/docker-compose.yml +++ b/consul-dns-srv-demo/docker-compose.yml @@ -1,40 +1,39 @@ -nginxplus: - build: ./nginxplus - container_name: nginxplus - links: - - consul - ports: - - "80:80" - - "8080:8080" - -consul: - command: "-server -bootstrap -node consul -advertise ${HOST_IP} -config-file /etc/consul.d/config.json" - image: progrium/consul:latest - container_name: consul - ports: - - "8300:8300" - - "8400:8400" - - "8500:8500" - - "8600:53" - - "8600:53/udp" - volumes: - - "./consul_dns_config.json:/etc/consul.d/config.json" - environment: - - HOST_IP - -registrator: - command: consul://consul:8500 - image: gliderlabs/registrator:latest - container_name: registrator - links: - - consul - volumes: - - "/var/run/docker.sock:/tmp/docker.sock" - -http: - image: nginxdemos/hello:latest - labels: - SERVICE_80_NAME: http - SERVICE_TAGS: production - ports: - - "80" +version: '3' +services: + nginxplus: + build: ./nginxplus + container_name: nginxplus + links: + - consul + ports: + - "80:80" + - "8080:8080" + consul: + command: "-server -bootstrap -node consul -advertise ${HOST_IP} -config-file /etc/consul.d/config.json" + image: progrium/consul:latest + container_name: consul + ports: + - "8300:8300" + - "8400:8400" + - "8500:8500" + - "8600:53" + - "8600:53/udp" + volumes: + - "./consul_dns_config.json:/etc/consul.d/config.json" + environment: + - HOST_IP + registrator: + command: consul://consul:8500 + image: gliderlabs/registrator:latest + container_name: registrator + links: + - consul + volumes: + - "/var/run/docker.sock:/tmp/docker.sock" + http: + image: nginxdemos/hello:latest + labels: + SERVICE_80_NAME: http + SERVICE_TAGS: production + ports: + - "80" diff --git a/consul-dns-srv-demo/nginxplus/Dockerfile b/consul-dns-srv-demo/nginxplus/Dockerfile index 152a4b2b..8b972d71 100644 --- a/consul-dns-srv-demo/nginxplus/Dockerfile +++ b/consul-dns-srv-demo/nginxplus/Dockerfile @@ -1,35 +1,49 @@ -FROM ubuntu:14.04 +# For Debian 9 +FROM debian:stretch-slim -MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com" - -# Set the debconf front end to Noninteractive -RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections - -RUN apt-get update && apt-get install -y -q wget apt-transport-https +LABEL maintainer="NGINX Docker Maintainers " # Download certificate and key from the customer portal (https://cs.nginx.com) # and copy to the build context -ADD nginx-repo.crt /etc/ssl/nginx/ -ADD nginx-repo.key /etc/ssl/nginx/ - -# Get other files required for installation -# RUN wget -q -O /etc/ssl/nginx/CA.crt https://cs.nginx.com/static/files/CA.crt -RUN wget -q -O - http://nginx.org/keys/nginx_signing.key | apt-key add - -RUN wget -q -O /etc/apt/apt.conf.d/90nginx https://cs.nginx.com/static/files/90nginx - -RUN printf "deb https://plus-pkgs.nginx.com/ubuntu `lsb_release -cs` nginx-plus\n" >/etc/apt/sources.list.d/nginx-plus.list +COPY nginx-repo.crt /etc/ssl/nginx/ +COPY nginx-repo.key /etc/ssl/nginx/ # Install NGINX Plus -RUN apt-get update && apt-get install -y nginx-plus - -# forward request logs to Docker log collector -RUN ln -sf /dev/stdout /var/log/nginx/access.log -RUN ln -sf /dev/stderr /var/log/nginx/error.log +RUN set -x \ + && apt-get update && apt-get upgrade -y \ + && apt-get install --no-install-recommends --no-install-suggests -y apt-transport-https ca-certificates gnupg1 \ + && \ + NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \ + found=''; \ + for server in \ + ha.pool.sks-keyservers.net \ + hkp://keyserver.ubuntu.com:80 \ + hkp://p80.pool.sks-keyservers.net:80 \ + pgp.mit.edu \ + ; do \ + echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ + apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \ + done; \ + test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \ + echo "Acquire::https::plus-pkgs.nginx.com::Verify-Peer \"true\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::Verify-Host \"true\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::SslCert \"/etc/ssl/nginx/nginx-repo.crt\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::SslKey \"/etc/ssl/nginx/nginx-repo.key\";" >> /etc/apt/apt.conf.d/90nginx \ + && printf "deb https://plus-pkgs.nginx.com/debian stretch nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \ + && apt-get update && apt-get install -y nginx-plus \ + && apt-get remove --purge --auto-remove -y gnupg1 \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /etc/ssl/nginx + +# Forward request logs to Docker log collector +RUN ln -sf /dev/stdout /var/log/nginx/access.log \ + && ln -sf /dev/stderr /var/log/nginx/error.log EXPOSE 80 8080 443 +STOPSIGNAL SIGTERM + RUN rm -v /etc/nginx/conf.d/* -ADD app.conf /etc/nginx/conf.d/app.conf -ADD logo.png /usr/share/nginx/html/logo.png +COPY app.conf /etc/nginx/conf.d/app.conf CMD ["nginx", "-g", "daemon off;"] diff --git a/consul-dns-srv-demo/nginxplus/app.conf b/consul-dns-srv-demo/nginxplus/app.conf index cee5016f..18129287 100644 --- a/consul-dns-srv-demo/nginxplus/app.conf +++ b/consul-dns-srv-demo/nginxplus/app.conf @@ -2,46 +2,35 @@ resolver consul:53 valid=2s; resolver_timeout 2s; upstream backend { - zone upstream_backend 64k; - server service.consul service=http resolve; - } + zone upstream_backend 64k; + server service.consul service=http resolve; +} match hello { - status 200; - header Content-Type = text/html; - body ~ "Hello"; - } + status 200; + header Content-Type = text/html; + body ~ "Hello"; +} server { - listen 80; - status_zone backend; + listen 80; + status_zone backend; -location / { - proxy_pass http://backend; - health_check interval=2s match=hello; # uri=/ by default - } + location / { + proxy_pass http://backend; + health_check interval=2s match=hello; + } } server { - listen 8080; - root /usr/share/nginx/html; - - # Redirect requests for / to /dashboard.html - location = / { - return 301 /dashboard.html; - } + listen 8080; + root /usr/share/nginx/html; -location /api { - api write=on; - #allow 192.168.1.0/24; - #deny all; -} - -location = /dashboard.html { - root /usr/share/nginx/html; -} + location /api { + api write=on; + } -location /swagger-ui { - root /usr/share/nginx/html; + location = / { + return 301 /dashboard.html; + } } - } diff --git a/consul-dns-srv-demo/nginxplus/logo.png b/consul-dns-srv-demo/nginxplus/logo.png deleted file mode 100644 index b2f48c4d5d41aa35e3d64b1e37c75aadb5566dbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12587 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 N07*qoM6N<$f(lBXo;&~m diff --git a/consul-dns-srv-demo/provision.sh b/consul-dns-srv-demo/provision.sh index d287f5bb..d71bf1db 100755 --- a/consul-dns-srv-demo/provision.sh +++ b/consul-dns-srv-demo/provision.sh @@ -1,10 +1,9 @@ #!/bin/bash - if [ ${HOST_IP} ]; then - echo "HOST_IP=${HOST_IP}" + echo "HOST_IP=${HOST_IP}" else - ipaddr=`/sbin/ifconfig eth1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'` - echo "export HOST_IP=$ipaddr" | tee -a ~/.bash_aliases - . ~/.bash_aliases - /usr/local/bin/docker-compose up -d + ipaddr=$(ip -f inet a show enp0s8 | grep -oP "(?<=inet ).+(?=\/)") + echo "export HOST_IP=$ipaddr" | tee -a ~/.bash_aliases + . ~/.bash_aliases + /usr/local/bin/docker-compose -f /srv/NGINX-Demos/consul-dns-srv-demo/docker-compose.yml up -d fi diff --git a/consul-dns-srv-demo/setup_consul_dns_srv_demo.yml b/consul-dns-srv-demo/setup_consul_dns_srv_demo.yml index 91d028e9..46f13de8 100644 --- a/consul-dns-srv-demo/setup_consul_dns_srv_demo.yml +++ b/consul-dns-srv-demo/setup_consul_dns_srv_demo.yml @@ -1,33 +1,31 @@ - hosts: all - sudo: true + become: true tasks: - - - name: Setup Consul Demo | Install curl from apt - apt: update_cache=yes pkg=curl - - - name: Setup Consul Demo | Install git from apt - apt: update_cache=yes pkg=git - - - name: Setup Consul Demo | Install docker.io from apt - shell: curl -sSL https://get.docker.com/ | sh - - - name: Setup Consul Demo | Install docker-compose - shell: curl -L https://github.com/docker/compose/releases/download/1.10.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose - - - name: Setup Consul Demo | Apply executable permissions to the docker-compose binary - shell: chmod +x /usr/local/bin/docker-compose - - - name: Setup Consul Demo | Copy docker-compose under /etc/bash_completion. - shell: curl -L https://raw.githubusercontent.com/docker/compose/1.10.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose - - - name: NGINX Plus | Copying NGINX Plus repository certificate - copy: src=files/nginx-repo.crt dest=/srv/NGINX-Demos/consul-dns-srv-demo/nginxplus/nginx-repo.crt - - - name: NGINX Plus | Copying NGINX Plus repository key - copy: src=files/nginx-repo.key dest=/srv/NGINX-Demos/consul-dns-srv-demo/nginxplus/nginx-repo.key - - - name: Setup Consul Demo | Executing provision.sh (sets HOST_IP, builds the container images and starts them) - shell: ./provision.sh - args: - chdir: /srv/NGINX-Demos/consul-dns-srv-demo/ - + - name: Setup Consul DNS Demo | Install curl and jq from apt + apt: + update_cache: yes + name: + - curl + - jq + - name: Setup Consul DNS Demo | Download docker.io install script + get_url: + url: https://get.docker.com + dest: /tmp/get-docker.sh + mode: +x + - name: Setup Consul DNS Demo | Install docker + shell: /tmp/get-docker.sh + - name: Setup Consul DNS Demo | Delete docker.io install script + file: + path: /tmp/get-docker.sh + state: absent + - name: Setup Consul DNS Demo | Download docker-compose + get_url: + url: https://github.com/docker/compose/releases/download/1.23.2/docker-compose-Linux-x86_64 + dest: /usr/local/bin/docker-compose + mode: +x + - name: Setup Consul DNS Demo | Copy docker-compose under /etc/bash_completion + get_url: + url: https://raw.githubusercontent.com/docker/compose/1.23.2/contrib/completion/bash/docker-compose + dest: /etc/bash_completion.d/docker-compose + - name: Setup Consul DNS Demo | Executing provision.sh (sets HOST_IP, builds the container images and starts them) + shell: /srv/NGINX-Demos/consul-dns-srv-demo/provision.sh diff --git a/consul-template-demo/README.md b/consul-template-demo/README.md index 624453ed..48d16015 100644 --- a/consul-template-demo/README.md +++ b/consul-template-demo/README.md @@ -2,53 +2,54 @@ This demo shows NGINX being used in conjuction with Consul, a popular Service discovery platform and Consul-Template, a generic template rendering tool that provides a convenient way to populate values from Consul into the file system using a daemon. -. This demo is based on docker and spins' up the following containers: +This demo is based on docker and spins' up the following containers: -* [Consul](http://www.consul.io) for service discovery -* [Registrator](https://github.com/gliderlabs/registrator) to register services with Consul. Registrator monitors for containers being started and stopped and updates Consul when a container changes state. -* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port, request URI, local time of the webserver and the client IP address. This is to simulate backend servers NGINX will be load balancing across. -* and ofcourse open source [NGINX](http://nginx.org/) +* [Consul](http://www.consul.io) for service discovery +* [Registrator](https://github.com/gliderlabs/registrator) to register services with Consul. Registrator monitors for containers being started and stopped and updates Consul when a container changes state. +* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port, request URI, local time of the webserver and the client IP address. This is to simulate backend servers NGINX will be load balancing across. +* [NGINX](http://nginx.org/) Open Source. ## Prerequisites and Required Software -The following software needs to be installed on your laptop: +The following software needs to be installed: -* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM +* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM ## Setting up the demo -* NGINX will be listening on port 80 on your docker host. - 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running +1. NGINX will be listening on port 80 on your docker host. - ``` - $ docker-machine ip default - 192.168.99.100 - ``` - 1. If you are using Docker for Mac, the IP address you need to use is 172.17.0.1 + 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running - Export this IP into an environment variable HOST_IP by running `export HOST_IP=192.168.99.100` OR `export HOST_IP=172.17.0.1` (used by docker-compose.yml below) + ``` + $ docker-machine ip default + 192.168.99.100 + ``` -* Now to spin up all the containers run: + 2. If you are using Docker for Mac, the IP address you need to use is 172.17.0.1 -``` -$ docker-compose up -d -``` -You should have a bunch of containers up and running: + Export this IP into an environment variable HOST_IP by running `export HOST_IP=192.168.99.100` OR `export HOST_IP=172.17.0.1` (used by docker-compose.yml below) -``` -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -aea80813b12d consultemplatedemo_nginx "/usr/bin/runsvdir /e" 3 days ago Up 25 seconds 0.0.0.0:80->80/tcp, 443/tcp nginx -08c5a8cec952 gliderlabs/registrator:latest "/bin/registrator -in" 3 days ago Up 25 seconds registrator -5a7bf3bb3a25 progrium/consul "/bin/start -server -" 3 days ago Up 26 seconds 53/tcp, 0.0.0.0:8300->8300/tcp, 0.0.0.0:8400->8400/tcp, 8301-8302/tcp, 0.0.0.0:8500->8500/tcp, 8301-8302/udp, 0.0.0.0:8600->53/udp consul -a95c766b8ab5 nginxdemos/hello:latest "nginx -g 'daemon off" 3 days ago Up 25 seconds 443/tcp, 0.0.0.0:32846->80/tcp consultemplatedemo_http_1 -``` +2. Now to spin up all the containers run: + + `$ docker-compose up -d` + + You should have a bunch of containers up and running: + + ``` + $ docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + aea80813b12d consultemplatedemo_nginx "/usr/bin/runsvdir /e" 3 days ago Up 25 seconds 0.0.0.0:80->80/tcp, 443/tcp nginx + 08c5a8cec952 gliderlabs/registrator:latest "/bin/registrator -in" 3 days ago Up 25 seconds registrator + 5a7bf3bb3a25 progrium/consul "/bin/start -server -" 3 days ago Up 26 seconds 53/tcp, 0.0.0.0:8300->8300/tcp, 0.0.0.0:8400->8400/tcp, 8301-8302/tcp, 0.0.0.0:8500->8500/tcp, 8301-8302/udp, 0.0.0.0:8600->53/udp consul + a95c766b8ab5 nginxdemos/hello:latest "nginx -g 'daemon off" 3 days ago Up 25 seconds 443/tcp, 0.0.0.0:32846->80/tcp consultemplatedemo_http_1 + ``` ## Running the demo -NGINX is listening on port 80 on your Docker Host, and runs Consul Template. Consul Template listens to Consul for changes to the service catalog, rewrites Nginx config file and reloads Nginx on any changes. +NGINX is listening on port 80 on your Docker Host, and runs Consul Template. Consul Template listens to Consul for changes to the service catalog, rewrites Nginx config file and reloads Nginx on any changes. -So now just go to `http://` (Note: Docker for Mac runs on IP address 127.0.0.1) and the main index.html should pop up with a list of the services that have been disovered. There should be a single `http` service. Clicking on that link will take you to the Consul UI page showing the list of all registered services. +So now just go to `http://` (Note: Docker for Mac runs on IP address 127.0.0.1) and the main index.html should pop up with a list of the services that have been disovered. There should be a single `http` service. Clicking on that link will take you to the Consul UI page showing the list of all registered services. From here you can scale up the http service: @@ -68,15 +69,15 @@ Stopping and removing consultemplatedemo_http_4 ... done Stopping and removing consultemplatedemo_http_5 ... done ``` -All the changes should be automatically reflected in the NGINX config file (/etc/nginx/conf.d/app.conf) inside NGINX container. +All the changes should be automatically reflected in the NGINX config file (/etc/nginx/conf.d/app.conf) inside the NGINX container. -Another feature we are using here is the HTTP health checks with Consul. Registrator allows to specify these health checks by using extra metadata in labels for your service. More details on this can be found [here](http://gliderlabs.com/registrator/latest/user/backends/#consul). With the following two labels (SERVICE_80_CHECK_HTTP: /http and SERVICE_80_CHECK_INTERVAL: 5s) applied to our http service in the docker-compose.yml file, Consul sends a /http request to all http containers every 5 seconds and expect a 200 OK response in return for a container to be considered healthy. If a 200 OK is not received, the container will be removed from Consul and in turn gremoved from upstream block within NGINX configuration as well. +Another feature we are using here is the HTTP health checks with Consul. Registrator allows to specify these health checks by using extra metadata in labels for your service. More details on this can be found [here](http://gliderlabs.com/registrator/latest/user/backends/#consul). With the following two labels (SERVICE_80_CHECK_HTTP: /http and SERVICE_80_CHECK_INTERVAL: 5s) applied to our http service in the docker-compose.yml file, Consul sends a /http request to all http containers every 5 seconds and expects a 200 OK response in return for a container to be considered healthy. If a 200 OK is not received, the container will be removed from Consul and in turn gremoved from upstream block within NGINX configuration as well. So lets stop a container and see if it gets removed from the load balancing pool + ``` $ docker stop consultemplatedemo_http_2 consultemplatedemo_http_2 ``` -On the Consul UI page (http://:8500/ui/#/dc1/services/http), you will observe the change and the container removed. Also the NGINX config file (/etc/nginx/conf.d/app.conf) will have just 2 server entries now indicating that the 3rd server entry corresponding to the container which was stopped was removed automatically. - +On the Consul UI page (http://:8500/ui/#/dc1/services/http), you will observe the change and the container removed. Also the NGINX config file (`/etc/nginx/conf.d/app.conf`) will have just 2 server entries now indicating that the 3rd server entry corresponding to the container which was stopped was removed automatically. diff --git a/consul-template-demo/clean_containers.sh b/consul-template-demo/clean_containers.sh index cb70d661..452fe07c 100755 --- a/consul-template-demo/clean_containers.sh +++ b/consul-template-demo/clean_containers.sh @@ -1,2 +1,2 @@ #!/bin/bash -docker rm -f `docker ps -qa` +docker rm -f $(docker ps -qa) diff --git a/consul-template-demo/docker-compose.yml b/consul-template-demo/docker-compose.yml index 9db84f58..feff793a 100644 --- a/consul-template-demo/docker-compose.yml +++ b/consul-template-demo/docker-compose.yml @@ -1,38 +1,37 @@ -nginx: - build: ./nginx - container_name: nginx - links: - - consul - ports: - - "80:80" - labels: - SERVICE_IGNORE: 'yes' - -consul: - command: -server -bootstrap -advertise ${HOST_IP} - image: progrium/consul - container_name: consul - labels: - SERVICE_IGNORE: 'yes' - ports: - - "8500:8500" - -registrator: - command: "-internal consul://consul:8500" - image: gliderlabs/registrator:latest - container_name: registrator - links: - - consul - volumes: - - "/var/run/docker.sock:/tmp/docker.sock" - -http: - image: nginxdemos/hello:latest - labels: - SERVICE_80_NAME: http - SERVICE_80_CHECK_HTTP: / - SERVICE_80_CHECK_INTERVAL: 5s - SERVICE_443_IGNORE: 'yes' - SERVICE_TAGS: production - ports: - - "80" +version: '3' +services: + nginx: + build: ./nginx + container_name: nginx + links: + - consul + ports: + - "80:80" + labels: + SERVICE_IGNORE: 'yes' + consul: + command: -server -bootstrap -advertise ${HOST_IP} + image: progrium/consul + container_name: consul + labels: + SERVICE_IGNORE: 'yes' + ports: + - "8500:8500" + registrator: + command: "-internal consul://consul:8500" + image: gliderlabs/registrator:latest + container_name: registrator + links: + - consul + volumes: + - "/var/run/docker.sock:/tmp/docker.sock" + http: + image: nginxdemos/hello:latest + labels: + SERVICE_80_NAME: http + SERVICE_80_CHECK_HTTP: / + SERVICE_80_CHECK_INTERVAL: 5s + SERVICE_443_IGNORE: 'yes' + SERVICE_TAGS: production + ports: + - "80" diff --git a/consul-template-demo/nginx/Dockerfile b/consul-template-demo/nginx/Dockerfile index d0c903e1..df768ea7 100644 --- a/consul-template-demo/nginx/Dockerfile +++ b/consul-template-demo/nginx/Dockerfile @@ -1,28 +1,108 @@ -FROM ubuntu:14.04 +FROM debian:stretch-slim -MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com" +LABEL maintainer="NGINX Docker Maintainers " -# Set the debconf frontend to Noninteractive -RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections -RUN apt-get update && apt-get install -y -q wget apt-transport-https curl unzip lsb-release runit +ENV NGINX_VERSION 1.15.7-1~stretch +ENV NJS_VERSION 1.15.7.0.2.6-1~stretch -RUN wget http://nginx.org/keys/nginx_signing.key -RUN apt-key add nginx_signing.key -RUN rm nginx_signing.key -RUN printf "deb http://nginx.org/packages/mainline/ubuntu/ `lsb_release -cs` nginx\n" | tee /etc/apt/sources.list.d/nginx.list +RUN set -x \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y gnupg1 apt-transport-https ca-certificates \ + && \ + NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \ + found=''; \ + for server in \ + ha.pool.sks-keyservers.net \ + hkp://keyserver.ubuntu.com:80 \ + hkp://p80.pool.sks-keyservers.net:80 \ + pgp.mit.edu \ + ; do \ + echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ + apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \ + done; \ + test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \ + apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/* \ + && dpkgArch="$(dpkg --print-architecture)" \ + && nginxPackages=" \ + nginx=${NGINX_VERSION} \ + nginx-module-xslt=${NGINX_VERSION} \ + nginx-module-geoip=${NGINX_VERSION} \ + nginx-module-image-filter=${NGINX_VERSION} \ + nginx-module-njs=${NJS_VERSION} \ + " \ + && case "$dpkgArch" in \ + amd64|i386) \ +# arches officialy built by upstream + echo "deb https://nginx.org/packages/mainline/debian/ stretch nginx" >> /etc/apt/sources.list.d/nginx.list \ + && apt-get update \ + ;; \ + *) \ +# we're on an architecture upstream doesn't officially build for +# let's build binaries from the published source packages + echo "deb-src https://nginx.org/packages/mainline/debian/ stretch nginx" >> /etc/apt/sources.list.d/nginx.list \ + \ +# new directory for storing sources and .deb files + && tempDir="$(mktemp -d)" \ + && chmod 777 "$tempDir" \ +# (777 to ensure APT's "_apt" user can access it too) + \ +# save list of currently-installed packages so build dependencies can be cleanly removed later + && savedAptMark="$(apt-mark showmanual)" \ + \ +# build .deb files from upstream's source packages (which are verified by apt-get) + && apt-get update \ + && apt-get build-dep -y $nginxPackages \ + && ( \ + cd "$tempDir" \ + && DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)" \ + apt-get source --compile $nginxPackages \ + ) \ +# we don't remove APT lists here because they get re-downloaded and removed later + \ +# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies +# (which is done after we install the built packages so we don't have to redownload any overlapping dependencies) + && apt-mark showmanual | xargs apt-mark auto > /dev/null \ + && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \ + \ +# create a temporary local APT repo to install from (so that dependency resolution can be handled by APT, as it should be) + && ls -lAFh "$tempDir" \ + && ( cd "$tempDir" && dpkg-scanpackages . > Packages ) \ + && grep '^Package: ' "$tempDir/Packages" \ + && echo "deb [ trusted=yes ] file://$tempDir ./" > /etc/apt/sources.list.d/temp.list \ +# work around the following APT issue by using "Acquire::GzipIndexes=false" (overriding "/etc/apt/apt.conf.d/docker-gzip-indexes") +# Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied) +# ... +# E: Failed to fetch store:/var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied) + && apt-get -o Acquire::GzipIndexes=false update \ + ;; \ + esac \ + \ + && apt-get install --no-install-recommends --no-install-suggests -y \ + $nginxPackages \ + gettext-base \ + && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list \ + \ +# if we have leftovers from building, let's purge them (including extra, unnecessary build deps) + && if [ -n "$tempDir" ]; then \ + apt-get purge -y --auto-remove \ + && rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list; \ + fi -# Install NGINX OSS mainline version -RUN apt-get update && apt-get install -y nginx - -# forward request logs to docker log collector -RUN ln -sf /dev/stdout /var/log/nginx/access.log -RUN ln -sf /dev/stderr /var/log/nginx/error.log +# forward request and error logs to docker log collector +RUN ln -sf /dev/stdout /var/log/nginx/access.log \ + && ln -sf /dev/stderr /var/log/nginx/error.log EXPOSE 80 443 -ENV CT_URL https://releases.hashicorp.com/consul-template/0.15.0/consul-template_0.15.0_linux_amd64.zip -RUN curl -O $CT_URL && unzip consul-template_0.15.0_linux_amd64.zip -d /usr/local/bin +STOPSIGNAL SIGTERM + +RUN apt-get update \ + && apt-get install -y -q wget curl unzip lsb-release runit +ENV CT_URL https://releases.hashicorp.com/consul-template/0.19.5/consul-template_0.19.5_linux_amd64.zip +RUN curl -O $CT_URL +RUN unzip consul-template_0.19.5_linux_amd64.zip -d /usr/local/bin +# https://releases.hashicorp.com/consul-template/0.19.5/ ADD nginx.service /etc/service/nginx/run ADD consul-template.service /etc/service/consul-template/run RUN chmod +x /etc/service/nginx/run @@ -31,6 +111,5 @@ RUN chmod +x /etc/service/consul-template/run RUN rm -v /etc/nginx/conf.d/* ADD nginx.conf /etc/consul-templates/nginx.conf ADD index.html /etc/consul-templates/index.html -ADD logo.png /usr/share/nginx/html/logo.png CMD ["/usr/bin/runsvdir", "/etc/service"] diff --git a/consul-template-demo/nginx/consul-template.service b/consul-template-demo/nginx/consul-template.service index cdabb6a5..5a1209e4 100644 --- a/consul-template-demo/nginx/consul-template.service +++ b/consul-template-demo/nginx/consul-template.service @@ -1,6 +1,6 @@ #!/bin/sh exec consul-template \ - -consul=consul:8500 \ - -template "/etc/consul-templates/nginx.conf:/etc/nginx/conf.d/app.conf:service nginx reload" \ - -template "/etc/consul-templates/index.html:/usr/share/nginx/html/index.html" + -consul-addr consul:8500 \ + -template "/etc/consul-templates/nginx.conf:/etc/nginx/conf.d/app.conf:service nginx reload" \ + -template "/etc/consul-templates/index.html:/usr/share/nginx/html/index.html" diff --git a/consul-template-demo/nginx/logo.png b/consul-template-demo/nginx/logo.png deleted file mode 100644 index 4514ce5f446d4756c11ba36ee1be40f7445aaac7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12586 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 M07*qoM6N<$f~-`YG5`Po diff --git a/consul-template-demo/nginx/nginx.conf b/consul-template-demo/nginx/nginx.conf index aa486e53..829fc250 100644 --- a/consul-template-demo/nginx/nginx.conf +++ b/consul-template-demo/nginx/nginx.conf @@ -1,28 +1,27 @@ {{range services}} {{$name := .Name}} {{$service := service .Name}} upstream {{$name}} { - zone upstream-{{$name}} 64k; - least_conn; - {{range $service}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; - {{else}}server 127.0.0.1:65535; # force a 502{{end}} -} {{end}} + zone upstream-{{$name}} 64k; + least_conn; + {{range $service}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; + {{else}}server 127.0.0.1:65535; # force a 502{{end}} +} {{end}} server { - listen 80 default_server; + listen 80 default_server; - location / { - root /usr/share/nginx/html/; - index index.html; - } + location / { + root /usr/share/nginx/html/; + index index.html; + } - location /stub_status { - stub_status; - } + location /stub_status { + stub_status; + } {{range services}} {{$name := .Name}} - location /{{$name}} { - proxy_pass http://{{$name}}; - - rewrite ^/{{$name}}/(.*)$ /$1 break; - } + location /{{$name}} { + proxy_pass http://{{$name}}; + rewrite ^/{{$name}}/(.*)$ /$1 break; + } {{end}} } diff --git a/consul-template-demo/nginx/nginx.service b/consul-template-demo/nginx/nginx.service index b22f66af..8630a3c3 100644 --- a/consul-template-demo/nginx/nginx.service +++ b/consul-template-demo/nginx/nginx.service @@ -1,4 +1,3 @@ #!/bin/sh - -/usr/sbin/nginx -c /etc/nginx/nginx.conf -t && \ -exec /usr/sbin/nginx -c /etc/nginx/nginx.conf -g "daemon off;" +/usr/sbin/nginx -c /etc/nginx/nginx.conf -t \ +&& exec /usr/sbin/nginx -c /etc/nginx/nginx.conf -g "daemon off;" diff --git a/etcd-demo/README.md b/etcd-demo/README.md index 11d9e381..fc96493e 100644 --- a/etcd-demo/README.md +++ b/etcd-demo/README.md @@ -1,93 +1,89 @@ -# Demo to show Nginx Plus Dynamic Reconfiguration API (upstream_conf) with etcd +# Demo to show NGINX Plus Dynamic Reconfiguration API with etcd This demo shows NGINX Plus being used in conjuction with etcd, a distributed, consistent key-value store for shared configuration and service discovery. This demo is based on docker and spins' up the following containers: -* [etcd](https://github.com/coreos/etcd) for service discovery -* [Registrator](https://github.com/gliderlabs/registrator) to register services with etcd. Registrator monitors for containers being started and stopped and updates key-value pairs in etcd when a container changes state. -* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port, request URI, local time of the webserver and the client IP address. This is to simulate backend servers NGINX Plus will be load balancing across. -* and of course [NGINX Plus](http://www.nginx.com/products) (R8 or higher) +* [etcd](https://github.com/coreos/etcd) for service discovery +* [Registrator](https://github.com/gliderlabs/registrator) to register services with etcd. Registrator monitors for containers being started and stopped and updates key-value pairs in etcd when a container changes state. +* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port, request URI, local time of the webserver and the client IP address. This is to simulate backend servers NGINX Plus will be load balancing across. +* [NGINX Plus](http://www.nginx.com/products) (R13 or higher) The demo is based off the work described in this blog post: [Service Discovery for NGINX Plus with etcd](https://www.nginx.com/blog/service-discovery-nginx-plus-etcd/) - + ## Setup Options + ### Fully automated Vagrant/Ansible setup: Install Vagrant using the necessary package for your OS: -https://www.vagrantup.com/downloads.html + -1. Install provider for vagrant to use to start VM's. +1. Install provider for vagrant to use to start VM's. - The default provider is VirtualBox [Note that only VirtualBox versions 4.0 and higher are supported], which can be downloaded from the following link: + The default provider is VirtualBox (Note that only VirtualBox versions 4.0 and higher are supported), which can be downloaded from the following link: - https://www.virtualbox.org/wiki/Downloads + A full list of providers can be found at the following page, if you do not want to use VirtualBox: - https://docs.vagrantup.com/v2/providers/ + -1. Install Ansible: +2. Install Ansible: - http://docs.ansible.com/ansible/intro_installation.html + -1. Clone demo repo +3. Clone demo repo - ```$ git clone https://github.com/nginxinc/NGINX-Demos.git``` + `$ git clone https://github.com/nginxinc/NGINX-Demos.git` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```~/NGINX-Demos/ansible/files/``` +4. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `~/NGINX-Demos/etcd-demo/nginxplus` -1. Move into the etcd-demo directory and start the Vagrant vm: +5. Move into the etcd-demo directory and start the Vagrant vm: - ``` - $ cd ~/NGINX-Demos/etcd-demo - $ vagrant up - ``` - The ```vagrant up``` command will start the virtualbox VM and provision it using the ansible playbook file ~/NGINX-Demos/ansible/setup_etcd_demo.yml. The ansible playbook file also invokes another script provision.sh which sets the HOST_IP environment variable to the IP address of the eth1 interface (10.2.2.70 in this case assigned in the Vagrantfile) and invokes the ```docker-compose up -d``` command + ``` + $ cd ~/NGINX-Demos/etcd-demo + $ vagrant up + ``` -1. SSH into the newly created virtual machine and move into the /vagrant directory which contains the demo files: + The `vagrant up` command will start the virtualbox VM and provision it using the ansible playbook file `~/NGINX-Demos/etcd-demo/setup_etcd_demo.yml`. The ansible playbook file also invokes another script provision.sh which sets the HOST_IP environment variable to the IP address of the eth1 interface (10.2.2.70 in this case assigned in the Vagrantfile) and invokes the `docker-compose up -d` command - ``` - $ vagrant ssh - $ sudo su - ``` -The demo files will be in /srv/NGINX-Demos/etcd-demo +6. SSH into the newly created virtual machine and move into the /vagrant directory which contains the demo files: + + ``` + $ vagrant ssh + $ sudo su + ``` -1. Now simply follow the steps listed under section 'Running the demo'. + The demo files will be in `/srv/NGINX-Demos/etcd-demo` +7. Now simply follow the steps listed under section 'Running the demo'. ### Ansible only deployment -1. Create Ubuntu 14.04 VM +1. Create Ubuntu 18.04 LTS VM -1. Install Ansible on Ubuntu VM +2. Install Ansible on Ubuntu VM - ``` - $ sudo apt-get install ansible - ``` + `$ sudo apt-get install ansible` -1. Clone demo repo into ```/srv``` on Ubuntu VM: +3. Clone demo repo into `/srv` on Ubuntu VM: - ``` - $ cd /srv - $ sudo git clone https://github.com/nginxinc/NGINX-Demos.git - ``` + ``` + $ cd /srv + $ sudo git clone https://github.com/nginxinc/NGINX-Demos.git + ``` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```/srv/NGINX-Demos/ansible/files/``` +4. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `/srv/NGINX-Demos/etcd-demo/nginxplus` -1. Move into the etcd-demo directory which contains the demo files and set HOST_IP on line 5 in script.sh to the IP of your Ubuntu VM on which NGINX Plus will be listening. - ``` - $ cd /srv/NGINX-Demos/etcd-demo - ``` +5. Move into the etcd-demo directory which contains the demo files and set HOST_IP on line 5 in script.sh to the IP of your Ubuntu VM on which NGINX Plus will be listening. -1. Run the ansible playbook against localhost on Ubuntu VM: + `$ cd /srv/NGINX-Demos/etcd-demo` - ``` - $ sudo ansible-playbook -i "localhost," -c local /srv/NGINX-Demos/ansible/setup_etcd_demo.yml - ``` +6. Run the ansible playbook against localhost on Ubuntu VM: -1. Now simply follow the steps listed under section 'Running the demo'. + `$ sudo ansible-playbook -i "localhost," -c local /srv/NGINX-Demos/etcd-demo/setup_etcd_demo.yml` +7. Now simply follow the steps listed under section 'Running the demo'. ### Manual Install @@ -95,60 +91,59 @@ The demo files will be in /srv/NGINX-Demos/etcd-demo The following software needs to be installed: -* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM -* [jq](https://stedolan.github.io/jq/), I used [brew](http://brew.sh) to install it: `brew install jq` -* [etcd](https://github.com/coreos/etcd) & etcdctl, a command line client for etcd. Follow the steps under 'Getting etcd' section and and copy over etcdctl executable under /usr/local/bin and make sure this path is present in $PATH variable +* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM +* [jq](https://stedolan.github.io/jq/), I used [brew](http://brew.sh) to install it: `brew install jq` +* [etcd](https://github.com/coreos/etcd) & etcdctl, a command line client for etcd. Follow the steps under 'Getting etcd' section and and copy over etcdctl executable under /usr/local/bin and make sure this path is present in $PATH variable As the demo uses NGINX Plus a `nginx-repo.crt` and `nginx-repo.key` needs to be copied into the `nginxplus/` directory #### Setting up the demo -1. Clone demo repo +1. Clone demo repo - ```$ git clone https://github.com/nginxinc/NGINX-Demos.git``` + `$ git clone https://github.com/nginxinc/NGINX-Demos.git` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```~/NGINX-Demos/etcd-demo/nginxplus/``` +2. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `~/NGINX-Demos/etcd-demo/nginxplus/` -1. Move into the demo directory: +3. Move into the demo directory: + + `$ cd ~/NGINX-Demos/etcd-demo` + +4. If you have run this demo previously or have any docker containers running, start with a clean slate by running + + `$ ./clean-containers.sh` + +5. NGINX Plus will be listening on port 80 on docker host + + 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running - ``` - $ cd ~/NGINX-Demos/etcd-demo - ``` -1. If you have run this demo previously or have any docker containers running, start with a clean slate by running ``` - $ ./clean-containers.sh + $ docker-machine ip default + 192.168.99.100 ``` -1. NGINX Plus will be listening on port 80 on docker host - 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running + 2. If you are using Docker for Mac, the IP address you need to use is 127.0.0.1 - ``` - $ docker-machine ip default - 192.168.99.100 - ``` - 1. If you are using Docker for Mac, the IP address you need to use is 127.0.0.1 + **Export this IP into an environment variable named HOST_IP by running `export HOST_IP=x.x.x.x` command. This variable is used by docker-compose.yml file** - Export this IP into an environment variable named HOST_IP by running `export HOST_IP=x.x.x.x` command. This variable is used by docker-compose.yml file +6. Spin up the etcd, Registrator and NGINX Plus containers first: -1. Spin up the etcd, Registrator and NGINX Plus containers first: + `$ docker-compose up -d` - ``` - $ docker-compose up -d - ``` +7. Execute the etcd_exec_watch.sh script in background (This invokes an etcdctl exec-watch command watching for changes in etcd keys and trigger script.sh whenever a change is detected). -1. Execute the etcd_exec_watch.sh script in background (This invokes an etcdctl exec-watch command watching for changes in etcd keys and trigger script.sh whenever a change is detected). - ``` - $ ./etcd_exec_watch.sh & - ``` + `$ ./etcd_exec_watch.sh &` -1. Spin up the nginxdemos/hello container which is the backend http service - ``` - $ docker-compose -f create-http-service.yml up -d - ``` +8. Spin up the nginxdemos/hello container which is the backend http service + + `$ docker-compose -f create-http-service.yml up -d` + +9. Now follow the steps under section 'Running the demo' ## Running the demo -1. You should have a bunch of containers up and running now: +1. You should have a bunch of containers up and running now: + ``` $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES @@ -158,16 +153,17 @@ As the demo uses NGINX Plus a `nginx-repo.crt` and `nginx-repo.key` needs to be 9fd1ab126773 quay.io/coreos/etcd:v2.0.8 "/etcd -name etcd0 -a" 26 seconds ago Up 25 seconds 0.0.0.0:2379-2380->2379-2380/tcp, 0.0.0.0:4001->4001/tcp, 7001/tcp etcd ``` -1. If you followed the Fully automated Vagrant/Ansible setup option above, HOST_IP referred below is the IP assigned to your Vagrant VM (i.e 10.2.2.70 in Vagrantfile) and is set already. And if you followed the Ansible only deployment option, HOST_IP will be the IP of your Ubuntu VM on which NGINX Plus is listening (IP of the interface set on line 6 of provision.sh, set to eth1 by default). For the manual install option, HOST_IP was already set above to `docker-machine ip default` OR 127.0.0.1 in case of Docker for Mac +2. If you followed the Fully automated Vagrant/Ansible setup option above, HOST_IP referred below is the IP assigned to your Vagrant VM (i.e 10.2.2.70 in Vagrantfile) and is set already. And if you followed the Ansible only deployment option, HOST_IP will be the IP of your Ubuntu VM on which NGINX Plus is listening (IP of the interface set on line 6 of provision.sh, set to eth1 by default). For the manual install option, HOST_IP was already set above to `docker-machine ip default` OR 127.0.0.1 in case of Docker for Mac + +3. Go to `http://` in your favorite browser window and that will take you to one of the nginx-hello containers printing its hostname, IP Address and the port of the container. `http://:8080/` will bring up the NGINX Plus dashboard. The configuration file NGINX Plus is using here is /etc/nginx/conf.d/app.conf which is included from /etc/nginx/nginx.conf. If you would like to see all the services registered with etcd you could do a `curl http://$HOST_IP:4001/v2/keys | jq '.'`. **We are also using the persistent on-the-fly reconfiguration introduced in NGINX Plus R8 using the [state](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#state) directive. This means that NGINX Plus will save the upstream conf across reloads by writing it to a file on disk.** -1. Go to `http://` in your favorite browser window and that will take you to one of the nginx-hello containers printing its hostname, IP Address and the port of the container. `http://:8080/` will bring up the NGINX Plus dashboard. The configuration file NGINX Plus is using here is /etc/nginx/conf.d/app.conf which is included from /etc/nginx/nginx.conf. If you would like to see all the services registered with etcd you could do a `curl http://$HOST_IP:4001/v2/keys | jq '.'`. **We are also using the persistent on-the-fly reconfiguration introduced in NGINX Plus R8 using the [state](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#state) directive. This means that NGINX Plus will save the upstream conf across reloads by writing it to a file on disk.** +4. Now scale up and scale down the http service using the commands below. Go to the Upstreams tab on Nginx Plus dashboard and observe the change in the list of servers being added/removed from the backend group accordingly. -1. Now scale up and scale down the http service using the commands below. Go to the Upstreams tab on Nginx Plus dashboard and observe the change in the list of servers being added/removed from the backend group accordingly. ``` - $ docker-compose -f create-http-service.yml scale http=5 - $ docker-compose -f create-http-service.yml scale http=3 + $ docker-compose -f create-http-service.yml up -d --scale http=5 + $ docker-compose -f create-http-service.yml up -d --scale http=3 ``` -1. The way this works is everytime there is a change in etcd, script.sh gets triggered (through etcd_exec_watch.sh) which checks for some of the environment variables set by etcd and adds the server specified by ETCD_WATCH_VALUE to the NGINX upstream block if ETCD_WATCH_ACTION is 'set' and removes it if ETCD_WATCH_ACTION is 'delete'. The removal happens by traversing through all NGINX Plus upstreams and removing the ones not present in etcd. +5. The way this works is everytime there is a change in etcd, script.sh gets triggered (through etcd_exec_watch.sh) which checks for some of the environment variables set by etcd and adds the server specified by ETCD_WATCH_VALUE to the NGINX upstream block if ETCD_WATCH_ACTION is 'set' and removes it if ETCD_WATCH_ACTION is 'delete'. The removal happens by traversing through all NGINX Plus upstreams and removing the ones not present in etcd. All the changes should be automatically reflected in the NGINX config and show up on the NGINX Plus Dashboard. diff --git a/etcd-demo/Vagrantfile b/etcd-demo/Vagrantfile index 45a2bac6..5ba1833b 100644 --- a/etcd-demo/Vagrantfile +++ b/etcd-demo/Vagrantfile @@ -1,14 +1,15 @@ -VAGRANTFILE_API_VERSION = "2" - Vagrant.configure(2) do |config| - config.vm.box = "ubuntu/trusty64" + config.vm.box = "ubuntu/bionic64" config.vm.network "private_network", :ip => "10.2.2.70" config.vm.synced_folder "../etcd-demo/", "/srv/NGINX-Demos/etcd-demo" config.vm.provision :ansible do |ansible| ansible.playbook = "./setup_etcd_demo.yml" + ansible.extra_vars = { + ansible_python_interpreter:"/usr/bin/python3" + } end end diff --git a/etcd-demo/clean_containers.sh b/etcd-demo/clean_containers.sh index cb70d661..452fe07c 100755 --- a/etcd-demo/clean_containers.sh +++ b/etcd-demo/clean_containers.sh @@ -1,2 +1,2 @@ #!/bin/bash -docker rm -f `docker ps -qa` +docker rm -f $(docker ps -qa) diff --git a/etcd-demo/create-http-service.yml b/etcd-demo/create-http-service.yml index cbcd4dc0..770accdb 100644 --- a/etcd-demo/create-http-service.yml +++ b/etcd-demo/create-http-service.yml @@ -1,7 +1,9 @@ -http: - image: nginxdemos/hello:latest - labels: - SERVICE_80_NAME: http - SERVICE_TAGS: production - ports: - - "80" +version: '3' +services: + http: + image: nginxdemos/hello:latest + labels: + SERVICE_80_NAME: http + SERVICE_TAGS: production + ports: + - "80" diff --git a/etcd-demo/docker-compose.yml b/etcd-demo/docker-compose.yml index dba352e7..7e69de35 100644 --- a/etcd-demo/docker-compose.yml +++ b/etcd-demo/docker-compose.yml @@ -1,27 +1,26 @@ -nginxplus: - build: ./nginxplus - container_name: nginxplus - links: - - etcd - ports: - - "80:80" - - "8080:8080" - -etcd: - command: "-name etcd0 -advertise-client-urls http://${HOST_IP}:2379,http://${HOST_IP}:4001 -listen-client-urls http://0.0.0.0:2379,http://0.0.0.0:4001 -initial-advertise-peer-urls http://${HOST_IP}:2380 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster-1 -initial-cluster etcd0=http://${HOST_IP}:2380" - image: quay.io/coreos/etcd:v2.0.8 - container_name: etcd - ports: - - "4001:4001" - - "2380:2380" - - "2379:2379" - -registrator: - command: etcd://etcd:4001 - image: gliderlabs/registrator:latest - container_name: registrator - links: - - etcd - volumes: - - "/var/run/docker.sock:/tmp/docker.sock" - +version: '3' +services: + nginxplus: + build: ./nginxplus + container_name: nginxplus + links: + - etcd + ports: + - "80:80" + - "8080:8080" + etcd: + command: "-name etcd0 -advertise-client-urls http://${HOST_IP}:2379,http://${HOST_IP}:4001 -listen-client-urls http://0.0.0.0:2379,http://0.0.0.0:4001 -initial-advertise-peer-urls http://${HOST_IP}:2380 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster-1 -initial-cluster etcd0=http://${HOST_IP}:2380" + image: quay.io/coreos/etcd:v2.0.8 + container_name: etcd + ports: + - "4001:4001" + - "2380:2380" + - "2379:2379" + registrator: + command: etcd://etcd:4001 + image: gliderlabs/registrator:latest + container_name: registrator + links: + - etcd + volumes: + - "/var/run/docker.sock:/tmp/docker.sock" diff --git a/etcd-demo/etcd_exec_watch.sh b/etcd-demo/etcd_exec_watch.sh index 290f5886..790524de 100755 --- a/etcd-demo/etcd_exec_watch.sh +++ b/etcd-demo/etcd_exec_watch.sh @@ -1,2 +1,3 @@ #!/bin/bash -etcdctl --no-sync --endpoint http://$HOST_IP:4001 exec-watch --recursive / -- sh -c ./script.sh; +HOST_IP=$(ip -f inet a show enp0s8 | grep -oP "(?<=inet ).+(?=\/)") +etcdctl --no-sync --endpoint http://$HOST_IP:4001 exec-watch --recursive / -- sh -c /srv/NGINX-Demos/etcd-demo/script.sh; diff --git a/etcd-demo/nginxplus/Dockerfile b/etcd-demo/nginxplus/Dockerfile index 197d55d1..8b972d71 100644 --- a/etcd-demo/nginxplus/Dockerfile +++ b/etcd-demo/nginxplus/Dockerfile @@ -1,35 +1,49 @@ -FROM ubuntu:14.04 +# For Debian 9 +FROM debian:stretch-slim -MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com" - -# Set the debconf front end to Noninteractive -RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections - -RUN apt-get update && apt-get install -y -q wget apt-transport-https +LABEL maintainer="NGINX Docker Maintainers " # Download certificate and key from the customer portal (https://cs.nginx.com) # and copy to the build context -ADD nginx-repo.crt /etc/ssl/nginx/ -ADD nginx-repo.key /etc/ssl/nginx/ - -# Get other files required for installation -RUN wget -q -O /etc/ssl/nginx/CA.crt https://cs.nginx.com/static/files/CA.crt -RUN wget -q -O - http://nginx.org/keys/nginx_signing.key | apt-key add - -RUN wget -q -O /etc/apt/apt.conf.d/90nginx https://cs.nginx.com/static/files/90nginx - -RUN printf "deb https://plus-pkgs.nginx.com/ubuntu `lsb_release -cs` nginx-plus\n" >/etc/apt/sources.list.d/nginx-plus.list +COPY nginx-repo.crt /etc/ssl/nginx/ +COPY nginx-repo.key /etc/ssl/nginx/ # Install NGINX Plus -RUN apt-get update && apt-get install -y nginx-plus - -# forward request logs to Docker log collector -RUN ln -sf /dev/stdout /var/log/nginx/access.log -RUN ln -sf /dev/stderr /var/log/nginx/error.log +RUN set -x \ + && apt-get update && apt-get upgrade -y \ + && apt-get install --no-install-recommends --no-install-suggests -y apt-transport-https ca-certificates gnupg1 \ + && \ + NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \ + found=''; \ + for server in \ + ha.pool.sks-keyservers.net \ + hkp://keyserver.ubuntu.com:80 \ + hkp://p80.pool.sks-keyservers.net:80 \ + pgp.mit.edu \ + ; do \ + echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ + apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \ + done; \ + test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \ + echo "Acquire::https::plus-pkgs.nginx.com::Verify-Peer \"true\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::Verify-Host \"true\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::SslCert \"/etc/ssl/nginx/nginx-repo.crt\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::SslKey \"/etc/ssl/nginx/nginx-repo.key\";" >> /etc/apt/apt.conf.d/90nginx \ + && printf "deb https://plus-pkgs.nginx.com/debian stretch nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \ + && apt-get update && apt-get install -y nginx-plus \ + && apt-get remove --purge --auto-remove -y gnupg1 \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /etc/ssl/nginx + +# Forward request logs to Docker log collector +RUN ln -sf /dev/stdout /var/log/nginx/access.log \ + && ln -sf /dev/stderr /var/log/nginx/error.log EXPOSE 80 8080 443 +STOPSIGNAL SIGTERM + RUN rm -v /etc/nginx/conf.d/* -ADD app.conf /etc/nginx/conf.d/app.conf -ADD logo.png /usr/share/nginx/html/logo.png +COPY app.conf /etc/nginx/conf.d/app.conf CMD ["nginx", "-g", "daemon off;"] diff --git a/etcd-demo/nginxplus/app.conf b/etcd-demo/nginxplus/app.conf index b57ef3f3..cde8a042 100644 --- a/etcd-demo/nginxplus/app.conf +++ b/etcd-demo/nginxplus/app.conf @@ -1,46 +1,33 @@ - upstream backend { - zone upstream_backend 64k; - state /tmp/upstream.conf; - } - - match hello { - status 200; - header Content-Type = text/html; - body ~ "Hello"; - } - - server { - listen 80; - status_zone backend; - - location / { - health_check match=hello; - proxy_pass http://backend; - } - - location /upstream_conf { - upstream_conf; - - #allow 127.0.0.1; # permit access from localhost - #deny all; # deny access from everywhere else - } - } - - server { - listen 8080; - root /usr/share/nginx/html; - access_log off; - - # Redirect requests for / to /status.html - location = / { - return 301 /status.html; - } - - location = /status.html { } - - # Everything beginning with /status (except for /status.html) is - # processed by the status handler - location /status { - status; - } - } +upstream backend { + zone upstream_backend 64k; + state /tmp/upstream.conf; +} + +match hello { + status 200; + header Content-Type = text/html; + body ~ "Hello"; +} + +server { + listen 80; + status_zone backend; + + location / { + proxy_pass http://backend; + health_check interval=2s match=hello; + } +} + +server { + listen 8080; + root /usr/share/nginx/html; + + location /api { + api write=on; + } + + location = / { + return 301 /dashboard.html; + } +} diff --git a/etcd-demo/nginxplus/index.html b/etcd-demo/nginxplus/index.html deleted file mode 100644 index e15a473a..00000000 --- a/etcd-demo/nginxplus/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - -Welcome to nginx! - - - -

Welcome to nginx!

- -

For online documentation and support please refer to -nginx.org.
-Commercial support is available at -nginx.com.

- -

Thank you for using nginx.

- - diff --git a/etcd-demo/nginxplus/logo.png b/etcd-demo/nginxplus/logo.png deleted file mode 100644 index b2f48c4d5d41aa35e3d64b1e37c75aadb5566dbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12587 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 N07*qoM6N<$f(lBXo;&~m diff --git a/etcd-demo/provision.sh b/etcd-demo/provision.sh index d287f5bb..79a73252 100755 --- a/etcd-demo/provision.sh +++ b/etcd-demo/provision.sh @@ -1,10 +1,9 @@ #!/bin/bash - if [ ${HOST_IP} ]; then - echo "HOST_IP=${HOST_IP}" + echo "HOST_IP=${HOST_IP}" else - ipaddr=`/sbin/ifconfig eth1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'` - echo "export HOST_IP=$ipaddr" | tee -a ~/.bash_aliases - . ~/.bash_aliases - /usr/local/bin/docker-compose up -d + ipaddr=$(ip -f inet a show enp0s8 | grep -oP "(?<=inet ).+(?=\/)") + echo "export HOST_IP=$ipaddr" | tee -a ~/.bash_aliases + . ~/.bash_aliases + /usr/local/bin/docker-compose -f /srv/NGINX-Demos/etcd-demo/docker-compose.yml up -d fi diff --git a/etcd-demo/script.sh b/etcd-demo/script.sh index 56d07e19..f6d7ff98 100755 --- a/etcd-demo/script.sh +++ b/etcd-demo/script.sh @@ -1,55 +1,67 @@ #!/bin/bash +if [[ -z "$HOST_IP" ]]; then + echo "HOST_IP not set in etcd container. Setting it to 10.2.2.70 (IP address assigned in the Vagrantfile)" + HOST_IP=10.2.2.70 +fi + +# HOST_IP=$(ip -f inet a show enp0s8 | grep -oP "(?<=inet ).+(?=\/)") CURL='/usr/bin/curl' OPTIONS='-s' ETCD_KEYS_API="http://$HOST_IP:4001/v2/keys" ETCD_MACHINES_API="http://$HOST_IP:4001/v2/machines" -STATUS_UPSTREAMS_API="http://$HOST_IP:8080/status/upstreams" -UPSTREAM_CONF_API="http://$HOST_IP/upstream_conf?" +STATUS_UPSTREAMS_API="http://$HOST_IP:8080/api/3/http/upstreams" + +# Get the list of current NGINX upstreams +upstreams=$($CURL $OPTIONS $STATUS_UPSTREAMS_API | jq -r '. as $in | keys[]') +servers=$($CURL $OPTIONS ${STATUS_UPSTREAMS_API}/${upstreams}/servers) +echo "NGINX upstreams in $upstreams:" +echo $servers -# Get the list of current Nginx upstreams -upstreams=$($CURL $OPTIONS $STATUS_UPSTREAMS_API | jq -r '. as $in| keys[]') # Get the IP etcd is listening on endpoint=$($CURL $OPTIONS $ETCD_MACHINES_API) echo "endpoint=$endpoint" IFS=':/' read -ra list <<< "$endpoint" #Convert string to array etcdip=${list[3]} echo "etcdip=$etcdip" + # Check for ETCD_WATCH_ACTION & act accordingly if [[ $ETCD_WATCH_ACTION == "set" ]]; then - IFS=':' read -ra list <<< "$ETCD_WATCH_VALUE" #Convert string to array - port=${list[1]} - entry=$etcdip:$port - echo "$entry added to NGINX upstream group $upstreams!" - add_entry=$($CURL $OPTIONS "{$UPSTREAM_CONF_API}add=&upstream=$upstreams&server=$entry") + IFS=':' read -ra list <<< "$ETCD_WATCH_VALUE" #Convert string to array + port=${list[1]} + entry=$etcdip:$port + $CURL -X POST -d '{"server": "'$entry'"}' $OPTIONS "${STATUS_UPSTREAMS_API}/${upstreams}/servers" + echo "Added $entry to the NGINX upstream group $upstreams!" elif [[ $ETCD_WATCH_ACTION == "delete" ]]; then - # Loop through the Nginx upstreams and remove the ones not present in etcd - servers=$($CURL $OPTIONS {$UPSTREAM_CONF_API}upstream=$upstreams) - for params in ${servers[@]}; do - if [[ $params =~ ":" ]]; then - server=$params - continue - elif [[ $params =~ "id=" ]]; then - id=$params - else - continue - fi - # Loop through the servers in Etcd & check if $server exists - ports=$($CURL $OPTIONS $ETCD_KEYS_API/http | jq --raw-output '.node.nodes[].value') - found=0 - for port in ${ports[@]}; do - entry=$etcdip$port - if [[ $server =~ $entry ]]; then - #echo "$server matches etcd $entry" - found=1 - break - else - continue - fi - done - if [ $found -eq 0 ]; then - remove_entry=$($CURL $OPTIONS "{$UPSTREAM_CONF_API}remove=&upstream=$upstreams&$id") - echo "$server removed from nginx upstream block $upstreams!" - fi + # Loop through the NGINX upstreams and remove the ones not present in etcd + servers=($($CURL $OPTIONS ${STATUS_UPSTREAMS_API}/${upstreams}/servers | jq -c '.[]')) + for params in ${servers[@]}; do + if [[ $params =~ "server" ]]; then + server=$(echo $params | jq '.server') + continue + elif [[ $params =~ "id" ]]; then + id=$(echo $params | jq '.id') + else + continue + fi + + # Loop through the servers in etcd & check if $server exists + ports=$($CURL $OPTIONS $ETCD_KEYS_API/http | jq --raw-output '.node.nodes[].value') + found=0 + for port in ${ports[@]}; do + entry=$etcdip$port + if [[ $server =~ $entry ]]; then + echo "$server matches etcd entry $entry" + found=1 + break + else + continue + fi done + + if [ $found -eq 0 ]; then + $CURL -X DELETE $OPTIONS "{$STATUS_UPSTREAMS_API}/$upstreams/servers/$id" + echo "Removed $server # $id from NGINX upstream block $upstreams!" + fi + done fi diff --git a/etcd-demo/setup_etcd_demo.yml b/etcd-demo/setup_etcd_demo.yml index bedda2bd..258f8442 100644 --- a/etcd-demo/setup_etcd_demo.yml +++ b/etcd-demo/setup_etcd_demo.yml @@ -1,54 +1,58 @@ - hosts: all - sudo: true + become: true tasks: - - - name: Setup Etcd Demo | Install curl from apt - apt: update_cache=yes pkg=curl - - - name: Setup Etcd Demo | Install git from apt - apt: update_cache=yes pkg=git - - - name: Setup Etcd Demo | Install jq from apt - apt: update_cache=yes pkg=jq - - - name: Setup Etcd Demo | Install docker.io from apt - shell: curl -sSL https://get.docker.com/ | sh - - - name: Setup Etcd Demo | Install docker-compose - shell: curl -L https://github.com/docker/compose/releases/download/1.10.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose - - - name: Setup Etcd Demo | Apply executable permissions to the docker-compose binary - shell: chmod +x /usr/local/bin/docker-compose - - - name: Setup Consul Demo | Copy docker-compose under /etc/bash_completion. - shell: curl -L https://raw.githubusercontent.com/docker/compose/1.10.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose - - - name: NGINX Plus | Copying NGINX Plus repository certificate - copy: src=files/nginx-repo.crt dest=/srv/NGINX-Demos/etcd-demo/nginxplus/nginx-repo.crt - - - name: NGINX Plus | Copying NGINX Plus repository key - copy: src=files/nginx-repo.key dest=/srv/NGINX-Demos/etcd-demo/nginxplus/nginx-repo.key - + - name: Setup Etcd Demo | Install curl, git and jq from apt + apt: + update_cache: yes + name: + - curl + - git + - jq + - name: Setup Etcd Demo | Download docker.io install script + get_url: + url: https://get.docker.com + dest: /tmp/get-docker.sh + mode: +x + - name: Setup Etcd Demo | Install docker + shell: /tmp/get-docker.sh + - name: Setup Etcd Demo | Delete docker.io install script + file: + path: /tmp/get-docker.sh + state: absent + - name: Setup Etcd Demo | Download docker-compose + get_url: + url: https://github.com/docker/compose/releases/download/1.23.2/docker-compose-Linux-x86_64 + dest: /usr/local/bin/docker-compose + mode: +x + - name: Setup Etcd Demo | Copy docker-compose under /etc/bash_completion + get_url: + url: https://raw.githubusercontent.com/docker/compose/1.23.2/contrib/completion/bash/docker-compose + dest: /etc/bash_completion.d/docker-compose - name: Setup Etcd Demo | Executing provision.sh (sets HOST_IP, builds the container images and starts them) - shell: ./provision.sh - args: - chdir: /srv/NGINX-Demos/etcd-demo/ - - - name: Setup Etcd Demo | Install etcd and etcdctl - command: "{{item}}" + shell: /srv/NGINX-Demos/etcd-demo/provision.sh + - name: Setup Etcd Demo | Download etcd and etcdctl + get_url: + url: https://github.com/coreos/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz + dest: /tmp/etcd-v3.3.10-linux-amd64.tar.gz + - name: Setup Etcd Demo | Untar etcd and etcdctl + unarchive: + remote_src: yes + src: /tmp/etcd-v3.3.10-linux-amd64.tar.gz + dest: /tmp + - name: Setup Etcd Demo | Copy etcd and etcdctl + copy: + remote_src: yes + src: /tmp/etcd-v3.3.10-linux-amd64/etcdctl + dest: /usr/local/bin/etcdctl + mode: +x + - name: Setup Etcd Demo | Delete etcd and etcdctl tar + file: + path: "{{ item }}" + state: absent with_items: - - curl -L https://github.com/coreos/etcd/releases/download/v2.2.4/etcd-v2.2.4-linux-amd64.tar.gz -o etcd-v2.2.4-linux-amd64.tar.gz - - tar xzvf etcd-v2.2.4-linux-amd64.tar.gz - - cp etcd-v2.2.4-linux-amd64/etcdctl /usr/local/bin/ - args: - chdir: /tmp/ - + - /tmp/etcd-v3.3.10-linux-amd64.tar.gz + - /tmp/etcd-v3.3.10-linux-amd64 - name: Setup Etcd Demo | Execute etcd_exec_watch.sh script - shell: nohup ./etcd_exec_watch.sh & - args: - chdir: /srv/NGINX-Demos/etcd-demo/ - - - name: Setup Etcd Demo | Spin up the two hello-world containers which will act as NGINX Plus upstreams - shell: /usr/local/bin/docker-compose -f create-services.yml up -d - args: - chdir: /srv/NGINX-Demos/etcd-demo/ + shell: nohup /srv/NGINX-Demos/etcd-demo/etcd_exec_watch.sh /dev/null 2>&1 & + - name: Setup Etcd Demo | Spin up the nginxdemos/hello container which is the backend http service + shell: /usr/local/bin/docker-compose -f /srv/NGINX-Demos/etcd-demo/create-http-service.yml up -d diff --git a/zookeeper-demo/README.md b/zookeeper-demo/README.md index aad76afa..e1d5c5a5 100644 --- a/zookeeper-demo/README.md +++ b/zookeeper-demo/README.md @@ -1,12 +1,12 @@ -# Demo to show Nginx Plus Dynamic Reconfiguration API (upstream_conf) with Zookeeper +# Demo to show NGINX Plus Dynamic Reconfiguration API with Zookeeper This demo shows NGINX Plus being used in conjuction with Apache Zookeeper, which can be used for service discovery. This demo is based on docker and spins' up the following containers: -* [Zookeeper](https://zookeeper.apache.org/) for service discovery. Hereby referred as ZK -* [Registrator](https://github.com/gliderlabs/registrator), a service registry bridge for docker with a pluggable adapter for ZK backend. It monitors state change of service containers and updates ZK. -* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port to simulate backend servers -* and of course [NGINX Plus](http://www.nginx.com/products) R8 +* [Zookeeper](https://zookeeper.apache.org/) for service discovery. Hereby referred as ZK +* [Registrator](https://github.com/gliderlabs/registrator), a service registry bridge for docker with a pluggable adapter for ZK backend. It monitors state change of service containers and updates ZK. +* [nginxdemos/hello](https://hub.docker.com/r/nginxdemos/hello/) as a NGINX webserver that serves a simple page containing its hostname, IP address and port to simulate backend servers +* [NGINX Plus](http://www.nginx.com/products) (R13 or higher) The demo is based off the work described in this blog post: [Service Discovery with NGINX Plus and Zookeeper](https://www.nginx.com/blog/service-discovery-nginx-plus-zookeeper/) @@ -16,159 +16,157 @@ The demo is based off the work described in this blog post: [Service Discovery w Install Vagrant using the necessary package for your OS: -https://www.vagrantup.com/downloads.html + -1. Install provider for vagrant to use to start VM's. +1. Install provider for vagrant to use to start VM's. - The default provider is VirtualBox [Note that only VirtualBox versions 4.0 and higher are supported], which can be downloaded from the following link: + The default provider is VirtualBox (Note that only VirtualBox versions 4.0 and higher are supported), which can be downloaded from the following link: - https://www.virtualbox.org/wiki/Downloads + A full list of providers can be found at the following page, if you do not want to use VirtualBox: - https://docs.vagrantup.com/v2/providers/ + -1. Install Ansible: +2. Install Ansible: - http://docs.ansible.com/ansible/intro_installation.html + -1. Clone demo repo +3. Clone demo repo - ```$ git clone https://github.com/nginxinc/NGINX-Demos.git``` + `$ git clone https://github.com/nginxinc/NGINX-Demos.git` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```~/NGINX-Demos/ansible/files/``` +4. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `~/NGINX-Demos/zookeeper-demo/nginxplus` -1. Move into the zookeeper-demo directory and start the Vagrant vm: +5. Move into the zookeeper-demo directory and start the Vagrant vm: - ``` - $ cd ~/NGINX-Demos/zookeeper-demo - $ vagrant up - ``` - The ```vagrant up``` command will start the virtualbox VM and provision it using the ansible playbook file ~/NGINX-Demos/ansible/setup_zookeeper_demo.yml. This ansible playbook file setsup the environment, invokes another script provision.sh which sets the HOST_IP environment variable to the IP address of the eth1 interface (10.2.2.70 in this case assigned in the Vagrantfile) and invokes the ```docker-compose up -d``` command + ``` + $ cd ~/NGINX-Demos/zookeeper-demo + $ vagrant up + ``` -1. SSH into the newly created virtual machine and move into the /vagrant directory which contains the demo files: + The `vagrant up` command will start the virtualbox VM and provision it using the ansible playbook file `~/NGINX-Demos/zookeeper-demo/setup_zookeeper_demo.yml`. The ansible playbook file also invokes another script provision.sh which sets the HOST_IP environment variable to the IP address of the eth1 interface (10.2.2.70 in this case assigned in the Vagrantfile) and invokes the `docker-compose up -d` command - ``` - $ vagrant ssh - $ sudo su - ``` -The demo files will be in /srv/NGINX-Demos/zookeeper-demo +6. SSH into the newly created virtual machine and move into the /vagrant directory which contains the demo files: -1. Now simply follow the steps listed under section 'Running the demo'. + ``` + $ vagrant ssh + $ sudo su + ``` + The demo files will be in `/srv/NGINX-Demos/zookeeper-demo` + +7. Now simply follow the steps listed under section 'Running the demo'. ### Ansible only deployment -1. Create Ubuntu 14.04 VM +1. Create Ubuntu 18.04 LTS VM + +2. Install Ansible on Ubuntu VM -1. Install Ansible on Ubuntu VM + `$ sudo apt-get install ansible` - ``` - $ sudo apt-get install ansible - ``` +3. Clone demo repo into `/srv` on Ubuntu VM: -1. Clone demo repo into ```/srv``` on Ubuntu VM: + ``` + $ cd /srv + $ sudo git clone https://github.com/nginxinc/NGINX-Demos.git + ``` - ``` - $ cd /srv - $ sudo git clone https://github.com/nginxinc/NGINX-Demos.git - ``` +4. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `/srv/NGINX-Demos/zookeeper-demo/nginxplus` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```/srv/NGINX-Demos/ansible/files/``` +5. Move into zookeeper-demo directory and set the HOST_IP environment variable to the public IP of your ubuntu VM -1. cd into zookeeper-demo dir & Set the HOST_IP environment variable to the public IP of your ubuntu VM - ``` - $ cd /srv/NGINX-Demos/zookeeper-demo - $ export HOST_IP=x.x.x.x - ``` + ``` + $ cd /srv/NGINX-Demos/zookeeper-demo + $ export HOST_IP=x.x.x.x + ``` -1. Run the ansible playbook against localhost on Ubuntu VM: +6. Run the ansible playbook against localhost on Ubuntu VM: - ``` - $ sudo ansible-playbook -i "localhost," -c local /srv/NGINX-Demos/ansible/setup_zookeeper_demo.yml - ``` + `$ sudo ansible-playbook -i "localhost," -c local /srv/NGINX-Demos/zookeeper-demo/setup_zookeeper_demo.yml` -1. Now simply follow the steps listed under section 'Running the demo'. +7. Now simply follow the steps listed under section 'Running the demo'. - ### Manual Install #### Prerequisites and Required Software The following software needs to be installed: -* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM +* [Docker for Mac](https://www.docker.com/products/docker#/mac) if you are running this locally on your MAC **OR** [docker-compose](https://docs.docker.com/compose/install) if you are running this on a linux VM + +As the demo uses NGINX Plus a `nginx-repo.crt` and `nginx-repo.key` needs to be copied into the `nginxplus/` directory #### Setting up the demo -1. Clone demo repo - ```$ git clone https://github.com/nginxinc/NGINX-Demos.git``` +1. Clone demo repo + + `$ git clone https://github.com/nginxinc/NGINX-Demos.git` + +2. Copy `nginx-repo.key` and `nginx-repo.crt` files for your account to `~/NGINX-Demos/zookeeper-demo/nginxplus/` -1. Copy ```nginx-repo.key``` and ```nginx-repo.crt``` files for your account to ```~/NGINX-Demos/zookeeper-demo/nginxplus/``` +3. Move into the demo directory: -1. Move into the demo directory: + `$ cd ~/NGINX-Demos/zookeeper-demo` - ``` - $ cd ~/NGINX-Demos/zookeeper-demo - ``` +4. If you have run this demo previously or have any docker containers running, start with a clean slate by running -1. If you have run this demo previously or have any docker containers running, start with a clean slate by running - ``` - $ ./clean-containers.sh - ``` + `$ ./clean-containers.sh` -1. NGINX Plus will be listening on port 80 on your docker host. - 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running +5. NGINX Plus will be listening on port 80 on your docker host. - ``` - $ docker-machine ip default - 192.168.99.100 - ``` - 1. If you are using Docker for Mac, the IP address you need to use is 172.17.0.1 + 1. If you are using Docker Toolbox, you can get the IP address of your docker-machine (default here) by running - **Export this IP into an environment variable named HOST_IP by running `export HOST_IP=x.x.x.x` command. This variable is used by docker-compose.yml file** + ``` + $ docker-machine ip default + 192.168.99.100 + ``` -1. Spin up the zookeeper, Registrator and NGINX Plus containers first: + 2. If you are using Docker for Mac, the IP address you need to use is 172.17.0.1 - ``` - $ docker-compose up -d - ``` + **Export this IP into an environment variable named HOST_IP by running `export HOST_IP=x.x.x.x` command. This variable is used by docker-compose.yml file** -1. Now cd into zookeeper directoy and execute the following two `docker exec` commands. The first one is to create a /services path under ZK and the second one is to watch for changes (additions/deletions under the /services/http path in ZK). It triggers script.sh whenever a change in the number of http service containers is detected - ``` - $ cd zookeeper - $ docker exec -ti zookeeper ./zk-tool create /services -d abc - $ docker exec -ti zookeeper ./zk-tool watch-children /services/http - ``` +6. Spin up the zookeeper, Registrator and NGINX Plus containers first: -1. Now in a different tab under the zookeeper-demo dir, Spin up the nginxdemos/hello container which is the backend http service - ``` - $ docker-compose -f create-http-service.yml up -d - ``` + `$ docker-compose up -d` -1. Now follow the steps under section 'Running the demo' +7. Now cd into zookeeper directoy and execute the following two `docker exec` commands. The first one is to create a /services path under ZK and the second one is to watch for changes (additions/deletions under the /services/http path in ZK). It triggers script.sh whenever a change in the number of http service containers is detected + + ``` + $ cd zookeeper + $ docker exec -ti zookeeper ./zk-tool create /services -d abc + $ docker exec -ti zookeeper ./zk-tool watch-children /services/http + ``` + +8. Now in a different tab in the zookeeper-demo directory, spin up the nginxdemos/hello container which is the backend http service + + `$ docker-compose -f create-http-service.yml up -d` + +9. Now follow the steps under section 'Running the demo' ## Running the demo -1. You should have a bunch of containers up and running now: +1. You should have a bunch of containers up and running now: + + ``` + $ docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + ed66c3ac7563 nginxdemos/hello:latest "nginx -g 'daemon ..." 6 minutes ago Up 6 minutes 443/tcp, 0.0.0.0:32778->80/tcp zookeeperdemo_http_1 + 142d64081f2b gliderlabs/registrator:latest "/bin/registrator ..." 9 minutes ago Up 9 minutes registrator + 4abcc06eb1bd zookeeperdemo_nginxplus "nginx -g 'daemon ..." 9 minutes ago Up 9 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp, 443/tcp nginxplus + 69be5bf69e8c zookeeperdemo_zookeeper "/opt/zookeeper/bi..." 9 minutes ago Up 9 minutes 0.0.0.0:2181->2181/tcp, 0.0.0.0:2888->2888/tcp, 0.0.0.0:3888->3888/tcp, 0.0.0.0:9888->9888/tcp zookeeper + ``` - ``` - $ docker ps - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - ed66c3ac7563 nginxdemos/hello:latest "nginx -g 'daemon ..." 6 minutes ago Up 6 minutes 443/tcp, 0.0.0.0:32778->80/tcp zookeeperdemo_http_1 - 142d64081f2b gliderlabs/registrator:latest "/bin/registrator ..." 9 minutes ago Up 9 minutes registrator - 4abcc06eb1bd zookeeperdemo_nginxplus "nginx -g 'daemon ..." 9 minutes ago Up 9 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp, 443/tcp nginxplus - 69be5bf69e8c zookeeperdemo_zookeeper "/opt/zookeeper/bi..." 9 minutes ago Up 9 minutes 0.0.0.0:2181->2181/tcp, 0.0.0.0:2888->2888/tcp, 0.0.0.0:3888->3888/tcp, 0.0.0.0:9888->9888/tcp zookeeper - ``` +2. Go to `http://` (Note: Docker for Mac runs on IP address 127.0.0.1) in your favorite browser window and it will take you to one of the two NGINX hello containers printing its hostname, IP Address and port number, request URI, local time of the webserver and the client IP address. `http://:8080/` will bring up the NGINX Plus dashboard. The configuration file NGINX Plus is using here is `/etc/nginx/conf.d/app.conf` which is included from `/etc/nginx/nginx.conf`. -1. Go to `http://` (Note: Docker for Mac runs on IP address 127.0.0.1) in your favorite browser window and it will take you to one of the two NGINX hello containers printing its hostname, IP Address and port number, request URI, local time of the webserver and the client IP address. `http://:8080/` will bring up the NGINX Plus dashboard. The configuration file NGINX Plus is using here is /etc/nginx/conf.d/app.conf which is included from /etc/nginx/nginx.conf. +3. Now scale up and scale down the http service using the commands below. Go to the Upstreams tab on Nginx Plus dashboard and observe the change in the list of servers being added/removed from the backend group accordingly. -1. Now scale up and scale down the http service using the commands below. Go to the Upstreams tab on Nginx Plus dashboard and observe the change in the list of servers being added/removed from the backend group accordingly. - ``` - $ docker-compose -f create-http-service.yml scale http=5 - $ docker-compose -f create-http-service.yml scale http=3 - ``` + ``` + $ docker-compose -f create-http-service.yml up -d --scale http=5 + $ docker-compose -f create-http-service.yml up -d --scale http=3 + ``` -1. The way this works is using [Watches](https://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#sc_zkDataMode_watches) feature of Zookeeper, eveytime there is a change in the list of services, a handler (script.sh) is invoked through zk-tool. This bash script gets the list of all Nginx Plus upstreams using its status and upstream_conf APIs, loops through all the containers registered with ZK which are tagged with SERVICE_TAG "production" using 'zk-tool list /services'. and adds them to the upstream group using upstream_conf API if not present already. It also removes the upstreams from Nginx upstream group which are not present in ZK. +4. The way this works is using [Watches](https://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#sc_zkDataMode_watches) feature of Zookeeper, eveytime there is a change in the list of services, a handler (`script.sh`) is invoked through zk-tool. This bash script gets the list of all Nginx Plus upstreams using its status and upstream_conf APIs, loops through all the containers registered with ZK which are tagged with SERVICE_TAG "production" using 'zk-tool list /services'. and adds them to the upstream group using upstream_conf API if not present already. It also removes the upstreams from Nginx upstream group which are not present in ZK. All the changes should be automatically reflected in the NGINX config and show up on the NGINX Plus Dashboard. diff --git a/zookeeper-demo/Vagrantfile b/zookeeper-demo/Vagrantfile index 7bd43da1..7c7824bb 100644 --- a/zookeeper-demo/Vagrantfile +++ b/zookeeper-demo/Vagrantfile @@ -1,14 +1,15 @@ -VAGRANTFILE_API_VERSION = "2" - Vagrant.configure(2) do |config| - config.vm.box = "ubuntu/trusty64" + config.vm.box = "ubuntu/bionic64" config.vm.network "private_network", :ip => "10.2.2.70" config.vm.synced_folder "../zookeeper-demo/", "/srv/NGINX-Demos/zookeeper-demo" config.vm.provision :ansible do |ansible| ansible.playbook = "./setup_zookeeper_demo.yml" + ansible.extra_vars = { + ansible_python_interpreter:"/usr/bin/python3" + } end end diff --git a/zookeeper-demo/clean_containers.sh b/zookeeper-demo/clean_containers.sh index cb70d661..452fe07c 100755 --- a/zookeeper-demo/clean_containers.sh +++ b/zookeeper-demo/clean_containers.sh @@ -1,2 +1,2 @@ #!/bin/bash -docker rm -f `docker ps -qa` +docker rm -f $(docker ps -qa) diff --git a/zookeeper-demo/create-http-service.yml b/zookeeper-demo/create-http-service.yml index d661bb20..770accdb 100644 --- a/zookeeper-demo/create-http-service.yml +++ b/zookeeper-demo/create-http-service.yml @@ -1,7 +1,9 @@ -http: - image: nginxdemos/hello:latest - labels: - SERVICE_80_NAME: http - SERVICE_TAGS: production - ports: - - "80" +version: '3' +services: + http: + image: nginxdemos/hello:latest + labels: + SERVICE_80_NAME: http + SERVICE_TAGS: production + ports: + - "80" diff --git a/zookeeper-demo/docker-compose.yml b/zookeeper-demo/docker-compose.yml index 5537e124..6d3dbdc1 100644 --- a/zookeeper-demo/docker-compose.yml +++ b/zookeeper-demo/docker-compose.yml @@ -1,31 +1,30 @@ -nginxplus: - build: ./nginxplus - container_name: nginxplus - links: - - zookeeper - ports: - - "80:80" - - "8080:8080" - -zookeeper: - build: ./zookeeper - container_name: zookeeper - ports: - - "2181:2181" - - "2888:2888" - - "3888:3888" - - "9888:9888" - environment: - ZK_DATADIR: /var/log/zookeeper - environment: - - HOST_IP - -registrator: - command: zookeeper://zookeeper:2181/services - image: gliderlabs/registrator:latest - container_name: registrator - links: - - zookeeper - volumes: - - "/var/run/docker.sock:/tmp/docker.sock" - +version: '3' +services: + nginxplus: + build: ./nginxplus + container_name: nginxplus + links: + - zookeeper + ports: + - "80:80" + - "8080:8080" + zookeeper: + build: ./zookeeper + container_name: zookeeper + ports: + - "2181:2181" + - "2888:2888" + - "3888:3888" + - "9888:9888" + environment: + ZK_DATADIR: /var/log/zookeeper + environment: + - HOST_IP + registrator: + command: zookeeper://zookeeper:2181/services + image: gliderlabs/registrator:latest + container_name: registrator + links: + - zookeeper + volumes: + - "/var/run/docker.sock:/tmp/docker.sock" diff --git a/zookeeper-demo/nginxplus/Dockerfile b/zookeeper-demo/nginxplus/Dockerfile index 197d55d1..8b972d71 100644 --- a/zookeeper-demo/nginxplus/Dockerfile +++ b/zookeeper-demo/nginxplus/Dockerfile @@ -1,35 +1,49 @@ -FROM ubuntu:14.04 +# For Debian 9 +FROM debian:stretch-slim -MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com" - -# Set the debconf front end to Noninteractive -RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections - -RUN apt-get update && apt-get install -y -q wget apt-transport-https +LABEL maintainer="NGINX Docker Maintainers " # Download certificate and key from the customer portal (https://cs.nginx.com) # and copy to the build context -ADD nginx-repo.crt /etc/ssl/nginx/ -ADD nginx-repo.key /etc/ssl/nginx/ - -# Get other files required for installation -RUN wget -q -O /etc/ssl/nginx/CA.crt https://cs.nginx.com/static/files/CA.crt -RUN wget -q -O - http://nginx.org/keys/nginx_signing.key | apt-key add - -RUN wget -q -O /etc/apt/apt.conf.d/90nginx https://cs.nginx.com/static/files/90nginx - -RUN printf "deb https://plus-pkgs.nginx.com/ubuntu `lsb_release -cs` nginx-plus\n" >/etc/apt/sources.list.d/nginx-plus.list +COPY nginx-repo.crt /etc/ssl/nginx/ +COPY nginx-repo.key /etc/ssl/nginx/ # Install NGINX Plus -RUN apt-get update && apt-get install -y nginx-plus - -# forward request logs to Docker log collector -RUN ln -sf /dev/stdout /var/log/nginx/access.log -RUN ln -sf /dev/stderr /var/log/nginx/error.log +RUN set -x \ + && apt-get update && apt-get upgrade -y \ + && apt-get install --no-install-recommends --no-install-suggests -y apt-transport-https ca-certificates gnupg1 \ + && \ + NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \ + found=''; \ + for server in \ + ha.pool.sks-keyservers.net \ + hkp://keyserver.ubuntu.com:80 \ + hkp://p80.pool.sks-keyservers.net:80 \ + pgp.mit.edu \ + ; do \ + echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ + apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \ + done; \ + test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \ + echo "Acquire::https::plus-pkgs.nginx.com::Verify-Peer \"true\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::Verify-Host \"true\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::SslCert \"/etc/ssl/nginx/nginx-repo.crt\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::plus-pkgs.nginx.com::SslKey \"/etc/ssl/nginx/nginx-repo.key\";" >> /etc/apt/apt.conf.d/90nginx \ + && printf "deb https://plus-pkgs.nginx.com/debian stretch nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \ + && apt-get update && apt-get install -y nginx-plus \ + && apt-get remove --purge --auto-remove -y gnupg1 \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /etc/ssl/nginx + +# Forward request logs to Docker log collector +RUN ln -sf /dev/stdout /var/log/nginx/access.log \ + && ln -sf /dev/stderr /var/log/nginx/error.log EXPOSE 80 8080 443 +STOPSIGNAL SIGTERM + RUN rm -v /etc/nginx/conf.d/* -ADD app.conf /etc/nginx/conf.d/app.conf -ADD logo.png /usr/share/nginx/html/logo.png +COPY app.conf /etc/nginx/conf.d/app.conf CMD ["nginx", "-g", "daemon off;"] diff --git a/zookeeper-demo/nginxplus/app.conf b/zookeeper-demo/nginxplus/app.conf index 8becedf4..cde8a042 100644 --- a/zookeeper-demo/nginxplus/app.conf +++ b/zookeeper-demo/nginxplus/app.conf @@ -1,46 +1,33 @@ - upstream backend { - zone upstream_backend 64k; - state /tmp/upstream.conf; - } - - match hello { - status 200; - header Content-Type = text/html; - body ~ "Hello"; - } - - server { - listen 80; - status_zone backend; - - location / { - health_check match=hello; - proxy_pass http://backend; - } - - location /upstream_conf { - upstream_conf; - - #allow 127.0.0.1; # permit access from localhost - #deny all; # deny access from everywhere else - } - } - - server { - listen 8080; - root /usr/share/nginx/html; - access_log off; - - # Redirect requests for / to /status.html - location = / { - return 301 /status.html; - } - - location = /status.html { } - - # Everything beginning with /status (except for /status.html) is - # processed by the status handler - location /status { - status; - } - } +upstream backend { + zone upstream_backend 64k; + state /tmp/upstream.conf; +} + +match hello { + status 200; + header Content-Type = text/html; + body ~ "Hello"; +} + +server { + listen 80; + status_zone backend; + + location / { + proxy_pass http://backend; + health_check interval=2s match=hello; + } +} + +server { + listen 8080; + root /usr/share/nginx/html; + + location /api { + api write=on; + } + + location = / { + return 301 /dashboard.html; + } +} diff --git a/zookeeper-demo/nginxplus/logo.png b/zookeeper-demo/nginxplus/logo.png deleted file mode 100644 index b2f48c4d5d41aa35e3d64b1e37c75aadb5566dbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12587 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 N07*qoM6N<$f(lBXo;&~m diff --git a/zookeeper-demo/provision.sh b/zookeeper-demo/provision.sh index fb8c5ed5..6c219770 100755 --- a/zookeeper-demo/provision.sh +++ b/zookeeper-demo/provision.sh @@ -1,10 +1,9 @@ #!/bin/bash - if [ ${HOST_IP} ]; then - ipaddr=${HOST_IP} + echo "HOST_IP=${HOST_IP}" else - ipaddr=`/sbin/ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'` + ipaddr=$(ip -f inet a show enp0s8 | grep -oP "(?<=inet ).+(?=\/)") + echo "export HOST_IP=$ipaddr" | tee -a ~/.bash_aliases + . ~/.bash_aliases + /usr/local/bin/docker-compose -f /srv/NGINX-Demos/zookeeper-demo/docker-compose.yml up -d fi -echo "export HOST_IP=$ipaddr" | tee -a ~/.bash_aliases -. ~/.bash_aliases -/usr/local/bin/docker-compose up -d diff --git a/zookeeper-demo/setup_zookeeper_demo.yml b/zookeeper-demo/setup_zookeeper_demo.yml index a9e20ac5..48236c2e 100644 --- a/zookeeper-demo/setup_zookeeper_demo.yml +++ b/zookeeper-demo/setup_zookeeper_demo.yml @@ -1,47 +1,37 @@ - hosts: all - sudo: true + become: true tasks: - - - name: Setup Zookeeper Demo | Install curl from apt - apt: update_cache=yes pkg=curl - - - name: Setup Zookeeper Demo | Install git from apt - apt: update_cache=yes pkg=git - - - name: Setup Zookeeper Demo | Install docker.io from apt - shell: curl -sSL https://get.docker.com/ | sh - - - name: Setup Zookeeper Demo | Install docker-compose - shell: curl -L https://github.com/docker/compose/releases/download/1.10.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose - - - name: Setup Zookeeper Demo | Apply executable permissions to the docker-compose binary - shell: chmod +x /usr/local/bin/docker-compose - - - name: Setup Zookeeper Demo | Copy docker-compose under /etc/bash_completion. - shell: curl -L https://raw.githubusercontent.com/docker/compose/1.10.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose - - - name: NGINX Plus | Copying NGINX Plus repository certificate - copy: src=files/nginx-repo.crt dest=/srv/NGINX-Demos/zookeeper-demo/nginxplus/nginx-repo.crt - - - name: NGINX Plus | Copying NGINX Plus repository key - copy: src=files/nginx-repo.key dest=/srv/NGINX-Demos/zookeeper-demo/nginxplus/nginx-repo.key - - - name: Setup Zookeeper Demo | Executing provision.sh (sets HOST_IP, builds the container images and starts them). This step will take a while the first time since its going to download & build few big docker images... - shell: ./provision.sh - args: - chdir: /srv/NGINX-Demos/zookeeper-demo/ - + - name: Setup Zookeeper Demo | Install curl and git from apt + apt: + update_cache: yes + name: + - curl + - git + - name: Setup Zookeeper Demo | Download docker.io install script + get_url: + url: https://get.docker.com + dest: /tmp/get-docker.sh + mode: +x + - name: Setup Zookeeper Demo | Install docker + shell: /tmp/get-docker.sh + - name: Setup Zookeeper Demo | Delete docker.io install script + file: + path: /tmp/get-docker.sh + state: absent + - name: Setup Zookeeper Demo | Download docker-compose + get_url: + url: https://github.com/docker/compose/releases/download/1.23.2/docker-compose-Linux-x86_64 + dest: /usr/local/bin/docker-compose + mode: +x + - name: Setup Zookeeper Demo | Copy docker-compose under /etc/bash_completion + get_url: + url: https://raw.githubusercontent.com/docker/compose/1.23.2/contrib/completion/bash/docker-compose + dest: /etc/bash_completion.d/docker-compose + - name: Setup Zookeeper Demo | Executing provision.sh (sets HOST_IP, builds the container images and starts them) + shell: /srv/NGINX-Demos/zookeeper-demo/provision.sh - name: Setup Zookeeper Demo | Create a dummy znode under /services path inside the zk container shell: docker exec -i zookeeper ./zk-tool create /services -d abc - args: - chdir: /srv/NGINX-Demos/zookeeper-demo/zookeeper - - name: Setup Zookeeper Demo | Watch for changes under /services/http path inside the zk container shell: docker exec -i zookeeper ./zk-tool watch-children /services/http & - args: - chdir: /srv/NGINX-Demos/zookeeper-demo/zookeeper - - - name: Setup Zookeeper Demo | Spin up the two NGINX hello containers which will act as NGINX Plus upstreams - shell: /usr/local/bin/docker-compose -f create-http-service.yml up -d - args: - chdir: /srv/NGINX-Demos/zookeeper-demo/ + - name: Setup Zookeeper Demo | Spin up the nginxdemos/hello container which is the backend http service + shell: /usr/local/bin/docker-compose -f /srv/NGINX-Demos/zookeeper-demo/create-http-service.yml up -d diff --git a/zookeeper-demo/zookeeper/Dockerfile b/zookeeper-demo/zookeeper/Dockerfile index bf0c32fb..dd879236 100644 --- a/zookeeper-demo/zookeeper/Dockerfile +++ b/zookeeper-demo/zookeeper/Dockerfile @@ -1,42 +1,54 @@ -FROM ubuntu:14.04 -MAINTAINER Kunal Pariani +# For Ubuntu 18 +FROM ubuntu:bionic -LABEL name="zookeeper" version="3.4.11" +LABEL name="zookeeper" version="3.4.13" -RUN apt-get update && apt-get install -y software-properties-common wget curl bash +# Install required software +RUN apt-get update && apt-get install -y software-properties-common jq wget curl gnupg2 # Setup the openjdk 8 repo RUN add-apt-repository ppa:openjdk-r/ppa + # Install java8 -RUN apt-get update && apt-get install -y openjdk-8-jdk jq +RUN apt-get update && apt-get install -y openjdk-8-jdk + # Setup JAVA_HOME, this is useful for docker commandline ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/ + RUN export JAVA_HOME -RUN wget -q -O - http://apache.mirrors.pair.com/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz | tar -xzf - -C /opt \ - && mv /opt/zookeeper-3.4.11 /opt/zookeeper \ - && cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg \ - && mkdir -p /tmp/zookeeper +RUN wget -q -O - https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz | tar -xzf - -C /opt \ + && mv /opt/zookeeper-3.4.13 /opt/zookeeper \ + && cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg \ + && mkdir -p /tmp/zookeeper -# Copy over zk-tool and script.sh -ADD zk-tool /opt/zookeeper/ -ADD script.sh /opt/zookeeper/ +# Copy over zk-tool and script.sh +COPY zk-tool /opt/zookeeper/ +COPY script.sh /opt/zookeeper/ # Install ruby using RVM # Install RVM first -RUN /bin/bash -c "curl -sSL https://rvm.io/mpapis.asc | gpg --import - \ - && curl -L get.rvm.io | bash -s stable \ - && source /etc/profile.d/rvm.sh \ - && rvm install 2.1.4 \ - && rvm use 2.1.4 --default" +RUN /bin/bash -xc \ + 'for server in \ + ha.pool.sks-keyservers.net \ + hkp://keyserver.ubuntu.com:80 \ + hkp://p80.pool.sks-keyservers.net:80 \ + pgp.mit.edu \ + ; do \ + gpg2 --keyserver "$server" --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB; \ + done; \ + curl -sSL https://get.rvm.io | bash -s stable \ + && source /etc/profile.d/rvm.sh \ + && rvm install 2.6.0 \ + && rvm use 2.6.0 --default' ENV RVM_HOME /usr/local/rvm -ENV RUBY_HOME /usr/local/rvm/rubies/ruby-2.1.4 +ENV RUBY_HOME /usr/local/rvm/rubies/ruby-2.6.0 ENV PATH $PATH:$RVM_HOME/bin:$RUBY_HOME/bin # Install the ruby gems required for zk-tool RUN gem install thor \ - && gem install zk + && gem install zk EXPOSE 2181 2888 3888 WORKDIR /opt/zookeeper diff --git a/zookeeper-demo/zookeeper/script.sh b/zookeeper-demo/zookeeper/script.sh index 31389154..9c458b09 100755 --- a/zookeeper-demo/zookeeper/script.sh +++ b/zookeeper-demo/zookeeper/script.sh @@ -1,62 +1,61 @@ #!/bin/bash if [[ -z "$HOST_IP" ]]; then - echo "HOST_IP not set inside zookeeper container. Setting it to 10.2.2.70 (IP address assigned in the Vagrantfile)" - HOST_IP=10.2.2.70 + echo "HOST_IP not set inside zookeeper container. Setting it to 10.2.2.70 (IP address assigned in the Vagrantfile)" + HOST_IP=10.2.2.70 fi CURL='/usr/bin/curl' OPTIONS='-s' ZK_LIST_SERVICES="./zk-tool list /services" -STATUS_UPSTREAMS_API="http://$HOST_IP:8080/status/upstreams" -UPSTREAM_CONF_API="http://$HOST_IP/upstream_conf?" +STATUS_UPSTREAMS_API="http://$HOST_IP:8080/api/3/http/upstreams" -# Get the list of current Nginx upstreams -upstreams=$($CURL $OPTIONS $STATUS_UPSTREAMS_API | jq -r '. as $in| keys[]') -servers=$($CURL $OPTIONS {$UPSTREAM_CONF_API}upstream=$upstreams) -echo "Nginx upstreams in upstream group $upstreams:" +# Get the list of current NGINX upstreams +upstreams=$($CURL $OPTIONS $STATUS_UPSTREAMS_API | jq -r '. as $in | keys[]') +servers=$($CURL $OPTIONS ${STATUS_UPSTREAMS_API}/${upstreams}/servers) +echo "NGINX upstreams in $upstreams:" echo $servers # Loop through the registered servers in ZK tagged with production (i.e backend servers to be proxied through nginx) -# add the ones not present in the Nginx upstream block +# add the ones not present in the NGINX upstream block echo "Servers registered with ZK:" ip=$HOST_IP ports=$($ZK_LIST_SERVICES | grep production | jq '.PublicPort') for port in $ports; do - entry=$ip:$port - echo $entry - if [[ ! $servers =~ $entry ]]; then - $CURL $OPTIONS "{$UPSTREAM_CONF_API}add=&upstream=$upstreams&server=$entry" - echo "Added $entry to the nginx upstream group $upstreams!" - fi + entry=$ip:$port + echo $entry + if [[ ! $servers =~ $entry ]]; then + $CURL -X POST -d '{"server": "'$entry'"}' $OPTIONS "${STATUS_UPSTREAMS_API}/${upstreams}/servers" + echo "Added $entry to the nginx upstream group $upstreams!" + fi done -# Loop through the Nginx upstreams and remove the ones not present in ZK -servers=$($CURL $OPTIONS {$UPSTREAM_CONF_API}upstream=$upstreams) +# Loop through the NGINX upstreams and remove the ones not present in ZK +servers=($($CURL $OPTIONS ${STATUS_UPSTREAMS_API}/${upstreams}/servers | jq -c '.[]')) for params in ${servers[@]}; do - if [[ $params =~ ":" ]]; then - server=$params - continue - elif [[ $params =~ "id=" ]]; then - id=$params + if [[ $params =~ "server" ]]; then + server=$(echo $params | jq '.server') + continue + elif [[ $params =~ "id" ]]; then + id=$(echo $params | jq '.id') + else + continue + fi + + ports=$($ZK_LIST_SERVICES | grep production | jq '.PublicPort') + found=0 + for port in $ports; do + entry=$ip:$port + if [[ $server =~ $entry ]]; then + echo "$server matches zk entry $entry" + found=1 + break else - continue + continue fi + done - ports=$($ZK_LIST_SERVICES | grep production | jq '.PublicPort') - found=0 - for port in $ports; do - entry=$ip:$port - if [[ $server =~ $entry ]]; then - #echo "$server matches zk entry $entry" - found=1 - break - else - continue - fi - done - - if [ $found -eq 0 ]; then - $CURL $OPTIONS "{$UPSTREAM_CONF_API}remove=&upstream=$upstreams&$id" - echo "Removed $server # $id from nginx upstream block $upstreams!" - fi + if [ $found -eq 0 ]; then + $CURL -X DELETE $OPTIONS "{$STATUS_UPSTREAMS_API}/$upstreams/servers/$id" + echo "Removed $server # $id from NGINX upstream block $upstreams!" + fi done