Added folders as well...
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
version: "3.3"
|
||||
services:
|
||||
agile-redis:
|
||||
image: 127.0.0.1:5000/agile-redis
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./agile-redis-Dockerfile.yml
|
||||
ports:
|
||||
- "6379:6379"
|
||||
@@ -0,0 +1,9 @@
|
||||
FROM redis:5
|
||||
|
||||
COPY agile-redis-entrypoint.sh /usr/local/bin/
|
||||
|
||||
RUN chmod +x /usr/local/bin/agile-redis-entrypoint.sh
|
||||
|
||||
VOLUME /etc/redis
|
||||
|
||||
ENTRYPOINT ["agile-redis-entrypoint.sh"]
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
CONF_FILE=/etc/redis/redis.conf
|
||||
|
||||
if [ ! -f $CONF_FILE ]
|
||||
then
|
||||
echo "appendonly yes" > $CONF_FILE
|
||||
|
||||
if [ -n "$REDIS_MASTER_HOST" ]
|
||||
then
|
||||
echo "slaveof $REDIS_MASTER_HOST ${REDIS_MASTER_PORT:-6379}" >> $CONF_FILE
|
||||
fi
|
||||
chown redis:redis $CONF_FILE
|
||||
fi
|
||||
|
||||
exec docker-entrypoint.sh redis-server /etc/redis/redis.conf
|
||||
@@ -0,0 +1,9 @@
|
||||
version: "3.3"
|
||||
services:
|
||||
agile-redis:
|
||||
image: 127.0.0.1:5000/agile-redis-sentinel
|
||||
ports:
|
||||
- '26379:26379'
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./agile-redis-sentinel-Dockerfile.yml
|
||||
@@ -0,0 +1,23 @@
|
||||
FROM redis:5
|
||||
|
||||
EXPOSE 26379
|
||||
|
||||
ADD agile-redis-sentinel.conf /etc/redis/sentinel.conf
|
||||
|
||||
RUN chown redis:redis /etc/redis/sentinel.conf
|
||||
|
||||
ENV REDIS_MASTER_NAME=mymaster \
|
||||
REDIS_MASTER_HOST=redis-master \
|
||||
REDIS_MASTER_PORT=6379 \
|
||||
SENTINEL_QUORUM=2 \
|
||||
SENTINEL_DOWN_AFTER=30000\
|
||||
SENTINEL_PARALLEL_SYNC=1 \
|
||||
SENTINEL_FAILOVER_TIMEOUT=180000
|
||||
|
||||
COPY agile-redis-sentinel-entrypoint.sh /usr/local/bin/
|
||||
|
||||
RUN chmod +x /usr/local/bin/agile-redis-sentinel-entrypoint.sh
|
||||
|
||||
VOLUME /etc/redis
|
||||
|
||||
ENTRYPOINT ["agile-redis-sentinel-entrypoint.sh"]
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
sed -i "s/\$REDIS_MASTER_NAME/$REDIS_MASTER_NAME/g" /etc/redis/sentinel.conf
|
||||
sed -i "s/\$REDIS_MASTER_HOST/$REDIS_MASTER_HOST/g" /etc/redis/sentinel.conf
|
||||
sed -i "s/\$REDIS_MASTER_PORT/$REDIS_MASTER_PORT/g" /etc/redis/sentinel.conf
|
||||
sed -i "s/\$SENTINEL_QUORUM/$SENTINEL_QUORUM/g" /etc/redis/sentinel.conf
|
||||
sed -i "s/\$SENTINEL_DOWN_AFTER/$SENTINEL_DOWN_AFTER/g" /etc/redis/sentinel.conf
|
||||
sed -i "s/\$SENTINEL_PARALLEL_SYNC/$SENTINEL_PARALLEL_SYNC/g" /etc/redis/sentinel.conf
|
||||
sed -i "s/\$SENTINEL_FAILOVER_TIMEOUT/$SENTINEL_FAILOVER_TIMEOUT/g" /etc/redis/sentinel.conf
|
||||
exec docker-entrypoint.sh redis-server /etc/redis/sentinel.conf --sentinel
|
||||
@@ -0,0 +1,195 @@
|
||||
# Example sentinel.conf (from http://download.redis.io/redis-stable/sentinel.conf)
|
||||
|
||||
# *** IMPORTANT ***
|
||||
#
|
||||
# By default Sentinel will not be reachable from interfaces different than
|
||||
# localhost, either use the 'bind' directive to bind to a list of network
|
||||
# interfaces, or disable protected mode with "protected-mode no" by
|
||||
# adding it to this configuration file.
|
||||
#
|
||||
# Before doing that MAKE SURE the instance is protected from the outside
|
||||
# world via firewalling or other means.
|
||||
#
|
||||
# For example you may use one of the following:
|
||||
#
|
||||
# bind 127.0.0.1 192.168.1.1
|
||||
#
|
||||
# protected-mode no
|
||||
|
||||
# port <sentinel-port>
|
||||
# The port that this sentinel instance will run on
|
||||
port 26379
|
||||
|
||||
# sentinel announce-ip <ip>
|
||||
# sentinel announce-port <port>
|
||||
#
|
||||
# The above two configuration directives are useful in environments where,
|
||||
# because of NAT, Sentinel is reachable from outside via a non-local address.
|
||||
#
|
||||
# When announce-ip is provided, the Sentinel will claim the specified IP address
|
||||
# in HELLO messages used to gossip its presence, instead of auto-detecting the
|
||||
# local address as it usually does.
|
||||
#
|
||||
# Similarly when announce-port is provided and is valid and non-zero, Sentinel
|
||||
# will announce the specified TCP port.
|
||||
#
|
||||
# The two options don't need to be used together, if only announce-ip is
|
||||
# provided, the Sentinel will announce the specified IP and the server port
|
||||
# as specified by the "port" option. If only announce-port is provided, the
|
||||
# Sentinel will announce the auto-detected local IP and the specified port.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# sentinel announce-ip $SENTINEL_IP
|
||||
|
||||
# dir <working-directory>
|
||||
# Every long running process should have a well-defined working directory.
|
||||
# For Redis Sentinel to chdir to /tmp at startup is the simplest thing
|
||||
# for the process to don't interfere with administrative tasks such as
|
||||
# unmounting filesystems.
|
||||
dir /tmp
|
||||
|
||||
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
|
||||
#
|
||||
# Tells Sentinel to monitor this master, and to consider it in O_DOWN
|
||||
# (Objectively Down) state only if at least <quorum> sentinels agree.
|
||||
#
|
||||
# Note that whatever is the ODOWN quorum, a Sentinel will require to
|
||||
# be elected by the majority of the known Sentinels in order to
|
||||
# start a failover, so no failover can be performed in minority.
|
||||
#
|
||||
# Slaves are auto-discovered, so you don't need to specify slaves in
|
||||
# any way. Sentinel itself will rewrite this configuration file adding
|
||||
# the slaves using additional configuration options.
|
||||
# Also note that the configuration file is rewritten when a
|
||||
# slave is promoted to master.
|
||||
#
|
||||
# Note: master name should not include special characters or spaces.
|
||||
# The valid charset is A-z 0-9 and the three characters ".-_".
|
||||
sentinel monitor $REDIS_MASTER_NAME $REDIS_MASTER_HOST $REDIS_MASTER_PORT $SENTINEL_QUORUM
|
||||
|
||||
# sentinel auth-pass <master-name> <password>
|
||||
#
|
||||
# Set the password to use to authenticate with the master and slaves.
|
||||
# Useful if there is a password set in the Redis instances to monitor.
|
||||
#
|
||||
# Note that the master password is also used for slaves, so it is not
|
||||
# possible to set a different password in masters and slaves instances
|
||||
# if you want to be able to monitor these instances with Sentinel.
|
||||
#
|
||||
# However you can have Redis instances without the authentication enabled
|
||||
# mixed with Redis instances requiring the authentication (as long as the
|
||||
# password set is the same for all the instances requiring the password) as
|
||||
# the AUTH command will have no effect in Redis instances with authentication
|
||||
# switched off.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# sentinel auth-pass $REDIS_MASTER_NAME MySUPER--secret-0123passw0rd
|
||||
|
||||
# sentinel down-after-milliseconds <master-name> <milliseconds>
|
||||
#
|
||||
# Number of milliseconds the master (or any attached slave or sentinel) should
|
||||
# be unreachable (as in, not acceptable reply to PING, continuously, for the
|
||||
# specified period) in order to consider it in S_DOWN state (Subjectively
|
||||
# Down).
|
||||
#
|
||||
# Default is 30 seconds.
|
||||
sentinel down-after-milliseconds $REDIS_MASTER_NAME $SENTINEL_DOWN_AFTER
|
||||
|
||||
# sentinel parallel-syncs <master-name> <numslaves>
|
||||
#
|
||||
# How many slaves we can reconfigure to point to the new slave simultaneously
|
||||
# during the failover. Use a low number if you use the slaves to serve query
|
||||
# to avoid that all the slaves will be unreachable at about the same
|
||||
# time while performing the synchronization with the master.
|
||||
sentinel parallel-syncs $REDIS_MASTER_NAME $SENTINEL_PARALLEL_SYNC
|
||||
|
||||
# sentinel failover-timeout <master-name> <milliseconds>
|
||||
#
|
||||
# Specifies the failover timeout in milliseconds. It is used in many ways:
|
||||
#
|
||||
# - The time needed to re-start a failover after a previous failover was
|
||||
# already tried against the same master by a given Sentinel, is two
|
||||
# times the failover timeout.
|
||||
#
|
||||
# - The time needed for a slave replicating to a wrong master according
|
||||
# to a Sentinel current configuration, to be forced to replicate
|
||||
# with the right master, is exactly the failover timeout (counting since
|
||||
# the moment a Sentinel detected the misconfiguration).
|
||||
#
|
||||
# - The time needed to cancel a failover that is already in progress but
|
||||
# did not produced any configuration change (SLAVEOF NO ONE yet not
|
||||
# acknowledged by the promoted slave).
|
||||
#
|
||||
# - The maximum time a failover in progress waits for all the slaves to be
|
||||
# reconfigured as slaves of the new master. However even after this time
|
||||
# the slaves will be reconfigured by the Sentinels anyway, but not with
|
||||
# the exact parallel-syncs progression as specified.
|
||||
#
|
||||
# Default is 3 minutes.
|
||||
sentinel failover-timeout $REDIS_MASTER_NAME $SENTINEL_FAILOVER_TIMEOUT
|
||||
|
||||
# SCRIPTS EXECUTION
|
||||
#
|
||||
# sentinel notification-script and sentinel reconfig-script are used in order
|
||||
# to configure scripts that are called to notify the system administrator
|
||||
# or to reconfigure clients after a failover. The scripts are executed
|
||||
# with the following rules for error handling:
|
||||
#
|
||||
# If script exits with "1" the execution is retried later (up to a maximum
|
||||
# number of times currently set to 10).
|
||||
#
|
||||
# If script exits with "2" (or an higher value) the script execution is
|
||||
# not retried.
|
||||
#
|
||||
# If script terminates because it receives a signal the behavior is the same
|
||||
# as exit code 1.
|
||||
#
|
||||
# A script has a maximum running time of 60 seconds. After this limit is
|
||||
# reached the script is terminated with a SIGKILL and the execution retried.
|
||||
|
||||
# NOTIFICATION SCRIPT
|
||||
#
|
||||
# sentinel notification-script <master-name> <script-path>
|
||||
#
|
||||
# Call the specified notification script for any sentinel event that is
|
||||
# generated in the WARNING level (for instance -sdown, -odown, and so forth).
|
||||
# This script should notify the system administrator via email, SMS, or any
|
||||
# other messaging system, that there is something wrong with the monitored
|
||||
# Redis systems.
|
||||
#
|
||||
# The script is called with just two arguments: the first is the event type
|
||||
# and the second the event description.
|
||||
#
|
||||
# The script must exist and be executable in order for sentinel to start if
|
||||
# this option is provided.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# sentinel notification-script $REDIS_MASTER_NAME /var/redis/notify.sh
|
||||
|
||||
# CLIENTS RECONFIGURATION SCRIPT
|
||||
#
|
||||
# sentinel client-reconfig-script <master-name> <script-path>
|
||||
#
|
||||
# When the master changed because of a failover a script can be called in
|
||||
# order to perform application-specific tasks to notify the clients that the
|
||||
# configuration has changed and the master is at a different address.
|
||||
#
|
||||
# The following arguments are passed to the script:
|
||||
#
|
||||
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
|
||||
#
|
||||
# <state> is currently always "failover"
|
||||
# <role> is either "leader" or "observer"
|
||||
#
|
||||
# The arguments from-ip, from-port, to-ip, to-port are used to communicate
|
||||
# the old address of the master and the new address of the elected slave
|
||||
# (now a master).
|
||||
#
|
||||
# This script should be resistant to multiple invocations.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# sentinel client-reconfig-script $REDIS_MASTER_NAME /var/redis/reconfig.sh
|
||||
@@ -0,0 +1,76 @@
|
||||
version: "3.3"
|
||||
services:
|
||||
|
||||
redis-sentinel:
|
||||
image: 127.0.0.1:5000/agile-redis-sentinel
|
||||
volumes:
|
||||
- sentinel-conf:/etc/redis
|
||||
deploy:
|
||||
mode: global
|
||||
environment:
|
||||
- REDIS_MASTER_HOST=${REDIS_MASTER_IP}
|
||||
- SENTINEL_DOWN_AFTER=5000
|
||||
- SENTINEL_FAILOVER=15000
|
||||
networks:
|
||||
- host
|
||||
|
||||
redis-master:
|
||||
image: 127.0.0.1:5000/agile-redis
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
- redis-conf:/etc/redis
|
||||
deploy:
|
||||
mode: global
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == ${REDIS_MASTER_HOSTNAME}
|
||||
networks:
|
||||
- host
|
||||
|
||||
redis-slave-node1:
|
||||
image: 127.0.0.1:5000/agile-redis
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
- redis-conf:/etc/redis
|
||||
environment:
|
||||
- REDIS_MASTER_HOST=${REDIS_MASTER_IP}
|
||||
deploy:
|
||||
mode: global
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == ${REDIS_SLAVE_NODE1_HOSTNAME}
|
||||
networks:
|
||||
- host
|
||||
|
||||
redis-slave-node2:
|
||||
image: 127.0.0.1:5000/agile-redis
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
- redis-conf:/etc/redis
|
||||
environment:
|
||||
- REDIS_MASTER_HOST=${REDIS_MASTER_IP}
|
||||
deploy:
|
||||
mode: global
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == ${REDIS_SLAVE_NODE2_HOSTNAME}
|
||||
networks:
|
||||
- host
|
||||
|
||||
agile-python-app:
|
||||
image: 127.0.0.1:5000/agile-python-app
|
||||
ports:
|
||||
- "38000:611"
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 3
|
||||
environment:
|
||||
- SENTINEL_HOST=${SENTINEL_IP}
|
||||
|
||||
volumes:
|
||||
redis-data:
|
||||
redis-conf:
|
||||
sentinel-conf:
|
||||
networks:
|
||||
host:
|
||||
external: true
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
echo "--------------------------------------------------------------------------------------------------------------"
|
||||
echo " REDIS STACK DEPLOYMENT "
|
||||
echo "--------------------------------------------------------------------------------------------------------------"
|
||||
|
||||
export SENTINEL_HOSTNAME=$1 #serveur17
|
||||
export REDIS_MASTER_HOSTNAME=$2 #serveur17
|
||||
export REDIS_SLAVE_NODE1_HOSTNAME=$3 #serveur18
|
||||
export REDIS_SLAVE_NODE2_HOSTNAME=$4 #serveur19
|
||||
|
||||
if [ -z $SENTINEL_HOSTNAME ] || [ -z $REDIS_MASTER_HOSTNAME ] || [ -z $REDIS_SLAVE_NODE1_HOSTNAME ] || [ -z $REDIS_SLAVE_NODE2_HOSTNAME ] ; then
|
||||
echo "Status: Arguments missing. Cannot continue to build the stack. Missing SENTINEL_HOSTNAME, REDIS_MASTER_HOSTNAME, REDIS_SLAVE_NODE1_HOSTNAME, REDIS_SLAVE_NODE1_HOSTNAME" >&2
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
|
||||
echo "1- Start to push on registry the redis docker image which can be used as master or slave in the stack..."
|
||||
docker compose -f agile-redis-master-slave/agile-redis-Dockercompose.yml build
|
||||
docker compose -f agile-redis-master-slave/agile-redis-Dockercompose.yml push
|
||||
echo "(1)End to build and push redis image to registry."
|
||||
echo "-------------------------------------------------------\n"
|
||||
|
||||
echo "2- Start to push on registry the redis docker image which will be used to build sentinel..."
|
||||
docker compose -f agile-redis-sentinel/agile-redis-sentinel-Dockercompose.yml build
|
||||
docker compose -f agile-redis-sentinel/agile-redis-sentinel-Dockercompose.yml push
|
||||
echo "(2)End to build and push redis sentinel image to registry."
|
||||
echo "-------------------------------------------------------\n"
|
||||
|
||||
|
||||
echo "3- Start to push our python app example on the registry..."
|
||||
docker compose -f python-app-example/compose-app.yml build
|
||||
docker compose -f python-app-example/compose-app.yml push
|
||||
echo "(3)End to push our python app example on the registry."
|
||||
echo "-------------------------------------------------------\n"
|
||||
|
||||
|
||||
echo "4- Start to deploy the stack..."
|
||||
export SENTINEL_IP=`docker node inspect --format {{.Status.Addr}} $SENTINEL_HOSTNAME`
|
||||
export REDIS_MASTER_IP=`docker node inspect --format {{.Status.Addr}} $REDIS_MASTER_HOSTNAME`
|
||||
|
||||
echo "Sentinel hostname and IP: $SENTINEL_HOSTNAME - $SENTINEL_IP"
|
||||
echo "Redis Master hostname and IP: $REDIS_MASTER_HOSTNAME - $REDIS_MASTER_IP"
|
||||
echo "Redis slave 1 hostname: $REDIS_SLAVE_NODE1_HOSTNAME"
|
||||
echo "Redis slave 2 hostname: $REDIS_SLAVE_NODE2_HOSTNAME"
|
||||
|
||||
docker stack deploy -c agile-redis-stack.yml stackredis
|
||||
printf "(4)End to deploy the stack... Please wait until the services started\n\n\n"
|
||||
|
||||
sleep 3s
|
||||
|
||||
printf "Status: The stack deployment has been completed.\n\n"
|
||||
|
||||
|
||||
docker service ls
|
||||
printf "If all services replicas are not already deployed, please run << docker service ls >> to see if it now completed.\n"
|
||||
@@ -0,0 +1,24 @@
|
||||
from pypy:3-6
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Bundle app source
|
||||
COPY app.py /usr/src/app
|
||||
COPY requirements.txt /usr/src/app
|
||||
|
||||
RUN apt-get update
|
||||
|
||||
RUN apt-get install -y vim
|
||||
|
||||
# install requirements
|
||||
RUN pip install --upgrade pip
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
RUN mkdir -p /usr/src/logs
|
||||
|
||||
|
||||
EXPOSE 611
|
||||
|
||||
VOLUME ["/usr/src/app"]
|
||||
|
||||
ENTRYPOINT ["pypy3", "app.py"]
|
||||
@@ -0,0 +1,30 @@
|
||||
import os
|
||||
from flask import Flask
|
||||
from redis.sentinel import Sentinel
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
sentinelHost = os.environ.get("SENTINEL_HOST", None)
|
||||
sentinelPort = int(os.environ.get("SENTINEL_PORT", 26379))
|
||||
redisMasterName = os.environ.get("REDIS_MASTER_NAME", 'mymaster')
|
||||
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def hello():
|
||||
if sentinelHost is not None and sentinelPort is not None:
|
||||
try:
|
||||
sentinel = Sentinel([(sentinelHost, sentinelPort)], socket_timeout=0.1)
|
||||
redis_master = sentinel.master_for(redisMasterName, socket_timeout=0.1)
|
||||
redis_slave = sentinel.slave_for(redisMasterName, socket_timeout=0.1)
|
||||
|
||||
incr_and_return_count = redis_master.incr('hits')
|
||||
count_from_slave = redis_slave.get('hits')
|
||||
return 'Hello World! I have been seen {} times. Yes Yeah\n'.format(count_from_slave)
|
||||
except Exception as e:
|
||||
return sentinelHost+ " "+ str(sentinelPort) + 'Exception handled when started to perform actions: Details error {}\n'.format(e)
|
||||
else:
|
||||
return 'Environment variable sentinelHost or sentinelPort is not found or empty. \n'
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=611, debug=True)
|
||||
@@ -0,0 +1,7 @@
|
||||
version: "3.3"
|
||||
services:
|
||||
agile-python-app:
|
||||
image: 127.0.0.1:5000/agile-python-app
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./Dockerfile.yml
|
||||
@@ -0,0 +1,2 @@
|
||||
flask
|
||||
redis
|
||||
Reference in New Issue
Block a user