Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add environment variables to set up a cluster without manual steps #59

Open
JorritSalverda opened this issue Jan 12, 2017 · 10 comments
Open

Comments

@JorritSalverda
Copy link

JorritSalverda commented Jan 12, 2017

I'm trying to run couchbase/server:community-4.5.0 in a Kubernetes StatefulSet. It would be tremendously helpful if this docker image exposed a number of environment variables to configure the nodes automatically.

  • MASTER_NODE
  • PORT
  • RAM_SIZE_MB
  • INDEX_RAM_SIZE_MB
  • FTS_RAM_SIZE_MB
  • SERVICES
  • STORAGE_SETTING
  • USER
  • PASSWORD

On the first node to be created this action could initialize the cluster:

couchbase-cli cluster-init \
  --cluster-username=${USER} \
  --cluster-password=${PASSWORD} \
  --cluster-port=${PORT} \
  --services=${SERVICES} \
  --cluster-ramsize=${RAM_SIZE_MB} \
  --cluster-index-ramsize=${INDEX_RAM_SIZE_MB} \
  --cluster-fts-ramsize=${FTS_RAM_SIZE_MB} \
  --index-storage-setting=${STORAGE_SETTING}

On the other nodes they would run the following command to get added to the cluster:

couchbase-cli rebalance \
  --cluster=${MASTER_NODE}:${PORT} \
  --user=${USER} \
  --password=${PASSWORD} \
  --server-add=$(hostname):${PORT} \
  --server-add-username=${USER} \
  --server-add-password=${PASSWORD} \
  --service=${SERVICES}
@abacaphiliac
Copy link

+1

@tleyden
Copy link
Contributor

tleyden commented Mar 15, 2017

For a given container to figure out if they are the initial node, pretty sure it requires coordination or a global viewpoint of some sort.

Some work in progress that may be relevant:

https://github.com/couchbase/cbbootstrap
https://github.com/couchbase/sync-gateway-ami

@ceejatec
Copy link
Contributor

I think - although I'm not sure - that the request is for the container to read a series of environment variables and configure themselves accordingly. For instance, MASTER_NODE would generally be unset, and if it was unset, the container would assume it was meant to be the master node and configure itself as a single-node cluster with cluster-init, etc. If MASTER_NODE was set (via "docker run -e MASTER_NODE=xxx"), then the container would configure itself as a new node in an existing cluster, joining the cluster and triggering a rebalance.

Apologies to the OP if I'm misstating the intent.

I think it's a good idea in general, although it would take a little time to come up with the right set of knobs. For instance, the phrase "master node" isn't a good one since a Couchbase cluster comprises peers with no explicit master. Also I think PORT should probably be omitted, and all containers should assume everything is operating on default ports. Etc. But in general I like the idea, and it would as you say make it easier to set up clusters quickly.

@tleyden
Copy link
Contributor

tleyden commented Mar 16, 2017

@ceejatec ok thanks for the clarification, now it makes a little more sense.

@JorritSalverda what about a generic solution where you could stash a script in a special directory like /opt/couchbase/post-launch-hooks and it would call your script, and all environment variables that were set via the Docker CLI would be available?

So you would launch docker via:

docker run couchbase -v /host/path/to/post-launch-hook.sh:/opt/couchbase/post-launch-hooks/post-launch-hook.sh -e MASTER_NODE=MASTER_NODE -e .. etc

and then after Couchbase launches, your script would be invoked:


if MASTER_NODE:
    couchbase-cli rebalance \
       --cluster=${MASTER_NODE}:${PORT} \
       etc...
else
    couchbase-cli cluster-init \
       --cluster-username=${USER} \

and would pick up the environment variables that you set.

Would that work for your use case?

@tleyden
Copy link
Contributor

tleyden commented Mar 16, 2017

@ceejatec since /opt/couchbase/post-launch-hooks doesn't exist, do you know if it's possible to fork off a background process in entrypoint.sh and have that poll until couchbase launches and then perform an action.

For example:

post-launch-hook.sh

    WaitForCouchbaseServerLaunch()
    if MASTER_NODE:
         couchbase-cli cluster-init ..
         return 
    else:
         couchbase-cli rebalance ..
         return 

entrypoint.sh

#!/bin/bash
set -e

# Invoke post-launch-hook.sh and background it
post-launch-hook.sh &  

[[ "$1" == "couchbase-server" ]] && {
    echo "Starting Couchbase Server -- Web UI available at http://<ip>:8091 and logs available in /opt/couchbase/var/lib/couchbase/logs"
    exec /usr/sbin/runsvdir-start
}

exec "$@"

Or would that be frowned upon as non-best-practice for launching a process via docker? Is there any restrictions like the main process needs to be PID 1 or something like that? (vague memory)

I guess the other way to do a workaround such as this would be to use something like http://supervisord.org/

@corbinu
Copy link

corbinu commented Mar 17, 2017

So I believe that this does not violate best practice as my understanding as that the main process requirement is about making sure that you have 1 process per container to track if that process crashes. A backgrounded setup script would be fine since it's only Couchbase who's failure that needs to end the container (a perfect example of what not to do is try putting PHP/Apache/MySQL all in the same container as failure of any of the three processes should end the container).

It is a bit out of date but I could probably write a startup script based upon this old container I wrote. Obviously the script included here shouldn't depend on consul.
https://github.com/corbinu/consul-couchbase

@valeriomazzeo
Copy link

@asarkar
Copy link

asarkar commented Dec 13, 2017

We do something very similar to what shown by @JorritSalverda in Kubernetes. However, another option would be not to bake the initialization logic in the CB image, because it can get out of hand pretty fast, and use a "sidecar" container instead. You'd deploy another container that would run HTTP calls against CB master to do the work. Unfortunately, the CLI is not an independently distributed binary (no reason it can't be, just isn't), so REST is the only option from outside the CB container.

@ipaulbogdan
Copy link

5 years later no big updates...did any of you found a good way to init the db? I need it for local development and integration tests. I was expecting something like postgresql's docker-entrypoint-initdb.d to be supported.

@MartianH
Copy link

Hello, am having the same problem in docker-compose. I cannot seem to just give environment variables to at least have a working user.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants