docker容器创建后新增端口映射

需求场景:目前所做的动态插桩工具需要对 docker 容器中的 java web程序进行插桩,动态插桩工具能够根据 java web程序使用的端口号自动查找 web 程序的进程号,即 pid 。查找 pid 的时候使用了 netstat 命令,而做实验的 docker 容器 demo 中默认是不带有该工具的。

1、创建的docker容器中没有netstat命令的解决方式

首先进入docker容器,此处不举例了,然后执行以下命令

apt-get update
apt-get install net-tools

2、基于已有的docker容器新增端口映射

因为所做的项目有些涉密,对方应该不允许对他们的docker配置文件进行修改,此处采用曲线救国方法,使用iptables命令

(1) 根据容器id获取容器ip

需要注意容器每次重新启动时,容器ip可能会发生变化,而容器id不会改变

docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container-ID>

结果如下,需要注意,在创建这个14bd容器时,并没有指定宿主机与该容器的端口映射规则
在这里插入图片描述

(2)iptable转发端口

将宿主机的8745端口映射到容器的8745端口,注意该规则加到了nat中名字为 DOCKER 的chain中

iptables -t nat -A  DOCKER -p tcp --dport 8745 -j DNAT --to-destination 172.16.10.4:8745

iptables新增的端口映射规则,不会体现在 docker ps 命令中,即docker ps显示的结果不变,如图
在这里插入图片描述
此处需要使用以下命令来查看刚刚新增的规则

iptables -t nat -nvL --line-numbers

指令参数解释

-t选项指定要操作的表,省略"-t 表名"时,默认表示操作filter表
-L表示列出规则,即查看规则
-v显示更多信息
-n不对地址进行名称反解,直接显示ip地址
--line-numbers 或--line,显示规则的序号
-x计数器中的信息显示为精确的计数值,而不是经过可读优化的计数值。

docker容器创建后新增端口映射_第1张图片
由图中可以看出映射规则确实增加了。(8413,8144是调用插桩工具的java web程序,添加方式跟上面所讲的相同,此处不再赘述)

(3)删除iptables中指定的映射规则

通用方法

语法规则:iptables -t 表名 -D chain rulenum [options]

其中: chain 是链的意思,就是INPUT FORWARD 之类的定语,在该例子中为 DOCKER
rulenum 是该条规则的编号。 即指定–line-numbers参数显示的编号

此处删除刚刚新增的8745端口映射,语句为

iptables -t nat -D DOCKER 5

docker容器创建后新增端口映射_第2张图片

另一种方法

第二种办法是 -A 命令的映射,不过用-D替换-A。当你的链中规则很复杂,而你不想计算它们的编号的时候这就十分有用了。
也就是说,你如何一开始时用iptables -A…. 语句定义了一个规则,那么删除此条规则时直接用 -D 来代替- A, 其余的都不变即可,而不需要什么编号了。

即创建时使用如下指令

iptables -t nat -A  DOCKER -p tcp --dport 8745 -j DNAT --to-destination 172.16.10.4:8745

删除时使用以下指令即可

iptables -t nat -D  DOCKER -p tcp --dport 8745 -j DNAT --to-destination 172.16.10.4:8745

docker容器创建后新增端口映射_第3张图片
docker容器创建后新增端口映射_第4张图片

3、将插桩工具(projectInsert)与调用插桩工具的JavaWeb程序(executecall.jar)复制进docker容器中

以下内容有些文不对题,只是个人为了较完整的记录整个流程
docker复制命令

语法规则 docker cp [宿主机文件路径] [容器id]:[容器中存放该文件的路径]
docker cp projectInsert 14b:/
docker cp executecall.jar 14b:/

4、进入待插桩的docker容器,后台方式启动executecall.jar

docker exec -it 14b /bin/bash
touch log.txt
nohup java -jar executecall.jar >log.txt 2>&1 &

executecall.jar日志内容会输出到log.txt文件中

停止executecall.jar程序

(1)可以直接重新启动docker容器

(2)使用kill命令,结束掉executecall.jar进程

注:8143为excutecall.jar使用的端口号

netstat -anp | grep 8143
kill -9 PID

参考的文章

  1. 【Docker】Docker容器中安装netstat命令
  2. 如何获取 docker 容器(container)的 ip 地址
  3. 修改docker容器端口映射的方法
  4. iptables 2: 规则的查看、添加、删除、修改
  5. iptables规则的删除-怎么删除一条已有的iptables规则
  6. CentOS里用命令行运行不挂断的Java程序

你可能感兴趣的:(linux与docker学习)