How to run RedisInsight V2 and a Redis Cluster on Docker localhost using user-defined bridge?

414 Views Asked by At

We've noticed many peers are struggling with the RedisInsight V2 setup and a dockerized Redis Cluster on Windows. We are running Windows 11 and the latest Docker Desktop with WLS2 activated. Since macvlan, ipvlan and host network types are not available on Windows (development machines), we are somewhat limited.

Below we describe first how we are creating our local development setup. Which is fine - with the only caveat of the ugly if-statement in our python cluster connection.

Our Question: How are other windows teams developing locally for/with a Redis Cluster?

How we develop locally:

We pull up the cluster nodes with docker compose including a custom image of RedisInsight V2.

version: '3.8'
name: 'fa-redis-cluster-local'
services:
  node1:
    container_name: leader_1
    image: redis/redis-stack-server:latest
    ports:
      - "7000:6379"
      #- "8001:8001"
    volumes:
      - ./redis-data/node1:/data
    command: redis-server /data/redis-cluster.conf
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    networks:
      network_redis_cluster:
        ipv4_address: 172.30.0.11

  node2:
    container_name: leader_2
    image: redis/redis-stack-server:latest
    ports:
      - "7001:6379"
    volumes:
      - ./redis-data/node2:/data
    command: redis-server /data/redis-cluster.conf
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    networks:
      network_redis_cluster:
        ipv4_address: 172.30.0.12

  node3:
    container_name: leader_3
    image: redis/redis-stack-server:latest
    ports:
      - "7002:6379"
    volumes:
      - ./redis-data/node3:/data
    command: redis-server /data/redis-cluster.conf
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    networks:
      network_redis_cluster:
        ipv4_address: 172.30.0.13

  redisinsight:
    container_name: redisinsight
    image: oblakstudio/redisinsight:latest
    ports:
      - "8001:5000"
    depends_on:
      - node1
      - node2
      - node3
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    networks:
      network_redis_cluster:
        ipv4_address: 172.30.0.14

  # redisinsight:
  #   image: redislabs/redisinsight:latest
  #   ports:
  #     - "8001:8001"
  #   environment:
  #     - ALLOW_EMPTY_PASSWORD=yes
  #   networks:
  #     network_redis_cluster:
  #       ipv4_address: 172.30.0.14

networks:
  network_redis_cluster:
    name: network_redis_cluster
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.30.0.0/24
          gateway: 172.30.0.1

Then we create the cluster binding the nodes to each other:

docker exec -it leader_1 redis-cli --cluster create 172.30.0.11:6379 172.30.0.12:6379 172.30.0.13:6379 --cluster-replicas 0

We need to map the bridge network address/port with the localhost address/port in our python code BEFORE we can invoke a redis-cluster object.

from redis.cluster import RedisCluster, ClusterNode

nodes = [ClusterNode('127.0.0.1', 7000), ClusterNode('127.0.0.1', 7001), ClusterNode('127.0.0.1', 7002)]
if ENVIRONMENT == 'DEV':
    address_remap_dict = {
        "172.30.0.11:6379": ("127.0.0.1", 7000),
        "172.30.0.12:6379": ("127.0.0.1", 7001),
        "172.30.0.13:6379": ("127.0.0.1", 7002),
    }

    def address_remap(address):
        host, port = address
        return address_remap_dict.get(f"{host}:{port}", address)    

    # rc = RedisCluster(startup_nodes=nodes, decode_responses=True, skip_full_coverage_check=True)
    rc = RedisCluster(startup_nodes=nodes, decode_responses=True, skip_full_coverage_check=True, address_remap=address_remap)
else:
    rc = RedisCluster(startup_nodes=nodes, decode_responses=True, skip_full_coverage_check=True)

This works and we can connect to the cluster using our Python app.

INFO redis nodes: {'cluster_state': 'ok', 'cluster_slots_assigned': '16384', 'cluster_slots_ok': '16384', 'cluster_slots_pfail': '0', 'cluster_slots_fail': '0', 'cluster_known_nodes': '3', 'cluster_size': '3', 'cluster_current_epoch': '3', 'cluster_my_epoch': '1', 'cluster_stats_messages_ping_sent': '578', 'cluster_stats_messages_pong_sent': '649', 'cluster_stats_messages_sent': '1227', 'cluster_stats_messages_ping_received': '647', 'cluster_stats_messages_pong_received': '578', 'cluster_stats_messages_meet_received': '2', 'cluster_stats_messages_received': '1227'}

Now, we notice people tried to connect to the cluster having a host-installed RedisInsight V2 Version. That will not work, since you cannot reach the hosts within the bridged networks by hostname or ip, which Redis uses to answer the requests from RedisInsight. Thus, use the containerized RedisInsight V2 available on http://localhost:8001. Then add a database using one of the IPs of the nodes defined in the docker compose file. That is 172.30.0.11-13. Make sure you use the 6379 port for all of these IPs and not 7000-7002.

That does the trick(s). Is there anyone that has a better way

enter image description here

0

There are 0 best solutions below