0%

ERROR network conf_default id has active endpoints

现象

表象是容器无法 stop, restart, rm , 登录主机后执行

1
2
3
4
[root@orderer0 /home/blockchain/peer0.org1/conf]# docker-compose down
Stopping peer0.org1 ... done
Removing network conf_default
ERROR: network conf_default id a3a2c67620436cc49e406a52ad724df3cbe93f965b7e4427b36ed811075d2e06 has active endpoints

临时处理

  1. 检查 network

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    [root@orderer0 /home/blockchain]# docker network inspect conf_default
    [
    {
    "Name": "conf_default",
    "Id": "412177b0cf14414b191fc99ab4411d65c201e52424217476eb6b5cc861a5b603",
    "Created": "2019-11-21T22:08:45.523133411+08:00",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
    "Driver": "default",
    "Options": null,
    "Config": [
    {
    "Subnet": "172.21.0.0/16",
    "Gateway": "172.21.0.1"
    }
    ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
    "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {
    "19ffaa8a2c03891c1883f962e0076a04ec9461bfc8364d60052e34e5464e9762": {
    "Name": "peer0.org1", # 关联的 Containers name
    "EndpointID": "1f82857982ba62ce6003e15bb140686a24859ca7374bca110ab7e481af56c855",
    "MacAddress": "02:42:ac:15:00:02",
    "IPv4Address": "172.21.0.2/16",
    "IPv6Address": ""
    },
    "9c7dd8270317bb09aac306a9aa952b05fff5fa0a65ef3f4f7c4e1a5d8c03bf1e": {
    "Name": "dev-peer0.org1.finblockchain.cn-fft-2.0.0", # 关联的 Containers name
    "EndpointID": "33dbba6e9cc513d4e0b293fa7f2d4415bb1c13aa4d1c0c87f86d2063409b7bd1",
    "MacAddress": "02:42:ac:15:00:03",
    "IPv4Address": "172.21.0.3/16",
    "IPv6Address": ""
    }
    },
    "Options": {},
    "Labels": {}
    }
    ]
  2. 断开关联的 Containers name 网络

    1
    2
    # docker network disconnect -f net_default peer0.org1
    # docker network disconnect -f net_default dev-peer0.org1.finblockchain.cn-fft-2.0.0
  3. 然后就可以正常执行

    1
    # docker-compose down

    根本解决

    docker.service中加上:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [Service]
    MountFlags=slave
    ```
    来保证 docker 及 container 运行在 私有 的 **mount namespace** 上。当 docker 以这种方式启动时,可以使用 `grep /mnt /proc/self/mountinfo` 来检测以这种方式启动的容器确实看不到 **mount point** 了,而之前遗留的挂载点仍然可以看到。

    很多线上机器已经跑着业务容器不能重启 **docker daemon** 怎么办?

    在生产中,需要尽可能保证所有的操作 不影响正在运行的业务容器。

    所以,在已有条件下,既不能停止 nginx,又不能重启 **docker daemon**,唯一的方法只有在 `docker-compose down` 出错的情况下通过执行
    ```sh
    # docker rm -f $(docker ps -a -q -f status=dead)

    来强制删除 dead container 了。虽然仍然会有错误信息提示,但是可以看到 Dead container 确实被删除了。之后可以正常运行 docker-compose up -d

有没有方法可以在不影响业务容器的前提下重新配置 docker daemon 呢?

docker 从 1.12.0 开始支持在 不重启 container 的情况下重启 docker daemon,只需要在 docker daemon 启动时增加 --live-restore=true 这个参数。可惜的是,该参数直到目前仍不支持 daemon reload(类似 nginx 的 reload 和 restart),只能重启 dockerd 后生效

本质

挂载点泄露实际上是 RHEL/CentOS 内核的一个 bug,目前预计会在 RHEL7.4 kernel 中修复

目前在 RHEL/CentOS 下需要在 docker.service 中增加 MountFlags=slave 来保证 mount namespace 是私有的,不会造成挂载点泄露。

另外,挂载点泄露在各种 storage driver 中都存在,比如最常见的 devicemeppaeroverlay

但是,目前 RHEL/CentOS 版本下 MountFlags=slave--live-restore 两个给力的参数不能同时存在。因为 MountFlags=slave 会导致 docker daemon 每次重启时私有挂载命名空间都会发生变化,而 --live-restore 又相当于使得容器持有了变化之前的旧的挂载点信息,因此,当重启 docker daemon 之后,执行 docker exec 试图进入容器时会报错:

rpc error: code = 13 desc = invalid header field value "oci runtime error: exec failed: container_linux.go:247: starting container process caused \"process_linux.go:75: starting setns process caused \\\"fork/exec /proc/self/exe: no such file or directory\\\"\"\n"

值得一提的是,虽然无法进入容器,但是容器依旧工作正常并且 docker logs 也没问题。

坚持原创技术分享,您的支持将鼓励我继续创作!