今天在公司部署开发环境的中间件。
目前有三个服务,mongodb nginx yapi,由于是开发环境,为了简单部署所以直接使用了docker容器来部署,并把mongodb的数据目录,nginx配置文件映射到宿主机。
我首先创建了一个volume用来存储mongodb的数据,防止容器被删除后数据丢失
sudo docker volume create mongodbdata
在
docker-compose.yml
中用volumes挂载到
/data/db
然后我创建了两个网络
sudo docker network create n-nginx
sudo docker network create n-mongodb
分别作为mongodb的服务网络和nginx转发时可以接触的网络
yapi服务同时加入了这两个网络,这使得它既可以连接内网中的mongodb 又可以被nginx转发到宿主机的端口上对外提供服务
(yapi 不能配置context Path也是一个坑,这个有机会再说)
然后问题来了,我想调试一下我内网中mongodb的数据,但是我的mongodb容器并没有对外开放任何一个端口,但是我是临时想开一个这个外网访问,又不想去改docker-compose。
我查询了一下百度,发现很多人会直接去配置ip-tables来将子网的端口放开,看到那一大堆配置我直接就放弃了,不仅不优雅,也不是临时访问一下这个需求的解决方案。
于是我继续搜索,发现有人提到这个socat,于是我去github主页看了一下,果然它的第二个use case就是我想要实现的效果,于是我就果断了试了一下
sudo docker run --publish 27017:27017 --link mongodb:target --net n-mongodb alpine/socat tcp-listen:27017,fork,reuseaddr tcp-connect:target:27017
用mongodb连接工具试了一下,果然就成功了。
如果加了-d 参数,这个容器可以以守护进程的方式一直运行,可以长期提供服务。不仅仅是一个临时的方案。当然如果是要永远开启,建议还是直接修改容器的启动参数。
另外,一个docker-compose.yml文件中配置多个外部网络好像有好几种实现方法,我贴一下我的实现方法,这一块我也不是特别明白,但是这样确定可用
services:
network:
- n-mongodb
- n-nginx
networks:
n-mongodb:
external: true
n-nginx:
external: true
如果是只连一个外部网络,网上的帖子还有另一种配置,我试了也是可用的
networks:
default:
external:
name: n-nginx
GitHub - alpine-docker/socat: Run socat command in alpine container
下面我来介绍下docker通过端口映射来实现网络访问
一、从外部访问容器应用
在启动容器的时候,如果不指定对应参数,在容器外部是无法通过网络来访问容器内的网络应用和服务的。
当容器中运行一些网络应用,要让外部访问这些应用时,可以通过-P或-p参数指定端口映射。
先来说说p和P吧
-p 可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器
-P 它会随机映射一个端口至容器内部开放的网络端口(范围不详,似乎都上万)
先申明一下,我这边
client ip address 为192.168.0.225
通过以上命令创建新的镜像文件,run -p参数开放新端口出来;实际使用上不方便。
宿主机(host)上修改iptables 规则,开放容器的响应端口;参考网上的命令
iptables -t nat -A DOCKER -p tcp -dport 8080 -j DNAT --to-destination 172.17.0.2:8080
当我们创建nginx镜像时,并且启动nginx时,我们只能在容器内部区访问n
开放docker正在运行镜像的端口
下载docker
docker从0-1docker下载可以直接查看之前写的一个帖子。介意使用Linux或者Mac去下载,因为使用Windows会有一些问题
修改端口
关闭我们要修改端口的镜像
docker ps // 查看当前有没有启动的镜像,如果没有就如下图
docker stop 容器的ID
进入docker文件目录,
cd ~/Library/Containers/com.docker.docker
使用screen进行登陆
cd /Data/vms/0
Docker 端口映射即映射容器内应用的服务端口到本机宿主机器。
当容器中运行一些网络应用,要让外部访问这些应用时,可以通过 -P 或 -p 参数两种方式来指定端口映射。
1. 随机映射
使用 -P 参数时,Docker 会随机映射一个端口到内部容器开放的网络端口,如下开启一个 nginx 服务:
$ docker run -d -P nginx
e93349d539119dc48dc841e117f6388d6afa6a6065b75a5b4aedaf5fb2a051fc
$ docker ps
CONTAINER ID IMAGE COMMAN