docker - 如何告诉我的脚本等待 consul 选举领导者,然后再尝试在启动时向其添加键/值对?

标签 docker consul consul-template

我的开发环境由一个容器中的本地 consul 服务器和另一个容器中的应用程序(运行 consul-template)组成,所有这些都与 docker-compose 链接。我希望一切都无缝地启动并且无需手动干预开发(安全性不是问题),因此我想通过安装特定文件在启动时以编程方式将默认键/值对添加到 consul。

我一直遇到这个问题,每当我尝试在启动时使用 API 将 k/v 对添加到 consul 时,它都会失败并出现错误 2016/06/03 21:10:15 [ERR] http: Request PUT /v1/kv/app/secret_key, error: No cluster leader from=[::1]:58888 .如果我事先添加一个 sleep 命令,给 consul 足够的时间来选举领导者,它就可以工作。但是,必须有更好的方法来同步执行此操作,对吧?尤其是当集群中只有一个节点时。

这就是我到目前为止所拥有的。
Dockerfile

FROM voxxit/consul

ARG REFRESHED_AT="2016-06-01"
ARG DOCKERIZE_VERSION="v0.2.0"
ENV CONSUL_ADDR="http://localhost:8500"

ADD "https://github.com/jwilder/dockerize/releases/download/${DOCKERIZE_VERSION}/dockerize-linux-amd64-${DOCKERIZE_VERSION}.tar.gz" /tmp
RUN set -x && \
    apk add --update curl jq && \
    cd /tmp && \
    tar -C /usr/local/bin -xzvf dockerize-linux-amd64-${DOCKERIZE_VERSION}.tar.gz && \
    rm -rf /var/cache/apk/* /tmp/*

RUN mkdir -p /etc/consul.d/data
COPY ./consul.json /etc/consul.d/
COPY ./entrypoint.sh /
RUN chmod +x /entrypoint.sh

WORKDIR /etc/consul.d/data
VOLUME ["/etc/consul.d/data"]

ENTRYPOINT ["/entrypoint.sh"]
CMD ["dockerize", "-stdout", "/var/log/consul.out", "-stderr", "/var/log/consul.err"]
entrypoint.sh
#!/bin/bash -e

# Start consul server and wait for it
nohup consul agent -config-file=/etc/consul.d \
    >/var/log/consul.out 2>/var/log/consul.err &
dockerize -wait "${CONSUL_ADDR}" # <-- Not working as I'd hoped

DEFAULT_CONFIG="/etc/consul.d/data/default.json"

if [ -f $DEFAULT_CONFIG ]; then
    # Bulk upload default k/v pairs
    while IFS=" " read -r key value; do
        prefix="${APP_NAME}"
        result=$(curl -s -X PUT -d "$value" "${CONSUL_ADDR}/v1/kv/${prefix}/${key}")
        if [ "$result" != "true" ]; then
            echo "ERROR loading $value into $key for $prefix"
            exit 1
        fi
    done < <(jq -r 'to_entries|map("\(.key) \(.value|tostring)")|.[]' $DEFAULT_CONFIG)
fi

echo "init complete - ready for start up"
exec "$@"
consul.json
{
"bootstrap": true,
"client_addr": "0.0.0.0",
"data_dir": "/data",
"enable_syslog": false,
"log_level": "INFO",
"server": true,
"ui_dir": "/ui",
"http_api_response_headers": {
    "Access-Control-Allow-Origin": "*"
}
}

必须有某种方法可以暂停批量上传,直到我确定 consul 已启动并运行。

最佳答案

我遇到了类似的问题,我通过指定预期的 Consul 节点的数量(使用命令行参数 Bootstrap cannot be provided with an expected server count 而不是简单的 -bootstrap-expect=5 )解决了我的问题( -boostrap )在单个节点上。

关于docker - 如何告诉我的脚本等待 consul 选举领导者,然后再尝试在启动时向其添加键/值对?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37645610/

相关文章:

postgresql - Kubernetes PostgreSQL : How do I store config files elsewhere than the data directory?

docker - 使用容器时如何使用 flask-session 将 redis 设置为缓存?

python - 如何在 python 的 consul 中查找 dns 服务记录?

Docker 中的 NGINX 和 Consul 模板

templates - 在 consul-template 的循环中覆盖变量

docker - 在Docker容器内创建领事客户端代理时如何传递参数?

go - 如何从 map 中获取 key

networking - 调用 tcp : lookup xxx. xxx.xxx.xxx: 没有这样的主机

Docker 安装 : ImportError: cannot import name '_gi' from 'gi' (/usr/lib/python3/dist-packages/gi/__init__. py)

java - 即使无法联系发现服务器,是否有办法启动 Discovery 客户端 Spring 应用程序?