13

我正在用马拉松部署一个简单的 hello world nginx 容器,一切似乎都运行良好,除了我有 6 个不会从领事注销的容器。docker ps显示没有容器在运行。

我尝试使用/v1/catalog/deregister端点取消注册服务,但它们不断回来。然后我杀死了注册器容器,并再次尝试取消注册。他们回来了。

我正在运行注册器

docker run -d --name agent-registrator -v /var/run/docker.sock:/tmp/docker.sock --net=host gliderlabs/registrator consul://127.0.0.1:8500 -deregister-on-success -cleanup

有 1 个领事代理正在运行。

重新启动机器(这是本地 vm 上的单节点安装)不会使服务消失。

如何让这些容器消失?

4

6 回答 6

9

使用 http api 删除服务是另一个更好的解决方案。在我弄清楚如何使用 https api 之前,我只是想出了如何手动删除服务。

要使用 http api 删除服务,请使用以下命令: curl -v -X PUT http://<consul_ip_address>:8500/v1/agent/service/deregister/<ServiceID>

请注意,您是三件事的组合:运行容器的主机的 IP 地址、容器的名称和容器的内部端口(即 80 用于 apache,3000 用于节点 js,8000 用于 django,等)全部由科林斯分隔:

以下是实际情况的示例: curl -v -X PUT http://1.2.3.4:8500/v1/agent/service/deregister/192.168.1.1:sharp_apple:80

如果您想要一种简单的方法来获取 ServiceID,那么只需 curl 包含僵尸的服务: curl -s http://<consul_ip_address>:8500/v1/catalog/service/<your_services_name>

下面是一个名为 someapp 的服务的真实示例,它将返回其下的所有服务: curl -s http://1.2.3.4:8500/v1/catalog/service/someapp

于 2016-06-12T18:00:13.117 回答
2

不要使用目录,而不是使用代理,原因是目录由代理维护,即使您从目录中删除它也会由代理重新同步,删除僵尸服务 shell 脚本:

leader="$(curl http://ONE-OF-YOUR-CLUSTER:8500/v1/status/leader | sed 

's/:8300//' | sed 's/"//g')"
while :
do
serviceID="$(curl http://$leader:8500/v1/health/state/critical | ./jq '.[0].ServiceID' | sed 's/"//g')"
node="$(curl http://$leader:8500/v1/health/state/critical | ./jq '.[0].Node' | sed 's/"//g')"
echo "serviceID=$serviceID, node=$node"
size=${#serviceID}
echo "size=$size"
if [ $size -ge 7 ]; then
curl --request PUT http://$node:8500/v1/agent/service/deregister/$serviceID
else
break
fi
done
curl http://$leader:8500/v1/health/state/critical

json parser jq 用于字段检索

于 2018-02-08T06:19:35.490 回答
2

以下是如何彻底删除所有僵尸服务:进入您的领事服务器,找到包含僵尸的 json 文件的位置并删除它们。

例如,我在容器中运行 consul:

docker run --restart=unless-stopped -d -h consul0 --name consul0 -v /mnt:/data \
    -p $(hostname -i):8300:8300 \
    -p $(hostname -i):8301:8301 \
    -p $(hostname -i):8301:8301/udp \
    -p $(hostname -i):8302:8302 \
    -p $(hostname -i):8302:8302/udp \
    -p $(hostname -i):8400:8400 \
    -p $(hostname -i):8500:8500 \
    -p $(ifconfig docker0 | awk '/\<inet\>/ { print $2}' | cut -d: -f2):53:53/udp \
    progrium/consul -server -advertise $(hostname -i) -bootstrap-expect 3

-v /mnt:/data请注意,这是 consul 存储的所有数据所在的标志。对我来说,它位于/mnt. 在此目录下,您将找到其他几个目录。

config raft serf services tmp

进入services,您将看到包含您服务的 json 信息的文件,找到任何包含僵尸信息的文件并将其删除。然后重启领事。然后对集群中具有僵尸的每个服务器重复此操作。

于 2016-06-07T22:34:37.590 回答
1

在 Consul 集群中,代理被认为是权威的。如果您使用 HTTP Api /v1/catalog/deregister 端点取消注册服务,只要其他代理知道该服务,它就会不断返回。这就是 Gossip 协议的工作方式。

如果您希望服务立即消失,您需要在终止节点上的服务之前发出consul leave以正确注销主机代理。

于 2015-12-12T19:04:22.703 回答
1

这是 Consul 和 registrator 的问题之一,如果该服务没有与之关联的检查,则该服务将一直存在,直到它被取消注册并“活跃”。因此,最好让服务也注册健康检查。这样,如果注册者搞砸并忘记取消注册服务(我看到这种情况经常发生),它们至少会变得至关重要。亚历克斯的回答是,删除领事的数据/服务目录中的文件(然后领事重新加载)肯定可以删除服务,但如果容器仍然存在并正在运行,注册者将重新添加它们。显然,较新的注册器版本更擅长清理,但我的成功参差不齐。现在我根本不使用 registrator,因为它没有添加健康检查。

于 2016-08-31T17:25:51.033 回答
0

尝试切换到 v5

docker run -d --name agent-registrator -v /var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:v5 -internal consul://172.16.0.4:8500

于 2015-09-01T10:02:56.700 回答