「Docker」- 配置端口监听(以允许 Docker Engine API 访问) @20210316

问题描述

我们需要调用 Docker Engine API 以获取某些数据,主要用于调试及查看。(在程序集成时,应该使用类库,而不是直接调用接口)

但是 Docker 默认监听 Unix Domain Socket 文件,因此无法使用 Postman 接口调试工具。解决方法是使 Docker 服务监听 TCP 端口。

该笔记将记录:如何使 Docker 服务监听 TCP 端口。

注意事项

虽然使用 Insomnia Designer 可以访问 Unix Domain Socket 文件,但是开启 Docker 服务的 TCP 监听还是有意义的。

在下面的演示中,我们同时进行 UDS 与 TCP 监听,可以根据实际情况进行调整。

我们使用 Debian GNU/Linux 10 (buster) 作为测试环境,但也应该适用于其他 Linux 发行版。

解决方法

我们有以下几种方案:
1)修改 docker.service 配置;(适用于在安装时设置,此时没有正在运行的容器)
2)启用 docker live-restore 配置,然后再修改;(适用于生产环境)
3)使用 Nginx 反向代理;(该方案对于 docker 的无侵入性,且可操作性强)

方案一、修改 docker.service 配置(常规方法)

// 修改 docker.service 配置,添加如下配置

# systemctl edit docker.service
[Service]
ExecStart=
ExecStart=/usr/sbin/dockerd -H fd:// -H tcp://127.0.0.1:2375 $DOCKER_OPTS

// 重启服务

# systemctl restart docker.service

// 测试接口

# curl http://127.0.0.1:2375/v1.39/containers/json
[]

注意事项:
1)我们只监听 127.0.0.1:2375 端口以测试,所以外部主机无法访问。如果需要外部主机访问,可以修改为 0.0.0.0:2375 地址,但是要做好网络安全设置,或者启用 TLS 认证。
2)在测试主机中,由于没有运行中的容器,所以最后的测试接口返回空数组([]);

方案二、针对生产环境(复杂操作,但推荐)

Enable TCP port 2375 for external connection to Docker
dockerd | Docker Documentation
Keep containers alive during daemon downtime | Docker Documentation
How do I expose the docker API over TCP? - Server Fault
sudo - How to resolve "service start-limit-hit" - Ask Ubuntu

在生产环境中,我们不能重启 Docker 服务,否则容器会停止。当容器停止后,我们不仅要处理被停止的容器,可能还要处理其他连带问题(比如容器启动依赖顺序)。

操作步骤

下面是解决该问题的操作步骤(请理解步骤含义之后,再进行操作):

// 开启 live-restart 功能,使 docker 的重启不会导致 containerd 结束容器

# vim /etc/docker/daemon.json
{
    ...
    "live-restore": true,
    ...
}

// 使 live-restore 配置生效

# systemctl reload docker.service

// 追加配置,使其 dockerd 监控 TCP(新增)与 UDS(原有)

# vim /etc/docker/daemon.json
{
    ...
    "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
    ...
}

// 修改 docker.service 文件,追加如下配置。这里只是删除  -H fd:// 选项(因为 -H 不能与 hosts 共存)

# systemctl edit docker.service
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock

// 重启服务
// 注意事项:在重启时,服务会中断(因为 docker-proxy 重启,但是并不是因为容器停止)

# systemctl restart docker.service

// 访问验证

# curl http://127.0.0.1:2375/v1.39/containers/json

解释说明

这里需要明白以下几点:
1)docker client => docker server => containerd => our containers
2)而 live-restore 的作用就是“剥离” dockerd 与 containerd 服务的影响关系;

在启用 live-restore 特性时,使用 killall -KILL dockerd 服务,容器并不会停止,停止的只是 dockerd 与 docker-proxy 服务,所以会出现中断(这是是网络中断)。

但是当 dockerd 再次启动时,1)会连接 containerd 服务,继续管理原有容器,2)启动 docker-proxy 服务,即网络恢复。

注意事项

所以该方法的缺点就是「短暂的服务中断」(中断时间约为 systemctl restart docker.service 重启时间),但是总好过「直接重启 docker 服务再处理停止的容器」。

docker.service: Failed with result 'start-limit-hit'.
1)通常不会遇到该错误,该错误是因为我们频繁执行 systemctl restart docker.service 进行验证。
2)可以执行 systemctl reset-failed docker.service 进行解决

方案三、使用 Nginx 代理

修改 docker.service 的麻烦在于会影响升级,即使使用 systemctl edit docker.service 也有可能存在该问题。

此时,可以通过 Nginx 反向代理 Unix Socket 解决(这里不再展开详细说明,根据实际情况进行配置即可):

server {
	listen 127.0.0.1:2375;
	location / {
		proxy_pass http://unix:/var/run/docker.sock:/;
	}
}

该方法完全无需修改 Docker 任何配置,但是引入 Nginx 也许会增加些复杂性。

此外,Nginx 需要具有访问 /var/run/docker.sock 权限。在 Ubuntu 18.04 中,通过将 www-data 加入 docker 组来授权(执行 adduser www-data nginx 命令)。

附加说明

关于 fd:// 参数:它并不是告诉 Docker 打开 UDS 监听,而是 systemd 处理并传递给 Docker 服务。可以在命令行中直接执行 ExecStart 命令进行验证。—— sockets - what does fd:// mean exactly in dockerd -H fd:// - Stack Overflow

参考文献

Develop with Docker Engine API | Docker Documentation
api - How to make docker listening to unix and TCP socket under centos with systemd - Stack Overflow
Proxy a unix socket HTTP server to a tcp port using nginx.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: docker-compose 端口映射是指将容器内部的端口映射到宿主机上的端口,实现容器与宿主机之间的通信。在docker-compose.yml文件中,可以通过配置ports关键字实现端口映射。 具体使用方法如下: 1. 在docker-compose.yml文件中的对应服务的配置下方添加ports关键字。 2. 在ports后紧跟着宿主机端口:容器内部端口的形式,例如:"3000:80",表示将容器内部的80端口映射到宿主机上的3000端口。 3. 可以配置多个端口映射,使用空格分隔开,例如:"3000:80 8080:8080",表示将容器内部的80端口映射到宿主机上的3000端口,并将容器内部的8080端口映射到宿主机上的8080端口。 4. 使用端口映射后,可以通过访问宿主机的对应端口来与容器进行通信,例如,在上述例子中,可以通过访问localhost:3000来访问容器中的应用程序。 需要注意的是,端口映射只是实现了容器与宿主机之间的通信,但并没有修改容器内部的网络配置。因此,容器内部的应用程序仍然需要监听容器内部的端口。 总之,docker-compose的端口映射为我们提供了一种简便的方式来实现容器与宿主机之间的网络通信,方便我们进行开发和测试工作。 ### 回答2: Docker-compose端口映射是一种在Docker容器和宿主机之间建立端口映射的方法。通过端口映射,可以将容器内部的服务发布到宿主机的指定端口上,从而可以通过宿主机的IP地址和映射的端口访问容器内的服务。 在docker-compose.yml文件中,可以使用"ports"关键字来定义端口映射。端口映射的格式为"宿主机端口:容器端口",例如"8080:80"表示将容器的80端口映射到宿主机的8080端口上。 通过端口映射,可以实现以下几点: 1. 容器内的服务可以通过宿主机的IP地址和映射的端口进行访问。例如,如果将容器的80端口映射到宿主机的8080端口上,那么可以使用"http://宿主机IP地址:8080"来访问容器内的服务。 2. 可以实现容器容器之间的通信。如果多个容器在同一网络中,可以通过容器的名称和映射的端口进行通信。 3. 可以将多个容器的服务映射到宿主机的不同端口上。通过不同的端口映射,可以同时在宿主机上运行多个容器,并通过不同的端口访问它们的服务。 需要注意的是,端口映射只是一种将容器内部的端口映射到宿主机端口上的方法,并不能改变容器内部的服务监听端口。因此,在容器内部的服务中仍需要使用容器内部的端口来进行监听访问。而端口映射则是为了方便通过宿主机进行访问

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值