apache / apache/couchdb

docker/kubrenetes nodes discovery

Open
#2,142 9 comments 0 reactions 0 assignees View on GitHub
enhancement patches-welcome
Dominant language
Erlang
Stars
7k
Forks
1.1k
Avg merge
1d 16h
Merged PRs (30d)
9

Description

## Summary

I can create docker stack using this file
```yaml
version: "3.7"

networks:
main:

services:
couchdb:
image: couchdb:2.3.1
environment:
- NODENAME=couchdb-{{.Task.Slot}}
- COUCHDB_SECRET=monster
- ERL_FLAGS="-setcookie monster"
ports:
- "5984"
- "5986"
networks:
- main
deploy:
replicas: 5
```

And command
```sh
docker stack deploy --compose-file docker-compose.yaml kazoo
```
This will create
1. `kazoo_main` network
1. `couchdb` service
1. five couchdb containers with unique names

Could you implement following logic for couchdb node discovery and automatic cluster formation.

**resolv ${SEED_DNS_NAME}**
```sh
root@dbef6f82ce5f:/# nslookup ${SEED_DNS_NAME}
Server: 127.0.0.11
Address: 127.0.0.11#53

Non-authoritative answer:
Name: tasks.couchdb
Address: 10.0.52.7
Name: tasks.couchdb
Address: 10.0.52.6
Name: tasks.couchdb
Address: 10.0.52.5
Name: tasks.couchdb
Address: 10.0.52.4
Name: tasks.couchdb
Address: 10.0.52.3
```

Now we can couchdb nodes names
```sh
root@dbef6f82ce5f:/# curl http://10.0.52.3:5984/_membership
{"all_nodes":["couchdb@couchdb-5"],"cluster_nodes":["couchdb@couchdb-5"]}
root@dbef6f82ce5f:/# curl http://10.0.52.4:5984/_membership
{"all_nodes":["couchdb@couchdb-1"],"cluster_nodes":["couchdb@couchdb-1"]}
root@dbef6f82ce5f:/# curl http://10.0.52.5:5984/_membership
{"all_nodes":["couchdb@couchdb-2"],"cluster_nodes":["couchdb@couchdb-2"]}
root@dbef6f82ce5f:/# curl http://10.0.52.6:5984/_membership
{"all_nodes":["couchdb@couchdb-3"],"cluster_nodes":["couchdb@couchdb-3"]}
root@dbef6f82ce5f:/# curl http://10.0.52.7:5984/_membership
{"all_nodes":["couchdb@couchdb-4"],"cluster_nodes":["couchdb@couchdb-4"]}
```

Now we can join cluster nodes into cluster using commands
```
curl -X PUT "http://localhost:5986/_nodes/couchdb@couchdb-1/10.0.52.4" -d {}
curl -X PUT "http://localhost:5986/_nodes/couchdb@couchdb-2/10.0.52.5" -d {}
curl -X PUT "http://localhost:5986/_nodes/couchdb@couchdb-3/10.0.52.6" -d {}
curl -X PUT "http://localhost:5986/_nodes/couchdb@couchdb-4/10.0.52.7" -d {}
curl -X PUT "http://localhost:5986/_nodes/couchdb@couchdb-5/10.0.52.3" -d {}
```

Here I suggest extended command join syntax to use `runtime` containers IP address.

If couchdb node is restarted, then
1. node again resolve `${SEED_DNS_NAME}` and gets current couchdb nodes IP addresses;
1. request `/_node/_local/_system` resource from each IP and gets couchdb node
name behind each IP
1. update own map of couchdb nodes and their IP addresses

## Additional context

This feature may be used in `docker swarm` and `kubernetes` clouds.
In kubernetes need use statefulset + service like
```yaml
# file contains database headless service
# creates kubernetes dns records for database daemons
# required for database nodes discovery
apiVersion: v1
kind: Service
metadata:
name: db
spec:
type: ClusterIP
clusterIP: None
publishNotReadyAddresses: true
selector:
app: db
```
Kubernetes service yaml file must contain `publishNotReadyAddresses: true`

Contributor guide

Open the contributing guide

Research direction

Start with the proposed DNS lookup of ${SEED_DNS_NAME}, the CouchDB /_membership and /_node/_local/_system endpoints, and the _nodes join requests described in the issue. Define how discovery and automatic cluster formation should work for Docker Swarm and Kubernetes, including restart recovery; done means nodes can resolve peers, map their CouchDB names to IPs, join the cluster, and refresh that map.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, erlang, kubernetes
Domain
cloud, databases, distributed-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.